Ejemplo n.º 1
0
def test_apply_transaction(  # noqa: F811
        chain_without_block_validation, funded_address,
        funded_address_private_key):
    chain = chain_without_block_validation  # noqa: F811

    # Don't change these variables
    vm = chain.get_vm()
    chaindb = copy.deepcopy(vm.chaindb)
    block0 = copy.deepcopy(vm.block)
    prev_block_hash = chain.get_canonical_block_by_number(0).hash
    initial_state_root = vm.block.header.state_root

    # (1) Get VM.apply_transaction(transaction) result for assertion
    # The first transaction
    chain1 = copy.deepcopy(chain)
    vm_example = chain1.get_vm()
    recipient1 = decode_hex('0x1111111111111111111111111111111111111111')
    amount = 100
    from_ = funded_address
    tx1 = new_transaction(
        vm_example,
        from_,
        recipient1,
        amount,
        private_key=funded_address_private_key,
    )
    computation, result_block = vm_example.apply_transaction(tx1)

    # The second transaction
    recipient2 = decode_hex('0x2222222222222222222222222222222222222222')
    tx2 = new_transaction(
        vm_example,
        from_,
        recipient2,
        amount,
        private_key=funded_address_private_key,
    )
    computation, result_block = vm_example.apply_transaction(tx2)
    assert len(result_block.transactions) == 2

    # (2) Test State.apply_transaction(...)
    # Use SpuriousDragonState to apply transaction
    chaindb1 = copy.deepcopy(chaindb)
    block1 = copy.deepcopy(block0)
    prev_hashes = vm.get_prev_hashes(
        last_block_hash=prev_block_hash,
        db=vm.chaindb,
    )
    execution_context = block1.header.create_execution_context(prev_hashes)
    state1 = SpuriousDragonState(
        chaindb=chaindb1,
        execution_context=execution_context,
        state_root=block1.header.state_root,
        receipts=[],
    )
    parent_hash = copy.deepcopy(prev_hashes[0])

    computation, block, _ = state1.apply_transaction(
        tx1,
        block1,
    )
    access_logs1 = computation.state.access_logs

    # Check if prev_hashes hasn't been changed
    assert parent_hash == prev_hashes[0]
    # Make sure that block1 hasn't been changed
    assert block1.header.state_root == initial_state_root
    execution_context = block.header.create_execution_context(prev_hashes)
    state1 = SpuriousDragonState(
        chaindb=chaindb1,
        execution_context=execution_context,
        state_root=block.header.state_root,
        receipts=computation.state.receipts,
    )
    computation, block, _ = state1.apply_transaction(
        tx2,
        block,
    )
    access_logs2 = computation.state.access_logs
    post_state = computation.state

    # Check AccessLogs
    witness_db = ChainDB(MemoryDB(access_logs2.writes))
    state_db = witness_db.get_state_db(block.header.state_root, read_only=True)
    assert state_db.get_balance(recipient2) == amount
    with pytest.raises(KeyError):
        _ = state_db.get_balance(recipient1)

    # Check block data are correct
    assert block.header.state_root == result_block.header.state_root
    assert block.header.gas_limit == result_block.header.gas_limit
    assert block.header.gas_used == result_block.header.gas_used
    assert block.header.transaction_root == result_block.header.transaction_root
    assert block.header.receipt_root == result_block.header.receipt_root

    # Make sure that state1 hasn't been changed
    assert post_state.state_root == result_block.header.state_root

    # (3) Testing using witness as db data
    # Witness_db
    block2 = copy.deepcopy(block0)

    witness_db = ChainDB(MemoryDB(access_logs1.reads))
    prev_hashes = vm.get_prev_hashes(
        last_block_hash=prev_block_hash,
        db=vm.chaindb,
    )
    execution_context = block2.header.create_execution_context(prev_hashes)
    # Apply the first transaction
    state2 = SpuriousDragonState(
        chaindb=witness_db,
        execution_context=execution_context,
        state_root=block2.header.state_root,
        receipts=[],
    )
    computation, block, _ = state2.apply_transaction(
        tx1,
        block2,
    )

    # Update witness_db
    recent_trie_nodes = merge(access_logs2.reads, access_logs1.writes)
    witness_db = ChainDB(MemoryDB(recent_trie_nodes))
    execution_context = block.header.create_execution_context(prev_hashes)
    # Apply the second transaction
    state2 = SpuriousDragonState(
        chaindb=witness_db,
        execution_context=execution_context,
        state_root=block.header.state_root,
        receipts=computation.state.receipts,
    )
    computation, block, _ = state2.apply_transaction(
        tx2,
        block,
    )

    # After applying
    assert block.header.state_root == computation.state.state_root
    assert block.header.transaction_root == result_block.header.transaction_root
    assert block.header.receipt_root == result_block.header.receipt_root
    assert block.hash == result_block.hash

    # (3) Testing using witness_db and block_header to reconstruct state
    prev_hashes = vm.get_prev_hashes(
        last_block_hash=prev_block_hash,
        db=vm.chaindb,
    )
    execution_context = block.header.create_execution_context(prev_hashes)
    state3 = SpuriousDragonState(
        chaindb=witness_db,
        execution_context=execution_context,
        state_root=block.header.state_root,
    )
    assert state3.state_root == post_state.state_root
    assert state3.state_root == result_block.header.state_root
