Example #1
0
def test_PAYGAS_zero_gas_price(unvalidated_shard_chain):  # noqa: F811
    # Case 2: PAYGAS triggered with 0 gas price
    chain = unvalidated_shard_chain
    vm = chain.get_vm()

    PAYGAS_contract_normal = PAYGAS_contracts["PAYGAS_contract_normal"]
    PAYGAS_contract_address = decode_hex(PAYGAS_contract_normal['address'])
    normal_PAYGAS_contract_deploy_tx = new_sharding_transaction(
        tx_initiator=PAYGAS_contract_address,
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=PAYGAS_contract_normal['bytecode'],
    )
    computation, _ = vm.apply_transaction(normal_PAYGAS_contract_deploy_tx)
    assert not computation.is_error

    # Trigger the PAYGAS contract with gas price set to 0
    recipient = decode_hex('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0c')
    amount = 100
    tx_initiator = PAYGAS_contract_address
    gas_price = bytes([0])
    vrs = 64 * b'\xAA' + b'\x01'
    trigger_tx = new_sharding_transaction(tx_initiator, recipient, amount,
                                          gas_price, vrs)

    with vm.state.state_db(read_only=True) as state_db:
        balance_before_trigger = state_db.get_balance(PAYGAS_contract_address)
    computation, _ = vm.apply_transaction(trigger_tx)
    assert not computation.is_error
    with vm.state.state_db(read_only=True) as state_db:
        # Check that balance of the contract is the same except the amount transfered
        assert balance_before_trigger == state_db.get_balance(
            PAYGAS_contract_address) + amount
