def test_not_enough_funds_to_run_payment_code(payment_node_network):
    network = payment_node_network
    node0: DockerNode = network.docker_nodes[0]
    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.d_client.get_balance(
        account_address=GENESIS_ACCOUNT.public_key_hex,
        block_hash=genesis_hash)
    assert genesis_balance == INITIAL_MOTES_AMOUNT
    session_args = ABI.args([
        ABI.account("account", GENESIS_ACCOUNT.public_key_hex),
        ABI.u64("amount", 10**7),
    ])
    node0.p_client.deploy(
        from_address=GENESIS_ACCOUNT.public_key_hex,
        session_contract=Contract.TRANSFER_TO_ACCOUNT,
        payment_contract=Contract.STANDARD_PAYMENT,
        public_key=GENESIS_ACCOUNT.public_key_path,
        private_key=GENESIS_ACCOUNT.private_key_path,
        gas_price=1,
        session_args=session_args,
        payment_args=ABI.args([ABI.u512("amount", 450)]),
    )

    latest_block_hash = parse_show_blocks(
        node0.d_client.show_blocks(1000))[0].summary.block_hash
    genesis_balance_after_transfer = node0.d_client.get_balance(
        account_address=GENESIS_ACCOUNT.public_key_hex,
        block_hash=latest_block_hash)
    assert genesis_balance == genesis_balance_after_transfer
Пример #2
0
def test_deploy_do_nothing_and_call_by_entry_point_and_version(
    casperlabs_client, faucet_funded_accounts, algorithm
):
    key_holder, private_key_pem_path = faucet_funded_accounts[algorithm]

    deploy_hash = casperlabs_client.deploy(
        session=WASM_DIRECTORY / "test_payment_stored.wasm",
        payment_amount=10000000,
        private_key=private_key_pem_path,
    )
    result = casperlabs_client.show_deploy(
        deploy_hash, wait_for_processed=True, timeout_seconds=300
    )
    for block_info in result.processing_results:
        assert (
            not block_info.is_error
        ), f"block_info.is_error: {block_info.error_message}"
    assert len(result.processing_results) > 0, "No block_info returned"

    deploy_hash = casperlabs_client.deploy(
        session=WASM_DIRECTORY / "transfer_to_account_u512_stored.wasm",
        payment_name="test_payment_hash",
        payment_entry_point="pay",
        payment_args=ABI.args([ABI.big_int("amount", 10000000)]),
        private_key=private_key_pem_path,
    )
    result = casperlabs_client.show_deploy(
        deploy_hash, wait_for_processed=True, timeout_seconds=300
    )
    for block_info in result.processing_results:
        assert (
            not block_info.is_error
        ), f"block_info.is_error: {block_info.error_message}"
    assert len(result.processing_results) > 0, "No block_info returned"

    session_args = ABI.args(
        [
            ABI.account(
                "target",
                "1000000000000000000000000000000000000000000000000000000000000000",
            ),
            ABI.big_int("amount", 123),
        ]
    )

    deploy_hash = casperlabs_client.deploy(
        session_name="transfer_to_account",
        session_entry_point="transfer",
        session_args=session_args,
        payment_amount=10000000,
        private_key=private_key_pem_path,
    )
    result = casperlabs_client.show_deploy(
        deploy_hash, wait_for_processed=True, timeout_seconds=300
    )
    for block_info in result.processing_results:
        assert (
            not block_info.is_error
        ), f"block_info.is_error: {block_info.error_message}"
    assert len(result.processing_results) > 0, "No block_info returned"
Пример #3
0
def faucet_fund_account(casperlabs_client,
                        account_hash_hex,
                        amount=10000000000):
    faucet_wasm_path = WASM_DIRECTORY / "faucet.wasm"
    assert faucet_wasm_path.exists(), (
        f"Needed wasm file: {faucet_wasm_path} does not exist.\n"
        "It should be built in `build_contracts.sh`.")
    session_args = ABI.args([
        ABI.account("target", account_hash_hex),
        ABI.big_int("amount", amount)
    ])

    deploy_hash = casperlabs_client.deploy(
        private_key=FAUCET_PRIVATE_KEY_PEM_PATH,
        session=faucet_wasm_path,
        session_args=session_args,
        payment_amount=1000000,
    )
    result = casperlabs_client.show_deploy(deploy_hash,
                                           wait_for_processed=True)
    assert (len(result.processing_results) >
            0), "No processing results from faucet transfer"
    block_hash = result.processing_results[0].block_info.summary.block_hash
    result = casperlabs_client.balance(account_hash_hex, block_hash.hex())
    assert result > 0, "balance of new account is not correct"
