Skip to content

Commit c9697f7

Browse files
authored
tests: add genesis tests with hardcoded hash values (leanEthereum#195)
1 parent a1ae091 commit c9697f7

1 file changed

Lines changed: 103 additions & 3 deletions

File tree

tests/consensus/devnet/state_transition/test_genesis.py

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
import pytest
1111
from consensus_testing import StateExpectation, StateTransitionTestFiller, generate_pre_state
1212

13-
from lean_spec.subspecs.containers.block import BlockBody
13+
from lean_spec.subspecs.containers.block import Block, BlockBody
1414
from lean_spec.subspecs.containers.block.types import Attestations
1515
from lean_spec.subspecs.containers.slot import Slot
16-
from lean_spec.subspecs.containers.state import Validators
16+
from lean_spec.subspecs.containers.state import State, Validators
1717
from lean_spec.subspecs.containers.state.types import (
1818
HistoricalBlockHashes,
1919
JustificationRoots,
@@ -22,7 +22,7 @@
2222
)
2323
from lean_spec.subspecs.containers.validator import Validator
2424
from lean_spec.subspecs.ssz.hash import hash_tree_root
25-
from lean_spec.types import Bytes32, Bytes52, Uint64
25+
from lean_spec.types import Bytes32, Bytes52, Uint64, ValidatorIndex
2626

2727
pytestmark = pytest.mark.valid_until("Devnet")
2828

@@ -154,3 +154,103 @@ def test_genesis_custom_validator_set(
154154
justifications_validators=JustificationValidators(data=[]),
155155
),
156156
)
157+
158+
159+
def test_genesis_block_hash_comparison() -> None:
160+
"""Test that genesis block hashes are deterministic and differ with different inputs."""
161+
# Create first genesis state with 3 validators
162+
# Fill pubkeys with different values (1, 2, 3)
163+
pubkeys1 = [Bytes52(bytes([i + 1] * 52)) for i in range(3)]
164+
validators1 = Validators(data=[Validator(pubkey=pubkey) for pubkey in pubkeys1])
165+
166+
genesis_state1 = State.generate_genesis(
167+
genesis_time=Uint64(1000),
168+
validators=validators1,
169+
)
170+
171+
# Generate genesis block from first state
172+
genesis_block1 = Block(
173+
slot=Slot(0),
174+
proposer_index=ValidatorIndex(0),
175+
parent_root=Bytes32.zero(),
176+
state_root=hash_tree_root(genesis_state1),
177+
body=BlockBody(attestations=Attestations(data=[])),
178+
)
179+
180+
# Compute hash of first genesis block
181+
genesis_block_hash1 = hash_tree_root(genesis_block1)
182+
183+
# Create a second genesis state with same config but regenerated (should produce same hash)
184+
genesis_state1_copy = State.generate_genesis(
185+
genesis_time=Uint64(1000),
186+
validators=validators1,
187+
)
188+
189+
genesis_block1_copy = Block(
190+
slot=Slot(0),
191+
proposer_index=ValidatorIndex(0),
192+
parent_root=Bytes32.zero(),
193+
state_root=hash_tree_root(genesis_state1_copy),
194+
body=BlockBody(attestations=Attestations(data=[])),
195+
)
196+
197+
genesis_block_hash1_copy = hash_tree_root(genesis_block1_copy)
198+
199+
# Same genesis spec should produce same hash
200+
assert genesis_block_hash1 == genesis_block_hash1_copy
201+
202+
# Create second genesis state with different validators
203+
# Fill pubkeys with different values (10, 11, 12)
204+
pubkeys2 = [Bytes52(bytes([i + 10] * 52)) for i in range(3)]
205+
validators2 = Validators(data=[Validator(pubkey=pubkey) for pubkey in pubkeys2])
206+
207+
genesis_state2 = State.generate_genesis(
208+
genesis_time=Uint64(1000), # Same genesis_time but different validators
209+
validators=validators2,
210+
)
211+
212+
genesis_block2 = Block(
213+
slot=Slot(0),
214+
proposer_index=ValidatorIndex(0),
215+
parent_root=Bytes32.zero(),
216+
state_root=hash_tree_root(genesis_state2),
217+
body=BlockBody(attestations=Attestations(data=[])),
218+
)
219+
220+
genesis_block_hash2 = hash_tree_root(genesis_block2)
221+
222+
# Different validators should produce different genesis block hash
223+
assert genesis_block_hash1 != genesis_block_hash2
224+
225+
# Create third genesis state with same validators but different genesis_time
226+
# Same as pubkeys1
227+
pubkeys3 = [Bytes52(bytes([i + 1] * 52)) for i in range(3)]
228+
validators3 = Validators(data=[Validator(pubkey=pubkey) for pubkey in pubkeys3])
229+
230+
genesis_state3 = State.generate_genesis(
231+
genesis_time=Uint64(2000), # Different genesis_time but same validators
232+
validators=validators3,
233+
)
234+
235+
genesis_block3 = Block(
236+
slot=Slot(0),
237+
proposer_index=ValidatorIndex(0),
238+
parent_root=Bytes32.zero(),
239+
state_root=hash_tree_root(genesis_state3),
240+
body=BlockBody(attestations=Attestations(data=[])),
241+
)
242+
243+
genesis_block_hash3 = hash_tree_root(genesis_block3)
244+
245+
# Different genesis_time should produce different genesis block hash
246+
assert genesis_block_hash1 != genesis_block_hash3
247+
248+
# Compare genesis block hashes with expected hex values
249+
hash1_hex = f"0x{genesis_block_hash1.hex()}"
250+
assert hash1_hex == "0x4c0bcc4750b71818224a826cd59f8bcb75ae2920eb3e75b4097b818be6d1049a"
251+
252+
hash2_hex = f"0x{genesis_block_hash2.hex()}"
253+
assert hash2_hex == "0x639b6162e6b432653a77a64b678717e7634428eda88ad6ccb1862e6397c0c47b"
254+
255+
hash3_hex = f"0x{genesis_block_hash3.hex()}"
256+
assert hash3_hex == "0x6593976e31c915b5d534e2ee6172652aed7690be24777947de39c726aa2af59e"

0 commit comments

Comments
 (0)