Example #2
0
def test_PAYGAS_triggered_twice(unvalidated_shard_chain):  # noqa: F811
    # Case 4: PAYGAS triggered twice
    chain = unvalidated_shard_chain
    vm = chain.get_vm()

    PAYGAS_contract_triggered_twice = PAYGAS_contracts[
        "PAYGAS_contract_triggered_twice"]
    PAYGAS_contract_address = decode_hex(
        PAYGAS_contract_triggered_twice['address'])
    PAYGAS_triggered_twice_deploy_tx = new_sharding_transaction(
        tx_initiator=PAYGAS_contract_address,
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=PAYGAS_contract_triggered_twice['bytecode'],
    )
    computation, _ = vm.apply_transaction(PAYGAS_triggered_twice_deploy_tx)
    assert not computation.is_error

    # Trigger the PAYGAS contract which will trigger PAYGAS twice
    # First time with gas_price specified in transaction data
    # Second time with 10*gas_price
    recipient = decode_hex('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0c')
    amount = 100
    tx_initiator = PAYGAS_contract_address
    gas_price = 33
    vrs = 64 * b'\xAA' + b'\x01'
    trigger_tx = new_sharding_transaction(
        tx_initiator,
        recipient,
        amount,
        bytes([gas_price]),
        vrs,
    )

    last_gas_used = vm.block.header.gas_used
    with vm.state.state_db(read_only=True) as state_db:
        balance_before_trigger = state_db.get_balance(PAYGAS_contract_address)
        recipient_balance_before_trigger = state_db.get_balance(recipient)
    computation, _ = vm.apply_transaction(trigger_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used - last_gas_used
    with vm.state.state_db(read_only=True) as state_db:
        # Check that PAYGAS account is charged with normal gas_price instead of 10*gas_price
        tx_fee = gas_used * gas_price
        balance_after_trigger = state_db.get_balance(
            PAYGAS_contract_address) + tx_fee + amount
        assert balance_before_trigger == balance_after_trigger
        assert state_db.get_balance(
            recipient) == recipient_balance_before_trigger + amount
Example #3
0
def test_CREATE2_deploy_contract_edge_cases(
        unvalidated_shard_chain):  # noqa: F811
    CREATE2_contracts = json.load(
        open(os.path.join(DIR, '../contract_fixtures/CREATE2_contracts.json')))
    simple_transfer_contract = CREATE2_contracts["simple_transfer_contract"]

    # First case: computed contract address not the same as provided in `transaction.to`
    chain = unvalidated_shard_chain
    code = "0xf3"
    computed_address = generate_CREATE2_contract_address(b"", decode_hex(code))
    first_failed_deploy_tx = new_sharding_transaction(
        tx_initiator=decode_hex(simple_transfer_contract['address']),
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=code,
        access_list=[[decode_hex(simple_transfer_contract['address'])],
                     [computed_address]])

    vm = chain.get_vm()
    computation, _ = vm.apply_transaction(first_failed_deploy_tx)
    assert isinstance(computation._error, IncorrectContractCreationAddress)
    gas_used = vm.block.header.gas_used
    assert gas_used > first_failed_deploy_tx.intrinsic_gas
    last_gas_used = gas_used

    # Next, complete deploying the contract
    successful_deploy_tx = new_sharding_transaction(
        tx_initiator=decode_hex(simple_transfer_contract['address']),
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=simple_transfer_contract['bytecode'],
    )
    computation, _ = vm.apply_transaction(successful_deploy_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used - last_gas_used
    assert gas_used > successful_deploy_tx.intrinsic_gas
    last_gas_used = gas_used

    # Second case: deploy to existing account
    second_failed_deploy_tx = successful_deploy_tx
    computation, _ = vm.apply_transaction(second_failed_deploy_tx)
    assert isinstance(computation._error, ContractCreationCollision)
    gas_used = vm.block.header.gas_used - last_gas_used
    assert gas_used > second_failed_deploy_tx.intrinsic_gas
Example #4
0
def test_trigger_PAYGAS(unvalidated_shard_chain):  # noqa: F811
    chain = unvalidated_shard_chain
    vm = chain.get_vm()

    PAYGAS_contract_normal = PAYGAS_contracts["PAYGAS_contract_normal"]
    simple_forwarder_contract = PAYGAS_contracts["simple_forwarder_contract"]
    PAYGAS_contract_address = decode_hex(PAYGAS_contract_normal['address'])
    deploy_tx = new_sharding_transaction(
        tx_initiator=PAYGAS_contract_address,
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=PAYGAS_contract_normal['bytecode'],
    )
    computation, _ = vm.apply_transaction(deploy_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used
    assert gas_used > deploy_tx.intrinsic_gas
    last_gas_used = gas_used

    # Trigger the contract
    recipient = decode_hex('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0c')
    amount = 0
    tx_initiator = PAYGAS_contract_address
    gas_price = 33
    vrs = 64 * b'\xAA' + b'\x01'
    trigger_tx = new_sharding_transaction(
        tx_initiator,
        recipient,
        amount,
        bytes([gas_price]),
        vrs,
    )

    with vm.state.state_db(read_only=True) as state_db:
        balance_before_trigger = state_db.get_balance(
            decode_hex(simple_forwarder_contract['address']))
    computation, _ = vm.apply_transaction(trigger_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used - last_gas_used
    assert gas_used > trigger_tx.intrinsic_gas
    last_gas_used = vm.block.header.gas_used
    with vm.state.state_db(read_only=True) as state_db:
        assert state_db.get_balance(
            tx_initiator) == balance_before_trigger - gas_used * gas_price
        assert state_db.get_balance(recipient) == amount
Example #5
0
def test_PAYGAS_not_triggered(unvalidated_shard_chain):  # noqa: F811
    # Case 1: PAYGAS not triggered
    chain = unvalidated_shard_chain
    vm = chain.get_vm()

    simple_forwarder_contract = PAYGAS_contracts["simple_forwarder_contract"]
    forwarder_contract_address = decode_hex(
        simple_forwarder_contract['address'])
    forwarder_contract_deploy_tx = new_sharding_transaction(
        tx_initiator=forwarder_contract_address,
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=simple_forwarder_contract['bytecode'],
    )
    computation, _ = vm.apply_transaction(forwarder_contract_deploy_tx)
    assert not computation.is_error

    # Trigger the forwarder contract which does not have PAYGAS opcode
    recipient = decode_hex('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0c')
    amount = 0
    tx_initiator = forwarder_contract_address
    gas_price = bytes([0])
    vrs = 64 * b'\xAA' + b'\x01'
    trigger_tx = new_sharding_transaction(tx_initiator, recipient, amount,
                                          gas_price, vrs)

    with vm.state.state_db(read_only=True) as state_db:
        balance_before_trigger = state_db.get_balance(
            forwarder_contract_address)
    computation, _ = vm.apply_transaction(trigger_tx)
    assert not computation.is_error
    with vm.state.state_db(read_only=True) as state_db:
        # Check that balance of the contract is the same
        assert balance_before_trigger == state_db.get_balance(
            forwarder_contract_address)
def test_contract_with_no_nonce_tracking(
        unvalidated_shard_chain):  # noqa: F811
    chain = unvalidated_shard_chain
    vm = chain.get_vm()

    no_nonce_tracking_contract = nonce_tracking_contracts[
        "no_nonce_tracking_contract"]
    no_nonce_tracking_contract_address = decode_hex(
        no_nonce_tracking_contract['address'])
    deploy_tx = new_sharding_transaction(
        tx_initiator=no_nonce_tracking_contract_address,
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=no_nonce_tracking_contract['bytecode'],
    )
    computation, _ = vm.apply_transaction(deploy_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used
    assert gas_used > deploy_tx.intrinsic_gas
    last_gas_used = gas_used

    # Trigger the contract
    recipient = b''
    nonce = 0
    tx_initiator = no_nonce_tracking_contract_address
    gas_price = 10
    vrs = 64 * b'\xAA' + b'\x01'
    access_list = [[tx_initiator, pad32(b'\x00')]]
    trigger_tx = new_sharding_transaction(
        tx_initiator,
        recipient,
        nonce,
        bytes([gas_price]),
        vrs,
        access_list=access_list,
    )

    with vm.state.state_db(read_only=True) as state_db:
        balance_before_trigger = state_db.get_balance(
            no_nonce_tracking_contract_address)
    computation, _ = vm.apply_transaction(trigger_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used - last_gas_used
    assert gas_used > trigger_tx.intrinsic_gas
    last_gas_used = vm.block.header.gas_used
    with vm.state.state_db(read_only=True) as state_db:
        assert state_db.get_balance(
            tx_initiator) == balance_before_trigger - gas_used * gas_price

    # Replay the same transaciton
    with vm.state.state_db(read_only=True) as state_db:
        balance_before_trigger = state_db.get_balance(
            no_nonce_tracking_contract_address)
    computation, _ = vm.apply_transaction(trigger_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used - last_gas_used
    assert gas_used > trigger_tx.intrinsic_gas
    last_gas_used = vm.block.header.gas_used
    with vm.state.state_db(read_only=True) as state_db:
        # Check that fee is charged since there's no replay protection
        assert state_db.get_balance(
            tx_initiator) == balance_before_trigger - gas_used * gas_price
Example #7
0
def test_sharding_apply_transaction(unvalidated_shard_chain):  # noqa: F811
    chain = unvalidated_shard_chain

    CREATE2_contracts = json.load(
        open(os.path.join(DIR, '../contract_fixtures/CREATE2_contracts.json')))
    simple_transfer_contract = CREATE2_contracts["simple_transfer_contract"]
    CREATE2_contract = CREATE2_contracts["CREATE2_contract"]
    simple_factory_contract_bytecode = CREATE2_contracts[
        "simple_factory_contract"]["bytecode"]

    # First test: simple ether transfer contract
    first_deploy_tx = new_sharding_transaction(
        tx_initiator=decode_hex(simple_transfer_contract['address']),
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=simple_transfer_contract['bytecode'],
    )

    vm = chain.get_vm()
    computation, _ = vm.apply_transaction(first_deploy_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used
    assert gas_used > first_deploy_tx.intrinsic_gas
    last_gas_used = gas_used

    # Transfer ether to recipient
    recipient = decode_hex('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0c')
    amount = 100
    tx_initiator = decode_hex(simple_transfer_contract['address'])
    transfer_tx = new_sharding_transaction(tx_initiator, recipient, amount,
                                           b'', b'')

    computation, _ = vm.apply_transaction(transfer_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used - last_gas_used
    assert gas_used > transfer_tx.intrinsic_gas
    last_gas_used = vm.block.header.gas_used
    with vm.state.state_db(read_only=True) as state_db:
        assert state_db.get_balance(recipient) == amount

    # Second test: contract that deploy new contract with CREATE2
    second_deploy_tx = new_sharding_transaction(
        tx_initiator=decode_hex(CREATE2_contract['address']),
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=CREATE2_contract['bytecode'],
    )

    computation, _ = vm.apply_transaction(second_deploy_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used - last_gas_used
    assert gas_used > second_deploy_tx.intrinsic_gas
    last_gas_used = vm.block.header.gas_used

    # Invoke the contract to deploy new contract
    tx_initiator = decode_hex(CREATE2_contract['address'])
    newly_deployed_contract_address = generate_CREATE2_contract_address(
        int_to_big_endian(0), decode_hex(simple_factory_contract_bytecode))
    invoke_tx = new_sharding_transaction(
        tx_initiator,
        b'',
        0,
        b'',
        b'',
        access_list=[[tx_initiator, pad32(b'')],
                     [newly_deployed_contract_address]])

    computation, _ = vm.apply_transaction(invoke_tx)
    assert not computation.is_error
    gas_used = vm.block.header.gas_used - last_gas_used
    assert gas_used > invoke_tx.intrinsic_gas
    with vm.state.state_db(read_only=True) as state_db:
        newly_deployed_contract_address = generate_CREATE2_contract_address(
            int_to_big_endian(0), decode_hex(simple_factory_contract_bytecode))
        assert state_db.get_code(
            newly_deployed_contract_address) == b'\xbe\xef'
        assert state_db.get_storage(decode_hex(CREATE2_contract['address']),
                                    0) == 1
Example #8
0
def test_PAYGAS_not_in_top_level_call(unvalidated_shard_chain):  # noqa: F811
    # Case 3: PAYGAS is not triggered in a top level call
    chain = unvalidated_shard_chain
    vm = chain.get_vm()

    PAYGAS_contract_normal = PAYGAS_contracts["PAYGAS_contract_normal"]
    simple_forwarder_contract = PAYGAS_contracts["simple_forwarder_contract"]

    # Use the forwarder contract to make the call to PAYGAS contract
    # Order: forwarder -> PAYGAS contract -> recipient

    forwarder_address = decode_hex(simple_forwarder_contract['address'])
    forwarder_contract_deploy_tx = new_sharding_transaction(
        tx_initiator=forwarder_address,
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=simple_forwarder_contract['bytecode'],
    )
    computation, _ = vm.apply_transaction(forwarder_contract_deploy_tx)
    assert not computation.is_error

    PAYGAS_contract_address = decode_hex(PAYGAS_contract_normal['address'])
    normal_PAYGAS_contract_deploy_tx = new_sharding_transaction(
        tx_initiator=PAYGAS_contract_address,
        data_destination=b'',
        data_value=0,
        data_msgdata=b'',
        data_vrs=b'',
        code=PAYGAS_contract_normal['bytecode'],
    )
    computation, _ = vm.apply_transaction(normal_PAYGAS_contract_deploy_tx)
    assert not computation.is_error

    recipient = decode_hex('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0c')
    amount = 100
    tx_initiator = forwarder_address
    vrs = 64 * b'\xAA' + b'\x01'
    access_list = [[tx_initiator], [recipient], [PAYGAS_contract_address]]
    trigger_tx = new_sharding_transaction(tx_initiator,
                                          PAYGAS_contract_address,
                                          amount,
                                          recipient,
                                          vrs,
                                          access_list=access_list)

    with vm.state.state_db(read_only=True) as state_db:
        PAYGAS_balance_before_trigger = state_db.get_balance(
            PAYGAS_contract_address)
        forwarder_balance_before_trigger = state_db.get_balance(
            forwarder_address)
        recipient_balance_before_trigger = state_db.get_balance(recipient)
    computation, _ = vm.apply_transaction(trigger_tx)
    assert not computation.is_error
    with vm.state.state_db(read_only=True) as state_db:
        # Check that balance of these accounts are the same except the amount transfered
        assert PAYGAS_balance_before_trigger == state_db.get_balance(
            PAYGAS_contract_address)
        assert forwarder_balance_before_trigger == state_db.get_balance(
            forwarder_address) + amount
        assert state_db.get_balance(
            recipient) == recipient_balance_before_trigger + amount