migrate to new role names in progress

pull/2861/head
Damon Ciarelli 2022-01-28 11:21:03 -08:00 committed by Kieran Prasch
parent 32f8513ad7
commit 2669cfdedd
4 changed files with 43 additions and 402 deletions

View File

@ -1282,7 +1282,6 @@ class ThresholdWorker(BaseActor):
self.is_me = is_me
self.__worker_address = worker_address
self.__operator_address = None
# PRE Application
self.pre_application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=self.registry)
@ -1295,21 +1294,21 @@ class ThresholdWorker(BaseActor):
return self.__worker_address
@property
def operator_address(self):
if not self.__operator_address:
self.__operator_address = self.get_operator_address()
return self.__operator_address
def staking_provider_address(self):
if not self.__staking_provider_address:
self.__staking_provider_address = self.get_staking_provider_address()
return self.__staking_provider_address
def get_operator_address(self):
self.__operator_address = self.pre_application_agent.get_operator_from_worker(self.worker_address)
return self.__operator_address
def get_staking_provider_address(self):
self.__staking_provider_address = self.pre_application_agent.get_staking_provider_from_operator(self.worker_address)
return self.__staking_provider_address
@property
def is_confirmed(self):
return self.pre_application_agent.is_worker_confirmed(self.worker_address)
return self.pre_application_agent.is_operator_confirmed(self.worker_address)
def confirm_worker_address(self, fire_and_forget: bool = True) -> Union[TxReceipt, HexBytes]:
txhash_or_receipt = self.pre_application_agent.confirm_worker_address(self.transacting_power, fire_and_forget=fire_and_forget)
def confirm_operator_address(self, fire_and_forget: bool = True) -> Union[TxReceipt, HexBytes]:
txhash_or_receipt = self.pre_application_agent.confirm_operator_address(self.transacting_power, fire_and_forget=fire_and_forget)
return txhash_or_receipt
def block_until_ready(self, poll_rate: int = None, timeout: int = None, feedback_rate: int = None):
@ -1327,11 +1326,11 @@ class ThresholdWorker(BaseActor):
funded, balance = True, Web3.fromWei(ether_balance, 'ether')
emitter.message(f"✓ Worker is funded with {balance} ETH", color='green')
if (not bonded) and (self.get_operator_address() != NULL_ADDRESS):
if (not bonded) and (self.get_staking_provider_address() != NULL_ADDRESS):
bonded = True
emitter.message(f"✓ Worker is bonded to {self.operator_address}", color='green')
emitter.message(f"✓ Worker is bonded to {self.worker_address}", color='green')
else:
emitter.message(f"Worker {self.worker_address } is not bonded to an operator.", color='yellow')
emitter.message(f"Operator {self.worker_address } is not bonded to a staking provider.", color='yellow')
time.sleep(poll_rate)

View File

