Skip to content

Commit 307cf7c

Browse files
committed
Reorder execution proof gossip checks
1 parent bf2e898 commit 307cf7c

2 files changed

Lines changed: 79 additions & 8 deletions

File tree

specs/_features/eip8025/p2p-interface.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,31 @@ def validate_execution_proof_gossip(
9393
Raises GossipIgnore or GossipReject on validation failure.
9494
"""
9595
proof_envelope = signed_proof_envelope.message
96+
97+
# [REJECT] The proof data is non-empty
98+
if len(proof_envelope.proof_data) == 0:
99+
raise GossipReject("execution proof envelope is invalid")
100+
101+
# [REJECT] The proof type is supported
102+
if proof_envelope.proof_type not in get_supported_proof_types():
103+
raise GossipReject("execution proof envelope is invalid")
104+
96105
beacon_block_root = proof_envelope.beacon_block_root
106+
107+
# [IGNORE] The proof's beacon block has been seen
108+
if beacon_block_root not in store.blocks:
109+
raise GossipIgnore("execution proof's beacon block has not been seen")
110+
97111
proof_root = hash_tree_root(proof_envelope)
98112

99113
# [IGNORE] The proof has not already been processed
100114
if proof_root in seen.execution_proof_roots.get(beacon_block_root, set()):
101115
raise GossipIgnore("execution proof has already been processed")
102116

117+
# [IGNORE] No valid proof is known for this beacon block and proof type
118+
if proof_envelope.proof_type in store.execution_proofs.get(beacon_block_root, {}):
119+
raise GossipIgnore("verified proof already known for this beacon block and proof type")
120+
103121
# [IGNORE] This is the prover's first valid or invalid proof for this key
104122
validator_index = signed_proof_envelope.validator_index
105123
prover_key = (beacon_block_root, proof_envelope.proof_type, validator_index)
@@ -108,20 +126,12 @@ def validate_execution_proof_gossip(
108126
"proof already seen from this prover for this beacon block and proof type"
109127
)
110128

111-
# [IGNORE] The proof's beacon block has been seen
112-
if beacon_block_root not in store.blocks:
113-
raise GossipIgnore("execution proof's beacon block has not been seen")
114-
115129
# [IGNORE] The proof's execution payload is available
116130
if beacon_block_root not in store.payloads:
117131
raise GossipIgnore("execution proof's payload is unavailable")
118132

119133
payload_envelope = store.payloads[beacon_block_root]
120134

121-
# [IGNORE] No valid proof is known for this beacon block and proof type
122-
if proof_envelope.proof_type in store.execution_proofs.get(beacon_block_root, {}):
123-
raise GossipIgnore("verified proof already known for this beacon block and proof type")
124-
125135
# [REJECT] The execution proof envelope passes validation
126136
state = store.block_states[beacon_block_root]
127137
try:

tests/core/pyspec/eth_consensus_specs/test/eip8025/unittests/test_gossip_execution_proof.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,67 @@ def test_gossip_handles_missing_execution_proof_block_context(spec, state):
185185
store.payloads[block_root] = payload
186186

187187

188+
@with_eip8025_and_later
189+
@spec_state_test
190+
def test_gossip_applies_cheap_checks_before_payload_lookup(spec, state):
191+
"""
192+
Apply message-local and deduplication checks before requiring the payload.
193+
"""
194+
store, block_root = setup_store_with_block(spec, state)
195+
signed_proof = make_signed_execution_proof_envelope(spec, state, block_root)
196+
store.payloads.pop(block_root)
197+
198+
# Reject message-local structural failures without block or payload context.
199+
unknown_root = spec.Root(b"\xaa" * 32)
200+
empty_proof = make_signed_execution_proof_envelope(spec, state, unknown_root, proof_data=b"")
201+
assert validate(spec, get_seen(spec), store, empty_proof) == (
202+
"reject",
203+
"execution proof envelope is invalid",
204+
)
205+
unsupported_proof = make_signed_execution_proof_envelope(
206+
spec, state, unknown_root, proof_type=UNSUPPORTED_LOW_PROOF_TYPE
207+
)
208+
assert validate(spec, get_seen(spec), store, unsupported_proof) == (
209+
"reject",
210+
"execution proof envelope is invalid",
211+
)
212+
213+
# Ignore known duplicates without requiring the payload.
214+
proof_root = signed_proof.message.hash_tree_root()
215+
seen = get_seen(spec)
216+
seen.execution_proof_roots[block_root] = {proof_root}
217+
assert validate(spec, seen, store, signed_proof) == (
218+
"ignore",
219+
"execution proof has already been processed",
220+
)
221+
222+
store.execution_proofs[block_root] = {signed_proof.message.proof_type: signed_proof.message}
223+
assert validate(spec, get_seen(spec), store, signed_proof) == (
224+
"ignore",
225+
"verified proof already known for this beacon block and proof type",
226+
)
227+
store.execution_proofs.pop(block_root)
228+
229+
seen = get_seen(spec)
230+
seen.execution_proof_provers.add(
231+
(
232+
block_root,
233+
signed_proof.message.proof_type,
234+
signed_proof.validator_index,
235+
)
236+
)
237+
assert validate(spec, seen, store, signed_proof) == (
238+
"ignore",
239+
"proof already seen from this prover for this beacon block and proof type",
240+
)
241+
242+
# A supported, unseen proof still requires the payload.
243+
assert validate(spec, get_seen(spec), store, signed_proof) == (
244+
"ignore",
245+
"execution proof's payload is unavailable",
246+
)
247+
248+
188249
@with_eip8025_and_later
189250
@spec_state_test
190251
@always_bls

0 commit comments

Comments
 (0)