Skip to content

Commit

Permalink
EIP-96: Add BLOCKHASH contract tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Jun 2, 2017
1 parent f271d17 commit 1761460
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 0 deletions.
3 changes: 3 additions & 0 deletions EIPS/eip-96/tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*.egg-info/
/.cache/
/__pycache__/
5 changes: 5 additions & 0 deletions EIPS/eip-96/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Usage

1. Setup virtualenv
2. `pip install -r requirements.txt`
3. `py.test`
3 changes: 3 additions & 0 deletions EIPS/eip-96/tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
six
pytest
ethereum==1.6.1
124 changes: 124 additions & 0 deletions EIPS/eip-96/tests/test_blockhash_contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import pytest
import os
from ethereum import tester, utils
from ethereum.config import default_config
from rlp.utils import decode_hex

from pprint import pprint

EIP_BLOCKHASH_CODE = decode_hex(
b'73fffffffffffffffffffffffffffffffffffffffe33141561006a5760014303600035610100820755610100810715156100455760003561010061010083050761010001555b6201000081071515610064576000356101006201000083050761020001555b5061013e565b4360003512151561008457600060405260206040f361013d565b61010060003543031315156100a857610100600035075460605260206060f361013c565b6101006000350715156100c55762010000600035430313156100c8565b60005b156100ea576101006101006000350507610100015460805260206080f361013b565b620100006000350715156101095763010000006000354303131561010c565b60005b1561012f57610100620100006000350507610200015460a052602060a0f361013a565b600060c052602060c0f35b5b5b5b5b' # noqa
)

BLOCKHASH_ADDR = decode_hex(b'00000000000000000000000000000000000000f0')
EIP_SYSTEM_ADDR = decode_hex(b'fffffffffffffffffffffffffffffffffffffffe')

SYSTEM_PRIV = os.urandom(32)
SYSTEM_ADDR = utils.privtoaddr(SYSTEM_PRIV)
SYSTEM_GAS_LIMIT = 1000000
SYSTEM_GAS_PRICE = 0
BLOCKHASH_CODE = EIP_BLOCKHASH_CODE.replace(EIP_SYSTEM_ADDR, SYSTEM_ADDR, 1)
NULL_HASH = b'\0' * 32

# Configure execution in pre-Metropolis mode.
default_config['HOMESTEAD_FORK_BLKNUM'] = 0
default_config['DAO_FORK_BLKNUM'] = 0
default_config['ANTI_DOS_FORK_BLKNUM'] = 0
default_config['CLEARING_FORK_BLKNUM'] = 0


class State(tester.state):
def exec_system(self):
"""Execute BLOCKHASH contract from SYSTEM account"""

prev_block_hash = self.block.get_parent().hash
assert len(prev_block_hash) == 32

gas_limit = tester.gas_limit
tester.gas_limit = SYSTEM_GAS_LIMIT

gas_price = tester.gas_price
tester.gas_price = SYSTEM_GAS_PRICE

output = self.send(sender=SYSTEM_PRIV, to=BLOCKHASH_ADDR, value=0,
evmdata=prev_block_hash)
assert len(output) == 0

tester.gas_limit = gas_limit
tester.gas_price = gas_price

def get_slot(self, index):
"""Get storage entry of BLOCKHASH_ADDR of given index"""
int_value = self.block.get_storage_data(BLOCKHASH_ADDR, index)
return utils.zpad(utils.coerce_to_bytes(int_value), 32)


@pytest.fixture(scope='module')
def state():
state = State()
state.block._set_acct_item(BLOCKHASH_ADDR, 'code', BLOCKHASH_CODE)

for i in range(257):
state.mine()
state.exec_system()

return state


def test_setup(state):
assert state.block.get_code(BLOCKHASH_ADDR) == BLOCKHASH_CODE
assert state.block.get_balance(SYSTEM_ADDR) == 0
assert state.block.get_nonce(SYSTEM_ADDR) > 0

assert state.get_slot(0) == state.blocks[256].hash
for i in range(1, 256):
assert state.get_slot(i) == state.blocks[i].hash

assert state.get_slot(256) == state.blocks[0].hash
assert state.get_slot(257) == state.blocks[256].hash
for i in range(258, 256 + 256):
assert state.get_slot(i) == NULL_HASH

assert state.get_slot(512) == state.blocks[0].hash
for i in range(513, 512 + 256):
assert state.get_slot(i) == NULL_HASH


def test_get_prev_block_hash(state):
prev = state.block.number - 1
pprint(prev)
expected_hash = state.blocks[prev].hash
arg = utils.zpad(utils.coerce_to_bytes(prev), 32)
out = state.profile(sender=tester.k1, to=BLOCKHASH_ADDR, value=0,
evmdata=arg)
assert out['output'] == expected_hash
assert out['gas'] == 330


def test_get_current_block_hash(state):
arg = utils.zpad(utils.coerce_to_bytes(state.block.number), 32)
out = state.profile(sender=tester.k1, to=BLOCKHASH_ADDR, value=0,
evmdata=arg)
assert out['output'] == b'\0' * 32
assert out['gas'] == 79


def test_get_future_block_hash(state):
arg = utils.zpad(utils.coerce_to_bytes(3**11 + 13), 32)
out = state.profile(sender=tester.k1, to=BLOCKHASH_ADDR, value=0,
evmdata=arg)
assert out['output'] == b'\0' * 32
assert out['gas'] == 79


def test_first256th_slot(state):
n = state.block.number
state.block.number = 60000 # Allow accessing 256th block hashes

arg = utils.zpad(utils.coerce_to_bytes(0), 32)
out = state.profile(sender=tester.k1, to=BLOCKHASH_ADDR, value=0,
evmdata=arg)
assert out['output'] == state.blocks[0].hash
assert out['gas'] == 429

state.block.number = n

0 comments on commit 1761460

Please sign in to comment.