Ejemplo n.º 2
0

FrontierStateForTesting = FrontierState.configure(
    __name__='FrontierStateForTesting',
    get_ancestor_hash=get_block_hash_for_testing,
)
HomesteadStateForTesting = HomesteadState.configure(
    __name__='HomesteadStateForTesting',
    get_ancestor_hash=get_block_hash_for_testing,
)
TangerineWhistleStateForTesting = TangerineWhistleState.configure(
    __name__='TangerineWhistleStateForTesting',
    get_ancestor_hash=get_block_hash_for_testing,
)
SpuriousDragonStateForTesting = SpuriousDragonState.configure(
    __name__='SpuriousDragonStateForTesting',
    get_ancestor_hash=get_block_hash_for_testing,
)
ByzantiumStateForTesting = ByzantiumState.configure(
    __name__='ByzantiumStateForTesting',
    get_ancestor_hash=get_block_hash_for_testing,
)

FrontierVMForTesting = FrontierVM.configure(
    __name__='FrontierVMForTesting',
    _state_class=FrontierStateForTesting,
    get_prev_hashes=get_prev_hashes_testing,
)
HomesteadVMForTesting = HomesteadVM.configure(
    __name__='HomesteadVMForTesting',
    _state_class=HomesteadStateForTesting,
    get_prev_hashes=get_prev_hashes_testing,
Ejemplo n.º 3
0
def test_apply_transaction(
        chain_without_block_validation,
        funded_address,
        funded_address_private_key):
    chain = chain_without_block_validation

    # Don't change these variables
    vm = chain.get_vm()
    chaindb = copy.deepcopy(vm.chaindb)
    block0 = copy.deepcopy(vm.block)
    prev_block_hash = chain.get_canonical_block_by_number(0).hash
    initial_state_root = vm.block.header.state_root

    # (1) Get VM.apply_transaction(transaction) result for assertion
    # The first transaction
    chain1 = copy.deepcopy(chain)
    vm_example = chain1.get_vm()
    recipient1 = decode_hex('0x1111111111111111111111111111111111111111')
    amount = 100
    from_ = funded_address
    tx1 = new_transaction(
        vm_example,
        from_,
        recipient1,
        amount,
        private_key=funded_address_private_key,
    )
    computation, result_block = vm_example.apply_transaction(tx1)

    # The second transaction
    recipient2 = decode_hex('0x2222222222222222222222222222222222222222')
    tx2 = new_transaction(
        vm_example,
        from_,
        recipient2,
        amount,
        private_key=funded_address_private_key,
    )
    computation, result_block = vm_example.apply_transaction(tx2)
    assert len(result_block.transactions) == 2

    # (2) Test State.apply_transaction(...)
    # Use SpuriousDragonState to apply transaction
    chaindb1 = copy.deepcopy(chaindb)
    block1 = copy.deepcopy(block0)
    prev_hashes = vm.get_prev_hashes(
        last_block_hash=prev_block_hash,
        db=vm.chaindb,
    )
    execution_context = block1.header.create_execution_context(prev_hashes)
    state1 = SpuriousDragonState(
        chaindb=chaindb1,
        execution_context=execution_context,
        state_root=block1.header.state_root,
        gas_used=0,
    )
    parent_hash = copy.deepcopy(prev_hashes[0])

    computation, block, _ = state1.apply_transaction(
        tx1,
        block1,
    )

    # Check if prev_hashes hasn't been changed
    assert parent_hash == prev_hashes[0]
    # Make sure that block1 hasn't been changed
    assert block1.header.state_root == initial_state_root
    execution_context = block.header.create_execution_context(prev_hashes)
    state1 = SpuriousDragonState(
        chaindb=chaindb1,
        execution_context=execution_context,
        state_root=block.header.state_root,
        gas_used=computation.state.gas_used,
    )
    computation, block, _ = state1.apply_transaction(
        tx2,
        block,
    )
    post_state = computation.state

    # Check block data are correct
    assert block.header.state_root == result_block.header.state_root
    assert block.header.gas_limit == result_block.header.gas_limit
    assert block.header.gas_used == result_block.header.gas_used
    assert block.header.transaction_root == result_block.header.transaction_root
    assert block.header.receipt_root == result_block.header.receipt_root

    # Make sure that state1 hasn't been changed
    assert post_state.state_root == result_block.header.state_root