Skip to content

Commit 50ecc74

Browse files
authored
Merge pull request #910 from ethereum/witness-additions
feat(verkle): add parent root to witness
2 parents 7b25809 + eade208 commit 50ecc74

File tree

5 files changed

+45
-87
lines changed

5 files changed

+45
-87
lines changed

.github/configs/evm.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,5 @@ pectra-devnet-3:
2222
verkle:
2323
impl: geth
2424
repo: gballet/go-ethereum
25-
# ref: kaustinen-with-shapella
26-
ref: jsign-witness-fix
25+
ref: kaustinen-with-shapella
2726
evm-bin: evm

src/ethereum_test_specs/blockchain.py

Lines changed: 36 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,7 @@ def count_blobs(txs: List[Transaction]) -> int:
106106
Returns the number of blobs in a list of transactions.
107107
"""
108108
return sum(
109-
[
110-
len(tx.blob_versioned_hashes)
111-
for tx in txs
112-
if tx.blob_versioned_hashes is not None
113-
]
109+
[len(tx.blob_versioned_hashes) for tx in txs if tx.blob_versioned_hashes is not None]
114110
)
115111

116112

@@ -247,10 +243,7 @@ class Block(Header):
247243
returned by the `evm_transition_tool`.
248244
"""
249245
exception: (
250-
List[TransactionException | BlockException]
251-
| TransactionException
252-
| BlockException
253-
| None
246+
List[TransactionException | BlockException] | TransactionException | BlockException | None
254247
) = None
255248
"""
256249
If set, the block is expected to be rejected by the client.
@@ -271,9 +264,7 @@ class Block(Header):
271264
"""
272265
List of withdrawals to perform for this block.
273266
"""
274-
requests: List[DepositRequest | WithdrawalRequest | ConsolidationRequest] | None = (
275-
None
276-
)
267+
requests: List[DepositRequest | WithdrawalRequest | ConsolidationRequest] | None = None
277268
"""
278269
Custom list of requests to embed in this block.
279270
"""
@@ -295,9 +286,7 @@ def set_environment(self, env: Environment) -> Environment:
295286
"""
296287
new_env_values["difficulty"] = self.difficulty
297288
new_env_values["fee_recipient"] = (
298-
self.fee_recipient
299-
if self.fee_recipient is not None
300-
else Environment().fee_recipient
289+
self.fee_recipient if self.fee_recipient is not None else Environment().fee_recipient
301290
)
302291
new_env_values["gas_limit"] = (
303292
self.gas_limit or env.parent_gas_limit or Environment().gas_limit
@@ -322,9 +311,7 @@ def set_environment(self, env: Environment) -> Environment:
322311
if len(env.block_hashes) == 0:
323312
new_env_values["number"] = 0
324313
else:
325-
new_env_values["number"] = (
326-
max([Number(n) for n in env.block_hashes.keys()]) + 1
327-
)
314+
new_env_values["number"] = max([Number(n) for n in env.block_hashes.keys()]) + 1
328315

329316
if self.timestamp is not None:
330317
new_env_values["timestamp"] = self.timestamp
@@ -364,9 +351,8 @@ def make_genesis(
364351
assert (
365352
env.withdrawals is None or len(env.withdrawals) == 0
366353
), "withdrawals must be empty at genesis"
367-
assert (
368-
env.parent_beacon_block_root is None
369-
or env.parent_beacon_block_root == Hash(0)
354+
assert env.parent_beacon_block_root is None or env.parent_beacon_block_root == Hash(
355+
0
370356
), "parent_beacon_block_root must be empty at genesis"
371357

372358
pre_alloc = Alloc.merge(
@@ -403,15 +389,11 @@ def make_genesis(
403389
blob_gas_used=env.blob_gas_used,
404390
excess_blob_gas=env.excess_blob_gas,
405391
withdrawals_root=(
406-
Withdrawal.list_root(env.withdrawals)
407-
if env.withdrawals is not None
408-
else None
392+
Withdrawal.list_root(env.withdrawals) if env.withdrawals is not None else None
409393
),
410394
parent_beacon_block_root=env.parent_beacon_block_root,
411395
requests_root=(
412-
Requests(root=[]).trie_root
413-
if fork.header_requests_required(0, 0)
414-
else None
396+
Requests(root=[]).trie_root if fork.header_requests_required(0, 0) else None
415397
),
416398
)
417399

@@ -422,9 +404,7 @@ def make_genesis(
422404
withdrawals=None if env.withdrawals is None else [],
423405
deposit_requests=[] if fork.header_requests_required(0, 0) else None,
424406
withdrawal_requests=[] if fork.header_requests_required(0, 0) else None,
425-
consolidation_requests=[]
426-
if fork.header_requests_required(0, 0)
427-
else None,
407+
consolidation_requests=[] if fork.header_requests_required(0, 0) else None,
428408
).with_rlp(
429409
txs=[],
430410
requests=Requests() if fork.header_requests_required(0, 0) else None,
@@ -577,9 +557,7 @@ def generate_block_data(
577557

578558
requests = None
579559
if fork.header_requests_required(header.number, header.timestamp):
580-
requests_list: List[
581-
DepositRequest | WithdrawalRequest | ConsolidationRequest
582-
] = []
560+
requests_list: List[DepositRequest | WithdrawalRequest | ConsolidationRequest] = []
583561
if transition_tool_output.result.deposit_requests is not None:
584562
requests_list += transition_tool_output.result.deposit_requests
585563
if transition_tool_output.result.withdrawal_requests is not None:
@@ -607,11 +585,13 @@ def generate_block_data(
607585
)
608586
)
609587
transition_tool_output.alloc = previous_alloc
588+
# TODO: hack for now, replace with actual witness output once available from t8n
610589
if transition_tool_output.result.verkle_conversion_ended:
611-
# TODO: hack for now, replace with actual witness output once available from t8n
590+
witness_parent_root = transition_tool_output.result.parent_root
612591
transition_tool_output.witness = Witness(
613592
verkle_proof=transition_tool_output.result.verkle_proof,
614593
state_diff=transition_tool_output.result.state_diff,
594+
parent_root=witness_parent_root,
615595
)
616596
else:
617597
transition_tool_output.witness = None
@@ -669,8 +649,8 @@ def verify_witness(
669649
Compares the expected witness check allocation account against the values updated
670650
in the block execution witness state diff.
671651
"""
672-
witness_check_state_diff, witness_check_address_mapping = (
673-
t8n.get_witness_check_mapping(witness_check)
652+
witness_check_state_diff, witness_check_address_mapping = t8n.get_witness_check_mapping(
653+
witness_check
674654
)
675655
actual_stem_dict = {sd.stem: sd for sd in state_diff.root}
676656
expected_stem_dict = {sd.stem: sd for sd in witness_check_state_diff.root}
@@ -694,9 +674,7 @@ def verify_witness(
694674
)
695675

696676
actual_suffix_dict = {sd.suffix: sd for sd in stem_state_diff.suffix_diffs}
697-
expected_suffix_dict = {
698-
sd.suffix: sd for sd in expected_stem_state_diff.suffix_diffs
699-
}
677+
expected_suffix_dict = {sd.suffix: sd for sd in expected_stem_state_diff.suffix_diffs}
700678
# Check that all actual suffixes are in expected suffixes
701679
for actual_suffix, suffix_diff in actual_suffix_dict.items():
702680
actual_current_value = suffix_diff.current_value
@@ -715,9 +693,7 @@ def verify_witness(
715693
indent=4,
716694
)
717695
)
718-
if str(actual_current_value) != str(
719-
expected_suffix_state_diff.current_value
720-
):
696+
if str(actual_current_value) != str(expected_suffix_state_diff.current_value):
721697
raise ValueError(
722698
"Witness check failed - current value mismatch.\n\n"
723699
+ pformat(
@@ -726,9 +702,7 @@ def verify_witness(
726702
"stem": str(actual_stem),
727703
"suffix": actual_suffix,
728704
"value_actual": str(actual_current_value),
729-
"value_expected": str(
730-
expected_suffix_state_diff.current_value
731-
),
705+
"value_expected": str(expected_suffix_state_diff.current_value),
732706
},
733707
indent=4,
734708
)
@@ -752,12 +726,8 @@ def verify_witness(
752726
)
753727
)
754728

755-
actual_suffix_dict = {
756-
sd.suffix: sd for sd in actual_stem_state_diff.suffix_diffs
757-
}
758-
expected_suffix_dict = {
759-
sd.suffix: sd for sd in expected_stem_state_diff.suffix_diffs
760-
}
729+
actual_suffix_dict = {sd.suffix: sd for sd in actual_stem_state_diff.suffix_diffs}
730+
expected_suffix_dict = {sd.suffix: sd for sd in expected_stem_state_diff.suffix_diffs}
761731

762732
# Check that all expected suffixes are in actual suffixes
763733
for (
@@ -772,9 +742,7 @@ def verify_witness(
772742
"test_account_address": str(address),
773743
"stem": str(expected_stem),
774744
"suffix": expected_suffix,
775-
"value_expected": str(
776-
expected_suffix_state_diff.current_value
777-
),
745+
"value_expected": str(expected_suffix_state_diff.current_value),
778746
"value_actual": "value not found",
779747
},
780748
indent=4,
@@ -791,12 +759,8 @@ def verify_witness(
791759
"test_account_address": str(address),
792760
"stem": str(expected_stem),
793761
"suffix": expected_suffix,
794-
"value_actual": str(
795-
actual_suffix_state_diff.current_value
796-
),
797-
"value_expected": str(
798-
expected_suffix_state_diff.current_value
799-
),
762+
"value_actual": str(actual_suffix_state_diff.current_value),
763+
"value_expected": str(expected_suffix_state_diff.current_value),
800764
},
801765
indent=4,
802766
)
@@ -859,10 +823,7 @@ def make_fixture(
859823
txs=[FixtureTransaction.from_transaction(tx) for tx in txs],
860824
ommers=[],
861825
withdrawals=(
862-
[
863-
FixtureWithdrawal.from_withdrawal(w)
864-
for w in new_env.withdrawals
865-
]
826+
[FixtureWithdrawal.from_withdrawal(w) for w in new_env.withdrawals]
866827
if new_env.withdrawals is not None
867828
else None
868829
),
@@ -890,9 +851,7 @@ def make_fixture(
890851
if requests is not None
891852
else None
892853
),
893-
witness=FixtureWitness.from_witness(witness)
894-
if witness is not None
895-
else None,
854+
witness=FixtureWitness.from_witness(witness) if witness is not None else None,
896855
).with_rlp(txs=txs, requests=requests)
897856
if block.exception is None:
898857
fixture_blocks.append(fixture_block)
@@ -908,8 +867,7 @@ def make_fixture(
908867
expect_exception=block.exception,
909868
rlp_decoded=(
910869
None
911-
if BlockException.RLP_STRUCTURES_ENCODING
912-
in block.exception
870+
if BlockException.RLP_STRUCTURES_ENCODING in block.exception
913871
else fixture_block.without_rlp()
914872
),
915873
),
@@ -968,16 +926,14 @@ def make_hive_fixture(
968926

969927
for block in self.blocks:
970928
# TODO: fix witness for hive fixture? Do we need it?
971-
new_env, header, txs, new_alloc, requests, new_vkt, _ = (
972-
self.generate_block_data(
973-
t8n=t8n,
974-
fork=fork,
975-
block=block,
976-
previous_env=env,
977-
previous_alloc=alloc,
978-
previous_vkt=vkt,
979-
eips=eips,
980-
)
929+
new_env, header, txs, new_alloc, requests, new_vkt, _ = self.generate_block_data(
930+
t8n=t8n,
931+
fork=fork,
932+
block=block,
933+
previous_env=env,
934+
previous_alloc=alloc,
935+
previous_vkt=vkt,
936+
eips=eips,
981937
)
982938
if block.rlp is None:
983939
fixture_payloads.append(
@@ -996,9 +952,7 @@ def make_hive_fixture(
996952
env = apply_new_parent(new_env, header)
997953
head_hash = header.block_hash
998954
vkt = new_vkt
999-
fcu_version = fork.engine_forkchoice_updated_version(
1000-
header.number, header.timestamp
1001-
)
955+
fcu_version = fork.engine_forkchoice_updated_version(header.number, header.timestamp)
1002956
assert (
1003957
fcu_version is not None
1004958
), "A hive fixture was requested but no forkchoice update is defined. The framework should"

src/ethereum_test_types/verkle/tests/test_verkle_witness.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ def witness_data(state_diff_data, verkle_proof_data):
152152
return {
153153
"stateDiff": state_diff_data,
154154
"verkleProof": verkle_proof_data,
155+
"parentRoot": "0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad7",
155156
}
156157

157158

@@ -170,3 +171,6 @@ def test_witness_validation(witness_data):
170171
== 0x647ED3C87A4F764421EA2F5BFC73195812F6B7DD15AC2B8D295730C1DEDE1EDF
171172
)
172173
assert witness.state_diff.root[0].suffix_diffs[0].new_value is None
174+
assert witness.parent_root == (
175+
0x5B5FDFEDD6A0E932DA408AC7D772A36513D1EEE9B9926E52620C43A433AAD7
176+
)

src/ethereum_test_types/verkle/types.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from ethereum_test_base_types import (
1313
Address,
1414
CamelModel,
15-
HexNumber,
15+
ZeroPaddedHexNumber,
1616
PaddedFixedSizeBytes,
1717
)
1818
from ethereum_test_forks import Fork, Verkle
@@ -69,7 +69,7 @@ class VerkleProof(CamelModel):
6969
"""
7070

7171
other_stems: List[Stem]
72-
depth_extension_present: HexNumber
72+
depth_extension_present: ZeroPaddedHexNumber
7373
commitments_by_path: List[Hash]
7474
d: Hash
7575
ipa_proof: IpaProof | None = Field(None)
@@ -143,7 +143,7 @@ class Witness(CamelModel):
143143

144144
state_diff: StateDiff
145145
verkle_proof: VerkleProof
146-
# parent_state_root: Hash
146+
parent_root: Hash
147147

148148

149149
class VerkleTree(RootModel[Dict[Hash, Hash]]):

src/evm_transition_tool/types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class Result(CamelModel):
112112

113113
verkle_proof: VerkleProof | None = None
114114
state_diff: StateDiff | None = None
115+
parent_root: Hash | None = None
115116

116117

117118
class TransitionToolInput(CamelModel):

0 commit comments

Comments
 (0)