@ -1029,13 +1029,13 @@ class PREApplicationAgent(EthereumContractAgent):
return result
@contract_api(CONTRACT_CALL)
def get_operator_from_worker(self, worker_address: ChecksumAddress) -> ChecksumAddress:
result = self.contract.functions.operatorFromWorker(worker_address).call()
def get_staking_provider_from_operator(self, worker_address: ChecksumAddress) -> ChecksumAddress:
result = self.contract.functions.stakingProviderFromOperator(worker_address).call()
return result
@contract_api(CONTRACT_CALL)
def get_worker_from_operator(self, operator: ChecksumAddress) -> ChecksumAddress:
result = self.contract.functions.getWorkerFromOperator(operator).call()
def get_operator_from_staking_provider(self, operator: ChecksumAddress) -> ChecksumAddress:
result = self.contract.functions.getOperatorFromStakingProvider(operator).call()
return result
@contract_api(CONTRACT_CALL)
@ -1044,8 +1044,8 @@ class PREApplicationAgent(EthereumContractAgent):
return result
@contract_api(CONTRACT_CALL)
def is_worker_confirmed(self, worker: ChecksumAddress) -> bool:
result = self.contract.functions.isWorkerConfirmed(worker).call()
def is_operator_confirmed(self, worker: ChecksumAddress) -> bool:
result = self.contract.functions.isOperatorConfirmed(worker).call()
return result
@contract_api(CONTRACT_CALL)
@ -1068,7 +1068,7 @@ class PREApplicationAgent(EthereumContractAgent):
#
@contract_api(TRANSACTION)
def confirm_worker_address(self, transacting_power: TransactingPower, fire_and_forget: bool = True) -> TxReceipt:
def confirm_operator_address(self, transacting_power: TransactingPower, fire_and_forget: bool = True) -> TxReceipt:
"""Confirm the sender's account as a worker"""
contract_function: ContractFunction = self.contract.functions.confirmWorkerAddress()
receipt = self.blockchain.send_transaction(contract_function=contract_function,

View File

@ -881,7 +881,7 @@ class SimplePREAppWorkTracker(WorkTrackerBaseClass):
return True
def _final_work_prep_before_transaction(self):
should_continue = self.worker.get_operator_address() != NULL_ADDRESS
should_continue = self.worker.get_staking_provider_address() != NULL_ADDRESS
if should_continue:
return True
self.log.warn('COMMIT PREVENTED - Worker is not bonded to an operator.')
@ -891,9 +891,9 @@ class SimplePREAppWorkTracker(WorkTrackerBaseClass):
"""Makes an initial/replacement worker commitment transaction"""
transacting_power = self.worker.transacting_power
with transacting_power:
txhash = self.worker.confirm_worker_address(fire_and_forget=True) # < --- blockchain WRITE
self.log.info(f"Confirming worker address {self.worker.worker_address} with operator {self.worker.operator_address} - TxHash: {txhash.hex()}")
return txhash
txhash = self.worker.confirm_operator_address(fire_and_forget=True) # < --- blockchain WRITE
self.log.info(f"Confirming worker address {self.worker.worker_address} with staking provider {self.worker.staking_provider_address} - TxHash: {txhash.hex()}")
return txhash
class StakeList(UserList):

View File

@ -39,377 +39,19 @@ CONFIRMATION_SLOT = 1
MIN_WORKER_SECONDS = 24 * 60 * 60
def log(message):
logger.debug(message)
print(message)
def test_bond_worker(testerchain, threshold_staking, pre_application, token_economics):
creator, operator1, operator2, operator3, operator4, worker1, worker2, worker3, owner3, *everyone_else = \
testerchain.client.accounts
min_authorization = token_economics.minimum_allowed_locked
MIN_WORKER_SECONDS = 24 * 60 * 60
worker_log = pre_application.events.WorkerBonded.createFilter(fromBlock='latest')
# Prepare operators: two with intermediary contract and two just an operator
tx = threshold_staking.functions.setRoles(operator1).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setStakes(operator1, min_authorization, 0, 0).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setRoles(operator2).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setStakes(
operator2, min_authorization // 3, min_authorization // 3, min_authorization // 3 - 1).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setRoles(operator3, owner3, everyone_else[0], everyone_else[1]).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setStakes(operator3, 0, min_authorization, 0).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setRoles(operator4).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setStakes(operator4, 0, 0, min_authorization).transact()
testerchain.wait_for_receipt(tx)
assert pre_application.functions.getWorkerFromOperator(operator1).call() == NULL_ADDRESS
assert pre_application.functions.operatorFromWorker(operator1).call() == NULL_ADDRESS
assert pre_application.functions.getWorkerFromOperator(operator2).call() == NULL_ADDRESS
assert pre_application.functions.operatorFromWorker(operator2).call() == NULL_ADDRESS
assert pre_application.functions.getWorkerFromOperator(operator3).call() == NULL_ADDRESS
assert pre_application.functions.operatorFromWorker(operator3).call() == NULL_ADDRESS
assert pre_application.functions.getWorkerFromOperator(operator4).call() == NULL_ADDRESS
assert pre_application.functions.operatorFromWorker(operator4).call() == NULL_ADDRESS
# Operator can't confirm worker address because there is no worker by default
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.confirmWorkerAddress().transact({'from': operator1})
testerchain.wait_for_receipt(tx)
# Operator can't bond another operator as worker
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.bondWorker(operator1, operator2).transact({'from': operator1})
testerchain.wait_for_receipt(tx)
# Operator can't bond worker if stake is less than minimum
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.bondWorker(operator2, worker1).transact({'from': operator2})
testerchain.wait_for_receipt(tx)
# Only operator or stake owner can bond worker
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.bondWorker(operator3, worker1).transact({'from': everyone_else[0]})
testerchain.wait_for_receipt(tx)
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.bondWorker(operator3, worker1).transact({'from': everyone_else[1]})
testerchain.wait_for_receipt(tx)
# Operator bonds worker and now worker can make a confirmation
tx = pre_application.functions.bondWorker(operator3, worker1).transact({'from': owner3})
testerchain.wait_for_receipt(tx)
timestamp = testerchain.w3.eth.getBlock('latest').timestamp
assert pre_application.functions.getWorkerFromOperator(operator3).call() == worker1
assert pre_application.functions.operatorFromWorker(worker1).call() == operator3
assert not pre_application.functions.operatorInfo(operator3).call()[CONFIRMATION_SLOT]
assert not pre_application.functions.isWorkerConfirmed(worker1).call()
assert pre_application.functions.getOperatorsLength().call() == 1
assert pre_application.functions.operators(0).call() == operator3
# No active operators before confirmation
all_locked, operators = pre_application.functions.getActiveOperators(0, 0).call()
assert all_locked == 0
assert len(operators) == 0
tx = pre_application.functions.confirmWorkerAddress().transact({'from': worker1})
testerchain.wait_for_receipt(tx)
assert pre_application.functions.operatorInfo(operator3).call()[CONFIRMATION_SLOT]
assert pre_application.functions.isWorkerConfirmed(worker1).call()
number_of_events = 1
events = worker_log.get_all_entries()
assert len(events) == number_of_events
event_args = events[-1]['args']
assert event_args['operator'] == operator3
assert event_args['worker'] == worker1
assert event_args['startTimestamp'] == timestamp
# After confirmation worker is becoming active
all_locked, operators = pre_application.functions.getActiveOperators(0, 0).call()
assert all_locked == min_authorization
assert len(operators) == 1
assert to_checksum_address(operators[0][0]) == operator3
assert operators[0][1] == min_authorization
# Worker is in use so other operators can't bond him
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.bondWorker(operator4, worker1).transact({'from': operator4})
testerchain.wait_for_receipt(tx)
# # Worker can't be an operator
# tx = threshold_staking.functions.setRoles(worker1).transact()
# testerchain.wait_for_receipt(tx)
# tx = threshold_staking.functions.setStakes(worker1, min_authorization, 0, 0).transact()
# testerchain.wait_for_receipt(tx)
# with pytest.raises((TransactionFailed, ValueError)):
# tx = threshold_staking.functions.increaseAuthorization(
# worker1, min_authorization, pre_application.address).transact({'from': worker1})
# testerchain.wait_for_receipt(tx)
# Can't bond worker twice too soon
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.bondWorker(operator3, worker2).transact({'from': operator3})
testerchain.wait_for_receipt(tx)
# She can't unbond her worker too, until enough time has passed
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.bondWorker(operator3, NULL_ADDRESS).transact({'from': operator3})
testerchain.wait_for_receipt(tx)
# Let's advance some time and unbond the worker
testerchain.time_travel(seconds=MIN_WORKER_SECONDS)
tx = pre_application.functions.bondWorker(operator3, NULL_ADDRESS).transact({'from': operator3})
testerchain.wait_for_receipt(tx)
timestamp = testerchain.w3.eth.getBlock('latest').timestamp
assert pre_application.functions.getWorkerFromOperator(operator3).call() == NULL_ADDRESS
assert pre_application.functions.operatorFromWorker(operator3).call() == NULL_ADDRESS
assert pre_application.functions.operatorFromWorker(worker1).call() == NULL_ADDRESS
assert not pre_application.functions.operatorInfo(operator3).call()[CONFIRMATION_SLOT]
assert not pre_application.functions.isWorkerConfirmed(worker1).call()
assert pre_application.functions.getOperatorsLength().call() == 1
assert pre_application.functions.operators(0).call() == operator3
# Resetting worker removes from active list before next confirmation
all_locked, operators = pre_application.functions.getActiveOperators(0, 0).call()
assert all_locked == 0
assert len(operators) == 0
number_of_events += 1
events = worker_log.get_all_entries()
assert len(events) == number_of_events
event_args = events[-1]['args']
assert event_args['operator'] == operator3
# Now the worker has been unbonded ...
assert event_args['worker'] == NULL_ADDRESS
# ... with a new starting period.
assert event_args['startTimestamp'] == timestamp
# The operator can bond now a new worker, without waiting additional time.
tx = pre_application.functions.bondWorker(operator3, worker2).transact({'from': operator3})
testerchain.wait_for_receipt(tx)
timestamp = testerchain.w3.eth.getBlock('latest').timestamp
assert pre_application.functions.getWorkerFromOperator(operator3).call() == worker2
assert pre_application.functions.operatorFromWorker(worker2).call() == operator3
assert not pre_application.functions.operatorInfo(operator3).call()[CONFIRMATION_SLOT]
assert not pre_application.functions.isWorkerConfirmed(worker2).call()
assert pre_application.functions.getOperatorsLength().call() == 1
assert pre_application.functions.operators(0).call() == operator3
number_of_events += 1
events = worker_log.get_all_entries()
assert len(events) == number_of_events
event_args = events[-1]['args']
assert event_args['operator'] == operator3
assert event_args['worker'] == worker2
assert event_args['startTimestamp'] == timestamp
# Now the previous worker can no longer make a confirmation
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.confirmWorkerAddress().transact({'from': worker1})
testerchain.wait_for_receipt(tx)
# Only new worker can
tx = pre_application.functions.confirmWorkerAddress().transact({'from': worker2})
testerchain.wait_for_receipt(tx)
assert not pre_application.functions.isWorkerConfirmed(worker1).call()
assert pre_application.functions.isWorkerConfirmed(worker2).call()
assert pre_application.functions.operatorInfo(operator3).call()[CONFIRMATION_SLOT]
# Another staker can bond a free worker
tx = pre_application.functions.bondWorker(operator4, worker1).transact({'from': operator4})
testerchain.wait_for_receipt(tx)
timestamp = testerchain.w3.eth.getBlock('latest').timestamp
assert pre_application.functions.getWorkerFromOperator(operator4).call() == worker1
assert pre_application.functions.operatorFromWorker(worker1).call() == operator4
assert not pre_application.functions.isWorkerConfirmed(worker1).call()
assert not pre_application.functions.operatorInfo(operator4).call()[CONFIRMATION_SLOT]
assert pre_application.functions.getOperatorsLength().call() == 2
assert pre_application.functions.operators(1).call() == operator4
number_of_events += 1
events = worker_log.get_all_entries()
assert len(events) == number_of_events
event_args = events[-1]['args']
assert event_args['operator'] == operator4
assert event_args['worker'] == worker1
assert event_args['startTimestamp'] == timestamp
# # The first worker still can't be a staker
# tx = threshold_staking.functions.setRoles(worker1).transact()
# testerchain.wait_for_receipt(tx)
# tx = threshold_staking.functions.setStakes(worker1, min_authorization, 0, 0).transact()
# testerchain.wait_for_receipt(tx)
# with pytest.raises((TransactionFailed, ValueError)):
# tx = threshold_staking.functions.increaseAuthorization(
# worker1, min_authorization, pre_application.address).transact({'from': worker1})
# testerchain.wait_for_receipt(tx)
# Bond worker again
tx = pre_application.functions.confirmWorkerAddress().transact({'from': worker1})
testerchain.wait_for_receipt(tx)
assert pre_application.functions.isWorkerConfirmed(worker1).call()
assert pre_application.functions.operatorInfo(operator4).call()[CONFIRMATION_SLOT]
testerchain.time_travel(seconds=MIN_WORKER_SECONDS)
tx = pre_application.functions.bondWorker(operator4, worker3).transact({'from': operator4})
testerchain.wait_for_receipt(tx)
timestamp = testerchain.w3.eth.getBlock('latest').timestamp
assert pre_application.functions.getWorkerFromOperator(operator4).call() == worker3
assert pre_application.functions.operatorFromWorker(worker3).call() == operator4
assert pre_application.functions.operatorFromWorker(worker1).call() == NULL_ADDRESS
assert not pre_application.functions.isWorkerConfirmed(worker3).call()
assert not pre_application.functions.isWorkerConfirmed(worker1).call()
assert not pre_application.functions.operatorInfo(operator4).call()[CONFIRMATION_SLOT]
assert pre_application.functions.getOperatorsLength().call() == 2
assert pre_application.functions.operators(1).call() == operator4
# Resetting worker removes from active list before next confirmation
all_locked, operators = pre_application.functions.getActiveOperators(1, 0).call()
assert all_locked == 0
assert len(operators) == 0
number_of_events += 1
events = worker_log.get_all_entries()
assert len(events) == number_of_events
event_args = events[-1]['args']
assert event_args['operator'] == operator4
assert event_args['worker'] == worker3
assert event_args['startTimestamp'] == timestamp
# The first worker is free and can deposit tokens and become a staker
tx = threshold_staking.functions.setRoles(worker1).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setStakes(
worker1, min_authorization // 3, min_authorization // 3, min_authorization // 3).transact()
testerchain.wait_for_receipt(tx)
# tx = threshold_staking.functions.increaseAuthorization(
# worker1, min_authorization, pre_application.address).transact({'from': worker1})
# testerchain.wait_for_receipt(tx)
assert pre_application.functions.getWorkerFromOperator(worker1).call() == NULL_ADDRESS
assert pre_application.functions.operatorFromWorker(worker1).call() == NULL_ADDRESS
# Operator can't bond the first worker again because worker is an operator now
testerchain.time_travel(seconds=MIN_WORKER_SECONDS)
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.bondWorker(operator4, worker1).transact({'from': operator4})
testerchain.wait_for_receipt(tx)
# Operator without intermediary contract can bond itself as worker
# (Probably not best idea, but whatever)
tx = pre_application.functions.bondWorker(operator1, operator1).transact({'from': operator1})
testerchain.wait_for_receipt(tx)
timestamp = testerchain.w3.eth.getBlock('latest').timestamp
assert pre_application.functions.getWorkerFromOperator(operator1).call() == operator1
assert pre_application.functions.operatorFromWorker(operator1).call() == operator1
assert pre_application.functions.getOperatorsLength().call() == 3
assert pre_application.functions.operators(2).call() == operator1
number_of_events += 1
events = worker_log.get_all_entries()
assert len(events) == number_of_events
event_args = events[-1]['args']
assert event_args['operator'] == operator1
assert event_args['worker'] == operator1
assert event_args['startTimestamp'] == timestamp
# If stake will be less than minimum then confirmation is not possible
tx = threshold_staking.functions.setStakes(operator1, 0, min_authorization - 1, 0).transact()
testerchain.wait_for_receipt(tx)
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.confirmWorkerAddress().transact({'from': operator1})
testerchain.wait_for_receipt(tx)
# Now operator can make a confirmation
tx = threshold_staking.functions.setStakes(operator1, 0, 0, min_authorization).transact()
testerchain.wait_for_receipt(tx)
tx = pre_application.functions.confirmWorkerAddress().transact({'from': operator1})
testerchain.wait_for_receipt(tx)
# If stake will be less than minimum then operator is not active
all_locked, operators = pre_application.functions.getActiveOperators(0, 0).call()
assert all_locked == 2 * min_authorization
assert len(operators) == 2
assert to_checksum_address(operators[0][0]) == operator3
assert operators[0][1] == min_authorization
assert to_checksum_address(operators[1][0]) == operator1
assert operators[1][1] == min_authorization
tx = threshold_staking.functions.setStakes(operator1, 0, min_authorization - 1, 0).transact()
testerchain.wait_for_receipt(tx)
all_locked, operators = pre_application.functions.getActiveOperators(1, 0).call()
assert all_locked == 0
assert len(operators) == 0
def test_confirm_address(testerchain, threshold_staking, pre_application, token_economics, deploy_contract):
creator, operator, worker, *everyone_else = testerchain.client.accounts
min_authorization = token_economics.minimum_allowed_locked
confirmations_log = pre_application.events.WorkerConfirmed.createFilter(fromBlock='latest')
# Worker must be associated with operator that has minimum amount of tokens
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.confirmWorkerAddress().transact({'from': operator})
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setRoles(operator).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setStakes(operator, min_authorization - 1, 0, 0).transact()
testerchain.wait_for_receipt(tx)
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.confirmWorkerAddress().transact({'from': operator})
testerchain.wait_for_receipt(tx)
# Deploy intermediary contract
intermediary, _ = deploy_contract('Intermediary', pre_application.address)
# Bond contract as a worker
tx = threshold_staking.functions.setStakes(operator, min_authorization, 0, 0).transact()
testerchain.wait_for_receipt(tx)
tx = pre_application.functions.bondWorker(operator, intermediary.address).transact({'from': operator})
testerchain.wait_for_receipt(tx)
# But can't make a confirmation using an intermediary contract
with pytest.raises((TransactionFailed, ValueError)):
tx = intermediary.functions.confirmWorkerAddress().transact({'from': operator})
testerchain.wait_for_receipt(tx)
# Bond worker again and make confirmation
testerchain.time_travel(seconds=MIN_WORKER_SECONDS)
tx = pre_application.functions.bondWorker(operator, worker).transact({'from': operator})
testerchain.wait_for_receipt(tx)
tx = pre_application.functions.confirmWorkerAddress().transact({'from': worker})
testerchain.wait_for_receipt(tx)
assert pre_application.functions.isWorkerConfirmed(worker).call()
assert pre_application.functions.operatorInfo(operator).call()[CONFIRMATION_SLOT]
events = confirmations_log.get_all_entries()
assert len(events) == 1
event_args = events[-1]['args']
assert event_args['operator'] == operator
assert event_args['worker'] == worker
# Can't confirm twice
with pytest.raises((TransactionFailed, ValueError)):
tx = pre_application.functions.confirmWorkerAddress().transact({'from': worker})
testerchain.wait_for_receipt(tx)
def test_ursula_contract_interactions(ursula_decentralized_test_config, testerchain, threshold_staking, pre_application, token_economics, deploy_contract):
creator, operator, worker_address, *everyone_else = testerchain.client.accounts
creator, staking_provider, worker_address, *everyone_else = testerchain.client.accounts
min_authorization = token_economics.minimum_allowed_locked
# make an operators and some stakes
tx = threshold_staking.functions.setRoles(operator).transact()
# make an staking_providers and some stakes
tx = threshold_staking.functions.setRoles(staking_provider).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setStakes(operator, min_authorization, 0, 0).transact()
tx = threshold_staking.functions.setStakes(staking_provider, min_authorization, 0, 0).transact()
testerchain.wait_for_receipt(tx)
# make an ursula.
@ -421,20 +63,20 @@ def test_ursula_contract_interactions(ursula_decentralized_test_config, testerch
# it's not confirmed
assert blockchain_ursula.is_confirmed is False
# it has no operator
assert blockchain_ursula.get_operator_address() == NULL_ADDRESS
# it has no staking provider
assert blockchain_ursula.get_staking_provider_address() == NULL_ADDRESS
# now lets visit stake.nucypher.network and bond this worker
tx = pre_application.functions.bondWorker(operator, worker_address).transact({'from': operator})
tx = pre_application.functions.bondWorker(staking_provider, worker_address).transact({'from': staking_provider})
testerchain.wait_for_receipt(tx)
# now the worker has an operator
assert blockchain_ursula.get_operator_address() == operator
# now the worker has a staking provider
assert blockchain_ursula.get_staking_provider_address() == staking_provider
# but it still isn't confirmed
assert blockchain_ursula.is_confirmed is False
# lets confirm it. It will probably do this automatically in real life...
tx = blockchain_ursula.confirm_worker_address()
tx = blockchain_ursula.confirm_staking_provider_address()
testerchain.wait_for_receipt(tx)
assert blockchain_ursula.is_confirmed is True
@ -443,13 +85,13 @@ def test_ursula_contract_interactions(ursula_decentralized_test_config, testerch
@pytest_twisted.inlineCallbacks
def test_worker_auto_confirm_on_startup(mocker, ursula_decentralized_test_config, testerchain, threshold_staking, pre_application, token_economics, deploy_contract):
creator, operator, worker_address, *everyone_else = testerchain.client.accounts
creator, staking_provider, operator, *everyone_else = testerchain.client.accounts
min_authorization = token_economics.minimum_allowed_locked
# make an operators and some stakes
tx = threshold_staking.functions.setRoles(operator).transact()
# make an staking_providers and some stakes
tx = threshold_staking.functions.setRoles(staking_provider).transact()
testerchain.wait_for_receipt(tx)
tx = threshold_staking.functions.setStakes(operator, min_authorization, 0, 0).transact()
tx = threshold_staking.functions.setStakes(staking_provider, min_authorization, 0, 0).transact()
testerchain.wait_for_receipt(tx)
# Control time
@ -457,15 +99,15 @@ def test_worker_auto_confirm_on_startup(mocker, ursula_decentralized_test_config
WorkTracker.CLOCK = clock
# Bond the Worker and Staker
tx = pre_application.functions.bondWorker(operator, worker_address).transact({'from': operator})
tx = pre_application.functions.bondOperator(staking_provider, operator).transact({'from': staking_provider})
testerchain.wait_for_receipt(tx)
commit_spy = mocker.spy(Worker, 'confirm_worker_address')
commit_spy = mocker.spy(Worker, 'confirm_operator_address')
# replacement_spy = mocker.spy(WorkTracker, '_WorkTracker__fire_replacement_commitment')
# Make the Worker
ursula = ursula_decentralized_test_config.produce(
worker_address=worker_address,
worker_address=operator,
db_filepath=MOCK_DB,
rest_port=9151)
@ -474,7 +116,7 @@ def test_worker_auto_confirm_on_startup(mocker, ursula_decentralized_test_config
start_reactor=False,
worker=True,
eager=True,
block_until_ready=False) # "start" services
block_until_ready=True) # "start" services
def start():
log("Starting Worker for auto confirm address simulation")
@ -524,7 +166,7 @@ def test_worker_auto_confirm_on_startup(mocker, ursula_decentralized_test_config
assert commit_spy.call_count == expected_commitments
# assert replacement_spy.call_count == 0
assert ursula.is_confirmed is True
assert pre_application.functions.isOperatorConfirmed(operator).call()
# Behavioural Test, like a screenplay made of legos