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
def test_refund_after_session_code_error(payment_node_network):
    network = payment_node_network
    node0: DockerNode = network.docker_nodes[0]
    blocks = parse_show_blocks(node0.d_client.show_blocks(1000))
    genesis_init_balance = node0.client.get_balance(
        account_address=GENESIS_ACCOUNT.public_key_hex,
        block_hash=blocks[0].summary.block_hash,
    )

    deploy_hash = node0.p_client.deploy(
        from_address=GENESIS_ACCOUNT.public_key_hex,
        session_contract=Contract.ARGS_U512,
        payment_contract=Contract.STANDARD_PAYMENT,
        public_key=GENESIS_ACCOUNT.public_key_path,
        private_key=GENESIS_ACCOUNT.private_key_path,
        gas_price=1,
        session_args=ABI.args([ABI.u512("number", 100)]),
        payment_args=ABI.args([ABI.u32("amount", 10**6)])
        # 100 is a revert code.
    )
    result = node0.p_client.client.wait_for_deploy_processed(
        deploy_hash, on_error_raise=False)
    last_processing_result = result.processing_results[0]
    block_hash = last_processing_result.block_info.summary.block_hash.hex()
    cost = last_processing_result.cost

    assert cost == MAX_PAYMENT_COST / CONV_RATE
    motes = cost * CONV_RATE

    later_balance = node0.client.get_balance(
        account_address=GENESIS_ACCOUNT.public_key_hex, block_hash=block_hash)

    expected_sum = later_balance + motes
    assert genesis_init_balance == expected_sum
示例#3
0
 def abi_encode_args(self, method_name, parameters, kwargs):
     # When using proxy make sure that token_hash ('erc20') is the first argument
     args = (
         [parameters[p](p, kwargs[p]) for p in parameters if p == "erc20"] +
         [ABI.string_value("method", method_name)] +
         [parameters[p](p, kwargs[p]) for p in parameters if p != "erc20"])
     return ABI.args(args)
示例#4
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"
示例#5
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
示例#7
0
def bond_command(casperlabs_client, args):
    logging.info(f"BOND {args}")
    _set_session(args, "bonding.wasm")

    if not args.session_args:
        args.session_args = ABI.args_to_json(
            ABI.args([ABI.long_value("amount", args.amount)]))

    return deploy_command(casperlabs_client, args)
示例#8
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)
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,
    )
示例#10
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,
     )
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,
    )
示例#13
0
def _deploy_kwargs(args, private_key_accepted=True):
    from_addr = (
        getattr(args, "from")
        and bytes.fromhex(getattr(args, "from"))
        or getattr(args, "public_key")
        and read_pem_key(args.public_key)
        or private_to_public_key(args.private_key)
    )
    if from_addr and len(from_addr) != 32:
        raise Exception(
            "--from must be 32 bytes encoded as 64 characters long hexadecimal"
        )

    if not (args.payment_amount or args.payment_args):
        args.payment_amount = DEFAULT_PAYMENT_AMOUNT

    if args.payment_amount:
        args.payment_args = ABI.args_to_json(
            ABI.args([ABI.big_int("amount", int(args.payment_amount))])
        )

    d = dict(
        from_addr=from_addr,
        gas_price=args.gas_price,
        payment=args.payment,
        session=args.session,
        public_key=args.public_key or None,
        session_args=args.session_args
        and ABI.args_from_json(args.session_args)
        or None,
        payment_args=args.payment_args
        and ABI.args_from_json(args.payment_args)
        or None,
        payment_hash=args.payment_hash and bytes.fromhex(args.payment_hash),
        payment_name=args.payment_name,
        payment_uref=args.payment_uref and bytes.fromhex(args.payment_uref),
        session_hash=args.session_hash and bytes.fromhex(args.session_hash),
        session_name=args.session_name,
        session_uref=args.session_uref and bytes.fromhex(args.session_uref),
        ttl_millis=args.ttl_millis,
        dependencies=args.dependencies,
        chain_name=args.chain_name,
    )
    if private_key_accepted:
        d["private_key"] = args.private_key or None
    return d