def test_deploy_with_args(one_node_network, genesis_public_signing_key):
    """
    Deploys test contracts that do:

        revert(get_arg(0)); // for u32 and u512

    and

        revert(sum(address_bytes[u8; 32]) + u32); for multiple argument test.

    Tests args get correctly encoded and decoded in the contract.

    Test expects the test contracts args_u32.wasm and args_u512.wasm
    to deserialize correctly their arguments and then call revert with value
    of the argument (converted to a Rust native int, as expected by revert).
    If the test contracts don't fail or if their exit code is different
    than expected, the test will fail.
    """
    node = one_node_network.docker_nodes[0]
    client = node.p_client.client

    for wasm, encode in [
        (resources_path() / Contract.ARGS_U32, ABI.int_value),
        (resources_path() / Contract.ARGS_U512, ABI.big_int),
    ]:
        for number in [1, 12, 256, 1024]:
            block_hash = node.deploy_and_get_block_hash(
                GENESIS_ACCOUNT,
                wasm,
                on_error_raise=False,
                session_args=ABI.args([encode("number", number)]),
            )

            for deploy_info in client.showDeploys(block_hash):
                exit_code = number + USER_ERROR_MIN
                assert deploy_info.is_error is True
                assert deploy_info.error_message == f"Exit code: {exit_code}"

    wasm = resources_path() / Contract.ARGS_MULTI
    account_hex = "0101010102020202030303030404040405050505060606060707070708080808"
    number = 1000
    total_sum = sum([1, 2, 3, 4, 5, 6, 7, 8]) * 4 + number

    block_hash = node.deploy_and_get_block_hash(
        GENESIS_ACCOUNT,
        wasm,
        on_error_raise=False,
        session_args=ABI.args(
            [ABI.account("account", account_hex),
             ABI.u32("number", number)]),
    )

    for deploy_info in client.showDeploys(block_hash):
        exit_code = total_sum + USER_ERROR_MIN
        assert deploy_info.is_error is True
        assert deploy_info.error_message == f"Exit code: {exit_code}"

    for blockInfo in client.showBlocks(10):
        assert blockInfo.status.stats.block_size_bytes > 0
Пример #5
0
def do_transfer(
    ctx: ExecutionContext,
    cp1: Account,
    cp2: Account,
    amount: int,
    contract: ClientContract = None,
    is_refundable: bool = True,
    deploy_type: DeployType = DeployType.TRANSFER
) -> typing.Tuple[Deploy, Transfer]:
    """Executes a transfer between 2 counter-parties & returns resulting deploy hash.

    :param ctx: Execution context information.
    :param cp1: Account information of counter party 1.
    :param cp2: Account information of counter party 2.
    :param amount: Amount in motes to be transferred.
    :param contract: The transfer contract to call (if any).
    :param is_refundable: Flag indicating whether a refund is required.
    :param deploy_type: The type of deploy to dispatch.

    :returns: Dispatched deploy & transfer.

    """
    # Set client.
    node, client = utils.get_client(ctx)

    # Transfer using called contract - does not dispatch wasm.
    if contract:
        session_args = ABI.args([
            ABI.account("address", cp2.public_key),
            ABI.big_int("amount", amount)
        ])
        dhash = client.deploy(
            session_hash=bytes.fromhex(contract.chash),
            session_args=session_args,
            from_addr=cp1.public_key,
            private_key=cp1.private_key_as_pem_filepath,
            # TODO: allow these to be passed in via standard arguments
            payment_amount=defaults.CLX_TX_FEE,
            gas_price=defaults.CLX_TX_GAS_PRICE)

    # Transfer using stored contract - dispatches wasm.
    else:
        dhash = client.transfer(
            amount=amount,
            from_addr=cp1.public_key,
            private_key=cp1.private_key_as_pem_filepath,
            target_account_hex=cp2.public_key,
            # TODO: allow these to be passed in via standard arguments
            payment_amount=defaults.CLX_TX_FEE,
            gas_price=defaults.CLX_TX_GAS_PRICE)

    logger.log(
        f"PYCLX :: transfer :: {dhash} :: {amount} CLX :: {cp1.public_key[:8]} -> {cp2.public_key[:8]}"
    )

    return (node, dhash)
