def test_transfer_with_overdraft(one_node_network): acct1 = Account(1) acct2 = Account(2) node: DockerNode = one_node_network.docker_nodes[0] # Transfer 1000000 from genesis... to acct1... # For compatibility with EE with no execution cost # payment_contract="transfer_to_account.wasm" block_hash = node.transfer_to_account( to_account_id=1, amount=1000000, from_account_id="genesis", payment_contract="transfer_to_account.wasm", ) deploys = node.client.show_deploys(block_hash) assert not deploys[0].is_error, f"error_message: {deploys[0].error_message}" # Response not used, but assures account exist _ = account_state(node, block_hash, acct1) # Should error as account doesn't exist. with raises(Exception): _ = account_state(block_hash, acct2.public_key_hex) # No API currently exists for getting balance to check transfer. # Transfer 750000 from acct1... to acct2... block_hash = node.transfer_to_account( to_account_id=2, amount=750000, from_account_id=1, payment_contract="transfer_to_account.wasm", ) deploys = node.client.show_deploys(block_hash) assert not deploys[0].is_error, f"error_message: {deploys[0].error_message}" # Response not used, but assures account exist _ = account_state(node, block_hash, acct2) # Transfer 750000000000 from acct1... to acct2... # Should fail with acct1 overdrawn. Requires assert in contract to generate is_error. with raises(Exception): _ = node.transfer_to_account( to_account_id=2, amount=750000000000, from_account_id=1, payment_contract="transfer_to_account.wasm", )
def create_associate_deploy(acct_num: int): """ Add associated key of acct_num + 1 to acct_num account """ acct = Account(acct_num) associated_acct = Account(acct_num + 1) args = ABI.args( [ABI.account(associated_acct.public_key_binary), ABI.u32(1)]) _, deploy_hash_bytes = node.p_client.deploy( from_address=acct.public_key_hex, session_contract=Contract.ADD_ASSOCIATED_KEY, public_key=acct.public_key_path, private_key=acct.private_key_path, session_args=args, ) return deploy_hash_bytes.hex()
def test_account(self, node, amount=TEST_ACCOUNT_INITIAL_BALANCE) -> Account: name = test_name() if not name: # This happens when a thread tries to deploy. # Name of the test that spawned the thread does not appear on the inspect.stack. # Threads that don't want to use genesis account # should pass from_address, public_key and private_key to deploy explicitly. return self.genesis_account elif name not in self.test_accounts: with self._accounts_lock: self.test_accounts[name] = Account(self.next_key) logging.info( f"=== Creating test account #{self.next_key} {self.test_accounts[name].public_key_hex} for {name} " ) block_hash = node.transfer_to_account(self.next_key, amount) # Waiting for the block with transaction that created new account to propagate to all nodes. # Expensive, but some tests may rely on it. wait_for_block_hash_propagated_to_all_nodes( node.cl_network.docker_nodes, block_hash) for deploy in node.client.show_deploys(block_hash): assert (deploy.is_error is False), f"Account creation failed: {deploy}" self.next_key += 1 return self.test_accounts[name]
def test_scala_client_balance(one_node_network): node: DockerNode = one_node_network.docker_nodes[0] accounts = [Account(i) for i in range(1, 4)] block_hash = list(node.p_client.show_blocks(1))[0].summary.block_hash.hex() initial = [ balance(node, account.public_key_hex, block_hash) for account in accounts ] # Perform multiple transfers with end result of Acct1 = 200, Acct2 = 100, Acct3 = 700 hashes = node.transfer_to_accounts([(1, 1000), (2, 800, 1), (3, 700, 2)]) assert ( node.d_client.get_balance( account_address=accounts[0].public_key_hex, block_hash=hashes[-1] ) == initial[0] + 200 ) assert ( node.d_client.get_balance( account_address=accounts[1].public_key_hex, block_hash=hashes[-1] ) == initial[1] + 100 ) assert ( node.d_client.get_balance( account_address=accounts[2].public_key_hex, block_hash=hashes[-1] ) == initial[2] + 700 )
def test_transfer_with_overdraft(one_node_network): def account_state(block_hash, account): return node.d_client.query_state(block_hash=block_hash, key_type='address', key=account, path='') acct1 = Account(1) acct2 = Account(2) node: DockerNode = one_node_network.docker_nodes[0] # Transfer 1000000 from genesis... to acct1... block_hash = node.transfer_to_account(to_account_id=1, amount=1000000, from_account_id='genesis') deploys = node.client.show_deploys(block_hash) assert not deploys[0].is_error, f"error_message: {deploys[0].error_message}" # Response not used, but assures account exist _ = account_state(block_hash, acct1.public_key_hex) # Should error as account doesn't exist. with raises(Exception): _ = account_state(block_hash, acct2.public_key_hex) # No API currently exists for getting balance to check transfer. # Transfer 750000 from acct1... to acct2... block_hash = node.transfer_to_account(to_account_id=2, amount=750000, from_account_id=1) deploys = node.client.show_deploys(block_hash) assert not deploys[0].is_error, f"error_message: {deploys[0].error_message}" # Response not used, but assures account exist _ = account_state(block_hash, acct2.public_key_hex) # Transfer 750000 from acct1... to acct2... # Should fail with acct1 overdrawn. Requires assert in contract to generate is_error. with raises(Exception): _ = node.transfer_to_account(to_account_id=2, amount=750000, from_account_id=1)
def create_bonds_file(self) -> None: N = self.NUMBER_OF_BONDS path = f"{self.host_genesis_dir}/bonds.txt" os.makedirs(os.path.dirname(path)) with open(path, "a") as f: for i, pair in enumerate( Account(i) for i in range(FIRST_VALIDATOR_ACCOUNT, FIRST_VALIDATOR_ACCOUNT + N)): bond = N + 2 * i f.write(f"{pair.public_key} {bond}\n")
def bond( self, session_contract: str, payment_contract: str, amount: int, from_account_id: Union[str, int] = "genesis", ) -> str: abi_json_args = json.dumps([{"u32": amount}]) return self._deploy_and_propose_with_abi_args( session_contract, payment_contract, Account(from_account_id), abi_json_args )
def unbond( self, session_contract: str, payment_contract: str, maybe_amount: Optional[int] = None, from_account_id: Union[str, int] = "genesis", ) -> str: amount = 0 if maybe_amount is None else maybe_amount abi_json_args = json.dumps([{"u32": amount}]) return self._deploy_and_propose_with_abi_args( session_contract, payment_contract, Account(from_account_id), abi_json_args )
def test_transfer_to_accounts(node): # Notated uses of account ids in common.py a_id = 300 b_id = 299 c_id = 298 initial_amt = 100000000 acct_a = Account(a_id) acct_b = Account(b_id) acct_c = Account(c_id) # Setup accounts with enough to transfer and pay for transfer node.transfer_to_accounts([(a_id, initial_amt), (b_id, initial_amt)]) with raises(Exception): # Acct a has not enough funds so it should fail node.transfer_to_account( to_account_id=c_id, amount=initial_amt * 10, from_account_id=a_id ) # This is throwing an Exit 1. (Transfer Failure in Contract) node.transfer_to_account(to_account_id=c_id, amount=700, from_account_id=b_id) blocks = node.p_client.show_blocks(10) block = blocks.__next__() block_hash = block.summary.block_hash.hex() acct_a_bal = node.d_client.get_balance(acct_a.public_key_hex, block_hash) assert ( acct_a_bal < initial_amt ), "Should not have transferred any money, but spent on payment" acct_b_bal = node.d_client.get_balance(acct_b.public_key_hex, block_hash) assert ( acct_b_bal < initial_amt - 700 ), "Should be transfer_amt - 700 - payment for transfer" acct_c_bal = node.d_client.get_balance(acct_c.public_key_hex, block_hash) assert acct_c_bal == 700, "Should be result of only transfers in"
def test_error_in_payment_contract(payment_node_network): network = payment_node_network node0: DockerNode = network.docker_nodes[0] node0.use_docker_client() blocks = parse_show_blocks(node0.d_client.show_blocks(1000)) genesis_hash = blocks[0].summary.block_hash assert len( blocks) == 1 # There should be only one block - the genesis block genesis_balance = node0.client.get_balance( account_address=GENESIS_ACCOUNT.public_key_hex, block_hash=genesis_hash) assert genesis_balance == INITIAL_MOTES_AMOUNT from_account = Account("genesis") to_account = Account(1) session_args = ABI.args([ ABI.account(bytes.fromhex(to_account.public_key_hex)), ABI.u32(10**7) ]) payment_args = ABI.args([ABI.u512(10**6)]) response, deploy_hash_bytes = node0.p_client.deploy( from_address=from_account.public_key_hex, session_contract=Contract.TRANSFER_TO_ACCOUNT, payment_contract=Contract.ERR_STANDARD_PAYMENT, public_key=from_account.public_key_path, private_key=from_account.private_key_path, gas_price=1, session_args=session_args, payment_args=payment_args, ) genesis_balance_after_transfer = node0.client.get_balance( account_address=GENESIS_ACCOUNT.public_key_hex, block_hash=parse_show_blocks( node0.d_client.show_blocks(1000))[0].summary.block_hash, ) assert genesis_balance == genesis_balance_after_transfer
def test_error_in_payment_contract(payment_node_network): network = payment_node_network node0: DockerNode = network.docker_nodes[0] node0.use_docker_client() blocks = parse_show_blocks(node0.d_client.show_blocks(1000)) genesis_hash = blocks[0].summary.block_hash assert len( blocks) == 1 # There should be only one block - the genesis block genesis_balance = node0.client.get_balance( account_address=GENESIS_ACCOUNT.public_key_hex, block_hash=genesis_hash) assert genesis_balance == 10**9 from_account = Account("genesis") to_account = Account(1) args_json = json.dumps([{ "account": to_account.public_key_hex }, { "u32": 10**7 }]) ABI = node0.p_client.abi response, deploy_hash_bytes = node0.p_client.deploy( from_address=from_account.public_key_hex, session_contract="transfer_to_account.wasm", payment_contract="err_standard_payment.wasm", public_key=from_account.public_key_path, private_key=from_account.private_key_path, gas_price=1, gas_limit=MAX_PAYMENT_COST / CONV_RATE, session_args=ABI.args_from_json(args_json), payment_args=ABI.args([ABI.u512(10**6)]), ) genesis_balance_after_transfer = node0.client.get_balance( account_address=GENESIS_ACCOUNT.public_key_hex, block_hash=parse_show_blocks( node0.d_client.show_blocks(1000))[0].summary.block_hash, ) assert genesis_balance == genesis_balance_after_transfer
def test_transfer_with_overdraft(node): # Notated uses of account ids in common.py a_id = 297 b_id = 296 acct_a = Account(a_id) acct_b = Account(b_id) initial_amt = 100000000 block_hash = node.transfer_to_account(to_account_id=a_id, amount=initial_amt) deploys = node.client.show_deploys(block_hash) assert not deploys[0].is_error, f"error_message: {deploys[0].error_message}" # Response not used, but assures account exist _ = account_state(node, block_hash, acct_a) # Should error as account doesn't exist. with raises(Exception): _ = account_state(block_hash, acct_b.public_key_hex) # No API currently exists for getting balance to check transfer. # Transfer 750000 from acct1... to acct2... block_hash = node.transfer_to_account( to_account_id=b_id, amount=750, from_account_id=a_id ) deploys = node.client.show_deploys(block_hash) assert not deploys[0].is_error, f"error_message: {deploys[0].error_message}" # Response not used, but assures account exist _ = account_state(node, block_hash, acct_b) # Should fail with acct_a overdrawn. Requires assert in contract to generate is_error. with raises(Exception): _ = node.transfer_to_account( to_account_id=b_id, amount=initial_amt * 10, from_account_id=a_id )
def test_basic_transfer_to_account(payment_node_network): network = payment_node_network node = network.docker_nodes[0] to_account = Account(1) transfer_to_account( node, node.genesis_account.public_key_hex, to_account.public_key_hex, 1000000, public_key=node.genesis_account.public_key_path, private_key=node.genesis_account.private_key_path, )
def bond( self, session_contract: str, amount: int, from_account_id: Union[str, int] = "genesis", ) -> str: # NOTE: The Scala client is bundled with a bond contract that expects long_value, # but the integration test version expects int. json_args = json.dumps([{ "name": "amount", "value": { "int_value": amount } }]) return self._deploy_and_propose_with_abi_args(session_contract, Account(from_account_id), json_args)
def test_scala_client_balance(one_node_network): node: DockerNode = one_node_network.docker_nodes[0] # This is only in scala client, need to verify we are using correct one. node.use_docker_client() acct1, acct2, acct3 = [Account(i) for i in range(1, 4)] # Perform multiple transfers with end result of Acct1 = 200, Acct2 = 100, Acct3 = 700 hashes = node.transfer_to_accounts([(1, 1000), (2, 800, 1), (3, 700, 2)]) assert node.client.get_balance(account_address=acct1.public_key_hex, block_hash=hashes[-1]) == 200 assert node.client.get_balance(account_address=acct2.public_key_hex, block_hash=hashes[-1]) == 100 assert node.client.get_balance(account_address=acct3.public_key_hex, block_hash=hashes[-1]) == 700
def test_non_account_precondition_failure(trillion_payment_node_network): node = trillion_payment_node_network.docker_nodes[0] # Getting a non-existent account non_existent_account = Account(300) # Client returns deploy hash, but will not stay in buffer for proposes. _, deploy_hash = node.p_client.deploy( from_address=non_existent_account.public_key_hex, public_key=non_existent_account.public_key_path, private_key=non_existent_account.private_key_path, session_contract=Contract.HELLONAME, ) # Will have InternalError as no deploys to propose with pytest.raises(Exception) as e: _ = node.p_client.propose() # Verify reason for propose failure assert e.typename == "InternalError" assert str(e.value) == "StatusCode.OUT_OF_RANGE: No new deploys."
def unbond( self, session_contract: str, maybe_amount: Optional[int] = None, from_account_id: Union[str, int] = "genesis", ) -> str: # NOTE: The Scala client is bundled with an unbond contract that expects an optional # value, but the integration tests have their own version which expects an int # and turns 0 into None inside the contract itself # amount = {} if maybe_amount is None else {"int_value": maybe_amount} # json_args = json.dumps( # [{"name": "amount", "value": {"optional_value": amount}}] # ) json_args = json.dumps([{ "name": "amount", "value": { "int_value": maybe_amount or 0 } }]) return self._deploy_and_propose_with_abi_args(session_contract, Account(from_account_id), json_args)
def test_scala_client_balance(one_node_network): node: DockerNode = one_node_network.docker_nodes[0] accounts = [Account(i) for i in range(1, 3)] block_hash = list(node.p_client.show_blocks(1))[0].summary.block_hash.hex() initial_bal = { account.file_id: balance(node, account.public_key_hex, block_hash) for account in accounts } transfer_amt = {1: 100, 2: 800} # All have to come from genesis to have enough to pay for transaction hashes = node.transfer_to_accounts([(1, transfer_amt[1]), (2, transfer_amt[2])]) current_bal = { account.file_id: balance(node, account.public_key_hex, hashes[-1]) for account in accounts } for file_id in (1, 2): assert current_bal[file_id] == initial_bal[file_id] + transfer_amt[file_id]
def get_key(self): key_pair = Account(self._next_key_number) self._next_key_number += 1 return key_pair
def transfer_to_account( self, to_account_id: int, amount: int, from_account_id: Union[str, int] = "genesis", session_contract: str = Contract.TRANSFER_TO_ACCOUNT, payment_contract: str = Contract.STANDARD_PAYMENT, payment_args: bytes = MAX_PAYMENT_ABI, gas_price: int = 1, is_deploy_error_check: bool = True, ) -> str: """ Performs a transfer using the from account if given (or genesis if not) :param to_account_id: 1-20 index of test account for transfer into :param amount: amount of motes to transfer (mote = smallest unit of token) :param from_account_id: default 'genesis' account, but previously funded account_id is also valid. :param session_contract: session contract to execute. :param payment_contract: Payment contract to execute. :param payment_args: Payment Amount ABI :param gas_price: Gas price :param is_deploy_error_check: Check that amount transfer is success. :returns block_hash in hex str """ logging.info(f"=== Transferring {amount} to {to_account_id}") assert ( is_valid_account(to_account_id) and to_account_id != "genesis" ), "Can transfer only to non-genesis accounts in test framework (1-20)." assert is_valid_account( from_account_id ), "Must transfer from a valid account_id: 1-20 or 'genesis'" from_account = Account(from_account_id) to_account = Account(to_account_id) ABI = self.p_client.abi session_args = ABI.args( [ABI.account(to_account.public_key_binary), ABI.u32(amount)]) response, deploy_hash_bytes = self.p_client.deploy( from_address=from_account.public_key_hex, session_contract=session_contract, payment_contract=payment_contract, public_key=from_account.public_key_path, private_key=from_account.private_key_path, gas_price=gas_price, session_args=session_args, payment_args=payment_args, ) deploy_hash_hex = deploy_hash_bytes.hex() assert len(deploy_hash_hex) == 64 response = self.p_client.propose() block_hash = response.block_hash.hex() assert len(deploy_hash_hex) == 64 if is_deploy_error_check: for deploy_info in self.p_client.show_deploys(block_hash): if deploy_info.is_error: raise Exception( f"transfer_to_account: {deploy_info.error_message}") return block_hash
""" Accounts have two threshold values: key_management_threshold deploy_threshold Both are initialized at 1. """ ADD_KEY_CONTRACT = "add_associated_key.wasm" # ABI: Account - Weight REMOVE_KEY_CONTRACT = "remove_associated_key.wasm" # ABI: Account UPDATE_KEY_CONTRACT = "update_associated_key.wasm" # ABI: Account - Weight SET_THRESHOLDS_CONTRACT = "set_key_thresholds.wasm" # ABI: KeyWeight - DeployWeight IDENTITY_KEY = Account(1) # 9d39 DEPLOY_KEY = Account(2) # 4e74 DEPLOY_KEY_WEIGHT = 10 KEY_MGMT_KEY = Account(3) # 58f7 KEY_MGMT_KEY_WEIGHT = 20 HIGH_WEIGHT_KEY = Account(4) # 1ca8 HIGH_WEIGHT_KEY_WEIGHT = 200 INITIAL_ACCOUNT_VALUE = 1000000000 def _add_update_associate_key( node, weight_key: Account, key: Account, weight: int, contract: str ): """ Handles both add and update calls due to commonality """ session_args = ABI.args( [ABI.account(bytes.fromhex(key.public_key_hex)), ABI.u32(weight)]
def test_key_management(one_node_network): onn = one_node_network node = onn.docker_nodes[0] node.use_python_client() identity_key = Account(1) # 9d39 node.transfer_to_account(1, 1000000) deploy_key = Account(2) # 4e74 key_mgmt_key = Account(3) # 58f7 high_weight_key = Account(4) # 1ca8 # Create deploy_acct key with weight of 10 block_hash = add_associated_key( node, identity_key=identity_key.public_key_hex, weight_key=identity_key, key=deploy_key.public_key_hex, weight=10, ) assert_deploy_is_not_error(node, block_hash) # Create key_mgmt key with weight of 20 block_hash = add_associated_key( node, identity_key=identity_key.public_key_hex, weight_key=identity_key, key=key_mgmt_key.public_key_hex, weight=20, ) assert_deploy_is_not_error(node, block_hash) # Create high weight key for updating once we exceed weights of others block_hash = add_associated_key( node, identity_key=identity_key.public_key_hex, weight_key=key_mgmt_key, key=high_weight_key.public_key_hex, weight=200, ) assert_deploy_is_not_error(node, block_hash) # Removing identity key from associated keys block_hash = remove_associated_key( node, identity_key=identity_key.public_key_hex, weight_key=key_mgmt_key, key=identity_key.public_key_hex, ) assert_deploy_is_not_error(node, block_hash) # Start thresholds under key weights set_key_thresholds( node, identity_key=identity_key.public_key_hex, weight_key=key_mgmt_key, deploy_weight=9, key_management_weight=19, ) assert_deploy_is_not_error(node, block_hash) # Remove deploy key block_hash = remove_associated_key( node, key=deploy_key.public_key_hex, identity_key=identity_key.public_key_hex, weight_key=key_mgmt_key, ) assert_deploy_is_not_error(node, block_hash) # Deploy with removed key with pytest.raises(Exception): block_hash = node.deploy_and_propose( from_address=identity_key.public_key_hex, payment_contract=HELLO_NAME_CONTRACT, session_contract=HELLO_NAME_CONTRACT, public_key=deploy_key.public_key_path, private_key=deploy_key.private_key_path, ) NonceRegistry.revert(identity_key.public_key_hex) # Add deploy_key back block_hash = add_associated_key( node, identity_key=identity_key.public_key_hex, weight_key=high_weight_key, key=deploy_key.public_key_hex, weight=10, ) assert_deploy_is_not_error(node, block_hash) # Deploy with weight over threshold block_hash = node.deploy_and_propose( from_address=identity_key.public_key_hex, payment_contract=HELLO_NAME_CONTRACT, session_contract=HELLO_NAME_CONTRACT, public_key=deploy_key.public_key_path, private_key=deploy_key.private_key_path, ) assert_deploy_is_not_error(node, block_hash) # Key management weight over threshold block_hash = set_key_thresholds( node, identity_key=identity_key.public_key_hex, weight_key=key_mgmt_key, deploy_weight=10, key_management_weight=20, ) assert_deploy_is_not_error(node, block_hash) # Deploy with weight at threshold block_hash = node.deploy_and_propose( from_address=identity_key.public_key_hex, payment_contract=HELLO_NAME_CONTRACT, session_contract=HELLO_NAME_CONTRACT, public_key=deploy_key.public_key_path, private_key=deploy_key.private_key_path, ) assert_deploy_is_not_error(node, block_hash) # Key management weight at threshold block_hash = set_key_thresholds( node, identity_key=identity_key.public_key_hex, weight_key=key_mgmt_key, deploy_weight=11, key_management_weight=21, ) assert_deploy_is_not_error(node, block_hash) # Deploy with weight under threshold with pytest.raises(Exception): block_hash = node.deploy_and_propose( from_address=identity_key.public_key_hex, payment_contract=HELLO_NAME_CONTRACT, session_contract=HELLO_NAME_CONTRACT, public_key=deploy_key.public_key_path, private_key=deploy_key.private_key_path, ) NonceRegistry.revert(identity_key.public_key_hex) # TODO: Figure out race condition and put proper check here rather than sleep. # We sometimes get an issue if we don't pause after the above exception. Need to track down. sleep(1) # Testing deploy after failure for Nonce issue. block_hash = node.deploy_and_propose( from_address=identity_key.public_key_hex, payment_contract=HELLO_NAME_CONTRACT, session_contract=HELLO_NAME_CONTRACT, public_key=high_weight_key.public_key_path, private_key=high_weight_key.private_key_path, ) assert_deploy_is_not_error(node, block_hash) # Key management weight under threshold block_hash = set_key_thresholds( node, identity_key=identity_key.public_key_hex, weight_key=key_mgmt_key, deploy_weight=10, key_management_weight=21, ) # First process of contract fails with a revert(100) assert_deploy_is_error(node, block_hash, "Exit code: 100") # Key management weight under threshold block_hash = remove_associated_key( node, key=deploy_key.public_key_hex, identity_key=identity_key.public_key_hex, weight_key=key_mgmt_key, ) # Contract fails with revert(1) assert_deploy_is_error(node, block_hash, "Exit code: 1") # Key management weight under threshold block_hash = add_associated_key( node, identity_key=identity_key.public_key_hex, weight_key=key_mgmt_key, key=identity_key.public_key_hex, weight=10, ) # Contract fails with revert(100) assert_deploy_is_error(node, block_hash, "Exit code: 100") # Key management weight under threshold block_hash = update_associated_key( node, identity_key=identity_key.public_key_hex, weight_key=key_mgmt_key, key=identity_key.public_key_hex, weight=10, ) # Contract fails with revert(100) assert_deploy_is_error(node, block_hash, "Exit code: 100")
def transfer_to_account( self, to_account_id: int, amount: int, from_account_id: Union[str, int] = "genesis", session_contract: str = "transfer_to_account.wasm", payment_contract: str = "standard_payment.wasm", gas_price: int = 1, gas_limit: int = MAX_PAYMENT_COST / CONV_RATE, is_deploy_error_check: bool = True, ) -> str: """ Performs a transfer using the from account if given (or genesis if not) :param to_account_id: 1-20 index of test account for transfer into :param amount: amount of motes to transfer (mote = smallest unit of token) :param from_account_id: default 'genesis' account, but previously funded account_id is also valid. :param session_contract: session contract to execute. :param payment_contract: Payment contract to execute. :param gas_price: Gas price :param gas_limit: Max gas price that can be expended. :param is_deploy_error_check: Check that amount transfer is success. :returns block_hash in hex str """ logging.info(f"=== Transfering {amount} to {to_account_id}") assert ( is_valid_account(to_account_id) and to_account_id != "genesis" ), "Can transfer only to non-genesis accounts in test framework (1-20)." assert is_valid_account( from_account_id ), "Must transfer from a valid account_id: 1-20 or 'genesis'" from_account = Account(from_account_id) to_account = Account(to_account_id) ABI = self.p_client.abi session_args = ABI.args( [ABI.account(to_account.public_key_binary), ABI.u32(amount)] ) # Until payment is on for all, we have to fix the default payment args if not self.config.is_payment_code_enabled: payment_contract = session_contract if session_contract == payment_contract: # Compatibility mode with the way things worked before execution cost era payment_args = None else: # NOTE: this shouldn't necesserily be amount # but this is temporary, anyway, eventually we want all tests # running with execution cost on. payment_args = ABI.args([ABI.u512(amount)]) response, deploy_hash_bytes = self.p_client.deploy( from_address=from_account.public_key_hex, session_contract=session_contract, payment_contract=payment_contract, public_key=from_account.public_key_path, private_key=from_account.private_key_path, gas_price=gas_price, gas_limit=gas_limit, session_args=session_args, payment_args=payment_args, ) deploy_hash_hex = deploy_hash_bytes.hex() assert len(deploy_hash_hex) == 64 response = self.p_client.propose() block_hash = response.block_hash.hex() assert len(deploy_hash_hex) == 64 if is_deploy_error_check: for deploy_info in self.p_client.show_deploys(block_hash): assert deploy_info.is_error is False return block_hash