def test_run_moe(click_runner, federated_ursulas): # Establish a running Teacher Ursula ursula = list(federated_ursulas)[0] teacher_uri = ursula.seed_node_metadata(as_teacher_uri=True) _ursula_output = yield threads.deferToThread(start_pytest_ursula_services, ursula=ursula) test_ws_port = select_test_port() args = ('moe', '--ws-port', test_ws_port, '--network', ':fake-domain:', '--teacher', teacher_uri, '--http-port', MOCK_URSULA_STARTING_PORT, '--learn-on-launch', # TODO: Dumb name. Don't use this in production. '--dry-run') result = yield threads.deferToThread(click_runner.invoke, nucypher_cli, args, catch_exceptions=False) assert result.exit_code == 0 assert f"Running Moe on 127.0.0.1:{MOCK_URSULA_STARTING_PORT}" assert f"WebSocketService starting on {test_ws_port}" reserved_ports = (CharacterConfiguration.DEFAULT_REST_PORT, CharacterConfiguration.DEFAULT_DEVELOPMENT_REST_PORT) assert MOCK_URSULA_STARTING_PORT not in reserved_ports
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 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_collect_rewards_integration(click_runner, testerchain, agency_local_registry, stakeholder_configuration_file_location, blockchain_alice, blockchain_bob, random_policy_label, beneficiary, preallocation_escrow_agent, mock_allocation_registry, manual_worker, token_economics, mock_transacting_power_activation, stake_value, policy_value, policy_rate): # Disable re-staking restake_args = ('stake', 'restake', '--disable', '--config-file', stakeholder_configuration_file_location, '--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, '--force') result = click_runner.invoke(nucypher_cli, restake_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 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 = preallocation_escrow_agent.principal_contract.address worker_address = manual_worker # The staker is staking. stakes = StakeList(registry=agency_local_registry, checksum_address=staker_address) stakes.refresh() assert stakes staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=agency_local_registry) assert worker_address == staking_agent.get_worker_from_staker(staker_address=staker_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, start_working_now=False, network_middleware=MockRestMiddleware()) 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) # 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 days = 3 now = testerchain.w3.eth.getBlock(block_identifier='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.confirm_activity() # Encrypt random_data = os.urandom(random.randrange(20, 100)) message_kit, signature = enrico.encrypt_message(message=random_data) # Decrypt cleartexts = blockchain_bob.retrieve(message_kit, 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 _ in range(5 - 1): # minus 1 because the first period was already confirmed in test_ursula_run logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.confirm_activity() current_period += 1 testerchain.time_travel(periods=1) # # WHERES THE MONEY URSULA?? - Collecting Rewards # balance = testerchain.client.get_balance(beneficiary) # Rewards will be unlocked after the # final confirmed 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} <<<<<<<<<<<<<<<<") # Since we are mocking the blockchain connection, manually consume the transacting power of the Beneficiary. mock_transacting_power_activation(account=beneficiary, password=INSECURE_DEVELOPMENT_PASSWORD) # Collect Policy Reward collection_args = ('stake', 'collect-reward', '--config-file', stakeholder_configuration_file_location, '--policy-reward', '--no-staking-reward', '--withdraw-address', beneficiary, '--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, '--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(beneficiary) assert collected_policy_reward > balance # # Collect Staking Reward # token_agent = ContractAgency.get_agent(agent_class=NucypherTokenAgent, registry=agency_local_registry) balance_before_collecting = token_agent.get_balance(address=staker_address) collection_args = ('stake', 'collect-reward', '--config-file', stakeholder_configuration_file_location, '--no-policy-reward', '--staking-reward', '--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # The beneficiary has withdrawn her staking rewards, which are now in the staking contract assert token_agent.get_balance(address=staker_address) >= balance_before_collecting
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with nucypher. If not, see <https://www.gnu.org/licenses/>. """ # WARNING This is not a mining script! # you will not perform any re-encryptions, and you will not get paid. # It might be (but might not be) useful for determining whether you have # the proper dependencies and configuration to run an actual mining node. from click.testing import CliRunner from nucypher.cli.main import nucypher_cli from nucypher.utilities.sandbox.constants import select_test_port click_runner = CliRunner() DEMO_NODE_PORT = select_test_port() DEMO_FLEET_STARTING_PORT = 11500 args = [ '--debug', 'ursula', 'run', '--federated-only', '--teacher-uri', f'https://127.0.0.1:{DEMO_FLEET_STARTING_PORT}', '--rest-port', DEMO_NODE_PORT, '--dev' ] nucypher_cli.main(args=args, prog_name="nucypher-cli")