def test_two_network_repeated_deploy(two_node_network):
    """
    Test that a repeated deploy is rejected on a different node
    """
    nodes = two_node_network.docker_nodes
    clis = [CLI(node) for node in nodes]
    accounts = (Account("genesis"), Account(1))

    # Generate and save signed_deploy
    with signed_deploy_file_path(clis[0], accounts[0]) as signed_deploy_path:
        # First deployment of signed_deploy from node-0 should succeed
        deploy_hash = clis[0]("send-deploy", "-i", signed_deploy_path)
        block_hash = nodes[0].wait_for_deploy_processed_and_get_block_hash(deploy_hash)

        deploy_info = clis[0]("show-deploy", deploy_hash)
        assert not deploy_info.processing_results[0].is_error

        wait_for_block_hash_propagated_to_all_nodes(nodes, block_hash)

        # Second deployment of signed_deploy to node-1 should fail.
        deploy_hash = clis[1]("send-deploy", "-i", signed_deploy_path)
        deploy_info = clis[1]("show-deploy", deploy_hash)
        assert not deploy_info.processing_results[0].is_error

        result = nodes[1].p_client.client.wait_for_deploy_processed(deploy_hash)
        assert "DISCARDED" in str(result)
        assert "Duplicate or expired" in str(result)
 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("account", associated_acct.public_key_binary),
         ABI.u32("amount", 1),
     ])
     return 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,
     )
Beispiel #3
0
def test_unbonding_without_bonding(one_node_network_fn):
    """
    Feature file: consensus.feature
    Scenario: unbonding a validator node which was not bonded to an existing network.
    """
    bonding_amount = 1
    account = Account(BONDING_ACCT)
    assert_pre_state_of_network(one_node_network_fn)
    add_funded_account_to_network(one_node_network_fn, BONDING_ACCT)
    assert (
        len(one_node_network_fn.docker_nodes) == 2
    ), "Total number of nodes should be 2."

    node0, node1 = one_node_network_fn.docker_nodes
    r = node0.d_client.unbond(bonding_amount, account.private_key_docker_path)
    assert "Success!" in r
    r = node0.d_client.propose()
    block_hash = extract_block_hash_from_propose_output(r)
    assert block_hash is not None
    # block_hash, account = unbond_from_network(one_node_network_fn, bonding_amount, BONDING_ACCT)

    r = node0.client.show_deploys(block_hash)[0]
    assert r.is_error is True
    assert r.error_message == "Exit code: 65280"

    block = node1.client.show_block(block_hash)
    block_ds = parse_show_block(block)
    bonds = list(
        filter(
            lambda x: x.validator_public_key == account.public_key_hex,
            block_ds.summary.header.state.bonds,
        )
    )
    assert len(bonds) == 0
 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]
Beispiel #5
0
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 test_one_network_repeated_deploy(one_node_network_fn):
    """
    Test that a repeated deploy is rejected on same node.
    """
    node = one_node_network_fn.docker_nodes[0]
    cli = CLI(node)
    account = Account("genesis")

    # Generate and save signed_deploy
    with signed_deploy_file_path(cli, account) as signed_deploy_path:
        # First deployment of signed_deploy, should succeed
        deploy_hash = cli("send-deploy", "-i", signed_deploy_path)
        deploy_info = cli.node.p_client.client.wait_for_deploy_processed(deploy_hash)
        blocks_with_deploy = [
            bi.block_info.summary.block_hash.hex()
            for bi in deploy_info.processing_results
        ]

        blocks_with_deploy_after_replay = [
            bi.block_info.summary.block_hash.hex()
            for bi in deploy_info.processing_results
        ]
        assert not deploy_info.processing_results[0].is_error

        # Second deployment of signed_deploy should fail
        deploy_hash = cli("send-deploy", "-i", signed_deploy_path)

        deploy_info = cli.node.p_client.client.wait_for_deploy_processed(deploy_hash)
        assert not deploy_info.processing_results[0].is_error
        blocks_with_deploy_after_replay = [
            bi.block_info.summary.block_hash.hex()
            for bi in deploy_info.processing_results
        ]
        assert blocks_with_deploy_after_replay == blocks_with_deploy
