Skip to content

Commit bd5f34c

Browse files
committed
Update usages of BlockHeader() and .from_parent()
Direct invocation of the header object is not allowed anymore, because different VMs now have different header types (as of EIP-1559 in London). So we must always invoke header creation through the VM. - Remove the BlockHeader() init in test_blockchain. - Remove HeaderChain, which seems to be completely unused in the code base. - Embrace that we need one global type that can decode all headers. - Add VM.create_genesis_header The genesis header now needs to be VM-aware, to handle EIP-1559. Rather than pass in a parent of None, it looks a bit cleaner to use the new create_genesis_header. - Create header from VM in opcode test (we need a proper London header at genesis)
1 parent 48bf83c commit bd5f34c

File tree

12 files changed

+117
-198
lines changed

12 files changed

+117
-198
lines changed

eth/abc.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3315,6 +3315,16 @@ def generate_block_from_parent_header_and_coinbase(cls,
33153315
"""
33163316
...
33173317

3318+
@classmethod
3319+
@abstractmethod
3320+
def create_genesis_header(cls, **genesis_params: Any) -> BlockHeaderAPI:
3321+
"""
3322+
Create a genesis header using this VM's rules.
3323+
3324+
This is currently equivalent to create_header_from_parent(None, **genesis_params)
3325+
"""
3326+
...
3327+
33183328
@classmethod
33193329
@abstractmethod
33203330
def get_block_class(cls) -> Type[BlockAPI]:

eth/chains/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ def from_genesis(cls,
247247
f"Expected {genesis_params['state_root']!r}"
248248
)
249249

250-
genesis_header = genesis_vm_class.create_header_from_parent(None, **genesis_params)
250+
genesis_header = genesis_vm_class.create_genesis_header(**genesis_params)
251251
return cls.from_genesis_header(base_db, genesis_header)
252252

253253
@classmethod

eth/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@
161161
GENESIS_NONCE = b'\x00\x00\x00\x00\x00\x00\x00B' # 0x42 encoded as big-endian-integer
162162
GENESIS_MIX_HASH = ZERO_HASH32
163163
GENESIS_EXTRA_DATA = b''
164+
GENESIS_BLOOM = 0
165+
GENESIS_GAS_USED = 0
166+
164167
#
165168
# Sha3 Keccak
166169
#

eth/tools/fixtures/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
)
99
from .helpers import ( # noqa: F401
1010
new_chain_from_fixture,
11+
genesis_fields_from_fixture,
1112
genesis_params_from_fixture,
1213
apply_fixture_block_to_chain,
1314
setup_state,

eth/tools/fixtures/helpers.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
StateAPI,
2525
VirtualMachineAPI,
2626
)
27+
from eth import constants
2728
from eth.db.atomic import AtomicDB
2829
from eth.chains.mainnet import (
2930
MainnetDAOValidatorVM,
@@ -165,7 +166,11 @@ def chain_vm_configuration(fixture: Dict[str, Any]) -> Iterable[Tuple[int, Type[
165166
raise ValueError(f"Network {network} does not match any known VM rules")
166167

167168

168-
def genesis_params_from_fixture(fixture: Dict[str, Any]) -> Dict[str, Any]:
169+
def genesis_fields_from_fixture(fixture: Dict[str, Any]) -> Dict[str, Any]:
170+
"""
171+
Convert all genesis fields in a fixture to a dictionary of header fields and values.
172+
"""
173+
169174
return {
170175
'parent_hash': fixture['genesisBlockHeader']['parentHash'],
171176
'uncles_hash': fixture['genesisBlockHeader']['uncleHash'],
@@ -185,6 +190,34 @@ def genesis_params_from_fixture(fixture: Dict[str, Any]) -> Dict[str, Any]:
185190
}
186191

187192

193+
def genesis_params_from_fixture(fixture: Dict[str, Any]) -> Dict[str, Any]:
194+
"""
195+
Convert a genesis fixture into a dict of the configurable header fields and values.
196+
197+
Some fields cannot be explicitly set when creating a new header, like
198+
parent_hash, which is automatically set to the empty hash.
199+
"""
200+
201+
params = genesis_fields_from_fixture(fixture)
202+
203+
# Confirm that (currently) non-configurable defaults are set correctly,
204+
# then remove them because they cannot be configured on the header.
205+
defaults = (
206+
('parent_hash', constants.GENESIS_PARENT_HASH),
207+
('uncles_hash', constants.EMPTY_UNCLE_HASH),
208+
('bloom', constants.GENESIS_BLOOM),
209+
('block_number', constants.GENESIS_BLOCK_NUMBER),
210+
('gas_used', constants.GENESIS_GAS_USED),
211+
)
212+
213+
for key, default_val in defaults:
214+
supplied_val = params.pop(key)
215+
if supplied_val != default_val:
216+
raise ValueError(f"Unexpected genesis {key}: {supplied_val}, expected: {default_val}")
217+
218+
return params
219+
220+
188221
def new_chain_from_fixture(fixture: Dict[str, Any],
189222
chain_cls: Type[ChainAPI] = MainnetChain) -> ChainAPI:
190223
base_db = AtomicDB()

eth/tools/rlp.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@
88
)
99

1010

11-
assert_imported_genesis_header_unchanged = replace_exceptions({
12-
ValidationError: AssertionError,
13-
})(validate_rlp_equal(obj_a_name='genesis header', obj_b_name='imported header'))
14-
15-
1611
assert_mined_block_unchanged = replace_exceptions({
1712
ValidationError: AssertionError,
1813
})(validate_rlp_equal(obj_a_name='provided block', obj_b_name='executed block'))

eth/vm/base.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,11 @@ def generate_block_from_parent_header_and_coinbase(cls,
454454
)
455455
return block
456456

457+
@classmethod
458+
def create_genesis_header(cls, **genesis_params) -> BlockHeaderAPI:
459+
# Create genesis header by setting the parent to None
460+
return cls.create_header_from_parent(None, **genesis_params)
461+
457462
@classmethod
458463
def get_block_class(cls) -> Type[BlockAPI]:
459464
if cls.block_class is None:

tests/core/chain-object/test_header_chain.py

Lines changed: 0 additions & 137 deletions
This file was deleted.

0 commit comments

Comments
 (0)