Пример #6
0
def remove_associated_key(node, weight_key: Account, key: Account):
    """ Removes a key from the IDENTITY_KEY account """
    args = ABI.args([ABI.account("account", key.public_key_hex)])
    return node.deploy_and_get_block_hash(
        weight_key,
        Contract.REMOVE_ASSOCIATED_KEY,
        on_error_raise=False,
        from_addr=IDENTITY_KEY.public_key_hex,
        public_key=weight_key.public_key_path,
        private_key=weight_key.private_key_path,
        session_args=args,
    )
Пример #7
0
def test_legacy_args_from_json():
    json_str = json.dumps(LEGACY_ARGS)
    args = ABI.args_from_json(json_str)
    assert args[0] == ABI.long_value("amount", long_value)
    assert args[1] == ABI.account("account", account)
    assert args[2] == ABI.optional_value("main_purse", None)
    assert args[3] == ABI.big_int("number", big_int_value)
    assert args[4] == ABI.bytes_value("my_bytes", account)

    assert args[5] == ABI.key_hash("my_hash", account)
    assert args[6] == ABI.key_address("my_address", account)
    assert args[7] == ABI.key_uref("my_uref", account, access_rights=5)
    assert args[8] == ABI.key_local("my_local", account)
 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,
     )
Пример #9
0
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)]
    )
    return node.deploy_and_get_block_hash(
        weight_key,
        contract,
        on_error_raise=False,
        from_addr=IDENTITY_KEY.public_key_hex,
        public_key=weight_key.public_key_path,
        private_key=weight_key.private_key_path,
        session_args=session_args,
    )
Пример #10
0
def test_args_to_json():
    args = [
        ABI.long_value("amount", long_value),
        ABI.account("account", account),
        ABI.optional_value("purse_id", None),
        ABI.big_int("number", big_int_value),
        ABI.bytes_value("my_bytes", account),
        ABI.key_hash("my_hash", account),
        ABI.key_address("my_address", account),
        ABI.key_uref("my_uref", account, access_rights=5),
        ABI.key_local("my_local", account),
    ]
    json_str1 = json.dumps(ARGS, ensure_ascii=True, sort_keys=True, indent=2)
    json_str2 = ABI.args_to_json(ABI.args(args),
                                 ensure_ascii=True,
                                 sort_keys=True,
                                 indent=2)
    assert json_str1 == json_str2
Пример #11
0
def transfer_command(casperlabs_client, args):
    _set_session(args, "transfer_to_account_u512.wasm")

    if not args.session_args:
        target_account_bytes = base64.b64decode(args.target_account)
        if len(target_account_bytes) != 32:
            target_account_bytes = bytes.fromhex(args.target_account)
            if len(target_account_bytes) != 32:
                raise Exception(
                    "--target_account must be 32 bytes base64 or base16 encoded"
                )

        args.session_args = ABI.args_to_json(
            ABI.args([
                ABI.account("account", target_account_bytes),
                ABI.u512("amount", args.amount),
            ]))

    return deploy_command(casperlabs_client, args)
Пример #12
0
def faucet_fund_account(casperlabs_client,
                        account_hash_hex,
                        amount=1000000000):
    faucet_wasm_path = WASM_DIRECTORY / "faucet.wasm"
    session_args = ABI.args([
        ABI.account("target", account_hash_hex),
        ABI.big_int("amount", amount)
    ])
    # TODO: validate faucet key path to make sure key gen worked during standup.
    deploy_hash = casperlabs_client.deploy(
        private_key=FAUCET_PRIVATE_KEY_PEM_PATH,
        session=faucet_wasm_path,
        session_args=session_args,
    )
    result = casperlabs_client.show_deploy(deploy_hash,
                                           wait_for_processed=True)
    block_hash = result.processing_results[0].block_info.summary.block_hash
    result = casperlabs_client.balance(account_hash_hex, block_hash.hex())
    assert result > 0
