def test_collect_policy_fee(testerchain, agency, policy_meta, token_economics, test_registry): token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry) staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) policy_agent = ContractAgency.get_agent(PolicyManagerAgent, registry=test_registry) staker = policy_meta.addresses[-1] worker = staking_agent.get_worker_from_staker(staker) worker_power = TransactingPower(account=worker, signer=Web3Signer(testerchain.client)) old_eth_balance = token_agent.blockchain.client.get_balance(staker) for _ in range(token_economics.minimum_locked_periods): testerchain.time_travel(periods=1) staking_agent.commit_to_next_period(transacting_power=worker_power) staker_power = TransactingPower(account=staker, signer=Web3Signer(testerchain.client)) receipt = policy_agent.collect_policy_fee(collector_address=staker, transacting_power=staker_power) assert receipt['status'] == 1, "Transaction Rejected" assert receipt['logs'][0]['address'] == policy_agent.contract_address new_eth_balance = token_agent.blockchain.client.get_balance(staker) assert new_eth_balance > old_eth_balance
def test_stake_in_idle_network(testerchain, token_economics, test_registry): # Let's fund a staker first token_agent = NucypherTokenAgent(registry=test_registry) tpower = TransactingPower(account=testerchain.etherbase_account, signer=Web3Signer(testerchain.client)) token_airdrop(transacting_power=tpower, addresses=testerchain.stakers_accounts, token_agent=token_agent, amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT) account = testerchain.stakers_accounts[0] tpower = TransactingPower(account=account, signer=Web3Signer(testerchain.client)) staker = Staker(transacting_power=tpower, domain=TEMPORARY_DOMAIN, registry=test_registry) # Since StakingEscrow hasn't been activated yet, deposit should work but making a commitment must fail amount = token_economics.minimum_allowed_locked periods = token_economics.minimum_locked_periods staker.initialize_stake(amount=amount, lock_periods=periods) staker.bond_worker(account) with pytest.raises((TransactionFailed, ValueError)): staker.staking_agent.commit_to_next_period(transacting_power=tpower)
def test_force_refund(testerchain, agency, token_economics, test_registry): bidder_address = testerchain.client.accounts[0] tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client)) bidder = Bidder(registry=test_registry, transacting_power=tpower, domain=TEMPORARY_DOMAIN) whales = bidder.get_whales() # Simulate force refund new_whales = whales.copy() while new_whales: whales.update(new_whales) whales = bidder._reduce_bids(whales) new_whales = bidder.get_whales() bidder_address = testerchain.client.accounts[1] tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client)) bidder = Bidder(registry=test_registry, transacting_power=tpower, domain=TEMPORARY_DOMAIN) worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) receipt = bidder.force_refund() assert receipt['status'] == 1 assert not bidder.get_whales() assert not worklock_agent.bidders_checked() # Compare off-chain and on-chain calculations min_bid = token_economics.worklock_min_allowed_bid for whale, bonus in whales.items(): contract_bid = worklock_agent.get_deposited_eth(whale) assert bonus == contract_bid - min_bid
def test_collect_staking_reward(agency, testerchain, test_registry): token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry) staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) staker_account, worker_account, *other = testerchain.unassigned_accounts # Commit to next period testerchain.time_travel(periods=1) tpower = TransactingPower(account=worker_account, signer=Web3Signer(testerchain.client)) staking_agent.commit_to_next_period(transacting_power=tpower) testerchain.time_travel(periods=2) # Mint staker_power = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client)) _receipt = staking_agent.mint(transacting_power=staker_power) old_balance = token_agent.get_balance(address=staker_account) owned_tokens = staking_agent.owned_tokens(staker_address=staker_account) staked = staking_agent.non_withdrawable_stake( staker_address=staker_account) receipt = staking_agent.collect_staking_reward( transacting_power=staker_power) assert receipt['status'] == 1, "Transaction Rejected" assert receipt['logs'][-1]['address'] == staking_agent.contract_address new_balance = token_agent.get_balance( address=staker_account) # not the shoes assert new_balance == old_balance + owned_tokens - staked assert staking_agent.owned_tokens(staker_address=staker_account) == staked
def test_transacting_power_sign_transaction(testerchain): eth_address = testerchain.unassigned_accounts[2] power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, signer=Web3Signer(testerchain.client), account=eth_address) assert power.is_active is False assert power.is_unlocked is False transaction_dict = { 'nonce': testerchain.client.w3.eth.getTransactionCount(eth_address), 'gasPrice': testerchain.client.w3.eth.gasPrice, 'gas': 100000, 'from': eth_address, 'to': testerchain.unassigned_accounts[1], 'value': 1, 'data': b'' } # The default state of the account is locked. assert not power.is_unlocked # Test a signature without unlocking the account with pytest.raises(power.AccountLocked): power.sign_transaction(transaction_dict=transaction_dict) # Sign power.activate() assert power.is_unlocked is True signed_transaction = power.sign_transaction( transaction_dict=transaction_dict) # Demonstrate that the transaction is valid RLP encoded. from eth_account._utils.transactions import Transaction restored_transaction = Transaction.from_bytes( serialized_bytes=signed_transaction) restored_dict = restored_transaction.as_dict() assert to_checksum_address(restored_dict['to']) == transaction_dict['to'] # Try signing with missing transaction fields del transaction_dict['gas'] del transaction_dict['nonce'] with pytest.raises(TypeError): power.sign_transaction(transaction_dict=transaction_dict) # Try signing with a re-locked account. power.lock_account() with pytest.raises(power.AccountLocked): power.sign_transaction(transaction_dict=transaction_dict) power.unlock_account(password=INSECURE_DEVELOPMENT_PASSWORD) assert power.is_unlocked is True # Tear-Down Test power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, signer=Web3Signer(testerchain.client), account=testerchain.etherbase_account) power.activate(password=INSECURE_DEVELOPMENT_PASSWORD)
def test_select_client_account_valid_sources(mocker, mock_stdin, test_emitter, mock_testerchain, patch_keystore, mock_accounts, selection, capsys): # From External Signer mock_stdin.line(str(selection)) mock_signer = mocker.patch.object(KeystoreSigner, 'from_signer_uri', return_value=Web3Signer( mock_testerchain.client)) selected_account = select_client_account(emitter=test_emitter, signer_uri=MOCK_SIGNER_URI) expected_account = mock_testerchain.client.accounts[selection] assert selected_account == expected_account mock_signer.assert_called_once_with(uri=MOCK_SIGNER_URI, testnet=True) assert mock_stdin.empty() captured = capsys.readouterr() assert GENERIC_SELECT_ACCOUNT in captured.out and f"Selected {selection}" in captured.out # From Wallet mock_stdin.line(str(selection)) expected_account = mock_testerchain.client.accounts[selection] selected_account = select_client_account(emitter=test_emitter, signer=Web3Signer( mock_testerchain.client)) assert selected_account == expected_account assert mock_stdin.empty() captured = capsys.readouterr() assert GENERIC_SELECT_ACCOUNT in captured.out and f"Selected {selection}" in captured.out # From pre-initialized Provider mock_stdin.line(str(selection)) expected_account = mock_testerchain.client.accounts[selection] selected_account = select_client_account(emitter=test_emitter, provider_uri=MOCK_PROVIDER_URI) assert selected_account == expected_account assert mock_stdin.empty() captured = capsys.readouterr() assert GENERIC_SELECT_ACCOUNT in captured.out and f"Selected {selection}" in captured.out # From uninitialized Provider mock_stdin.line(str(selection)) mocker.patch.object(BlockchainInterfaceFactory, 'is_interface_initialized', return_value=False) mocker.patch.object(BlockchainInterfaceFactory, '_interfaces', return_value={}) mocker.patch.object(BlockchainInterfaceFactory, 'get_interface', return_value=mock_testerchain) selected_account = select_client_account(emitter=test_emitter, provider_uri=MOCK_PROVIDER_URI) assert selected_account == expected_account assert mock_stdin.empty() captured = capsys.readouterr() assert GENERIC_SELECT_ACCOUNT in captured.out and f"Selected {selection}" in captured.out
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 test_deposit_tokens(testerchain, agency, token_economics, test_registry): token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry) staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) locked_tokens = token_economics.minimum_allowed_locked * 5 staker_account = testerchain.unassigned_accounts[0] balance = token_agent.get_balance(address=staker_account) assert balance == 0 # The staker receives an initial amount of tokens tpower = TransactingPower(account=testerchain.etherbase_account, signer=Web3Signer(testerchain.client)) _txhash = token_agent.transfer( amount=token_economics.minimum_allowed_locked * 10, target_address=staker_account, transacting_power=tpower) # # Deposit: The staker deposits tokens in the StakingEscrow contract. # Previously, she needs to approve this transfer on the token contract. # staker_power = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client)) _receipt = token_agent.approve_transfer( amount=token_economics.minimum_allowed_locked * 10, # Approve spender_address=staking_agent.contract_address, transacting_power=staker_power) receipt = staking_agent.deposit_tokens( amount=locked_tokens, lock_periods=token_economics.minimum_locked_periods, transacting_power=staker_power, staker_address=staker_account) # Check the receipt for the contract address success code assert receipt['status'] == 1, "Transaction Rejected" assert receipt['logs'][2]['address'] == staking_agent.contract_address testerchain.time_travel(periods=1) balance = token_agent.get_balance(address=staker_account) assert balance == locked_tokens assert staking_agent.get_locked_tokens( staker_address=staker_account) == locked_tokens
def test_bidding(testerchain, agency, token_economics, test_registry): min_allowed_bid = token_economics.worklock_min_allowed_bid max_bid = 2000 * min_allowed_bid small_bids = [ random.randrange(min_allowed_bid, 2 * min_allowed_bid) for _ in range(10) ] total_small_bids = sum(small_bids) min_potential_whale_bid = (max_bid - total_small_bids) // 9 whales_bids = [ random.randrange(min_potential_whale_bid, max_bid) for _ in range(9) ] initial_bids = small_bids + whales_bids for i, bid in enumerate(initial_bids): bidder_address = testerchain.client.accounts[i] tpower = TransactingPower(account=bidder_address, signer=Web3Signer(testerchain.client)) bidder = Bidder(registry=test_registry, domain=TEMPORARY_DOMAIN, transacting_power=tpower) assert bidder.get_deposited_eth == 0 receipt = bidder.place_bid(value=bid) assert receipt['status'] == 1 assert bidder.get_deposited_eth == bid
def token_airdrop(token_agent, amount: NU, origin: str, addresses: List[str]): """Airdrops tokens from creator address to all other addresses!""" signer = Web3Signer(token_agent.blockchain.client) signer.unlock_account(account=origin, password=INSECURE_DEVELOPMENT_PASSWORD) def txs(): args = { 'from': origin, 'gasPrice': token_agent.blockchain.client.gas_price } for address in addresses: contract_function = token_agent.contract.functions.transfer( address, int(amount)) _receipt = token_agent.blockchain.send_transaction( contract_function=contract_function, sender_address=origin, payload=args) yield _receipt receipts = list() for receipt in txs(): # One at a time receipts.append(receipt) return receipts
def test_early_claim(testerchain, agency, token_economics, test_registry): agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry) bidder = testerchain.client.accounts[0] tpower = TransactingPower(account=bidder, signer=Web3Signer(testerchain.client)) with pytest.raises(TransactionFailed): _receipt = agent.claim(transacting_power=tpower)
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=10) 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=10) assert locked_tokens > 0
def test_staker_collects_staking_reward(testerchain, test_registry, staker, blockchain_ursulas, agency, token_economics, ursula_decentralized_test_config): token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry) tpower = TransactingPower(account=testerchain.etherbase_account, signer=Web3Signer(testerchain.client)) # Give more tokens to staker token_airdrop(token_agent=token_agent, transacting_power=tpower, addresses=[staker.checksum_address], amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT) staker.initialize_stake( amount=NU(token_economics.minimum_allowed_locked, 'NuNit'), # Lock the minimum amount of tokens lock_periods=int(token_economics.minimum_locked_periods) ) # ... for the fewest number of periods # Get an unused address for a new worker worker_address = testerchain.unassigned_accounts[-1] staker.bond_worker(worker_address=worker_address) # Create this worker and bond it with the staker ursula = make_decentralized_ursulas( ursula_config=ursula_decentralized_test_config, stakers_addresses=[staker.checksum_address], workers_addresses=[worker_address], registry=test_registry, commit_now=False).pop() # ...mint few tokens... for _ in range(2): ursula.commit_to_next_period() testerchain.time_travel(periods=1) # Check mintable periods assert staker.mintable_periods() == 1 ursula.commit_to_next_period() # ...wait more... assert staker.mintable_periods() == 0 testerchain.time_travel(periods=2) assert staker.mintable_periods() == 2 # Capture the current token balance of the staker initial_balance = staker.token_balance assert token_agent.get_balance(staker.checksum_address) == initial_balance # Profit! staked = staker.non_withdrawable_stake() owned = staker.owned_tokens() staker.collect_staking_reward() assert staker.owned_tokens() == staked final_balance = staker.token_balance assert final_balance == initial_balance + owned - staked
def test_remove_inactive_stake(agency, testerchain, test_registry): staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) staker_account = testerchain.unassigned_accounts[0] staker_power = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client)) testerchain.time_travel(periods=1) staking_agent.mint(transacting_power=staker_power) current_period = staking_agent.get_current_period() original_stakes = list( staking_agent.get_all_stakes(staker_address=staker_account)) assert original_stakes[2].last_period == current_period - 1 current_locked_tokens = staking_agent.get_locked_tokens(staker_account, 0) next_locked_tokens = staking_agent.get_locked_tokens(staker_account, 1) receipt = staking_agent.remove_inactive_stake( transacting_power=staker_power, stake_index=2) assert receipt['status'] == 1 # Ensure stake was extended by one period. stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) assert len(stakes) == len(original_stakes) - 1 assert stakes[0] == original_stakes[0] assert stakes[1] == original_stakes[1] assert stakes[2] == original_stakes[4] assert stakes[3] == original_stakes[3] assert staking_agent.get_locked_tokens(staker_account, 1) == next_locked_tokens assert staking_agent.get_locked_tokens(staker_account, 0) == current_locked_tokens
def test_collect_inflation_rewards(software_stakeholder, manual_worker, testerchain, test_registry): # Get stake stake = software_stakeholder.staker.stakes[1] # Make bonded Worker tpower = TransactingPower(account=manual_worker, signer=Web3Signer(testerchain.client)) tpower.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) worker = Worker(is_me=True, transacting_power=tpower, domain=TEMPORARY_DOMAIN, worker_address=manual_worker, registry=test_registry) # Wait out stake lock periods, manually make a commitment once per period. for period in range(stake.periods_remaining - 1): worker.commit_to_next_period() testerchain.time_travel(periods=1) # Collect the staking reward in NU. result = software_stakeholder.staker.collect_staking_reward() # TODO: Make Assertions reasonable for this layer. # Consider recycling logic from test_collect_reward_integration CLI test. assert result
def test_claim(testerchain, agency, token_economics, test_registry): bidder_address = testerchain.client.accounts[11] bidder = Bidder(checksum_address=bidder_address, registry=test_registry, signer=Web3Signer(testerchain.client)) 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 test_merge(agency, testerchain, test_registry, token_economics): staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) staker_account = testerchain.unassigned_accounts[0] staker_power = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client)) stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) original_stake_1 = stakes[0] original_stake_2 = stakes[2] assert original_stake_1.last_period == original_stake_2.last_period current_locked_tokens = staking_agent.get_locked_tokens(staker_account, 0) next_locked_tokens = staking_agent.get_locked_tokens(staker_account, 1) receipt = staking_agent.merge_stakes(transacting_power=staker_power, stake_index_1=0, stake_index_2=2) assert receipt['status'] == 1 # Ensure stake was extended by one period. stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) new_stake = stakes[0] assert new_stake.locked_value == original_stake_1.locked_value + original_stake_2.locked_value assert staking_agent.get_locked_tokens(staker_account, 1) == next_locked_tokens assert staking_agent.get_locked_tokens(staker_account, 0) == current_locked_tokens
def test_transacting_power_sign_agent_transaction(testerchain, agency, test_registry): token_agent = NucypherTokenAgent(registry=test_registry) contract_function = token_agent.contract.functions.approve( testerchain.etherbase_account, 100) payload = { 'chainId': int(testerchain.client.chain_id), 'nonce': testerchain.client.w3.eth.getTransactionCount( testerchain.etherbase_account), 'from': testerchain.etherbase_account, 'gasPrice': testerchain.client.gas_price } unsigned_transaction = contract_function.buildTransaction(payload) # Sign with Transacting Power transacting_power = TransactingPower( password=INSECURE_DEVELOPMENT_PASSWORD, signer=Web3Signer(testerchain.client), account=testerchain.etherbase_account) signed_raw_transaction = transacting_power.sign_transaction( unsigned_transaction) # Demonstrate that the transaction is valid RLP encoded. restored_transaction = Transaction.from_bytes( serialized_bytes=signed_raw_transaction) restored_dict = restored_transaction.as_dict() assert to_checksum_address( restored_dict['to']) == unsigned_transaction['to']
def testerchain(_testerchain) -> TesterBlockchain: testerchain = _testerchain # Reset chain state pyevm_backend = testerchain.provider.ethereum_tester.backend snapshot = pyevm_backend.chain.get_canonical_block_by_number(0).hash pyevm_backend.revert_to_snapshot(snapshot) coinbase, *addresses = testerchain.client.accounts for address in addresses: balance = testerchain.client.get_balance(address) spent = DEVELOPMENT_ETH_AIRDROP_AMOUNT - balance if spent > 0: tx = {'to': address, 'from': coinbase, 'value': spent} txhash = testerchain.w3.eth.sendTransaction(tx) _receipt = testerchain.wait_for_receipt(txhash) eth_amount = Web3().fromWei(spent, 'ether') testerchain.log.info("Airdropped {} ETH {} -> {}".format(eth_amount, tx['from'], tx['to'])) BlockchainInterfaceFactory.register_interface(interface=testerchain, force=True) # Mock TransactingPower Consumption (Deployer) testerchain.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, signer=Web3Signer(client=testerchain.client), account=testerchain.etherbase_account) testerchain.transacting_power.activate() yield testerchain
def test_transacting_power_sign_message(testerchain): # Manually create a TransactingPower eth_address = testerchain.etherbase_account power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, signer=Web3Signer(testerchain.client), account=eth_address) # Manually unlock power.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) # Sign data_to_sign = b'Premium Select Luxury Pencil Holder' signature = power.sign_message(message=data_to_sign) # Verify is_verified = verify_eip_191(address=eth_address, message=data_to_sign, signature=signature) assert is_verified is True # Test invalid address/pubkey pair is_verified = verify_eip_191(address=testerchain.client.accounts[1], message=data_to_sign, signature=signature) assert is_verified is False
def test_stakers_and_workers_relationships(testerchain, agency, test_registry): staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) staker_account, worker_account, *other = testerchain.unassigned_accounts # The staker hasn't bond a worker yet assert NULL_ADDRESS == staking_agent.get_worker_from_staker( staker_address=staker_account) tpower = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client)) _txhash = staking_agent.bond_worker(transacting_power=tpower, worker_address=worker_account) # We can check the staker-worker relation from both sides assert worker_account == staking_agent.get_worker_from_staker( staker_address=staker_account) assert staker_account == staking_agent.get_staker_from_worker( worker_address=worker_account) # No staker-worker relationship random_address = to_checksum_address(os.urandom(20)) assert NULL_ADDRESS == staking_agent.get_worker_from_staker( staker_address=random_address) assert NULL_ADDRESS == staking_agent.get_staker_from_worker( worker_address=random_address)
def test_participant_status(click_runner, testerchain, agency_local_registry, token_economics): tpower = TransactingPower(account=testerchain.client.accounts[2], signer=Web3Signer(testerchain.client)) bidder = Bidder(transacting_power=tpower, domain=TEMPORARY_DOMAIN, registry=agency_local_registry) command = ('status', '--registry-filepath', agency_local_registry.filepath, '--participant-address', bidder.checksum_address, '--provider', TEST_PROVIDER_URI, '--signer', TEST_PROVIDER_URI, '--network', TEMPORARY_DOMAIN) result = click_runner.invoke(worklock, command, catch_exceptions=False) assert result.exit_code == 0 # Bidder-specific data is displayed assert bidder.checksum_address in result.output assert str(bidder.remaining_work) in result.output assert str(bidder.available_refund) in result.output # Worklock economics are displayed assert str(token_economics.worklock_boosting_refund_rate) in result.output assert str(NU.from_nunits( token_economics.worklock_supply)) in result.output
def test_nucypher_status_locked_tokens(click_runner, testerchain, agency_local_registry, stakers): staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=agency_local_registry) # All workers make a commitment for ursula in testerchain.ursulas_accounts: tpower = TransactingPower(account=ursula, signer=Web3Signer(testerchain.client)) tpower.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) staking_agent.commit_to_next_period(transacting_power=tpower) testerchain.time_travel(periods=1) periods = 2 status_command = ('locked-tokens', '--registry-filepath', str(agency_local_registry.filepath.absolute()), '--provider', TEST_PROVIDER_URI, '--network', TEMPORARY_DOMAIN, '--periods', periods) light_parameter = [False, True] for light in light_parameter: testerchain.is_light = light result = click_runner.invoke(status, status_command, catch_exceptions=False) assert result.exit_code == 0 current_period = staking_agent.get_current_period() all_locked = NU.from_nunits( staking_agent.get_global_locked_tokens(at_period=current_period)) assert re.search(f"Locked Tokens for next {periods} periods", result.output, re.MULTILINE) assert re.search(f"Min: {all_locked} - Max: {all_locked}", result.output, re.MULTILINE)
def bootstrap_network( cls, registry: Optional[BaseContractRegistry] = None, economics: Economics = None ) -> Tuple['TesterBlockchain', 'InMemoryContractRegistry']: """For use with metric testing scripts""" # Provider connection if registry is None: registry = InMemoryContractRegistry() testerchain = cls() if not BlockchainInterfaceFactory.is_interface_initialized( eth_provider_uri=testerchain.eth_provider_uri): BlockchainInterfaceFactory.register_interface( interface=testerchain) # Produce actor deployer_power = TransactingPower( signer=Web3Signer(testerchain.client), account=testerchain.etherbase_account) admin = ContractAdministrator(registry=registry, domain=TEMPORARY_DOMAIN, transacting_power=deployer_power, economics=economics or cls.DEFAULT_ECONOMICS) gas_limit = None # TODO: Gas management - #842 for deployer_class in admin.primary_deployer_classes: admin.deploy_contract(contract_name=deployer_class.contract_name, gas_limit=gas_limit) return testerchain, registry
def test_transacting_power_sign_transaction(testerchain): eth_address = testerchain.unassigned_accounts[2] power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, signer=Web3Signer(testerchain.client), account=eth_address) transaction_dict = { 'nonce': testerchain.client.w3.eth.getTransactionCount(eth_address), 'gasPrice': testerchain.client.w3.eth.gasPrice, 'gas': 100000, 'from': eth_address, 'to': testerchain.unassigned_accounts[1], 'value': 1, 'data': b'' } # Sign power.activate() signed_transaction = power.sign_transaction( transaction_dict=transaction_dict) # Demonstrate that the transaction is valid RLP encoded. from eth_account._utils.transactions import Transaction restored_transaction = Transaction.from_bytes( serialized_bytes=signed_transaction) restored_dict = restored_transaction.as_dict() assert to_checksum_address(restored_dict['to']) == transaction_dict['to'] # Try signing with missing transaction fields del transaction_dict['gas'] del transaction_dict['nonce'] with pytest.raises(TypeError): power.sign_transaction(transaction_dict=transaction_dict)
def test_lock_and_create(agency, testerchain, test_registry, token_economics): staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) staker_account, worker_account, *other = testerchain.unassigned_accounts staker_power = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client)) stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) stakes_length = len(stakes) current_locked_tokens = staking_agent.get_locked_tokens(staker_account, 0) next_locked_tokens = staking_agent.get_locked_tokens(staker_account, 1) amount = token_economics.minimum_allowed_locked receipt = staking_agent.lock_and_create( transacting_power=staker_power, lock_periods=token_economics.minimum_locked_periods, amount=amount) assert receipt['status'] == 1 # Ensure stake was extended by one period. stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) assert len(stakes) == stakes_length + 1 new_stake = stakes[-1] current_period = staking_agent.get_current_period() assert new_stake.last_period == current_period + token_economics.minimum_locked_periods assert new_stake.first_period == current_period + 1 assert new_stake.locked_value == amount assert staking_agent.get_locked_tokens(staker_account, 1) == next_locked_tokens + amount assert staking_agent.get_locked_tokens(staker_account, 0) == current_locked_tokens
def deployer_transacting_power(testerchain): transacting_power = TransactingPower( password=INSECURE_DEVELOPMENT_PASSWORD, signer=Web3Signer(client=testerchain.client), account=testerchain.etherbase_account) transacting_power.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) return transacting_power
def test_lock_and_increase(agency, testerchain, test_registry, token_economics): staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) staker_account, worker_account, *other = testerchain.unassigned_accounts staker_power = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client)) stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) original_stake = stakes[0] current_locked_tokens = staking_agent.get_locked_tokens(staker_account, 0) next_locked_tokens = staking_agent.get_locked_tokens(staker_account, 1) amount = staking_agent.calculate_staking_reward( staker_address=staker_account) receipt = staking_agent.lock_and_increase(transacting_power=staker_power, stake_index=0, amount=amount) assert receipt['status'] == 1 # Ensure stake was extended by one period. stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) new_stake = stakes[0] assert new_stake.locked_value == original_stake.locked_value + amount assert staking_agent.get_locked_tokens(staker_account, 1) == next_locked_tokens + amount assert staking_agent.get_locked_tokens(staker_account, 0) == current_locked_tokens
def manual_staker(testerchain, agency, test_registry): token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry) tpower = TransactingPower(account=testerchain.etherbase_account, signer=Web3Signer(testerchain.client)) # its okay to add this key if it already exists. address = '0xaaa23A5c74aBA6ca5E7c09337d5317A7C4563075' if address not in testerchain.client.accounts: staker_private_key = '13378db1c2af06933000504838afc2d52efa383206454deefb1836f8f4cd86f8' address = testerchain.provider.ethereum_tester.add_account( staker_private_key, 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) token_agent.transfer(amount=NU(200_000, 'NU').to_nunits(), transacting_power=tpower, target_address=address) yield address
def test_block_confirmations(testerchain, test_registry, mocker): origin = testerchain.etherbase_account transacting_power = TransactingPower(account=origin, signer=Web3Signer(testerchain.client)) # Mocks and test adjustments testerchain.TIMEOUT = 5 # Reduce timeout for tests, for the moment mocker.patch.object(testerchain.client, '_calculate_confirmations_timeout', return_value=1) EthereumClient.BLOCK_CONFIRMATIONS_POLLING_TIME = 0.1 EthereumClient.COOLING_TIME = 0 # Let's try to deploy a simple contract (ReceiveApprovalMethodMock) with 1 confirmation. # Since the testerchain doesn't mine new blocks automatically, this fails. with pytest.raises(EthereumClient.TransactionTimeout): _ = testerchain.deploy_contract(transacting_power=transacting_power, registry=test_registry, contract_name='ReceiveApprovalMethodMock', confirmations=1) # Trying again with no confirmation succeeds. contract, _ = testerchain.deploy_contract(transacting_power=transacting_power, registry=test_registry, contract_name='ReceiveApprovalMethodMock') # Trying a simple function of the contract with 1 confirmations fails too, for the same reason tx_function = contract.functions.receiveApproval(origin, 0, origin, b'') with pytest.raises(EthereumClient.TransactionTimeout): _ = testerchain.send_transaction(contract_function=tx_function, transacting_power=transacting_power, confirmations=1) # Trying again with no confirmation succeeds. receipt = testerchain.send_transaction(contract_function=tx_function, transacting_power=transacting_power, confirmations=0) assert receipt['status'] == 1