def set_key_thresholds(node, weight_key, key_mgmt_weight: int, deploy_weight: int):
    """ Sets key management and deploy thresholds for IDENTITY_KEY account """
    args = ABI.args(
        [
            ABI.u32("key_mgmt_weight", key_mgmt_weight),
            ABI.u32("deploy_weight", deploy_weight),
        ]
    )
    return node.deploy_and_get_block_hash(
        weight_key,
        Contract.SET_KEY_THRESHOLDS,
        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,
    )
示例#15
0
def do_deploy_client_contract(network: Network,
                              contract_type: ClientContractType,
                              contract_name: str) -> str:
    """Deploys a client side smart contract to chain for future reference.

    :param network: Network to which a client contract is being deployed.
    :param contract_type: Type of contract to be deployed.
    :param contract_name: Name of contract as specified in wasm blob.

    :returns: Contract hash (in hex format).

    """
    # Set client.
    _, client = utils.get_client(network)

    # Dispatch deploy.
    session = utils.get_client_contract_path(contract_type)
    session_args = ABI.args([ABI.string_value("target", "hash")])
    dhash = client.deploy(
        session=session,
        session_args=session_args,
        from_addr=network.faucet.public_key,
        private_key=network.faucet.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)
    logger.log(
        f"PYCLX :: deploy-contract :: {contract_type.value} :: deploy-hash={dhash} -> awaiting processing"
    )

    # Get block hash.
    dinfo = client.showDeploy(dhash, wait_for_processed=True)
    bhash = dinfo.processing_results[0].block_info.summary.block_hash.hex()
    logger.log(
        f"PYCLX :: deploy-contract :: {contract_type.value} :: deploy-hash={dhash} -> processing complete"
    )

    # Get contract hash.
    chash = utils.get_client_contract_hash(client, network.faucet, bhash,
                                           contract_name)
    logger.log(
        f"PYCLX :: deploy-contract :: {contract_type.value} :: contract-hash={chash}"
    )

    return chash
示例#16
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)
示例#17
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
示例#18
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
def check_cli_abi_unsigned(cli, unsigned_type, value, test_contract):
    account = GENESIS_ACCOUNT
    for number in [2, 256, 1024]:
        args = ABI.args([getattr(ABI, unsigned_type)("number", number)])
        session_args = ABI.args_to_json(args)
        args = ('deploy', '--from', account.public_key_hex, '--session',
                cli.resource(test_contract), '--session-args',
                cli.format_json_str(session_args), '--payment',
                cli.resource(Contract.STANDARD_PAYMENT),
                '--payment-args', cli.payment_json, '--private-key',
                cli.private_key_path(account), '--public-key',
                cli.public_key_path(account))
        logging.info(f"EXECUTING {' '.join(cli.expand_args(args))}")
        deploy_hash = cli(*args)

        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: {number}"
示例#20
0
def _deploy_kwargs(args, private_key_accepted=True):
    from_addr = (getattr(args, "from") and bytes.fromhex(getattr(args, "from"))
                 or private_to_public_key(args.private_key))
    if from_addr and len(from_addr) != 32:
        raise Exception(
            "--from must be 32 bytes encoded as 64 characters long hexadecimal"
        )

    if args.payment_amount:
        args.payment_args = ABI.args_to_json(
            ABI.args([ABI.big_int("amount", int(args.payment_amount))]))
        # Unless one of payment* options supplied use bundled standard-payment
        if not any((args.payment, args.payment_name, args.payment_hash,
                    args.payment_uref)):
            args.payment = bundled_contract("standard_payment.wasm")

    d = dict(
        from_addr=from_addr,
        gas_price=args.gas_price,
        payment=args.payment or args.session,
        session=args.session,
        public_key=args.public_key or None,
        session_args=args.session_args
        and ABI.args_from_json(args.session_args) or None,
        payment_args=args.payment_args
        and ABI.args_from_json(args.payment_args) or None,
        payment_hash=args.payment_hash and bytes.fromhex(args.payment_hash),
        payment_name=args.payment_name,
        payment_uref=args.payment_uref and bytes.fromhex(args.payment_uref),
        session_hash=args.session_hash and bytes.fromhex(args.session_hash),
        session_name=args.session_name,
        session_uref=args.session_uref and bytes.fromhex(args.session_uref),
        ttl_millis=args.ttl_millis,
        dependencies=args.dependencies,
        chain_name=args.chain_name,
    )
    if private_key_accepted:
        d["private_key"] = args.private_key or None
    return d
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}"
示例#23
0
    STANDARD_PAYMENT = "standard_payment.wasm"
    SUBCALL_REVERT_CALL = "subcall_revert_call.wasm"
    SUBCALL_REVERT_DEFINE = "subcall_revert_define.wasm"
    TRANSFER_TO_ACCOUNT = "transfer_to_account_u512.wasm"
    UPDATE_ASSOCIATED_KEY = "update_associated_key.wasm"


