Skip to content

Commit

Permalink
add CREATE2 contract add test
Browse files Browse the repository at this point in the history
  • Loading branch information
NIC619 committed Jan 15, 2018
1 parent 849d9f8 commit ad81d76
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 28 deletions.
33 changes: 24 additions & 9 deletions tests/core/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
from evm.vm.forks.sharding import ShardingVM

from tests.core.vm.contract_fixture import (
contract_bytecode,
contract_address,
simple_transfer_contract_bytecode,
simple_transfer_contract_address,
CREATE2_contract_bytecode,
CREATE2_contract_address,
)


Expand Down Expand Up @@ -83,11 +85,18 @@ def chain(chaindb):
return chain


SHARD_CHAIN_CONTRACTS_FIXTURE = {
"contract_code": contract_bytecode,
"deployed_address": contract_address,
"initial_balance": 100000000,
}
SHARD_CHAIN_CONTRACTS_FIXTURES = [
{
"contract_code": simple_transfer_contract_bytecode,
"deployed_address": simple_transfer_contract_address,
"initial_balance": 100000000,
},
{
"contract_code": CREATE2_contract_bytecode,
"deployed_address": CREATE2_contract_address,
"initial_balance": 100000000,
},
]


@pytest.fixture
Expand Down Expand Up @@ -133,8 +142,14 @@ def shard_chain_without_block_validation():
'timestamp': 1501851927,
}
genesis_state = {
SHARD_CHAIN_CONTRACTS_FIXTURE["deployed_address"]: {
'balance': SHARD_CHAIN_CONTRACTS_FIXTURE["initial_balance"],
SHARD_CHAIN_CONTRACTS_FIXTURES[0]["deployed_address"]: {
'balance': SHARD_CHAIN_CONTRACTS_FIXTURES[0]["initial_balance"],
'nonce': 0,
'code': b'',
'storage': {},
},
SHARD_CHAIN_CONTRACTS_FIXTURES[1]["deployed_address"]: {
'balance': SHARD_CHAIN_CONTRACTS_FIXTURES[1]["initial_balance"],
'nonce': 0,
'code': b'',
'storage': {},
Expand Down
61 changes: 49 additions & 12 deletions tests/core/vm/contract_fixture.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,57 @@
from eth_utils import decode_hex

from evm.utils.address import generate_CREATE2_contract_address

# contract code to be deployed
contract_lll_code = ['seq',
['return', # noqa: E127
0,
['lll',
['seq',
['mstore', 32, 1461501637330902918203684832716283019655932542976], # noqa: E501
['uclamplt', ['calldataload', 0], ['mload', 32]],
['assert', ['call', 0, ['calldataload', 0], ['calldataload', 32], 0, 0, 0, 0]], # noqa: E501
'stop'],
0]]] # noqa: E128
simple_transfer_contract_lll_code = ['seq',
['return', # noqa: E127
0,
['lll',
['seq',
['mstore', 32, 1461501637330902918203684832716283019655932542976], # noqa: E501
['uclamplt', ['calldataload', 0], ['mload', 32]], # noqa: E501
['assert', ['call', 0, ['calldataload', 0], ['calldataload', 32], 0, 0, 0, 0]], # noqa: E501
'stop'],
0]]] # noqa: E128


# compiled byte code
simple_transfer_contract_bytecode = b'0x61003e567401000000000000000000000000000000000000000060205260003560205181101558575060006000600060006020356000356000f1155857005b61000461003e0361000460003961000461003e036000f3' # noqa: E501


# address where this contract will be deployed
simple_transfer_contract_address = generate_CREATE2_contract_address(
b'',
decode_hex(simple_transfer_contract_bytecode)
)


simple_contract_factory_bytecode = b'\x61\xbe\xef\x60\x20\x52\x60\x02\x60\x3e\xf3'


# This contract will deploy a new contract and increment it's only storage variable 'nonce'
# every time it's invoked.
# Contract address: generate_CREATE2_contract_address(nonce, simple_contract_factory_bytecode)
# The bytecode of every new contract deployed is b'\xbe\xef'
CREATE2_contract_lll_code = ['seq',
['return', # noqa: E127
0,
['lll',
['seq',
['mstore', 32, ['sload', 0]],
['mstore', 64, 118167469832824678325960435],
['clamp_nonzero', ['create2', ['mload', 32], ['mload', 32], 85, 11]], # noqa: E501
['sstore', 0, ['add', ['mload', 32], 1]],
'stop'],
0]]] # noqa: E128


# compiled byte code
contract_bytecode = b'0x61003e567401000000000000000000000000000000000000000060205260003560205181101558575060006000600060006020356000356000f1155857005b61000461003e0361000460003961000461003e036000f3' # noqa: E501
CREATE2_contract_bytecode = '0x610039566000546020526a61beef6020526002603ef3604052600b6055602051602051fe8061002957600080fd5b50600160205101600055005b61000461003903610004600039610004610039036000f3' # noqa: E501


# address where this contract will be deployed
contract_address = generate_CREATE2_contract_address(b'', contract_bytecode)
CREATE2_contract_address = generate_CREATE2_contract_address(
b'',
decode_hex(CREATE2_contract_bytecode)
)
57 changes: 50 additions & 7 deletions tests/core/vm/test_sharding_vm.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
from eth_utils import decode_hex
from eth_utils import (
int_to_big_endian,
decode_hex,
)

from evm.utils.address import generate_CREATE2_contract_address

from tests.core.fixtures import ( # noqa: F401
shard_chain_without_block_validation,
Expand All @@ -7,26 +12,64 @@
new_sharding_transaction,
)
from tests.core.vm.contract_fixture import (
contract_bytecode,
contract_address,
simple_transfer_contract_bytecode,
simple_transfer_contract_address,
simple_contract_factory_bytecode,
CREATE2_contract_bytecode,
CREATE2_contract_address,
)


def test_sharding_transaction(shard_chain_without_block_validation): # noqa: F811
chain = shard_chain_without_block_validation
deploy_tx = new_sharding_transaction(contract_address, b'', 0, b'', b'', contract_bytecode)
# First test: simple ether transfer contract
first_deploy_tx = new_sharding_transaction(
simple_transfer_contract_address,
b'',
0,
b'',
b'',
simple_transfer_contract_bytecode
)

vm = chain.get_vm()
computation = vm.apply_transaction(deploy_tx)
computation = vm.apply_transaction(first_deploy_tx)
assert not computation.is_error

# Transfer ether to recipient
recipient = decode_hex('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0c')
amount = 100
tx_initiator = contract_address
tx_initiator = simple_transfer_contract_address
transfer_tx = new_sharding_transaction(tx_initiator, recipient, amount, b'', b'', b'')

computation = vm.execute_transaction(transfer_tx)
computation = vm.apply_transaction(transfer_tx)
assert not computation.is_error
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(
CREATE2_contract_address,
b'',
0,
b'',
b'',
CREATE2_contract_bytecode
)

computation = vm.apply_transaction(second_deploy_tx)
assert not computation.is_error

# Invoke the contract to deploy new contract
tx_initiator = CREATE2_contract_address
invoke_tx = new_sharding_transaction(tx_initiator, b'', 0, b'', b'', b'')

computation = vm.apply_transaction(invoke_tx)
assert not computation.is_error
with vm.state.state_db(read_only=True) as state_db:
newly_deployed_contract_address = generate_CREATE2_contract_address(
int_to_big_endian(0),
simple_contract_factory_bytecode
)
assert state_db.get_code(newly_deployed_contract_address) == b'\xbe\xef'
assert state_db.get_storage(CREATE2_contract_address, 0) == 1

0 comments on commit ad81d76

Please sign in to comment.