def test_verify_correctness(testerchain, agency, token_economics, test_registry): agent = ContractAgency.get_agent( WorkLockAgent, registry=test_registry) # type: WorkLockAgent caller = testerchain.client.accounts[0] assert not agent.bidders_checked() assert agent.estimate_verifying_correctness(gas_limit=100000) == 10 receipt = agent.verify_bidding_correctness(checksum_address=caller, gas_limit=100000) assert receipt['status'] == 1 assert agent.bidders_checked() assert agent.is_claiming_available()
def test_force_refund(testerchain, agency, token_economics, test_registry): agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) caller = testerchain.client.accounts[0] with pytest.raises(BlockchainInterface.InterfaceError): _receipt = agent.verify_bidding_correctness(checksum_address=caller, gas_limit=100000) receipt = agent.force_refund(checksum_address=caller, addresses=testerchain.client.accounts[2:11]) assert receipt['status'] == 1 assert agent.get_available_compensation(testerchain.client.accounts[2]) > 0
def test_nucypher_deploy_inspect_fully_deployed(click_runner, testerchain, agency): local_registry = LocalContractRegistry(filepath=MOCK_REGISTRY_FILEPATH) staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=local_registry) policy_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=local_registry) adjudicator_agent = ContractAgency.get_agent(AdjudicatorAgent, registry=local_registry) status_command = ('inspect', '--registry-infile', MOCK_REGISTRY_FILEPATH, '--provider', TEST_PROVIDER_URI, '--poa') result = click_runner.invoke(deploy, status_command, catch_exceptions=False) assert result.exit_code == 0 assert staking_agent.owner in result.output assert policy_agent.owner in result.output assert adjudicator_agent.owner in result.output
def test_cancel_bid(testerchain, agency, token_economics, test_registry): bidder = testerchain.client.accounts[1] agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) assert agent.get_deposited_eth(bidder) # Bid receipt = agent.cancel_bid(bidder) # Cancel assert receipt['status'] == 1 assert not agent.get_deposited_eth(bidder) # No more bid # Can't cancel a bid twice in a row with pytest.raises((TransactionFailed, ValueError)): _receipt = agent.cancel_bid(bidder)
def test_stake_detach_worker(click_runner, testerchain, token_economics, beneficiary, preallocation_escrow_agent, mock_allocation_registry, manual_worker, test_registry, individual_allocation, stakeholder_configuration_file_location): staker_address = preallocation_escrow_agent.principal_contract.address staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) assert manual_worker == staking_agent.get_worker_from_staker( staker_address=staker_address) testerchain.time_travel(periods=token_economics.minimum_worker_periods) init_args = ('stake', 'detach-worker', '--config-file', stakeholder_configuration_file_location, '--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, '--force') result = click_runner.invoke(nucypher_cli, init_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 staker = Staker(is_me=True, checksum_address=beneficiary, individual_allocation=individual_allocation, registry=test_registry) assert not staker.worker_address # Ok ok, let's set the worker again. init_args = ('stake', 'set-worker', '--config-file', stakeholder_configuration_file_location, '--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, '--worker-address', manual_worker, '--force') user_input = INSECURE_DEVELOPMENT_PASSWORD result = click_runner.invoke(nucypher_cli, init_args, input=user_input, catch_exceptions=False) assert result.exit_code == 0 staker = Staker(is_me=True, checksum_address=beneficiary, individual_allocation=individual_allocation, registry=test_registry) assert staker.worker_address == manual_worker
def paint_worklock_status(emitter, registry: BaseContractRegistry): from maya import MayaDT worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=registry) blockchain = worklock_agent.blockchain # Agency token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=registry) # Time start = MayaDT(worklock_agent.contract.functions.startBidDate().call()) end = MayaDT(worklock_agent.contract.functions.endBidDate().call()) duration = end - start remaining = end - maya.now() # TODO: Include calculated refund and deposit rates payload = f""" Time ====================================================== Start Date ........ {start} End Date .......... {end} Duration .......... {duration} Time Remaining .... {remaining} Economics ====================================================== ETH Pool .......... {blockchain.client.get_balance(worklock_agent.contract_address)} ETH Supply ........ {worklock_agent.get_eth_supply()} Lot Size .......... {NU.from_nunits(worklock_agent.lot_value)} Unclaimed Tokens .. {worklock_agent.get_unclaimed_tokens()} Boosting Refund ... {worklock_agent.contract.functions.boostingRefund().call()} Slowing Refund .... {worklock_agent.contract.functions.SLOWING_REFUND().call()} Refund Rate ....... {worklock_agent.get_refund_rate()} Deposit Rate ...... {worklock_agent.get_deposit_rate()} """ emitter.echo(payload) return
def transfer_tokens( # Admin Actor Options provider_uri, contract_name, config_root, poa, force, etherscan, hw_wallet, deployer_address, registry_infile, registry_outfile, dev, # Other target_address, value): """ Transfer tokens from contract's owner address to another address """ # Init emitter = StdoutEmitter() _ensure_config_root(config_root) deployer_interface = _initialize_blockchain(poa, provider_uri) # Warnings _pre_launch_warnings(emitter, etherscan, hw_wallet) # # Make Authenticated Deployment Actor # ADMINISTRATOR, deployer_address, local_registry = _make_authenticated_deployment_actor( emitter, provider_uri, deployer_address, deployer_interface, contract_name, registry_infile, registry_outfile, hw_wallet, dev, force) token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=local_registry) if not target_address: target_address = click.prompt("Enter recipient's checksum address", type=EIP55_CHECKSUM_ADDRESS) if not value: stake_value_range = click.FloatRange(min=0, clamp=False) value = NU.from_tokens( click.prompt(f"Enter value in NU", type=stake_value_range)) click.confirm( f"Transfer {value} from {deployer_address} to {target_address}?", abort=True) receipt = token_agent.transfer(amount=value, sender_address=deployer_address, target_address=target_address) emitter.echo(f"OK | Receipt: {receipt['transactionHash'].hex()}")
def test_refund(click_runner, testerchain, agency_local_registry, token_economics): bidder = testerchain.unassigned_accounts[1] worker_address = testerchain.unassigned_accounts[-1] # # WorkLock Staker-Worker # worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry) # Bidder is now STAKER. Bond a worker. staker = Staker(is_me=True, checksum_address=bidder, registry=agency_local_registry) receipt = staker.set_worker(worker_address=worker_address) assert receipt['status'] == 1 worker = Ursula(is_me=True, registry=agency_local_registry, checksum_address=bidder, worker_address=worker_address, rest_host=MOCK_IP_ADDRESS, rest_port=select_test_port()) # Ensure there is work to do remaining_work = worklock_agent.get_remaining_work(checksum_address=bidder) assert remaining_work > 0 # Do some work for i in range(3): receipt = worker.confirm_activity() assert receipt['status'] == 1 testerchain.time_travel(periods=1) command = ('refund', '--bidder-address', bidder, '--registry-filepath', agency_local_registry.filepath, '--provider', TEST_PROVIDER_URI, '--poa', '--force') user_input = f'{INSECURE_DEVELOPMENT_PASSWORD}\n' + 'Y\n' result = click_runner.invoke(worklock, command, input=user_input, catch_exceptions=False) assert result.exit_code == 0 # Less work to do... new_remaining_work = worklock_agent.get_remaining_work( checksum_address=bidder) assert new_remaining_work < remaining_work
def generate_node_table_components(node_info: dict, registry) -> dict: identity = html.Td(children=html.Div([ html.A(node_info['nickname'], href=f'https://{node_info["rest_url"]}/status', target='_blank') ])) # Fleet State fleet_state_div = [] fleet_state_icon = node_info['fleet_state_icon'] if fleet_state_icon is not UNKNOWN_FLEET_STATE: icon_list = node_info['fleet_state_icon'] fleet_state_div = icon_list fleet_state = html.Td(children=html.Div(fleet_state_div)) staker_address = node_info['staker_address'] # Blockchainy (TODO) staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry) current_period = staking_agent.get_current_period() last_confirmed_period = staking_agent.get_last_active_period( staker_address) status = get_node_status(staking_agent, staker_address, current_period, last_confirmed_period) etherscan_url = f'https://goerli.etherscan.io/address/{node_info["staker_address"]}' try: slang_last_seen = MayaDT.from_rfc3339( node_info['last_seen']).slang_time() except ParserError: slang_last_seen = node_info['last_seen'] components = { 'Status': status, 'Checksum': html.Td( html.A(f'{node_info["staker_address"][:10]}...', href=etherscan_url, target='_blank')), 'Nickname': identity, 'Launched': html.Td(node_info['timestamp']), 'Last Seen': html.Td([slang_last_seen, f" | Period {last_confirmed_period}"]), 'Fleet State': fleet_state } return components
def test_all_blockchain_ursulas_know_about_all_other_ursulas(blockchain_ursulas, agency, test_registry): """ Once launched, all Ursulas know about - and can help locate - all other Ursulas in the network. """ staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) for address in staking_agent.swarm(): for propagating_ursula in blockchain_ursulas[:1]: # Last Ursula is not staking if address == propagating_ursula.checksum_address: continue else: assert address in propagating_ursula.known_nodes.addresses(), "{} did not know about {}". \ format(propagating_ursula, Nickname.from_seed(address))
def test_withdraw_compensation(testerchain, agency, token_economics, test_registry): bidder_address = testerchain.client.accounts[12] bidder = Bidder(checksum_address=bidder_address, registry=test_registry) worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) assert worklock_agent.get_available_compensation( checksum_address=bidder_address) > 0 receipt = bidder.withdraw_compensation() assert receipt['status'] == 1 assert worklock_agent.get_available_compensation( checksum_address=bidder_address) == 0
def test_deployment_parameters(staking_escrow_deployer, token_deployer, token_economics, test_registry): token_address = staking_escrow_deployer.contract.functions.token().call() assert token_deployer.contract_address == token_address staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) params = staking_agent.staking_parameters() assert token_economics.staking_deployment_parameters[2:] == params[2:] assert token_economics.staking_deployment_parameters[1] == params[1] // params[3] assert token_economics.staking_deployment_parameters[0]*60*60 == params[0] # FIXME: Do we really want this?
def test_reward(testerchain, agency, token_economics, test_registry): testerchain.time_travel(hours=1) staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry) _policy_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=test_registry) origin = testerchain.etherbase_account ursula1 = testerchain.ursula_account(0) ursula2 = testerchain.ursula_account(1) origin_tpower = TransactingPower(signer=Web3Signer(client=testerchain.client), account=origin) ursula1_tpower = TransactingPower(signer=Web3Signer(client=testerchain.client), account=ursula1) ursula2_tpower = TransactingPower(signer=Web3Signer(client=testerchain.client), account=ursula2) # Prepare one staker prepare_staker(origin_tpower, staking_agent, token_agent, token_economics, ursula1, ursula1_tpower, token_economics.minimum_allowed_locked) prepare_staker(origin_tpower, staking_agent, token_agent, token_economics, ursula2, ursula2_tpower, token_economics.minimum_allowed_locked * 3) # 3x min ursulas_tpowers = [ursula1_tpower, ursula2_tpower] commit_to_next_period(staking_agent, ursulas_tpowers) testerchain.time_travel(periods=1) commit_to_next_period(staking_agent, ursulas_tpowers) assert staking_agent.calculate_staking_reward(staker_address=ursula1) == 0 assert staking_agent.calculate_staking_reward(staker_address=ursula2) == 0 # Get a reward switch = token_economics.first_phase_final_period() for i in range(1, switch + MAX_PERIODS_SECOND_PHASE): testerchain.time_travel(periods=1) commit_to_next_period(staking_agent, ursulas_tpowers) ursula1_rewards = staking_agent.calculate_staking_reward(staker_address=ursula1) ursula2_rewards = staking_agent.calculate_staking_reward(staker_address=ursula2) calculations_reward = token_economics.cumulative_rewards_at_period(i) error = abs((ursula1_rewards + ursula2_rewards - calculations_reward) / calculations_reward) if i <= switch: assert error < MAX_ERROR_FIRST_PHASE else: assert error < MAX_ERROR_SECOND_PHASE
def test_nucypher_status_network(click_runner, testerchain, agency_local_registry): network_command = ('network', '--registry-filepath', agency_local_registry.filepath, '--provider', TEST_PROVIDER_URI, '--poa') result = click_runner.invoke(status, network_command, catch_exceptions=False) assert result.exit_code == 0 token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=agency_local_registry) staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=agency_local_registry) policy_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=agency_local_registry) adjudicator_agent = ContractAgency.get_agent(AdjudicatorAgent, registry=agency_local_registry) agents = (token_agent, staking_agent, policy_agent, adjudicator_agent) for agent in agents: contract_regex = f"^{agent.contract_name} \\.+ {agent.contract_address}" assert re.search(contract_regex, result.output, re.MULTILINE) assert re.search(f"^Provider URI \\.+ {TEST_PROVIDER_URI}", result.output, re.MULTILINE) assert re.search(f"^Current Period \\.+ {staking_agent.get_current_period()}", result.output, re.MULTILINE)
def test_successful_claim(testerchain, agency, token_economics, test_registry): agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) bidder = testerchain.client.accounts[2] tpower = TransactingPower(account=bidder, signer=Web3Signer(testerchain.client)) # Ensure that the bidder is not staking. locked_tokens = staking_agent.get_locked_tokens(staker_address=bidder, periods=5) assert locked_tokens == 0 receipt = agent.claim(transacting_power=tpower) assert receipt['status'] == 1 # Cant claim more than once with pytest.raises(TransactionFailed): _receipt = agent.claim(transacting_power=tpower) # Ensure that the claimant is now the holder of a stake. locked_tokens = staking_agent.get_locked_tokens(staker_address=bidder, periods=5) assert locked_tokens > 0
def retrieve_from_blockchain( registry: BaseContractRegistry) -> BaseEconomics: # Agents token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=registry) staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry) adjudicator_agent = ContractAgency.get_agent(AdjudicatorAgent, registry=registry) worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=registry) # Token total_supply = token_agent.contract.functions.totalSupply().call() reward_supply = staking_agent.contract.functions.getReservedReward( ).call() # Not the "real" initial_supply value because used current reward instead of initial reward initial_supply = total_supply - reward_supply # Staking Escrow staking_parameters = list(staking_agent.staking_parameters()) seconds_per_period = staking_parameters.pop(0) staking_parameters.insert(3, seconds_per_period // 60 // 60) # hours_per_period # Adjudicator slashing_parameters = adjudicator_agent.slashing_parameters() # Worklock worklock_parameters = worklock_agent.worklock_parameters() # Aggregate (order-sensitive) economics_parameters = (initial_supply, total_supply, *staking_parameters, *slashing_parameters, *worklock_parameters) economics = BaseEconomics(*economics_parameters) return economics
def test_cancel_bid(click_runner, testerchain, agency_local_registry, token_economics): bidder = testerchain.unassigned_accounts[0] agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry) command = ('cancel-bid', '--bidder-address', bidder, '--registry-filepath', agency_local_registry.filepath, '--provider', TEST_PROVIDER_URI, '--poa', '--force', '--debug') result = click_runner.invoke(worklock, command, catch_exceptions=False) assert result.exit_code == 0 assert not agent.get_deposited_eth(bidder) # No more bid
def test_get_all_stakes(testerchain, agency, token_economics, test_registry): staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) staker_account = testerchain.unassigned_accounts[0] all_stakes = list( staking_agent.get_all_stakes(staker_address=staker_account)) assert len(all_stakes) == 1 stake_info = all_stakes[0] assert len(stake_info) == 3 start_period, end_period, value = stake_info assert end_period > start_period assert token_economics.maximum_allowed_locked > value > token_economics.minimum_allowed_locked
def test_cancel_after_bidding(testerchain, agency, token_economics, test_registry): # Wait until the bidding window closes... testerchain.time_travel(seconds=token_economics.bidding_duration + 1) bidder = testerchain.client.accounts[0] agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) assert agent.get_deposited_eth(bidder) # Bid receipt = agent.cancel_bid(bidder) # Cancel assert receipt['status'] == 1 assert not agent.get_deposited_eth(bidder) # No more bid
def software_stakeholder(testerchain, agency, stakeholder_config_file_location, test_registry): token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry) # Setup path = stakeholder_config_file_location if path.exists(): path.unlink() # 0xaAa482c790b4301bE18D75A0D1B11B2ACBEF798B stakeholder_private_key = '255f64a948eeb1595b8a2d1e76740f4683eca1c8f1433d13293db9b6e27676cc' address = testerchain.provider.ethereum_tester.add_account( private_key=stakeholder_private_key, password=INSECURE_DEVELOPMENT_PASSWORD) testerchain.provider.ethereum_tester.unlock_account( account=address, password=INSECURE_DEVELOPMENT_PASSWORD) tx = { 'to': address, 'from': testerchain.etherbase_account, 'value': Web3.toWei('1', 'ether') } txhash = testerchain.client.w3.eth.sendTransaction(tx) _receipt = testerchain.wait_for_receipt(txhash) # Mock TransactingPower consumption (Etherbase) transacting_power = TransactingPower( account=testerchain.etherbase_account, signer=Web3Signer(testerchain.client), password=INSECURE_DEVELOPMENT_PASSWORD) token_agent.transfer(amount=NU(200_000, 'NU').to_nunits(), transacting_power=transacting_power, target_address=address) # Create stakeholder from on-chain values given accounts over a web3 provider signer = Web3Signer(testerchain.client) signer.unlock_account(account=address, password=INSECURE_DEVELOPMENT_PASSWORD) stakeholder = StakeHolder(registry=test_registry, domain=TEMPORARY_DOMAIN, signer=signer, initial_address=address) # Teardown yield stakeholder if path.exists(): path.unlink()
def events(general_config, registry_options, contract_name, from_block, to_block, event_name): """Show events associated to NuCypher contracts.""" emitter, registry, blockchain = registry_options.setup( general_config=general_config) if not contract_name: if event_name: raise click.BadOptionUsage( option_name='--event-name', message='--event-name requires --contract-name') contract_names = [ STAKING_ESCROW_CONTRACT_NAME, POLICY_MANAGER_CONTRACT_NAME ] else: contract_names = [contract_name] if from_block is None: # Sketch of logic for getting the approximate block height of current period start, # so by default, this command only shows events of the current period last_block = blockchain.client.block_number staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry) current_period = staking_agent.get_current_period() current_period_start = datetime_at_period( period=current_period, seconds_per_period=staking_agent.staking_parameters()[0], start_of_period=True) seconds_from_midnight = int( (maya.now() - current_period_start).total_seconds()) blocks_from_midnight = seconds_from_midnight // AVERAGE_BLOCK_TIME_IN_SECONDS from_block = last_block - blocks_from_midnight if to_block is None: to_block = 'latest' # TODO: additional input validation for block numbers emitter.echo(f"Showing events from block {from_block} to {to_block}") for contract_name in contract_names: title = f" {contract_name} Events ".center(40, "-") emitter.echo(f"\n{title}\n", bold=True, color='green') agent = ContractAgency.get_agent_by_contract_name( contract_name, registry) names = agent.events.names if not event_name else [event_name] for name in names: emitter.echo(f"{name}:", bold=True, color='yellow') event_method = agent.events[name] for event_record in event_method(from_block=from_block, to_block=to_block): emitter.echo(f" - {event_record}")
def test_withdraw_from_preallocation( click_runner, testerchain, agency_local_registry, stakeholder_configuration_file_location, beneficiary, preallocation_escrow_agent, ): staker_address = preallocation_escrow_agent.principal_contract.address token_agent = ContractAgency.get_agent(agent_class=NucypherTokenAgent, registry=agency_local_registry) tokens_in_contract = NU.from_nunits( token_agent.get_balance(address=staker_address)) locked_preallocation = NU.from_nunits( preallocation_escrow_agent.unvested_tokens) collection_args = ( 'stake', 'preallocation', 'status', '--config-file', stakeholder_configuration_file_location, '--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, ) result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=True) assert result.exit_code == 0 assert f'NU balance: .......... {tokens_in_contract}' in result.output balance_before_collecting = token_agent.get_balance(address=beneficiary) collection_args = ('stake', 'preallocation', 'withdraw', '--config-file', stakeholder_configuration_file_location, '--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=True) assert result.exit_code == 0 assert token_agent.get_balance( address=staker_address) == locked_preallocation withdrawn_amount = tokens_in_contract - locked_preallocation balance_after_collecting = token_agent.get_balance(address=beneficiary) assert balance_after_collecting == balance_before_collecting + withdrawn_amount
def test_claim(testerchain, agency, token_economics, test_registry): bidder_address = testerchain.client.accounts[11] tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client)) bidder = Bidder(registry=test_registry, transacting_power=tpower, domain=TEMPORARY_DOMAIN) staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) # Ensure that the bidder is not staking. locked_tokens = staking_agent.get_locked_tokens( staker_address=bidder.checksum_address, periods=10) assert locked_tokens == 0 receipt = bidder.claim() assert receipt['status'] == 1 # Cant claim more than once with pytest.raises(Bidder.ClaimError): _receipt = bidder.claim() assert bidder.get_deposited_eth > token_economics.worklock_min_allowed_bid assert bidder.completed_work == 0 assert bidder.remaining_work <= token_economics.maximum_allowed_locked // 2 assert bidder.refunded_work == 0 # Ensure that the claimant is now the holder of an unbonded stake. locked_tokens = staking_agent.get_locked_tokens( staker_address=bidder.checksum_address, periods=10) assert locked_tokens <= token_economics.maximum_allowed_locked # Confirm the stake is unbonded worker_address = staking_agent.get_worker_from_staker( staker_address=bidder.checksum_address) assert worker_address == NULL_ADDRESS
def __init__(self, is_me: bool, individual_allocation: IndividualAllocationRegistry = None, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.log = Logger("staker") self.is_me = is_me self.__worker_address = None # Blockchain self.policy_agent = ContractAgency.get_agent( PolicyManagerAgent, registry=self.registry) # type: PolicyManagerAgent self.staking_agent = ContractAgency.get_agent( StakingEscrowAgent, registry=self.registry) # type: StakingEscrowAgent self.economics = TokenEconomicsFactory.get_economics( registry=self.registry) # Staking via contract self.individual_allocation = individual_allocation if self.individual_allocation: self.beneficiary_address = individual_allocation.beneficiary_address self.checksum_address = individual_allocation.contract_address self.preallocation_escrow_agent = PreallocationEscrowAgent( registry=self.registry, allocation_registry=self.individual_allocation, beneficiary=self.beneficiary_address) else: self.beneficiary_address = None self.preallocation_escrow_agent = None # Check stakes self.stakes = StakeList(registry=self.registry, checksum_address=self.checksum_address)
def initialize(self, metrics_prefix: str, registry: CollectorRegistry) -> None: super().initialize(metrics_prefix=metrics_prefix, registry=registry) contract_agent = ContractAgency.get_agent( self.contract_agent_class, registry=self.contract_registry) self.metrics["current_worker_is_me_gauge"] = Gauge( f'{metrics_prefix}_current_worker_is_me', 'Current worker is me', registry=registry) # set initial value self.metrics["current_worker_is_me_gauge"].set( contract_agent.get_worker_from_staker(self.staker_address) == self.operator_address)
def __init__(self, is_me: bool, work_tracker: WorkTracker = None, operator_address: ChecksumAddress = None, *args, **kwargs): super().__init__(*args, **kwargs) self.log = Logger("worker") self.is_me = is_me self.__operator_address = operator_address self.__staking_provider_address = None # set by block_until_ready if is_me: self.application_agent = ContractAgency.get_agent(PREApplicationAgent, registry=self.registry) self.work_tracker = work_tracker or WorkTracker(worker=self)
def test_prolong_stake(agency, testerchain, test_registry): staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) staker_account, worker_account, *other = testerchain.unassigned_accounts stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) original_termination = stakes[0].last_period receipt = staking_agent.prolong_stake(staker_address=staker_account, stake_index=0, periods=1) assert receipt['status'] == 1 # Ensure stake was extended by one period. stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) new_termination = stakes[0].last_period assert new_termination == original_termination + 1
def test_lock_restaking(agency, testerchain, test_registry): staker_account, worker_account, *other = testerchain.unassigned_accounts staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) current_period = staking_agent.get_current_period() terminal_period = current_period + 2 assert staking_agent.is_restaking(staker_account) assert not staking_agent.is_restaking_locked(staker_account) receipt = staking_agent.lock_restaking(staker_account, release_period=terminal_period) assert receipt['status'] == 1, "Transaction Rejected" assert staking_agent.is_restaking_locked(staker_account) testerchain.time_travel(periods=2) # Wait for re-staking lock to be released. assert not staking_agent.is_restaking_locked(staker_account)
def _collect_internal(self) -> None: # info base_payload = { 'app_version': nucypher.__version__, 'teacher_version': str(self.ursula.TEACHER_VERSION), 'host': str(self.ursula.rest_interface), 'domain': self.ursula.domain, 'nickname': str(self.ursula.nickname), 'nickname_icon': self.ursula.nickname_icon, 'fleet_state': str(self.ursula.known_nodes.checksum), 'known_nodes': str(len(self.ursula.known_nodes)) } self.metrics["learning_status"].state( 'running' if self.ursula._learning_task.running else 'stopped') self.metrics["known_nodes_gauge"].set(len(self.ursula.known_nodes)) if self.ursula._availability_tracker and self.ursula._availability_tracker.running: self.metrics["availability_score_gauge"].set( self.ursula._availability_tracker.score) else: self.metrics["availability_score_gauge"].set(-1) try: with self.ursula.datastore.query_by(Workorder) as work_orders: self.metrics["work_orders_gauge"].set(len(work_orders)) except RecordNotFound: self.metrics["work_orders_gauge"].set(0) if not self.ursula.federated_only: staking_agent = ContractAgency.get_agent( StakingEscrowAgent, registry=self.ursula.registry) locked = staking_agent.get_locked_tokens( staker_address=self.ursula.checksum_address, periods=1) missing_commitments = staking_agent.get_missing_commitments( checksum_address=self.ursula.checksum_address) decentralized_payload = { 'provider': str(self.ursula.provider_uri), 'active_stake': str(locked), 'missing_commitments': str(missing_commitments) } base_payload.update(decentralized_payload) try: with self.ursula.datastore.query_by( PolicyArrangement) as policy_arrangements: self.metrics["policies_held_gauge"].set( len(policy_arrangements)) except RecordNotFound: self.metrics["policies_held_gauge"].set(0) self.metrics["host_info"].info(base_payload)
def test_policy_manager_preparation(testerchain, transacting_power, token_economics, test_registry, new_policy_manager_deployer): new_policy_manager_deployer.deploy(deployment_mode=constants.BARE, ignore_deployed=True, transacting_power=transacting_power) # Data is still old, because there is no upgrade yet policy_manager_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=test_registry) assert policy_manager_agent.contract.functions.secondsPerPeriod().call( ) == token_economics.seconds_per_period assert policy_manager_agent.contract.functions.genesisSecondsPerPeriod( ).call() == token_economics.genesis_seconds_per_period