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",
        )
示例#2
0
 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)
示例#6
0
 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")
示例#7
0
 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
     )
示例#8
0
 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"
示例#10
0
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
示例#11
0
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
        )
示例#13
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,
    )
示例#14
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)
示例#15
0
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."
示例#17
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)
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
示例#20
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,
        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)]
示例#22
0
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")
示例#23
0
    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