Beispiel #7
0
def unbond_from_network(
    network: OneNodeNetwork, bonding_amount: int, account_number: int
):
    node = network.docker_nodes[1]
    account = Account(account_number)
    r = node.d_client.unbond(bonding_amount, account.private_key_docker_path)
    assert "Success!" in r
    r = node.d_client.propose()
    block_hash = extract_block_hash_from_propose_output(r)
    assert block_hash is not None
    return block_hash, account
Beispiel #8
0
 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
     )
Beispiel #9
0
 def unbond(
     self,
     session_contract: str,
     maybe_amount: Optional[int] = None,
     from_account_id: Union[str, int] = "genesis",
 ) -> str:
     json_args = json.dumps(
         [{"name": "amount", "value": {"int_value": maybe_amount or 0}}]
     )
     return self._deploy_with_abi_args_and_get_block_hash(
         session_contract, Account(from_account_id), json_args
     )
Beispiel #10
0
def bond_to_the_network(network: OneNodeNetwork, bond_amount: int, account_number: int):
    # Using account that will not exist in bonds.txt from high number
    account = Account(account_number)
    node0, node1 = network.docker_nodes
    response = node0.d_client.bond(
        amount=bond_amount, private_key=account.private_key_docker_path
    )
    assert "Success!" in response
    response = node0.d_client.propose()
    block_hash = extract_block_hash_from_propose_output(response)
    assert block_hash is not None
    return block_hash, account
Beispiel #11
0
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"
Beispiel #12
0
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 bond_to_the_network(network: OneNodeNetwork, bond_amount: int,
                        account_number: int, cli_method):
    account = Account(account_number)
    node0, node1 = network.docker_nodes
    cli = cli_method(node0)
    # fmt: off
    deploy_hash = cli("bond", "--amount", bond_amount, '--private-key',
                      cli.private_key_path(account), '--payment-amount',
                      EXECUTION_PAYMENT_AMOUNT)
    # fmt: on
    block_hash = cli.node.wait_for_deploy_processed_and_get_block_hash(
        deploy_hash, on_error_raise=False)
    return block_hash, account
