def test_collect_rewards_integration( click_runner, testerchain, agency_local_registry, stakeholder_configuration_file_location, blockchain_alice, blockchain_bob, random_policy_label, manual_staker, manual_worker, token_economics, mock_transacting_power_activation, policy_value, policy_rate): half_stake_time = token_economics.minimum_locked_periods // 2 # Test setup logger = Logger("Test-CLI") # Enter the Teacher's Logger, and current_period = 0 # State the initial period for incrementing staker_address = manual_staker worker_address = manual_worker staker = Staker(is_me=True, checksum_address=staker_address, registry=agency_local_registry) staker.refresh_stakes() # The staker is staking. assert staker.is_staking assert staker.stakes assert staker.worker_address == worker_address ursula_port = select_test_port() ursula = Ursula(is_me=True, checksum_address=staker_address, worker_address=worker_address, registry=agency_local_registry, rest_host='127.0.0.1', rest_port=ursula_port, network_middleware=MockRestMiddleware(), db_filepath=tempfile.mkdtemp(), domain=TEMPORARY_DOMAIN) MOCK_KNOWN_URSULAS_CACHE[ursula_port] = ursula assert ursula.worker_address == worker_address assert ursula.checksum_address == staker_address mock_transacting_power_activation(account=worker_address, password=INSECURE_DEVELOPMENT_PASSWORD) # Make a commitment for half the first stake duration for _ in range(half_stake_time): logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.commit_to_next_period() testerchain.time_travel(periods=1) current_period += 1 # Alice creates a policy and grants Bob access blockchain_alice.selection_buffer = 1 M, N = 1, 1 days = 3 now = testerchain.w3.eth.getBlock('latest').timestamp expiration = maya.MayaDT(now).add(days=days - 1) blockchain_policy = blockchain_alice.grant(bob=blockchain_bob, label=random_policy_label, m=M, n=N, value=policy_value, expiration=expiration, handpicked_ursulas={ursula}) # Ensure that the handpicked Ursula was selected for the policy arrangement = list(blockchain_policy._accepted_arrangements)[0] assert arrangement.ursula == ursula # Bob learns about the new staker and joins the policy blockchain_bob.start_learning_loop() blockchain_bob.remember_node(node=ursula) blockchain_bob.join_policy(random_policy_label, bytes(blockchain_alice.stamp)) # Enrico Encrypts (of course) enrico = Enrico(policy_encrypting_key=blockchain_policy.public_key, network_middleware=MockRestMiddleware()) verifying_key = blockchain_alice.stamp.as_umbral_pubkey() for index in range(half_stake_time - 5): logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.commit_to_next_period() # Encrypt random_data = os.urandom(random.randrange(20, 100)) ciphertext, signature = enrico.encrypt_message(plaintext=random_data) # Decrypt cleartexts = blockchain_bob.retrieve(ciphertext, enrico=enrico, alice_verifying_key=verifying_key, label=random_policy_label) assert random_data == cleartexts[0] # Ursula Staying online and the clock advancing testerchain.time_travel(periods=1) current_period += 1 # Finish the passage of time for the first Stake for _ in range(5): # plus the extended periods from stake division logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.commit_to_next_period() testerchain.time_travel(periods=1) current_period += 1 # # WHERES THE MONEY URSULA?? - Collecting Rewards # # The address the client wants Ursula to send rewards to burner_wallet = testerchain.w3.eth.account.create( INSECURE_DEVELOPMENT_PASSWORD) # The rewards wallet is initially empty, because it is freshly created assert testerchain.client.get_balance(burner_wallet.address) == 0 # Rewards will be unlocked after the # final committed period has passed (+1). logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) current_period += 1 logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") # At least half of the tokens are unlocked (restaking was enabled for some prior periods) assert staker.locked_tokens() >= token_economics.minimum_allowed_locked # Since we are mocking the blockchain connection, manually consume the transacting power of the Staker. mock_transacting_power_activation(account=staker_address, password=INSECURE_DEVELOPMENT_PASSWORD) # Collect Policy Fee collection_args = ('stake', 'collect-reward', '--config-file', stakeholder_configuration_file_location, '--policy-fee', '--no-staking-reward', '--staking-address', staker_address, '--withdraw-address', burner_wallet.address) result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # Policy Fee collected_policy_fee = testerchain.client.get_balance( burner_wallet.address) expected_collection = policy_rate * 30 assert collected_policy_fee == expected_collection # Finish the passage of time... once and for all # Extended periods from stake division for _ in range(9): ursula.commit_to_next_period() current_period += 1 logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) # # Collect Staking Reward # balance_before_collecting = staker.token_agent.get_balance( address=staker_address) collection_args = ('stake', 'collect-reward', '--config-file', stakeholder_configuration_file_location, '--no-policy-fee', '--staking-reward', '--staking-address', staker_address, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # The staker has withdrawn her staking rewards assert staker.token_agent.get_balance( address=staker_address) > balance_before_collecting
def paint_stakers(emitter, stakers: List[str], registry: BaseContractRegistry) -> None: staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry) current_period = staking_agent.get_current_period() emitter.echo(f"\nCurrent period: {current_period}") emitter.echo("\n| Stakers |\n") emitter.echo(f"{'Checksum address':42} Staker information") emitter.echo('=' * (42 + 2 + 53)) for staker_address in stakers: staker = Staker(is_me=False, checksum_address=staker_address, registry=registry) nickname = Nickname.from_seed(staker_address) emitter.echo( f"{staker_address} {'Nickname:':10} {nickname} {nickname.icon}") tab = " " * len(staker_address) owned_tokens = staker.owned_tokens() last_committed_period = staker.last_committed_period worker = staker.worker_address is_restaking = staker.is_restaking is_winding_down = staker.is_winding_down is_taking_snapshots = staker.is_taking_snapshots missing_commitments = current_period - last_committed_period owned_in_nu = round(owned_tokens, 2) current_locked_tokens = round(staker.locked_tokens(periods=0), 2) next_locked_tokens = round(staker.locked_tokens(periods=1), 2) emitter.echo(f"{tab} {'Owned:':10} {owned_in_nu}") emitter.echo( f"{tab} Staked in current period: {current_locked_tokens}") emitter.echo(f"{tab} Staked in next period: {next_locked_tokens}") if is_restaking: emitter.echo(f"{tab} {'Re-staking:':10} Yes") else: emitter.echo(f"{tab} {'Re-staking:':10} No") emitter.echo( f"{tab} {'Winding down:':10} {'Yes' if is_winding_down else 'No'}" ) emitter.echo( f"{tab} {'Snapshots:':10} {'Yes' if is_taking_snapshots else 'No'}" ) emitter.echo(f"{tab} {'Activity:':10} ", nl=False) if missing_commitments == -1: emitter.echo(f"Next period committed (#{last_committed_period})", color='green') elif missing_commitments == 0: emitter.echo( f"Current period committed (#{last_committed_period}). " f"Pending commitment to next period.", color='yellow') elif missing_commitments == current_period: emitter.echo(f"Never made a commitment", color='red') else: emitter.echo( f"Missing {missing_commitments} commitments " f"(last time for period #{last_committed_period})", color='red') emitter.echo(f"{tab} {'Worker:':10} ", nl=False) if worker == NULL_ADDRESS: emitter.echo(f"Worker not bonded", color='red') else: emitter.echo(f"{worker}") fees = prettify_eth_amount(staker.calculate_policy_fee()) emitter.echo(f"{tab} Unclaimed fees: {fees}") min_rate = prettify_eth_amount(staker.min_fee_rate) emitter.echo(f"{tab} Min fee rate: {min_rate}")
def test_collect_rewards_integration(click_runner, testerchain, stakeholder_configuration_file_location, blockchain_alice, blockchain_bob, random_policy_label, manual_staker, manual_worker, token_economics, policy_value, policy_rate): half_stake_time = token_economics.minimum_locked_periods // 2 # Test setup logger = Logger("Test-CLI") # Enter the Teacher's Logger, and current_period = 0 # State the initial period for incrementing staker_address = manual_staker worker_address = manual_worker staker = Staker(is_me=True, checksum_address=staker_address, blockchain=testerchain) # The staker is staking. assert staker.stakes assert staker.is_staking assert staker.worker_address == worker_address ursula_port = select_test_port() ursula = Ursula(is_me=True, checksum_address=staker_address, worker_address=worker_address, blockchain=testerchain, rest_host='127.0.0.1', rest_port=ursula_port, network_middleware=MockRestMiddleware()) MOCK_KNOWN_URSULAS_CACHE[ursula_port] = ursula assert ursula.worker_address == worker_address assert ursula.checksum_address == staker_address # Mock TransactingPower consumption (Worker-Ursula) ursula.blockchain.transacting_power = TransactingPower( account=worker_address, password=INSECURE_DEVELOPMENT_PASSWORD, blockchain=testerchain) ursula.blockchain.transacting_power.activate() # Confirm for half the first stake duration for _ in range(half_stake_time): logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.confirm_activity() testerchain.time_travel(periods=1) current_period += 1 # Alice creates a policy and grants Bob access blockchain_alice.selection_buffer = 1 M, N = 1, 1 expiration = maya.now() + datetime.timedelta(days=3) blockchain_policy = blockchain_alice.grant(bob=blockchain_bob, label=random_policy_label, m=M, n=N, value=policy_value, expiration=expiration, handpicked_ursulas={ursula}) # Ensure that the handpicked Ursula was selected for the policy arrangement = list(blockchain_policy._accepted_arrangements)[0] assert arrangement.ursula == ursula # Bob learns about the new staker and joins the policy blockchain_bob.start_learning_loop() blockchain_bob.remember_node(node=ursula) blockchain_bob.join_policy(random_policy_label, bytes(blockchain_alice.stamp)) # Enrico Encrypts (of course) enrico = Enrico(policy_encrypting_key=blockchain_policy.public_key, network_middleware=MockRestMiddleware()) verifying_key = blockchain_alice.stamp.as_umbral_pubkey() for index in range(half_stake_time - 5): ursula.confirm_activity() logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") # Encrypt random_data = os.urandom(random.randrange(20, 100)) ciphertext, signature = enrico.encrypt_message(message=random_data) # Decrypt cleartexts = blockchain_bob.retrieve(message_kit=ciphertext, data_source=enrico, alice_verifying_key=verifying_key, label=random_policy_label) assert random_data == cleartexts[0] # Ursula Staying online and the clock advancing testerchain.time_travel(periods=1) current_period += 1 # Finish the passage of time for the first Stake for _ in range(5): # plus the extended periods from stake division ursula.confirm_activity() current_period += 1 logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) # # WHERES THE MONEY URSULA?? - Collecting Rewards # # The address the client wants Ursula to send rewards to burner_wallet = testerchain.w3.eth.account.create( INSECURE_DEVELOPMENT_PASSWORD) # The rewards wallet is initially empty, because it is freshly created assert testerchain.client.get_balance(burner_wallet.address) == 0 # Rewards will be unlocked after the # final confirmed period has passed (+1). testerchain.time_travel(periods=1) current_period += 1 logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") # Half of the tokens are unlocked. assert staker.locked_tokens() == token_economics.minimum_allowed_locked # Simulate "Reconnection" within the CLI process to the testerchain def connect(self, *args, **kwargs): self._attach_provider(testerchain.provider) self.w3 = self.Web3(provider=self._provider) self.client = Web3Client.from_w3(w3=self.w3) BlockchainInterface.connect = connect # Since we are mocking the blockchain connection, manually consume the transacting power of the Staker. testerchain.transacting_power = TransactingPower( account=staker_address, password=INSECURE_DEVELOPMENT_PASSWORD, blockchain=testerchain) testerchain.transacting_power.activate() # Collect Policy Reward collection_args = ('stake', 'collect-reward', '--mock-networking', '--config-file', stakeholder_configuration_file_location, '--policy-reward', '--no-staking-reward', '--staking-address', staker_address, '--withdraw-address', burner_wallet.address, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # Policy Reward collected_policy_reward = testerchain.client.get_balance( burner_wallet.address) expected_collection = policy_rate * 30 assert collected_policy_reward == expected_collection # Finish the passage of time... once and for all # Extended periods from stake division for _ in range(9): ursula.confirm_activity() current_period += 1 logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) # Collect Inflation Reward collection_args = ('stake', 'collect-reward', '--mock-networking', '--config-file', stakeholder_configuration_file_location, '--no-policy-reward', '--staking-reward', '--staking-address', staker_address, '--withdraw-address', burner_wallet.address, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # The burner wallet has the reward ethers assert staker.token_agent.get_balance(address=staker_address)
def test_adjudicator_slashes(agency, testerchain, mock_ursula_reencrypts, token_economics, test_registry, mocker): staker_account = testerchain.staker_account(0) worker_account = testerchain.ursula_account(0) ##### STAKING ESCROW STUFF ##### token_agent, staking_agent, _policy_agent = agency locked_tokens = token_economics.minimum_allowed_locked * 5 # Mock Powerup consumption (Deployer) testerchain.transacting_power = TransactingPower( password=INSECURE_DEVELOPMENT_PASSWORD, account=testerchain.etherbase_account) testerchain.transacting_power.activate() # The staker receives an initial amount of tokens _txhash = token_agent.transfer( amount=locked_tokens, target_address=staker_account, sender_address=testerchain.etherbase_account) # Mock Powerup consumption (Staker) testerchain.transacting_power = TransactingPower( password=INSECURE_DEVELOPMENT_PASSWORD, account=staker_account) testerchain.transacting_power.activate() # Deposit: The staker deposits tokens in the StakingEscrow contract. staker = Staker(checksum_address=staker_account, is_me=True, registry=test_registry) staker.initialize_stake( amount=NU(locked_tokens, 'NuNit'), lock_periods=token_economics.minimum_locked_periods) assert staker.locked_tokens(periods=1) == locked_tokens # The staker hasn't set a worker yet assert BlockchainInterface.NULL_ADDRESS == staking_agent.get_worker_from_staker( staker_address=staker_account) _txhash = staking_agent.set_worker(staker_address=staker_account, worker_address=worker_account) 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) ###### END OF STAKING ESCROW STUFF #### adjudicator_agent = AdjudicatorAgent(registry=test_registry) bob_account = testerchain.bob_account bobby = NucypherTokenActor(checksum_address=bob_account, registry=test_registry) ursula = mock_ursula(testerchain, worker_account, mocker=mocker) # Let's create a bad cfrag evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True) assert not adjudicator_agent.was_this_evidence_evaluated(evidence) bobby_old_balance = bobby.token_balance # Mock Powerup consumption (Bob) testerchain.transacting_power = TransactingPower( password=INSECURE_DEVELOPMENT_PASSWORD, account=bob_account) testerchain.transacting_power.activate() adjudicator_agent.evaluate_cfrag(evidence=evidence, sender_address=bob_account) assert adjudicator_agent.was_this_evidence_evaluated(evidence) investigator_reward = bobby.token_balance - bobby_old_balance assert investigator_reward > 0 assert investigator_reward == token_economics.base_penalty / token_economics.reward_coefficient assert staker.locked_tokens(periods=1) < locked_tokens
def test_investigator_requests_slashing(testerchain, test_registry, agency, #mock_ursula_reencrypts, token_economics, mocker): staker_account = testerchain.staker_account(0) worker_account = testerchain.ursula_account(0) ##### STAKING ESCROW STUFF ##### 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 # The staker receives an initial amount of tokens tpower = TransactingPower(account=testerchain.etherbase_account, signer=Web3Signer(testerchain.client)) _txhash = token_agent.transfer(amount=locked_tokens, target_address=staker_account, transacting_power=tpower) # Deposit: The staker deposits tokens in the StakingEscrow contract. staker_tpower = TransactingPower(account=staker_account, signer=Web3Signer(testerchain.client)) staker = Staker(transacting_power=staker_tpower, domain=TEMPORARY_DOMAIN, registry=test_registry) staker.initialize_stake(amount=NU(locked_tokens, 'NuNit'), lock_periods=token_economics.minimum_locked_periods) assert staker.locked_tokens(periods=1) == locked_tokens # The staker hasn't bond a worker yet assert NULL_ADDRESS == staking_agent.get_worker_from_staker(staker_address=staker_account) _txhash = staking_agent.bond_worker(transacting_power=staker_tpower, worker_address=worker_account) 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) ###### END OF STAKING ESCROW STUFF #### bob_account = testerchain.bob_account bob_tpower = TransactingPower(account=bob_account, signer=Web3Signer(testerchain.client)) investigator = Investigator(registry=test_registry, transacting_power=bob_tpower, domain=TEMPORARY_DOMAIN) ursula = mock_ursula(testerchain, worker_account, mocker=mocker) # Let's create a bad cfrag evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True) assert not investigator.was_this_evidence_evaluated(evidence) bobby_old_balance = investigator.token_balance investigator.request_evaluation(evidence=evidence) assert investigator.was_this_evidence_evaluated(evidence) investigator_reward = investigator.token_balance - bobby_old_balance assert investigator_reward > 0 assert investigator_reward == token_economics.base_penalty / token_economics.reward_coefficient assert staker.locked_tokens(periods=1) < locked_tokens
def test_investigator_requests_slashing(testerchain, test_registry, agency, mock_ursula_reencrypts, token_economics, mock_transacting_power_activation, mocker): staker_account = testerchain.staker_account(0) worker_account = testerchain.ursula_account(0) ##### STAKING ESCROW STUFF ##### token_agent, staking_agent, _policy_agent = agency locked_tokens = token_economics.minimum_allowed_locked * 5 mock_transacting_power_activation(account=testerchain.etherbase_account, password=INSECURE_DEVELOPMENT_PASSWORD) # The staker receives an initial amount of tokens _txhash = token_agent.transfer( amount=locked_tokens, target_address=staker_account, sender_address=testerchain.etherbase_account) mock_transacting_power_activation(account=staker_account, password=INSECURE_DEVELOPMENT_PASSWORD) # Deposit: The staker deposits tokens in the StakingEscrow contract. staker = Staker(checksum_address=staker_account, is_me=True, registry=test_registry) staker.initialize_stake( amount=NU(locked_tokens, 'NuNit'), lock_periods=token_economics.minimum_locked_periods) assert staker.locked_tokens(periods=1) == locked_tokens # The staker hasn't bond a worker yet assert NULL_ADDRESS == staking_agent.get_worker_from_staker( staker_address=staker_account) _txhash = staking_agent.bond_worker(staker_address=staker_account, worker_address=worker_account) 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) ###### END OF STAKING ESCROW STUFF #### bob_account = testerchain.bob_account investigator = Investigator(registry=test_registry, checksum_address=bob_account) ursula = mock_ursula(testerchain, worker_account, mocker=mocker) # Let's create a bad cfrag evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True) assert not investigator.was_this_evidence_evaluated(evidence) bobby_old_balance = investigator.token_balance mock_transacting_power_activation(account=bob_account, password=INSECURE_DEVELOPMENT_PASSWORD) investigator.request_evaluation(evidence=evidence) assert investigator.was_this_evidence_evaluated(evidence) investigator_reward = investigator.token_balance - bobby_old_balance assert investigator_reward > 0 assert investigator_reward == token_economics.base_penalty / token_economics.reward_coefficient assert staker.locked_tokens(periods=1) < locked_tokens
def test_collect_rewards_integration( click_runner, testerchain, agency_local_registry, stakeholder_configuration_file_location, blockchain_alice, blockchain_bob, random_policy_label, manual_staker, manual_worker, token_economics, policy_value): half_stake_time = 2 * token_economics.minimum_locked_periods # Test setup logger = Logger("Test-CLI") # Enter the Teacher's Logger, and current_period = 0 # State the initial period for incrementing staker_address = manual_staker worker_address = manual_worker staker = Staker(domain=TEMPORARY_DOMAIN, checksum_address=staker_address, registry=agency_local_registry) staker.refresh_stakes() # The staker is staking. assert staker.is_staking assert staker.stakes assert staker.worker_address == worker_address ursula_port = select_test_port() ursula = Ursula(is_me=True, checksum_address=staker_address, signer=Web3Signer(testerchain.client), worker_address=worker_address, registry=agency_local_registry, rest_host=LOOPBACK_ADDRESS, rest_port=ursula_port, provider_uri=TEST_PROVIDER_URI, network_middleware=MockRestMiddleware(), db_filepath=tempfile.mkdtemp(), domain=TEMPORARY_DOMAIN) MOCK_KNOWN_URSULAS_CACHE[ursula_port] = ursula assert ursula.worker_address == worker_address assert ursula.checksum_address == staker_address # Make a commitment for half the first stake duration testerchain.time_travel(periods=1) for _ in range(half_stake_time): logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.commit_to_next_period() testerchain.time_travel(periods=1) current_period += 1 # Alice creates a policy and grants Bob access blockchain_alice.selection_buffer = 1 threshold, shares = 1, 1 duration_in_periods = 3 days = (duration_in_periods - 1) * (token_economics.hours_per_period // 24) now = testerchain.w3.eth.getBlock('latest').timestamp expiration = maya.MayaDT(now).add(days=days) blockchain_policy = blockchain_alice.grant(bob=blockchain_bob, label=random_policy_label, threshold=threshold, shares=shares, value=policy_value, expiration=expiration, ursulas={ursula}) # Ensure that the handpicked Ursula was selected for the policy treasure_map = blockchain_bob._decrypt_treasure_map( blockchain_policy.treasure_map, blockchain_policy.publisher_verifying_key) assert ursula.canonical_address in treasure_map.destinations # Bob learns about the new staker and joins the policy blockchain_bob.start_learning_loop() blockchain_bob.remember_node(node=ursula) # Enrico Encrypts (of course) enrico = Enrico(policy_encrypting_key=blockchain_policy.public_key, network_middleware=MockRestMiddleware()) verifying_key = blockchain_alice.stamp.as_umbral_pubkey() for index in range(half_stake_time - 5): logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.commit_to_next_period() # Encrypt random_data = os.urandom(random.randrange(20, 100)) message_kit = enrico.encrypt_message(plaintext=random_data) # Decrypt cleartexts = blockchain_bob.retrieve_and_decrypt( [message_kit], alice_verifying_key=verifying_key, encrypted_treasure_map=blockchain_policy.treasure_map) assert random_data == cleartexts[0] # Ursula Staying online and the clock advancing testerchain.time_travel(periods=1) current_period += 1 # Finish the passage of time for the first Stake for _ in range(5): # plus the extended periods from stake division logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.commit_to_next_period() testerchain.time_travel(periods=1) current_period += 1 # # WHERES THE MONEY URSULA?? - Collecting Rewards # # The address the client wants Ursula to send rewards to burner_wallet = testerchain.w3.eth.account.create( INSECURE_DEVELOPMENT_PASSWORD) # The rewards wallet is initially empty, because it is freshly created assert testerchain.client.get_balance(burner_wallet.address) == 0 # Rewards will be unlocked after the # final committed period has passed (+1). logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) current_period += 1 logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") # At least half of the tokens are unlocked (restaking was enabled for some prior periods) assert staker.locked_tokens() >= token_economics.minimum_allowed_locked # Collect Policy Fee collection_args = ('stake', 'rewards', 'withdraw', '--config-file', str(stakeholder_configuration_file_location.absolute()), '--fees', '--no-tokens', '--staking-address', staker_address, '--withdraw-address', burner_wallet.address) result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # Policy Fee collected_policy_fee = testerchain.client.get_balance( burner_wallet.address) expected_collection = policy_value assert collected_policy_fee == expected_collection # Finish the passage of time... once and for all # Extended periods from stake division for _ in range(9): ursula.commit_to_next_period() current_period += 1 logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) # # Collect Staking Reward # balance_before_collecting = staker.token_agent.get_balance( address=staker_address) collection_args = ('stake', 'rewards', 'withdraw', '--config-file', str(stakeholder_configuration_file_location.absolute()), '--no-fees', '--tokens', '--staking-address', staker_address, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # The staker has withdrawn her staking rewards assert staker.token_agent.get_balance( address=staker_address) > balance_before_collecting
def test_investigator_requests_slashing(session_testerchain, session_agency, mock_ursula_reencrypts, token_economics, slashing_economics): testerchain = session_testerchain staker_account = testerchain.staker_account(0) worker_account = testerchain.ursula_account(0) ##### STAKING ESCROW STUFF ##### token_agent, staking_agent, _policy_agent = session_agency locked_tokens = token_economics.minimum_allowed_locked * 5 # Mock Powerup consumption (Deployer) testerchain.transacting_power = TransactingPower(blockchain=testerchain, account=testerchain.etherbase_account) testerchain.transacting_power.activate() # The staker receives an initial amount of tokens _txhash = token_agent.transfer(amount=locked_tokens, target_address=staker_account, sender_address=testerchain.etherbase_account) # Mock Powerup consumption (Staker) testerchain.transacting_power = TransactingPower(blockchain=testerchain, account=staker_account) testerchain.transacting_power.activate() # Deposit: The staker deposits tokens in the StakingEscrow contract. staker = Staker(checksum_address=staker_account, is_me=True, blockchain=testerchain) staker.initialize_stake(amount=NU(locked_tokens, 'NuNit'), lock_periods=token_economics.minimum_locked_periods) assert staker.locked_tokens(periods=1) == locked_tokens # The staker hasn't set a worker yet assert BlockchainInterface.NULL_ADDRESS == staking_agent.get_worker_from_staker(staker_address=staker_account) _txhash = staking_agent.set_worker(staker_address=staker_account, worker_address=worker_account) 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) ###### END OF STAKING ESCROW STUFF #### bob_account = testerchain.bob_account investigator = Investigator(blockchain=testerchain, checksum_address=bob_account) ursula = mock_ursula(testerchain, worker_account) # Let's create a bad cfrag evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True) assert not investigator.was_this_evidence_evaluated(evidence) bobby_old_balance = investigator.token_balance # Mock Powerup consumption (Bob) testerchain.transacting_power = TransactingPower(blockchain=testerchain, account=bob_account) testerchain.transacting_power.activate() investigator.request_evaluation(evidence=evidence) assert investigator.was_this_evidence_evaluated(evidence) investigator_reward = investigator.token_balance - bobby_old_balance assert investigator_reward > 0 assert investigator_reward == slashing_economics.base_penalty / slashing_economics.reward_coefficient assert staker.locked_tokens(periods=1) < locked_tokens