# TEST Account Use Notes
# test_transfer_to_accounts: 300, 299, 298
# test_transfer_with_overdraft: 297, 296
# test_bonding: 295

MAX_PAYMENT_COST = 10000000
DEFAULT_PAYMENT_COST = 100000000
INITIAL_MOTES_AMOUNT = 10**20
MAX_PAYMENT_ABI = ABI.args([ABI.big_int("amount", MAX_PAYMENT_COST)])
DEFAULT_PAYMENT_ABI = ABI.args([ABI.big_int("amount", DEFAULT_PAYMENT_COST)])
CONV_RATE = 10
TEST_ACCOUNT_INITIAL_BALANCE = 1000000000
USER_ERROR_MIN = 65536

BOOTSTRAP_PATH = "/root/.casperlabs/bootstrap"

# Empty /etc/casperlabs means it has no chainspec.
# This is a directory in resources that will be mounted
# as /etc/casperlabs in the node's docker container.
EMPTY_ETC_CASPERLABS = "etc_casperlabs_empty"


@dataclasses.dataclass(eq=True, frozen=True)
class KeyPair:
示例#24
0
 def abi_encode_args(self, method_name, parameters, kwargs):
     args = [ABI.string_value("method", method_name)
             ] + [parameters[p](p, kwargs[p]) for p in parameters]
     return ABI.args(args)
def disable_test_multiple_deploys_per_block(cli):
    """
    Two deploys from the same account then propose.
    Both deploys should be be included in the new block.

    Create named purses to pay from for each deploy
    (standard payment cannot be used because it causes
    a WRITE against the main purse balance, but every
    deploy has a READ against that balance to check it meets
    the minimum balance condition, so standard payment calls
    always conflict with any other deploy from the same account)
    """
    account = cli.node.test_account
    cli.set_default_deploy_args('--from',
                                account.public_key_hex, '--private-key',
                                cli.private_key_path(account), '--public-key',
                                cli.public_key_path(account))

    # Create purse_1
    deploy_hash = cli(
        'deploy', '--session', cli.resource(Contract.CREATE_NAMED_PURSE),
        '--session-args',
        ABI.args_to_json(
            ABI.args([
                ABI.big_int("amount", 100000000),
                ABI.string_value("purse-name", "purse_1")
            ])), '--payment', cli.resource(Contract.STANDARD_PAYMENT),
        '--payment-args',
        ABI.args_to_json(ABI.args([ABI.big_int("amount", 100000000)])))
    check_no_errors(cli, deploy_hash)

    # Create purse_2
    deploy_hash = cli(
        'deploy', '--session', cli.resource(Contract.CREATE_NAMED_PURSE),
        '--session-args',
        ABI.args_to_json(
            ABI.args([
                ABI.big_int("amount", 100000000),
                ABI.string_value("purse-name", "purse_2")
            ])), '--payment', cli.resource(Contract.STANDARD_PAYMENT),
        '--payment-args',
        ABI.args_to_json(ABI.args([ABI.big_int("amount", 100000000)])))
    check_no_errors(cli, deploy_hash)

    # First deploy uses first purse for payment
    deploy_hash1 = cli(
        'deploy', '--from', account.public_key_hex, '--session',
        cli.resource(Contract.COUNTER_DEFINE), '--payment',
        cli.resource(Contract.PAYMENT_FROM_NAMED_PURSE), '--payment-args',
        ABI.args_to_json(
            ABI.args([
                ABI.big_int("amount", 100000000),
                ABI.string_value("purse-name", "purse_1")
            ])))

    # Second deploy uses second purse for payment
    deploy_hash2 = cli(
        'deploy', '--from', account.public_key_hex, '--session',
        cli.resource(Contract.MAILING_LIST_DEFINE), '--payment',
        cli.resource(Contract.PAYMENT_FROM_NAMED_PURSE), '--payment-args',
        ABI.args_to_json(
            ABI.args([
                ABI.big_int("amount", 100000000),
                ABI.string_value("purse-name", "purse_2")
            ])))
    block_hash = check_no_errors(cli, deploy_hash2)

    # Propose should include both deploys.
    deploys = list(cli("show-deploys", block_hash))
    # TODO: with auto-propose this may fail:
    assert len(deploys) == 2
    assert set(d.deploy.deploy_hash for d in deploys) == set(
        (deploy_hash1, deploy_hash2))