Пример #13
0
def make_transfers(client, account, target_account, amount, n):
    """
    Makes n transfers from account to account_target,
    n must be greater than 1.

    First n-1 deploys depends on a deploy that is sent to the node as the last one.
    This is in order to ensure that node doesn't put part of the set of deploys on a block
    before receiving all of them.

    Returns tuple (deploy_hash, [deploy_hashes]), where deploy_hash is the special
    deploy that all other deploys depend on.
    """
    if not n > 1:
        raise Exception("n must be > 1")

    deploy = client.make_deploy(
        from_addr=account.public_key_hex,
        session=bundled_contract("transfer_to_account_u512.wasm"),
        session_args=ABI.args([
            ABI.account("account",
                        bytes.fromhex(target_account.public_key_hex)),
            ABI.u512("amount", amount),
        ]),
        payment_amount=10000000,
    )
    deploy = client.sign_deploy(deploy, account.public_key_hex,
                                account.private_key_path)
    deploy_hash = deploy.deploy_hash.hex()

    deploy_hashes = [
        client.transfer(
            private_key=account.private_key_path,
            from_addr=account.public_key_hex,
            target_account_hex=target_account.public_key_hex,
            payment_amount=10000000,
            amount=1,
            dependencies=[deploy_hash],
        ) for _ in range(n - 1)
    ]

    client.send_deploy(deploy)
    return deploy_hash, deploy_hashes
Пример #14
0
def test_args_to_json():
    args = [
        ABI.long_value("amount", long_value),
        ABI.account("account", account),
        ABI.optional_value("main_purse", None),
        ABI.big_int("number", big_int_value),
        ABI.bytes_value("my_bytes", account),
        ABI.key_hash("my_hash", account),
        ABI.key_address("my_address", account),
        ABI.key_uref("my_uref", account, access_rights=5),
        ABI.key_local("my_local", account),
    ]
    json_str1 = json.dumps(LEGACY_ARGS,
                           ensure_ascii=True,
                           sort_keys=True,
                           indent=2)
    json_str2 = ABI.args_to_json(ABI.args(args),
                                 ensure_ascii=True,
                                 sort_keys=True,
                                 indent=2)
    # TODO: fix this test to use new json format
    assert json_str1 != json_str2
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 test_cli_abi_multiple(cli):
    account = GENESIS_ACCOUNT
    account_hex = "0101010102020202030303030404040405050505060606060707070708080808"
    number = 1000
    total_sum = sum([1, 2, 3, 4, 5, 6, 7, 8]) * 4 + number

    args = ABI.args(
        [ABI.account("account", account_hex),
         ABI.int_value("number", number)])
    session_args = ABI.args_to_json(args)
    deploy_hash = cli('deploy', '--from', account.public_key_hex, '--session',
                      cli.resource(Contract.ARGS_MULTI), '--session-args',
                      session_args, '--private-key',
                      cli.private_key_path(account), '--public-key',
                      cli.public_key_path(account), '--payment',
                      cli.resource(Contract.STANDARD_PAYMENT),
                      '--payment-args', cli.payment_json)
    cli.node.wait_for_deploy_processed_and_get_block_hash(deploy_hash,
                                                          on_error_raise=False)
    deploy_info = cli("show-deploy", deploy_hash)
    assert deploy_info.processing_results[0].is_error is True
    assert deploy_info.processing_results[
        0].error_message == f"User error: {total_sum}"
Пример #17
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)

        session_args = ABI.args([
            ABI.account("account", to_account.public_key_binary),
            ABI.u64("amount", amount),
        ])

        deploy_hash = 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,
        )

        client = self.p_client.client
        result = client.wait_for_deploy_processed(
            deploy_hash, on_error_raise=is_deploy_error_check)
        last_processing_result = result.processing_results[0]
        block_hash = last_processing_result.block_info.summary.block_hash.hex()
        if is_deploy_error_check and last_processing_result.is_error:
            raise Exception(
                f"transfer_to_account: {last_processing_result.error_message}")

        return block_hash