def unbond_from_network(network: OneNodeNetwork, bonding_amount: int,
                        account_number: int, cli_method):
    node = network.docker_nodes[1]
    account = Account(account_number)
    cli = cli_method(node)
    # fmt: off
    deploy_hash = cli("unbond", "--amount", bonding_amount, "--private-key",
                      cli.private_key_path(account), "--payment-amount",
                      EXECUTION_PAYMENT_AMOUNT)
    # fmt: on
    block_hash = cli.node.wait_for_deploy_processed_and_get_block_hash(
        deploy_hash, on_error_raise=False)
    return block_hash, account
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("account", to_account.public_key_hex),
        ABI.u64("amount", 10**7)
    ])
    payment_args = ABI.args([ABI.u512("amount", 10**6)])

    node0.p_client.deploy(
        from_address=from_account.public_key_hex,
        session_contract=Contract.TRANSFER_TO_ACCOUNT,
        payment_contract=Contract.DIRECT_REVERT,
        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 unbond_from_network(network: OneNodeNetwork, bonding_amount: int,
                        account_number: int):
    node = network.docker_nodes[1]
    account = Account(account_number)
    cli = CLI(node)
    # fmt: off
    cli("unbond", "--amount", bonding_amount, '--public-key',
        account.public_key_path, "--private-key", account.private_key_path,
        "--payment-amount", EXECUTION_PAYMENT_AMOUNT, "--from",
        account.public_key_hex)
    # fmt: on
    block_hash = cli("propose")
    return block_hash, account
def bond_to_the_network(network: OneNodeNetwork, bond_amount: int,
                        account_number: int):
    # Using account that will not exist in bonds.txt from high number
    account = Account(account_number)
    node0, node1 = network.docker_nodes
    cli = CLI(node0)
    # fmt: off
    cli("bond", "--amount", bond_amount, '--public-key',
        account.public_key_path, '--private-key', account.private_key_path,
        '--payment-amount', EXECUTION_PAYMENT_AMOUNT, '--from',
        account.public_key_hex)
    # fmt: on
    block_hash = cli("propose")
    return block_hash, account
Beispiel #18
0
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 add_funded_account_to_network(network: OneNodeNetwork,
                                  account_number: int):
    node0 = network.docker_nodes[0]
    prev_number = len(network.docker_nodes)
    account = network.add_new_node_to_network(account=Account(account_number))
    assert (len(network.docker_nodes) == prev_number +
            1), f"Total number of nodes should be {prev_number + 1}."
    response = node0.d_client.transfer(
        amount=1000000000,
        private_key=GENESIS_ACCOUNT.private_key_docker_path,
        target_account=account.public_key,
    )
    assert "Success!" in response
    deploy_hash = response.split()[2]
    node0.wait_for_deploy_processed_and_get_block_hash(deploy_hash)
Beispiel #20
0
 def create_genesis_accounts_file(self) -> None:
     bond_amount = self.config.bond_amount
     N = self.NUMBER_OF_BONDS
     # Creating a file where the node is expecting to see overrides, i.e. at ~/.casperlabs/chainspec/genesis
     path = f"{self.host_chainspec_dir}/genesis/accounts.csv"
     os.makedirs(os.path.dirname(path))
     with open(path, "a") as f:
         # Give the initial motes to the genesis account, so that tests which use
         # this way of creating accounts work. But the accounts could be just
         # created this way, without having to do a transfer.
         f.write(f"{GENESIS_ACCOUNT.public_key},{self.cl_network.initial_motes},0\n")
         for i, pair in enumerate(
             Account(i)
             for i in range(FIRST_VALIDATOR_ACCOUNT, FIRST_VALIDATOR_ACCOUNT + N)
         ):
             bond = bond_amount(i, N)
             f.write(f"{pair.public_key},0,{bond}\n")
def add_funded_account_to_network(network: OneNodeNetwork,
                                  account_number: int):
    node0 = network.docker_nodes[0]
    cli = CLI(node0)
    prev_number = len(network.docker_nodes)
    account = network.add_new_node_to_network(account=Account(account_number))
    assert (len(network.docker_nodes) == prev_number +
            1), f"Total number of nodes should be {prev_number + 1}."
    response = node0.d_client.transfer(
        amount=1000000000,
        private_key=GENESIS_ACCOUNT.private_key_docker_path,
        target_account=account.public_key,
    )
    assert "Success!" in response
    block_hash = cli("propose")
    for deployInfo in node0.p_client.showDeploys(block_hash):
        assert (deployInfo.is_error is
                False), f"Transfer Failed: {deployInfo.error_message}"
Beispiel #22
0
 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
     )
Beispiel #23
0
def add_funded_account_to_network(network: OneNodeNetwork, account_number: int):
    node0 = network.docker_nodes[0]
    prev_number = len(network.docker_nodes)
    account = network.add_new_node_to_network(account=Account(account_number))
    assert (
        len(network.docker_nodes) == prev_number + 1
    ), f"Total number of nodes should be {prev_number + 1}."
    response = node0.d_client.transfer(
        amount=1000000000,
        private_key=GENESIS_ACCOUNT.private_key_docker_path,
        target_account=account.public_key,
    )
    assert "Success!" in response
    response = node0.d_client.propose()
    block_hash = extract_block_hash_from_propose_output(response)
    assert block_hash is not None
    r = node0.client.show_deploys(block_hash)[0]
    assert r.is_error is False, f"Transfer Failed: {r.error_message}"
    assert r.error_message == ""