示例#26
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
示例#27
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
示例#28
0
文件: cli.py 项目: zie1ony/CasperLabs
class CLI:

    _DEFAULT_PAYMENT_JSON = ABI.args_to_json(
        ABI.args([ABI.big_int("amount", DEFAULT_PAYMENT_COST)]))

    def __init__(self, node, cli_cmd="casperlabs_client", tls_parameters=None):
        self.node = node
        self.host = (os.environ.get("TAG_NAME", None) and node.container_name
                     or "localhost")
        self.port = node.grpc_external_docker_port
        self.port_internal = node.grpc_internal_docker_port
        self.cli_cmd = cli_cmd
        self.tls_parameters = tls_parameters or {}
        self.default_deploy_args = []
        self.resources_directory = resources_path()

    def set_default_deploy_args(self, *args):
        """ Set args that will be appended to subsequent deploy command. """
        self.default_deploy_args = [str(arg) for arg in args]

    def resource(self, file_name):
        return self.resources_directory / file_name

    @property
    def _local_connection_details(self):
        return [
            "--host",
            f"{self.host}",
            "--port",
            f"{self.port}",
            "--port-internal",
            f"{self.port_internal}",
        ]

    def expand_args(self, args):
        connection_details = self._local_connection_details
        if self.tls_parameters:
            connection_details += reduce(
                add,
                [[str(p), str(self.tls_parameters[p])]
                 for p in self.tls_parameters],
            )
        string_args = [str(a) for a in list(args)]

        if args and args[0] == "deploy":
            string_args += self.default_deploy_args

        return "--help" in args and string_args or connection_details + string_args

    @staticmethod
    def parse_output(command, binary_output):

        if command in ("make-deploy", "sign-deploy"):
            return binary_output

        output = binary_output.decode("utf-8")

        if command in ("deploy", "send-deploy", "bond", "unbond", "transfer"):
            return output.split()[2]
            # "Success! Deploy 0d4036bebb95de793b28de452d594531a29f8dc3c5394526094d30723fa5ff65 deployed."

        if command == "show-blocks":
            return parse_show_blocks(output)

        if command == "show-deploys":
            return parse_show_deploys(output)

        if command in ("show-deploy", "show-block", "query-state"):
            return parse(output)

        if command in ("balance", ):
            # 'Balance:\n9d39b7fba47d07c1af6f711efe604a112ab371e2deefb99a613d2b3dcdfba414 : 1000000000'
            return int(output.split(":")[-1])

        return output

    def __call__(self, *args):
        command_line = [str(self.cli_cmd)] + self.expand_args(args)
        # logging.info(f"EXECUTING []: {command_line}")
        logging.info(f"EXECUTING: {' '.join(command_line)}")
        cp = subprocess.run(command_line,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
        binary_output = cp.stdout
        if cp.returncode != 0:
            output = binary_output
            try:
                output = binary_output.decode("utf-8")
            except UnicodeDecodeError:
                pass
            raise CLIErrorExit(cp, output)

        return self.parse_output(args[0], binary_output)

    def public_key_path(self, account):
        return account.public_key_path

    def private_key_path(self, account):
        return account.private_key_path

    def format_json_str(self, args: str) -> str:
        return args

    @property
    def payment_json(self) -> str:
        return self.format_json_str(self._DEFAULT_PAYMENT_JSON)
示例#29
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