def test_collect_policy_reward(testerchain, agency, policy_meta, token_economics): token_agent, staking_agent, policy_agent = agency agent = policy_agent staker = policy_meta.addresses[-1] worker = staking_agent.get_worker_from_staker(staker) # Mock Powerup consumption (Ursula-Worker) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=worker) old_eth_balance = token_agent.blockchain.client.get_balance(staker) for _ in range(token_economics.minimum_locked_periods): _receipt = staking_agent.confirm_activity(worker_address=worker) testerchain.time_travel(periods=1) # Mock Powerup consumption (Ursula-Staker) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=staker) receipt = agent.collect_policy_reward(collector_address=staker, staker_address=staker) assert receipt['status'] == 1, "Transaction Rejected" assert receipt['logs'][0]['address'] == agent.contract_address new_eth_balance = token_agent.blockchain.client.get_balance(staker) assert new_eth_balance > old_eth_balance
def test_staker_collects_staking_reward(testerchain, staker, blockchain_ursulas, agency, token_economics, ursula_decentralized_test_config): token_agent, staking_agent, policy_agent = agency # Capture the current token balance of the staker initial_balance = staker.token_balance assert token_agent.get_balance(staker.checksum_address) == initial_balance # Mock Powerup consumption (Staker) testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=staker.checksum_address) 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.set_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], confirm_activity=False, blockchain=testerchain).pop() # ...wait out the lock period... for _ in range(token_economics.minimum_locked_periods): testerchain.time_travel(periods=1) ursula.confirm_activity() # ...wait more... testerchain.time_travel(periods=2) # Mock Powerup consumption (Staker) testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=staker.checksum_address) # Profit! staker.collect_staking_reward() final_balance = token_agent.get_balance(staker.checksum_address) assert final_balance > initial_balance
def bootstrap_network(cls) -> Tuple['TesterBlockchain', Dict[str, EthereumContractAgent]]: """For use with metric testing scripts""" testerchain = cls(compiler=SolidityCompiler()) power = BlockchainPower(blockchain=testerchain, account=testerchain.client.etherbase) power.unlock_account(password=INSECURE_DEVELOPMENT_PASSWORD) testerchain.transacting_power = power origin = testerchain.client.etherbase deployer = Deployer(blockchain=testerchain, deployer_address=origin, bare=True) _txhashes, agents = deployer.deploy_network_contracts(staker_secret=STAKING_ESCROW_DEPLOYMENT_SECRET, policy_secret=POLICY_MANAGER_DEPLOYMENT_SECRET, adjudicator_secret=ADJUDICATOR_DEPLOYMENT_SECRET, user_escrow_proxy_secret=USER_ESCROW_PROXY_DEPLOYMENT_SECRET) return testerchain, agents
def test_collect_policy_reward(testerchain, agent, agency, token_economics): _token_agent, staking_agent, policy_agent = agency deployer_address, beneficiary_address, author, ursula, *everybody_else = testerchain.client.accounts # Mock Powerup consumption (Beneficiary) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=agent.beneficiary) _txhash = agent.deposit_as_staker( value=token_economics.minimum_allowed_locked, periods=token_economics.minimum_locked_periods) # User sets a worker in StakingEscrow via UserEscrow worker = testerchain.ursula_account(0) _receipt = agent.set_worker(worker_address=worker) testerchain.time_travel(periods=1) # Mock Powerup consumption (Alice) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=author) _txhash = policy_agent.create_policy( policy_id=os.urandom(16), author_address=author, value=to_wei(1, 'ether'), periods=2, initial_reward=0, node_addresses=[agent.contract_address]) # Mock Powerup consumption (Beneficiary-Worker) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=worker) _txhash = staking_agent.confirm_activity(worker_address=worker) testerchain.time_travel(periods=2) _txhash = staking_agent.confirm_activity(worker_address=worker) old_balance = testerchain.client.get_balance(account=agent.beneficiary) # Mock Powerup consumption (Beneficiary) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=agent.beneficiary) txhash = agent.collect_policy_reward() assert txhash # TODO assert testerchain.client.get_balance( account=agent.beneficiary) > old_balance
def test_deposit_tokens(testerchain, agency, token_economics): token_agent, staking_agent, _policy_agent = agency locked_tokens = token_economics.minimum_allowed_locked * 5 staker_account = testerchain.unassigned_accounts[0] # Mock Powerup consumption (Deployer) testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=testerchain.etherbase_account) balance = token_agent.get_balance(address=staker_account) assert balance == 0 # The staker receives an initial amount of tokens _txhash = token_agent.transfer( amount=token_economics.minimum_allowed_locked * 10, target_address=staker_account, sender_address=testerchain.etherbase_account) # Mock Powerup consumption (Ursula-Staker) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=staker_account) # # Deposit: The staker deposits tokens in the StakingEscrow contract. # Previously, she needs to approve this transfer on the token contract. # _receipt = token_agent.approve_transfer( amount=token_economics.minimum_allowed_locked * 10, # Approve target_address=staking_agent.contract_address, sender_address=staker_account) receipt = staking_agent.deposit_tokens( amount=locked_tokens, lock_periods=token_economics.minimum_locked_periods, sender_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_character_blockchain_power(testerchain, three_agents): # TODO: Handle multiple providers eth_address = testerchain.interface.w3.eth.accounts[0] sig_privkey = testerchain.interface.provider.ethereum_tester.backend._key_lookup[ eth_utils.to_canonical_address(eth_address)] sig_pubkey = sig_privkey.public_key signer = Character(is_me=True, checksum_address=eth_address) signer._crypto_power.consume_power_up(BlockchainPower(testerchain, eth_address)) # Due to testing backend, the account is already unlocked. power = signer._crypto_power.power_ups(BlockchainPower) power.is_unlocked = True # power.unlock_account('this-is-not-a-secure-password') data_to_sign = b'What does Ursula look like?!?' sig = power.sign_message(data_to_sign) is_verified = verify_eip_191(address=eth_address, message=data_to_sign, signature=sig) assert is_verified is True # Test a bad address/pubkey pair is_verified = verify_eip_191(address=testerchain.interface.w3.eth.accounts[1], message=data_to_sign, signature=sig) assert is_verified is False # Test a signature without unlocking the account power.is_unlocked = False with pytest.raises(PowerUpError): power.sign_message(b'test') # Test lockAccount call del power
def test_staker_locking_tokens(testerchain, agency, staker, token_economics): token_agent, staking_agent, policy_agent = agency # Mock Powerup consumption (Ursula-Staker) testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=staker.checksum_address) assert NU(token_economics.minimum_allowed_locked, 'NuNit') < staker.token_balance, "Insufficient staker balance" staker.initialize_stake( amount=NU(token_economics.minimum_allowed_locked, 'NuNit'), # Lock the minimum amount of tokens lock_periods=token_economics.minimum_locked_periods) # Verify that the escrow is "approved" to receive tokens allowance = token_agent.contract.functions.allowance( staker.checksum_address, staking_agent.contract_address).call() assert 0 == allowance # Staking starts after one period locked_tokens = staker.locked_tokens() assert 0 == locked_tokens locked_tokens = staker.locked_tokens(periods=1) assert token_economics.minimum_allowed_locked == locked_tokens
def test_collect_staking_reward(agency, testerchain): token_agent, staking_agent, _policy_agent = agency staker_account, worker_account, *other = testerchain.unassigned_accounts # Confirm Activity _receipt = staking_agent.confirm_activity(worker_address=worker_account) testerchain.time_travel(periods=2) # Mock Powerup consumption (Ursula-Staker) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=staker_account) # Mint _receipt = staking_agent.mint(staker_address=staker_account) old_balance = token_agent.get_balance(address=staker_account) receipt = staking_agent.collect_staking_reward( staker_address=staker_account) 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
def test_rapid_deployment(token_economics): compiler = SolidityCompiler() allocation_registry = InMemoryAllocationRegistry() blockchain = _TesterBlockchain(eth_airdrop=False, test_accounts=4, compiler=compiler) # TODO: #1092 - TransactingPower blockchain.transacting_power = BlockchainPower( blockchain=blockchain, account=blockchain.etherbase_account) deployer_address = blockchain.etherbase_account deployer = Deployer(blockchain=blockchain, deployer_address=deployer_address) deployer.deploy_network_contracts( staker_secret=STAKING_ESCROW_DEPLOYMENT_SECRET, policy_secret=POLICY_MANAGER_DEPLOYMENT_SECRET, adjudicator_secret=ADJUDICATOR_DEPLOYMENT_SECRET, user_escrow_proxy_secret=USER_ESCROW_PROXY_DEPLOYMENT_SECRET) all_yall = blockchain.unassigned_accounts # Start with some hard-coded cases... allocation_data = [{ 'address': all_yall[1], 'amount': token_economics.maximum_allowed_locked, 'duration': ONE_YEAR_IN_SECONDS }, { 'address': all_yall[2], 'amount': token_economics.minimum_allowed_locked, 'duration': ONE_YEAR_IN_SECONDS * 2 }, { 'address': all_yall[3], 'amount': token_economics.minimum_allowed_locked * 100, 'duration': ONE_YEAR_IN_SECONDS * 3 }] # Pile on the rest for _ in range(NUMBER_OF_ALLOCATIONS_IN_TESTS - len(allocation_data)): random_password = ''.join( random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(16)) acct = w3.eth.account.create(random_password) beneficiary_address = acct.address amount = random.randint(token_economics.minimum_allowed_locked, token_economics.maximum_allowed_locked) duration = random.randint( token_economics.minimum_locked_periods * ONE_YEAR_IN_SECONDS, (token_economics.maximum_locked_periods * ONE_YEAR_IN_SECONDS) * 3) random_allocation = { 'address': beneficiary_address, 'amount': amount, 'duration': duration } allocation_data.append(random_allocation) deployer.deploy_beneficiary_contracts( allocations=allocation_data, allocation_registry=allocation_registry)
def make_testerchain(): # Create new blockchain testerchain = _TesterBlockchain(eth_airdrop=True, free_transactions=False) # Set the deployer address from a freshly created test account testerchain.deployer_address = testerchain.etherbase_account testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=testerchain.etherbase_account) return testerchain
def stakers(agency, token_economics): token_agent, _staking_agent, _policy_agent = agency blockchain = token_agent.blockchain # Mock Powerup consumption (Deployer) blockchain.transacting_power = BlockchainPower( blockchain=blockchain, account=blockchain.etherbase_account) token_airdrop(origin=blockchain.etherbase_account, addresses=blockchain.stakers_accounts, token_agent=token_agent, amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT) stakers = list() for index, account in enumerate(blockchain.stakers_accounts): staker = Staker(is_me=True, checksum_address=account, blockchain=blockchain) # Mock TransactingPower consumption (Ursula-Staker) staker.blockchain.transacting_power = BlockchainPower( blockchain=staker.blockchain, account=staker.checksum_address) min_stake, balance = token_economics.minimum_allowed_locked, staker.token_balance amount = random.randint(min_stake, balance) # for a random lock duration min_locktime, max_locktime = token_economics.minimum_locked_periods, token_economics.maximum_locked_periods periods = random.randint(min_locktime, max_locktime) staker.initialize_stake(amount=amount, lock_periods=periods) # We assume that the staker knows in advance the account of her worker worker_address = blockchain.ursula_account(index) staker.set_worker(worker_address=worker_address) stakers.append(staker) # Stake starts next period (or else signature validation will fail) blockchain.time_travel(periods=1) yield stakers
def test_calculate_refund(testerchain, agency, policy_meta): token_agent, staking_agent, policy_agent = agency agent = policy_agent staker = policy_meta.addresses[-1] worker = staking_agent.get_worker_from_staker(staker) # Mock Powerup consumption (Ursula-Worker) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=worker) testerchain.time_travel(hours=9) _receipt = staking_agent.confirm_activity(worker_address=worker) # Mock Powerup consumption (Alice) testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=testerchain.alice_account) receipt = agent.calculate_refund(policy_id=policy_meta.policy_id, author_address=policy_meta.author) assert receipt['status'] == 1, "Transaction Rejected"
def test_confirm_activity(agency, testerchain): _token_agent, staking_agent, _policy_agent = agency staker_account, worker_account, *other = testerchain.unassigned_accounts # Mock Powerup consumption (Ursula-Worker) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=worker_account) receipt = staking_agent.confirm_activity(worker_address=worker_account) assert receipt['status'] == 1, "Transaction Rejected" assert receipt['logs'][0]['address'] == staking_agent.contract_address
def testerchain(): """ https://github.com/ethereum/eth-tester # available-backends """ # Create the blockchain testerchain = TesterBlockchain(eth_airdrop=True, free_transactions=True) # TODO: TransactingPower # Mock TransactingPower Consumption testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=testerchain.etherbase_account) testerchain.deployer_address = testerchain.etherbase_account yield testerchain testerchain.disconnect()
def test_approve_transfer(agent, token_economics): testerchain = agent.blockchain deployer, someone, *everybody_else = testerchain.client.accounts # Mock Powerup consumption testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=someone) # Approve receipt = agent.approve_transfer( amount=token_economics.minimum_allowed_locked, target_address=agent.contract_address, sender_address=someone) assert receipt['status'] == 1, "Transaction Rejected" assert receipt['logs'][0]['address'] == agent.contract_address
def test_transfer(agent, token_economics): testerchain = agent.blockchain origin, someone, *everybody_else = testerchain.client.accounts # Mock Powerup consumption (Deployer) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=origin) old_balance = agent.get_balance(someone) receipt = agent.transfer(amount=token_economics.minimum_allowed_locked, target_address=someone, sender_address=origin) assert receipt['status'] == 1, "Transaction Rejected" assert receipt['logs'][0]['address'] == agent.contract_address new_balance = agent.get_balance(someone) assert new_balance == old_balance + token_economics.minimum_allowed_locked
def idle_staker(testerchain, agency): token_agent, _staking_agent, _policy_agent = agency idle_staker_account = testerchain.unassigned_accounts[-2] # Mock Powerup consumption (Deployer) testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=testerchain.etherbase_account) token_airdrop(origin=testerchain.etherbase_account, addresses=[idle_staker_account], token_agent=token_agent, amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT) # Prepare idle staker idle_staker = Staker(is_me=True, checksum_address=idle_staker_account, blockchain=testerchain) yield idle_staker
def test_withdraw_tokens(testerchain, agent, agency, allocation_value): token_agent, staking_agent, policy_agent = agency deployer_address, beneficiary_address, *everybody_else = testerchain.client.accounts # Mock Powerup consumption (Beneficiary) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=agent.beneficiary) assert token_agent.get_balance( address=agent.contract_address) == agent.unvested_tokens with pytest.raises((TransactionFailed, ValueError)): agent.withdraw_tokens(value=allocation_value) testerchain.time_travel(seconds=TEST_DURATION) txhash = agent.withdraw_tokens(value=allocation_value) assert txhash # TODO assert token_agent.get_balance(address=agent.contract_address) == 0 assert token_agent.get_balance( address=beneficiary_address) == allocation_value
def test_create_policy(testerchain, agency, token_economics): token_agent, staking_agent, policy_agent = agency agent = policy_agent # Mock Powerup consumption testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=testerchain.alice_account) policy_id = os.urandom(16) node_addresses = list(staking_agent.sample(quantity=3, duration=1)) receipt = agent.create_policy(policy_id=policy_id, author_address=testerchain.alice_account, value=token_economics.minimum_allowed_locked, periods=10, initial_reward=20, node_addresses=node_addresses) assert receipt['status'] == 1, "Transaction Rejected" assert receipt['logs'][0]['address'] == agent.contract_address
def agent(testerchain, proxy_deployer, allocation_value) -> UserEscrowAgent: deployer_address, beneficiary_address, *everybody_else = testerchain.client.accounts # Mock Powerup consumption (Deployer) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=deployer_address) # Escrow escrow_deployer = UserEscrowDeployer( deployer_address=deployer_address, blockchain=testerchain, allocation_registry=TEST_ALLOCATION_REGISTRY) _txhash = escrow_deployer.deploy() escrow_deployer.initial_deposit(value=allocation_value, duration=TEST_DURATION) assert escrow_deployer.contract.functions.getLockedTokens().call( ) == allocation_value escrow_deployer.assign_beneficiary(beneficiary_address=beneficiary_address) escrow_deployer.enroll_principal_contract() assert escrow_deployer.contract.functions.getLockedTokens().call( ) == allocation_value _agent = escrow_deployer.make_agent() _direct_agent = UserEscrowAgent( blockchain=testerchain, allocation_registry=TEST_ALLOCATION_REGISTRY, beneficiary=beneficiary_address) assert _direct_agent == _agent assert _direct_agent.contract.abi == _agent.contract.abi assert _direct_agent.contract.address == _agent.contract.address assert _agent.principal_contract.address == escrow_deployer.contract.address assert _agent.principal_contract.abi == escrow_deployer.contract.abi assert _direct_agent.contract.abi == escrow_deployer.contract.abi assert _direct_agent.contract.address == escrow_deployer.contract.address yield _agent TEST_ALLOCATION_REGISTRY.clear()
def test_character_blockchain_power(testerchain): eth_address = testerchain.interface.w3.eth.accounts[0] sig_privkey = testerchain.interface._providers[0].ethereum_tester.backend.\ _key_lookup[eth_utils.to_canonical_address(eth_address)] sig_pubkey = sig_privkey.public_key signer = Character(is_me=True, checksum_address=eth_address) signer._crypto_power.consume_power_up( BlockchainPower(testerchain, eth_address)) # Due to testing backend, the account is already unlocked. power = signer._crypto_power.power_ups(BlockchainPower) power.is_unlocked = True #power.unlock_account('this-is-not-a-secure-password') data_to_sign = b'What does Ursula look like?!?' sig = power.sign_message(data_to_sign) is_verified = power.verify_message(eth_address, sig_pubkey.to_bytes(), data_to_sign, sig) assert is_verified == True # Test a bad message: with pytest.raises(PowerUpError): power.verify_message(eth_address, sig_pubkey.to_bytes(), data_to_sign + b'bad', sig) # Test a bad address/pubkey pair with pytest.raises(ValueError): power.verify_message(testerchain.interface.w3.eth.accounts[1], sig_pubkey.to_bytes(), data_to_sign, sig) # Test a signature without unlocking the account power.is_unlocked = False with pytest.raises(PowerUpError): power.sign_message(b'test') # Test lockAccount call del (power)
def test_invalid_workers_tolerance(testerchain, blockchain_ursulas, agency, idle_staker, token_economics, ursula_decentralized_test_config): # # Setup # lonely_blockchain_learner, blockchain_teacher, unsigned, *the_others = list( blockchain_ursulas) _, staking_agent, _ = agency warnings = [] def warning_trapper(event): if event['log_level'] == LogLevel.warn: warnings.append(event) # We start with an "idle_staker" (i.e., no tokens in StakingEscrow) assert 0 == staking_agent.owned_tokens(idle_staker.checksum_address) # Now let's create an active worker for this staker. # First, stake something (e.g. the bare minimum) amount = token_economics.minimum_allowed_locked periods = token_economics.minimum_locked_periods # Mock Powerup consumption (Staker) testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=idle_staker.checksum_address) idle_staker.initialize_stake(amount=amount, lock_periods=periods) # Stake starts next period (or else signature validation will fail) testerchain.time_travel(periods=1) idle_staker.stake_tracker.refresh() # We create an active worker node for this staker worker = make_ursula_for_staker( staker=idle_staker, worker_address=testerchain.unassigned_accounts[-1], ursula_config=ursula_decentralized_test_config, blockchain=testerchain, confirm_activity=True, ursulas_to_learn_about=None) # Since we confirmed activity, we need to advance one period testerchain.time_travel(periods=1) # The worker is valid and can be verified (even with the force option) worker.verify_node(force=True, network_middleware=MockRestMiddleware(), certificate_filepath="quietorl") # In particular, we know that it's bonded to a staker who is really staking. assert worker._worker_is_bonded_to_staker() assert worker._staker_is_really_staking() # OK. Now we learn about this worker. lonely_blockchain_learner.remember_node(worker) # The worker already confirmed one period before. Let's confirm the remaining 29. for i in range(29): worker.confirm_activity() testerchain.time_travel(periods=1) # The stake period has ended, and the staker wants her tokens back ("when lambo?"). # She withdraws up to the last penny (well, last nunit, actually). # Mock Powerup consumption (Staker) testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=idle_staker.checksum_address) idle_staker.mint() testerchain.time_travel(periods=1) i_want_it_all = staking_agent.owned_tokens(idle_staker.checksum_address) idle_staker.withdraw(i_want_it_all) # OK...so...the staker is not staking anymore ... assert 0 == staking_agent.owned_tokens(idle_staker.checksum_address) # ... but the worker node still is "verified" (since we're not forcing on-chain verification) worker.verify_node(network_middleware=MockRestMiddleware(), certificate_filepath="quietorl") # If we force, on-chain verification, the worker is of course not verified with pytest.raises(worker.NotStaking): worker.verify_node(force=True, network_middleware=MockRestMiddleware(), certificate_filepath="quietorl") # Let's learn from this invalid node lonely_blockchain_learner._current_teacher_node = worker globalLogPublisher.addObserver(warning_trapper) lonely_blockchain_learner.learn_from_teacher_node() # lonely_blockchain_learner.remember_node(worker) # The same problem occurs if we directly try to remember this node globalLogPublisher.removeObserver(warning_trapper) # TODO: What should we really check here? (#1075) assert len(warnings) == 1 warning = warnings[-1]['log_format'] assert str(worker) in warning assert "no active stakes" in warning # TODO: Cleanup logging templates assert worker not in lonely_blockchain_learner.known_nodes
def __init__(self, db_filepath: str, rest_host: str, rest_port: int, crash_on_error: bool = False, economics: TokenEconomics = None, distribute_ether: bool = True, *args, **kwargs): # Character super().__init__(*args, **kwargs) self.log = Logger(f"felix-{self.checksum_address[-6::]}") # Network self.rest_port = rest_port self.rest_host = rest_host self.rest_app = NOT_RUNNING self.crash_on_error = crash_on_error # Database self.db_filepath = db_filepath self.db = NO_DATABASE_AVAILABLE self.db_engine = create_engine(f'sqlite:///{self.db_filepath}', convert_unicode=True) # Blockchain blockchain_power = BlockchainPower(blockchain=self.blockchain, account=self.checksum_address) self._crypto_power.consume_power_up(blockchain_power) # blockchain_power.unlock_account(password=None) # TODO: TransactingPower self.token_agent = NucypherTokenAgent(blockchain=self.blockchain) self.reserved_addresses = [ self.checksum_address, BlockchainInterface.NULL_ADDRESS ] # Update reserved addresses with deployed contracts existing_entries = list(self.blockchain.registry.enrolled_addresses) self.reserved_addresses.extend(existing_entries) # Distribution self.__distributed = 0 # Track NU Output self.__airdrop = 0 # Track Batch self.__disbursement = 0 # Track Quantity self._distribution_task = LoopingCall(f=self.airdrop_tokens) self._distribution_task.clock = self._CLOCK self.start_time = NOT_RUNNING if not economics: economics = TokenEconomics() self.economics = economics self.MAXIMUM_DISBURSEMENT = economics.maximum_allowed_locked self.INITIAL_DISBURSEMENT = economics.minimum_allowed_locked # Optionally send ether with each token transaction self.distribute_ether = distribute_ether # Banner self.log.info(FELIX_BANNER.format(self.checksum_address))
def escrow(testerchain): # Mock Powerup consumption (Deployer) testerchain.transacting_power = BlockchainPower( blockchain=testerchain, account=testerchain.etherbase_account) escrow, _ = testerchain.deploy_contract('StakingEscrowForAdjudicatorMock') return escrow
def test_adjudicator_slashes(agency, testerchain, mock_ursula_reencrypts, token_economics, slashing_economics): 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 = BlockchainPower( blockchain=testerchain, account=testerchain.etherbase_account) # 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 = BlockchainPower(blockchain=testerchain, account=staker_account) # 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 #### adjudicator_agent = AdjudicatorAgent() bob_account = testerchain.bob_account bobby = NucypherTokenActor(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 adjudicator_agent.was_this_evidence_evaluated(evidence) bobby_old_balance = bobby.token_balance # Mock Powerup consumption (Bob) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=bob_account) 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 == slashing_economics.base_penalty / slashing_economics.reward_coefficient assert staker.locked_tokens(periods=1) < locked_tokens
def __init__( self, # Ursula rest_host: str, rest_port: int, certificate: Certificate = None, certificate_filepath: str = None, tls_private_key=None, # TODO: Derive from keyring db_name: str = None, db_filepath: str = None, is_me: bool = True, interface_signature=None, timestamp=None, # Blockchain miner_agent=None, checksum_address: str = None, # Character passphrase: str = None, abort_on_learning_error: bool = False, federated_only: bool = False, start_learning_now: bool = None, crypto_power=None, tls_curve: EllipticCurve = None, known_nodes: Iterable = None, **character_kwargs) -> None: # # Character # self._work_orders = list() Character.__init__(self, is_me=is_me, checksum_address=checksum_address, start_learning_now=start_learning_now, federated_only=federated_only, crypto_power=crypto_power, abort_on_learning_error=abort_on_learning_error, known_nodes=known_nodes, **character_kwargs) # # Self-Ursula # if is_me is True: # TODO: 340 self._stored_treasure_maps = dict() if not federated_only: Miner.__init__(self, is_me=is_me, miner_agent=miner_agent, checksum_address=checksum_address) # Access staking node via node's transacting keys blockchain_power = BlockchainPower( blockchain=self.blockchain, account=self.checksum_public_address) self._crypto_power.consume_power_up(blockchain_power) # Use blockchain power to substantiate stamp self.substantiate_stamp(passphrase=passphrase) # # ProxyRESTServer and TLSHostingPower # if not crypto_power or (TLSHostingPower not in crypto_power._power_ups): # TODO: Maybe we want _power_ups to be public after all? # We'll hook all the TLS stuff up unless the crypto_power was already passed. # # Self-Ursula # if is_me: self.suspicious_activities_witnessed = { 'vladimirs': [], 'bad_treasure_maps': [] } # # REST Server # rest_routes = ProxyRESTRoutes( db_name=db_name, db_filepath=db_filepath, network_middleware=self.network_middleware, federated_only=self.federated_only, # TODO: 466 treasure_map_tracker=self.treasure_maps, node_tracker=self.known_nodes, node_bytes_caster=self.__bytes__, work_order_tracker=self._work_orders, node_recorder=self.remember_node, stamp=self.stamp, verifier=self.verify_from, suspicious_activity_tracker=self. suspicious_activities_witnessed, certificate_dir=self.known_certificates_dir, ) rest_server = ProxyRESTServer( rest_host=rest_host, rest_port=rest_port, routes=rest_routes, ) self.rest_url = rest_server.rest_url self.datastore = rest_routes.datastore # TODO: Maybe organize this better? # # TLSHostingPower # tls_hosting_keypair = HostingKeypair( curve=tls_curve, host=rest_host, certificate=certificate, certificate_filepath=certificate_filepath, private_key=tls_private_key) tls_hosting_power = TLSHostingPower( rest_server=rest_server, keypair=tls_hosting_keypair) # # Stranger-Ursula # else: # REST Server # Unless the caller passed a crypto power, # we'll make our own TLSHostingPower for this stranger. rest_server = ProxyRESTServer(rest_host=rest_host, rest_port=rest_port) # # TLSHostingPower # if certificate or certificate_filepath: tls_hosting_power = TLSHostingPower( rest_server=rest_server, certificate_filepath=certificate_filepath, certificate=certificate) else: tls_hosting_keypair = HostingKeypair( curve=tls_curve, host=rest_host, certificate_filepath=certificate_filepath) tls_hosting_power = TLSHostingPower( rest_server=rest_server, keypair=tls_hosting_keypair) # OK - Now we have a ProxyRestServer and a TLSHostingPower for some Ursula self._crypto_power.consume_power_up(tls_hosting_power) # Consume! else: self.log.info( "Not adhering rest_server; Using the one on crypto_power.") # # Verifiable Node # certificate_filepath = self._crypto_power.power_ups( TLSHostingPower).keypair.certificate_filepath certificate = self._crypto_power.power_ups( TLSHostingPower).keypair.certificate VerifiableNode.__init__(self, certificate=certificate, certificate_filepath=certificate_filepath, interface_signature=interface_signature, timestamp=timestamp) # # Logging # if is_me: message = "Initialized Self {} | {}".format( self.__class__.__name__, self.checksum_public_address) self.log.info(message) else: message = "Initialized Stranger {} | {}".format( self.__class__.__name__, self.checksum_public_address) self.log.debug(message)
def test_deposit_and_withdraw_as_staker(testerchain, agent, agency, allocation_value, token_economics): token_agent, staking_agent, policy_agent = agency assert staking_agent.get_locked_tokens( staker_address=agent.contract_address) == 0 assert staking_agent.get_locked_tokens( staker_address=agent.contract_address, periods=1) == 0 assert agent.unvested_tokens == allocation_value assert token_agent.get_balance( address=agent.contract_address) == allocation_value # Mock Powerup consumption (Beneficiary) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=agent.beneficiary) # Move the tokens to the StakingEscrow receipt = agent.deposit_as_staker( value=token_economics.minimum_allowed_locked, periods=token_economics.minimum_locked_periods) assert receipt # TODO # User sets a worker in StakingEscrow via UserEscrow worker = testerchain.ursula_account(0) _receipt = agent.set_worker(worker_address=worker) assert token_agent.get_balance( address=agent.contract_address ) == allocation_value - token_economics.minimum_allowed_locked assert agent.unvested_tokens == allocation_value assert staking_agent.get_locked_tokens( staker_address=agent.contract_address) == 0 assert staking_agent.get_locked_tokens( staker_address=agent.contract_address, periods=1) == token_economics.minimum_allowed_locked assert staking_agent.get_locked_tokens( staker_address=agent.contract_address, periods=token_economics.minimum_locked_periods ) == token_economics.minimum_allowed_locked assert staking_agent.get_locked_tokens( staker_address=agent.contract_address, periods=token_economics.minimum_locked_periods + 1) == 0 # Mock Powerup consumption (Beneficiary-Worker) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=worker) for _ in range(token_economics.minimum_locked_periods): staking_agent.confirm_activity(worker_address=worker) testerchain.time_travel(periods=1) testerchain.time_travel(periods=1) # Mock Powerup consumption (Beneficiary) testerchain.transacting_power = BlockchainPower(blockchain=testerchain, account=agent.beneficiary) agent.mint() assert staking_agent.get_locked_tokens( staker_address=agent.contract_address) == 0 assert token_agent.get_balance( address=agent.contract_address ) == allocation_value - token_economics.minimum_allowed_locked txhash = agent.withdraw_as_staker( value=token_economics.minimum_allowed_locked) assert txhash # TODO assert token_agent.get_balance( address=agent.contract_address) == allocation_value # Release worker _txhash = agent.set_worker(worker_address=BlockchainInterface.NULL_ADDRESS) txhash = agent.withdraw_as_staker(value=staking_agent.owned_tokens( address=agent.contract_address)) assert txhash assert token_agent.get_balance( address=agent.contract_address) > allocation_value
def __init__(self, # Ursula rest_host: str, rest_port: int, certificate: Certificate = None, # TODO: from_certificate classmethod instead, use only filepath..? certificate_filepath: str = None, db_name: str = None, # TODO: deprecate db_name, use only filepath.? db_filepath: str = None, is_me: bool = True, interface_signature=None, # Blockchain miner_agent=None, checksum_address: str = None, registry_filepath: str = None, # Character abort_on_learning_error: bool = False, federated_only: bool = False, start_learning_now: bool = None, crypto_power=None, tls_curve: EllipticCurve = None, tls_private_key=None, # TODO: config here. #361 known_nodes: Iterable = None, **character_kwargs ) -> None: self._work_orders = [] Character.__init__(self, is_me=is_me, checksum_address=checksum_address, start_learning_now=start_learning_now, federated_only=federated_only, crypto_power=crypto_power, abort_on_learning_error=abort_on_learning_error, known_nodes=known_nodes, **character_kwargs) if not federated_only: Miner.__init__(self, is_me=is_me, miner_agent=miner_agent, checksum_address=checksum_address, registry_filepath=registry_filepath) blockchain_power = BlockchainPower(blockchain=self.blockchain, account=self.checksum_public_address) self._crypto_power.consume_power_up(blockchain_power) if is_me is True: # TODO: 340 self._stored_treasure_maps = {} if not federated_only: self.substantiate_stamp() if not crypto_power or (TLSHostingPower not in crypto_power._power_ups): # TODO: Maybe we want _power_ups to be public after all? # We'll hook all the TLS stuff up unless the crypto_power was already passed. if is_me: self.suspicious_activities_witnessed = {'vladimirs': [], 'bad_treasure_maps': []} rest_routes = ProxyRESTRoutes( db_name=db_name, db_filepath=db_filepath, network_middleware=self.network_middleware, federated_only=self.federated_only, treasure_map_tracker=self.treasure_maps, node_tracker=self.known_nodes, node_bytes_caster=self.__bytes__, work_order_tracker=self._work_orders, node_recorder=self.remember_node, stamp=self.stamp, verifier=self.verify_from, suspicious_activity_tracker=self.suspicious_activities_witnessed, certificate_dir=self.known_certificates_dir, ) rest_server = ProxyRESTServer( rest_host=rest_host, rest_port=rest_port, routes=rest_routes, ) self.rest_url = rest_server.rest_url self.datastore = rest_routes.datastore # TODO: Maybe organize this better? tls_hosting_keypair = HostingKeypair( common_name=self.checksum_public_address, private_key=tls_private_key, curve=tls_curve, host=rest_host, certificate=certificate, certificate_dir=self.known_certificates_dir) tls_hosting_power = TLSHostingPower(rest_server=rest_server, keypair=tls_hosting_keypair) else: # Unless the caller passed a crypto power, we'll make our own TLSHostingPower for this stranger. rest_server = ProxyRESTServer( rest_host=rest_host, rest_port=rest_port ) if certificate or certificate_filepath: tls_hosting_power = TLSHostingPower(rest_server=rest_server, certificate_filepath=certificate_filepath, certificate=certificate, certificate_dir=self.known_certificates_dir, common_name=self.checksum_public_address,) else: tls_hosting_keypair = HostingKeypair( common_name=self.checksum_public_address, curve=tls_curve, host=rest_host, certificate_filepath=certificate_filepath, certificate_dir=self.known_certificates_dir) tls_hosting_power = TLSHostingPower(rest_server=rest_server, keypair=tls_hosting_keypair) self._crypto_power.consume_power_up(tls_hosting_power) # Make this work for not me for certificate to work else: self.log.info("Not adhering rest_server; we'll use the one on crypto_power..") certificate_filepath = self._crypto_power.power_ups(TLSHostingPower).keypair.certificate_filepath certificate = self._crypto_power.power_ups(TLSHostingPower).keypair.certificate # VerifiableNode.from_tls_hosting_power(tls_hosting_power=self._crypto_power.power_ups(TLSHostingPower)) # TODO: use classmethod VerifiableNode.__init__(self, certificate=certificate, certificate_filepath=certificate_filepath, interface_signature=interface_signature) if is_me: message = "Initialized Self {} | {}".format(self.__class__.__name__, self.checksum_public_address) self.log.info(message) else: message = "Initialized Stranger {} | {}".format(self.__class__.__name__, self.checksum_public_address) self.log.debug(message)
def __init__( self, # Ursula rest_host: str, rest_port: int, domains: Set = ( GLOBAL_DOMAIN, ), # For now, serving and learning domains will be the same. certificate: Certificate = None, certificate_filepath: str = None, db_filepath: str = None, is_me: bool = True, interface_signature=None, timestamp=None, # Blockchain identity_evidence: bytes = constants.NOT_SIGNED, checksum_public_address: str = None, # Character password: str = None, abort_on_learning_error: bool = False, federated_only: bool = False, start_learning_now: bool = None, crypto_power=None, tls_curve: EllipticCurve = None, known_nodes: Iterable = None, **character_kwargs) -> None: # # Character # self._work_orders = list() Character.__init__(self, is_me=is_me, checksum_public_address=checksum_public_address, start_learning_now=start_learning_now, federated_only=federated_only, crypto_power=crypto_power, abort_on_learning_error=abort_on_learning_error, known_nodes=known_nodes, domains=domains, **character_kwargs) # # Self-Ursula # if is_me is True: # TODO: 340 self._stored_treasure_maps = dict() # # Staking Ursula # if not federated_only: Miner.__init__(self, is_me=is_me, checksum_address=checksum_public_address) # Access staking node via node's transacting keys TODO: Better handle ephemeral staking self ursula blockchain_power = BlockchainPower( blockchain=self.blockchain, account=self.checksum_public_address) self._crypto_power.consume_power_up(blockchain_power) # Use blockchain power to substantiate stamp, instead of signing key self.substantiate_stamp( password=password) # TODO: Derive from keyring # # ProxyRESTServer and TLSHostingPower # TODO: Maybe we want _power_ups to be public after all? # if not crypto_power or (TLSHostingPower not in crypto_power._power_ups): # # Ephemeral Self-Ursula # if is_me: self.suspicious_activities_witnessed = { 'vladimirs': [], 'bad_treasure_maps': [] } # # REST Server (Ephemeral Self-Ursula) # rest_app, datastore = make_rest_app( db_filepath=db_filepath, network_middleware=self.network_middleware, federated_only=self.federated_only, # TODO: 466 treasure_map_tracker=self.treasure_maps, node_tracker=self.known_nodes, node_bytes_caster=self.__bytes__, work_order_tracker=self._work_orders, node_recorder=self.remember_node, stamp=self.stamp, verifier=self.verify_from, suspicious_activity_tracker=self. suspicious_activities_witnessed, serving_domains=domains, ) # # TLSHostingPower (Ephemeral Self-Ursula) # tls_hosting_keypair = HostingKeypair( curve=tls_curve, host=rest_host, checksum_public_address=self.checksum_public_address) tls_hosting_power = TLSHostingPower( keypair=tls_hosting_keypair, host=rest_host) self.rest_server = ProxyRESTServer( rest_host=rest_host, rest_port=rest_port, rest_app=rest_app, datastore=datastore, hosting_power=tls_hosting_power) # # Stranger-Ursula # else: # TLSHostingPower if certificate or certificate_filepath: tls_hosting_power = TLSHostingPower( host=rest_host, public_certificate_filepath=certificate_filepath, public_certificate=certificate) else: tls_hosting_keypair = HostingKeypair( curve=tls_curve, host=rest_host, generate_certificate=False) tls_hosting_power = TLSHostingPower( host=rest_host, keypair=tls_hosting_keypair) # REST Server # Unless the caller passed a crypto power we'll make our own TLSHostingPower for this stranger. self.rest_server = ProxyRESTServer( rest_host=rest_host, rest_port=rest_port, hosting_power=tls_hosting_power) # # OK - Now we have a ProxyRestServer and a TLSHostingPower for some Ursula # self._crypto_power.consume_power_up(tls_hosting_power) # Consume! # # Verifiable Node # certificate_filepath = self._crypto_power.power_ups( TLSHostingPower).keypair.certificate_filepath certificate = self._crypto_power.power_ups( TLSHostingPower).keypair.certificate Teacher.__init__( self, domains=domains, certificate=certificate, certificate_filepath=certificate_filepath, interface_signature=interface_signature, timestamp=timestamp, identity_evidence=identity_evidence, substantiate_immediately=is_me and not federated_only, ) # # Logging / Updating # if is_me: self.known_nodes.record_fleet_state( additional_nodes_to_track=[self]) message = "THIS IS YOU: {}: {}".format(self.__class__.__name__, self) self.log.info(message) else: message = "Initialized Stranger {} | {}".format( self.__class__.__name__, self) self.log.debug(message)
def deploy(click_config, action, poa, provider_uri, geth, enode, deployer_address, contract_name, allocation_infile, allocation_outfile, registry_infile, registry_outfile, no_compile, amount, recipient_address, config_root, sync, force): """Manage contract and registry deployment""" ETH_NODE = None # # Validate # # Ensure config root exists, because we need a default place to put output files. config_root = config_root or DEFAULT_CONFIG_ROOT if not os.path.exists(config_root): os.makedirs(config_root) # # Connect to Blockchain # if geth: # Spawn geth child process ETH_NODE = NuCypherGethDevnetProcess(config_root=config_root) ETH_NODE.ensure_account_exists(password=click_config.get_password( confirm=True)) ETH_NODE.start() # TODO: Graceful shutdown provider_uri = ETH_NODE.provider_uri # Establish a contract registry from disk if specified registry, registry_filepath = None, (registry_outfile or registry_infile) if registry_filepath is not None: registry = EthereumContractRegistry( registry_filepath=registry_filepath) # Deployment-tuned blockchain connection blockchain = BlockchainDeployerInterface(provider_uri=provider_uri, poa=poa, registry=registry, compiler=SolidityCompiler(), fetch_registry=False, sync_now=sync) # # Deployment Actor # if not deployer_address: for index, address in enumerate(blockchain.client.accounts): click.secho(f"{index} --- {address}") choices = click.IntRange(0, len(blockchain.client.accounts)) deployer_address_index = click.prompt("Select deployer address", default=0, type=choices) deployer_address = blockchain.client.accounts[deployer_address_index] # Verify Address if not force: click.confirm("Selected {} - Continue?".format(deployer_address), abort=True) # TODO: Integrate with Deployer Actor (Character) blockchain.transacting_power = BlockchainPower(blockchain=blockchain, account=deployer_address) deployer = Deployer(blockchain=blockchain, deployer_address=deployer_address) # Verify ETH Balance click.secho(f"\n\nDeployer ETH balance: {deployer.eth_balance}") if deployer.eth_balance == 0: click.secho("Deployer address has no ETH.", fg='red', bold=True) raise click.Abort() if not blockchain.client.is_local: # (~ dev mode; Assume accounts are already unlocked) password = click.prompt("Enter ETH node password", hide_input=True) blockchain.client.unlockAccount(deployer_address, password) # Add ETH Bootnode or Peer if enode: if geth: blockchain.w3.geth.admin.addPeer(enode) click.secho(f"Added ethereum peer {enode}") else: raise NotImplemented # TODO: other backends # # Action switch # if action == 'upgrade': if not contract_name: raise click.BadArgumentUsage( message="--contract-name is required when using --upgrade") existing_secret = click.prompt( 'Enter existing contract upgrade secret', hide_input=True) new_secret = click.prompt('Enter new contract upgrade secret', hide_input=True, confirmation_prompt=True) deployer.upgrade_contract(contract_name=contract_name, existing_plaintext_secret=existing_secret, new_plaintext_secret=new_secret) elif action == 'rollback': existing_secret = click.prompt( 'Enter existing contract upgrade secret', hide_input=True) new_secret = click.prompt('Enter new contract upgrade secret', hide_input=True, confirmation_prompt=True) deployer.rollback_contract(contract_name=contract_name, existing_plaintext_secret=existing_secret, new_plaintext_secret=new_secret) elif action == "contracts": registry_filepath = deployer.blockchain.registry.filepath if os.path.isfile(registry_filepath): click.secho( f"\nThere is an existing contract registry at {registry_filepath}.\n" f"Did you mean 'nucypher-deploy upgrade'?\n", fg='yellow') click.confirm( "Optionally, destroy existing local registry and continue?", abort=True) click.confirm( f"Confirm deletion of contract registry '{registry_filepath}'?", abort=True) os.remove(registry_filepath) # # Deploy Single Contract # if contract_name: # TODO: Handle secret collection for single contract deployment try: deployer_func = deployer.deployers[contract_name] except KeyError: message = f"No such contract {contract_name}. Available contracts are {deployer.deployers.keys()}" click.secho(message, fg='red', bold=True) raise click.Abort() else: # Deploy single contract _txs, _agent = deployer_func() # TODO: Painting for single contract deployment if ETH_NODE: ETH_NODE.stop() return # # Stage Deployment # # Track tx hashes, and new agents __deployment_transactions = dict() __deployment_agents = dict() secrets = click_config.collect_deployment_secrets() click.clear() click.secho(NU_BANNER) w3 = deployer.blockchain.w3 click.secho(f"Current Time ........ {maya.now().iso8601()}") click.secho( f"Web3 Provider ....... {deployer.blockchain.provider_uri}") click.secho( f"Block ............... {deployer.blockchain.client.block_number}") click.secho( f"Gas Price ........... {deployer.blockchain.client.gas_price}") click.secho(f"Deployer Address .... {deployer.checksum_address}") click.secho(f"ETH ................. {deployer.eth_balance}") click.secho( f"Chain ID ............ {deployer.blockchain.client.chain_id}") click.secho( f"Chain Name .......... {deployer.blockchain.client.chain_name}") # Ask - Last chance to gracefully abort if not force: click.secho( "\nDeployment successfully staged. Take a deep breath. \n", fg='green') if click.prompt("Type 'DEPLOY' to continue") != 'DEPLOY': raise click.Abort() # Delay - Last chance to crash and abort click.secho(f"Starting deployment in 3 seconds...", fg='red') time.sleep(1) click.secho(f"2...", fg='yellow') time.sleep(1) click.secho(f"1...", fg='green') time.sleep(1) click.secho(f"Deploying...", bold=True) # # DEPLOY < ------- # txhashes, deployers = deployer.deploy_network_contracts( staker_secret=secrets.staker_secret, policy_secret=secrets.policy_secret, adjudicator_secret=secrets.adjudicator_secret, user_escrow_proxy_secret=secrets.escrow_proxy_secret) # Success __deployment_transactions.update(txhashes) # # Paint # total_gas_used = 0 # TODO: may be faulty for contract_name, transactions in __deployment_transactions.items(): # Paint heading heading = '\n{} ({})'.format( contract_name, deployers[contract_name].contract_address) click.secho(heading, bold=True) click.echo('*' * (42 + 3 + len(contract_name))) for tx_name, txhash in transactions.items(): # Wait for inclusion in the blockchain receipt = deployer.blockchain.w3.eth.waitForTransactionReceipt( txhash) click.secho("OK", fg='green', nl=False, bold=True) # Accumulate gas total_gas_used += int(receipt['gasUsed']) # Paint click.secho(" | {}".format(tx_name), fg='yellow', nl=False) click.secho(" | {}".format(txhash.hex()), fg='yellow', nl=False) click.secho(" ({} gas)".format(receipt['cumulativeGasUsed'])) click.secho("Block #{} | {}\n".format( receipt['blockNumber'], receipt['blockHash'].hex())) # Paint outfile paths click.secho( "Cumulative Gas Consumption: {} gas".format(total_gas_used), bold=True, fg='blue') registry_outfile = deployer.blockchain.registry.filepath click.secho('Generated registry {}'.format(registry_outfile), bold=True, fg='blue') # Save transaction metadata receipts_filepath = deployer.save_deployment_receipts( transactions=__deployment_transactions) click.secho(f"Saved deployment receipts to {receipts_filepath}", fg='blue', bold=True) elif action == "allocations": if not allocation_infile: allocation_infile = click.prompt("Enter allocation data filepath") click.confirm("Continue deploying and allocating?", abort=True) deployer.deploy_beneficiaries_from_file( allocation_data_filepath=allocation_infile, allocation_outfile=allocation_outfile) elif action == "transfer": token_agent = NucypherTokenAgent(blockchain=blockchain) click.confirm( f"Transfer {amount} from {token_agent.contract_address} to {recipient_address}?", abort=True) txhash = token_agent.transfer( amount=amount, sender_address=token_agent.contract_address, target_address=recipient_address) click.secho(f"OK | {txhash}") elif action == "destroy-registry": registry_filepath = deployer.blockchain.registry.filepath click.confirm( f"Are you absolutely sure you want to destroy the contract registry at {registry_filepath}?", abort=True) os.remove(registry_filepath) click.secho(f"Successfully destroyed {registry_filepath}", fg='red') else: raise click.BadArgumentUsage(message=f"Unknown action '{action}'") if ETH_NODE: ETH_NODE.stop()