Beispiel #24
0
    def create_genesis_accounts_file(self, path: str = None) -> None:
        bond_amount = self.config.bond_amount
        N = self.NUMBER_OF_BONDS
        try:
            os.makedirs(os.path.dirname(path))
        except OSError:
            pass

        with open(path, "w") as f:
            # Give the initial motes to the genesis account, so that tests which use
            # this way of creating accounts work. But the accounts could be just
            # created this way, without having to do a transfer.
            f.write(
                f"{GENESIS_ACCOUNT.public_key},{self.cl_network.initial_motes},0\n"
            )
            for i, pair in enumerate(
                    Account(i) for i in range(FIRST_VALIDATOR_ACCOUNT,
                                              FIRST_VALIDATOR_ACCOUNT + N)):
                bond = bond_amount(i, N)
                f.write(f"{pair.public_key},0,{bond}\n")
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.HELLO_NAME_DEFINE,
    )

    # 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 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.HELLO_NAME_DEFINE,
    )

    # Will have InternalError as no deploys to propose
    with pytest.raises(Exception) as e:
        node.p_client.client.wait_for_deploy_processed(deploy_hash)

    # Verify reason for propose failure
    assert "DISCARDED" in str(e.value)
    assert "Authorization failure: not authorized." in str(e.value)
def test_unbonding_without_bonding(one_node_network_fn, acct_num, cli_method):
    """
    Feature file: consensus.feature
    Scenario: unbonding a validator node which was not bonded to an existing network.
    """
    onn = one_node_network_fn
    bonding_amount = 1
    account = Account(acct_num)
    assert_pre_state_of_network(onn)
    add_funded_account_to_network(onn, acct_num)
    assert len(onn.docker_nodes) == 2, "Total number of nodes should be 2."

    node0, node1 = onn.docker_nodes
    cli = cli_method(node0)
    deploy_hash = cli(
        "unbond",
        "--amount",
        bonding_amount,
        "--private-key",
        cli.private_key_path(account),
        "--payment-amount",
        EXECUTION_PAYMENT_AMOUNT,
    )

    block_hash = cli.node.wait_for_deploy_processed_and_get_block_hash(
        deploy_hash, on_error_raise=False)

    r = node0.client.show_deploys(block_hash)[0]
    assert r.is_error is True
    assert r.error_message == "PoS error: 0"

    block = node1.client.show_block(block_hash)
    block_ds = parse_show_block(block)
    bonds = list(
        filter(
            lambda x: x.validator_public_key == account.public_key_hex,
            block_ds.summary.header.state.bonds,
        ))
    assert len(bonds) == 0
Beispiel #28
0
async def test_transfer_and_balance(node, client):
    test_account = Account(1)

    block_infos = await client.show_blocks()
    block_hash = block_infos[0].summary.block_hash.hex()
    genesis_account_balance = await client.balance(
        GENESIS_ACCOUNT.public_key_hex, block_hash)
    assert genesis_account_balance > 0

    transfer_amount = 10**7
    deploy_hash = await client.transfer(
        test_account.public_key_hex,
        transfer_amount,
        from_addr=GENESIS_ACCOUNT.public_key_hex,
        public_key=GENESIS_ACCOUNT.public_key_path,
        private_key=GENESIS_ACCOUNT.private_key_path,
        payment_amount=PAYMENT_AMOUNT,
    )
    deploy_info = await client.wait_for_deploy_processed(deploy_hash)
    block_hash = deploy_info.processing_results[
        0].block_info.summary.block_hash.hex()
    test_account_balance = await client.balance(test_account.public_key_hex,
                                                block_hash)
    assert test_account_balance == transfer_amount
Beispiel #29
0
import json
import time

from casperlabs_client import ABI
from casperlabs_local_net.casperlabs_accounts import Account
from casperlabs_local_net.casperlabs_network import TrillionPaymentNodeNetwork
from casperlabs_local_net.common import Contract
"""
Accounts have two threshold values:
    key_management_threshold
    deploy_threshold

Both are initialized at 1.
"""

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("account", key.public_key_hex),
        ABI.u32("amount", weight)
Beispiel #30
0
    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_IT,
        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)

        session_args = ABI.args(
            [
                ABI.account("account", to_account.public_key_binary),
                ABI.u32("amount", 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