Refine EIP-8025 ProofData type and gossip validation logic - #5593
Refine EIP-8025 ProofData type and gossip validation logic#5593frisitano wants to merge 16 commits into
ProofData type and gossip validation logic#5593Conversation
ProofData typing and size limits and simply gossip validation logicProofData typing and simply gossip validation logic
ProofData typing and simply gossip validation logicProofData type and simply gossip validation logic
ProofData type and simply gossip validation logicProofData type and gossip validation logic
|
Some additional changes to the spec cc: @dapplion |
| verify_execution_proof_envelope( | ||
| state, | ||
| signed_proof_envelope, | ||
| payload_envelope, | ||
| ) |
There was a problem hiding this comment.
We should be able to make this a single line now, without wrapping.
|
Hey @frisitano I've been sort of waiting for @dapplion to review this before giving it a proper review myself. Is that a requirement or would this be ready to review/merge without him? |
I don't think it's a requirement, just a nice-to-have. I trust that @dapplion and @nalepae will provide review and feedback as and when they have capacity. |
| *Note*: `MAX_SIGNED_EXECUTION_PROOF_ENVELOPE_SIZE` is derived from | ||
| `MAX_PROOF_SIZE` plus 145 bytes of fixed SSZ overhead: two 4-byte offsets, a | ||
| 1-byte `ProofType`, a 32-byte `Root`, an 8-byte `ValidatorIndex`, and a 96-byte | ||
| `BLSSignature`. | ||
|
|
||
| | Name | Value | | ||
| | ------------------------------------------ | -------------------------------------------------- | | ||
| | `MAX_SIGNED_EXECUTION_PROOF_ENVELOPE_SIZE` | `Uint64(MAX_PROOF_SIZE + 145)` (= 4,194,449 bytes) | |
There was a problem hiding this comment.
Clients don't really need to know how this is computed. Let's delete the note, revert this change, then add a test like the following which ensures the constant matches the computed value.
| raise GossipReject("execution proof envelope is invalid") | ||
|
|
||
| # [REJECT] The proof type is supported | ||
| if proof_envelope.proof_type not in get_supported_proof_types(): | ||
| raise GossipReject("execution proof envelope is invalid") |
There was a problem hiding this comment.
These error messages must be different, otherwise we would be unable to test them properly (indistinguishable). Let's do something like "execution proof is empty" and "unexpected proof type".
| payload_envelope = store.payloads[beacon_block_root] | ||
|
|
||
| # [IGNORE] No valid proof is known for this beacon block and proof type | ||
| if proof_envelope.proof_type in store.execution_proofs.get(beacon_block_root, {}): | ||
| raise GossipIgnore("verified proof already known for this beacon block and proof type") | ||
|
|
||
| # [REJECT] The execution proof envelope passes validation | ||
| state = store.block_states[beacon_block_root] | ||
| try: |
There was a problem hiding this comment.
Let's put the state definition above this check.
state = ...
payload_envelope = ...
# [REJECT] The execution proof envelope passes validation
try:There was a problem hiding this comment.
Hmm I just realized that these execution proof gossip tests are unit tests, not proper reference tests. This whole file needs to be re-written eventually; to be something more like this. But don't worry about this right now. We're planning to remove all tests for non-CFI'd EIPs. Updating the testing infrastructure for every proposed EIP is not sustainable; testing updates are way more invasive than a self-contained feature spec directory.
|
|
||
| ```python | ||
| class ProofData(ProgressiveList[Byte]): | ||
| class ProofData(ByteList): |
There was a problem hiding this comment.
What is the rationale behind this change?
Is it to ensure that a message is not too big (thanks to checking if proof size is not higher than (MAX_PROOF_SIZE)?
(If so, the message size is already bounded at the network layer by MAX_SIGNED_EXECUTION_PROOF_ENVELOPE_SIZE)
There was a problem hiding this comment.
Yes, it bounds the size of the gossiped message. The idea of this change is to provide the bound such that the limit is encoded into the type directly instead of needing an extra check elsewhere.
There was a problem hiding this comment.
MAX_SIGNED_EXECUTION_PROOF_ENVELOPE_SIZE is not actually enforced anywhere in code. It is this change that encodes the bound into the message.
| raise GossipIgnore("verified proof already known for this beacon block and proof type") | ||
|
|
||
| # [REJECT] The execution proof envelope passes validation | ||
| state = store.block_states[beacon_block_root] |
There was a problem hiding this comment.
The new version of the spec has no
if beacon_block_root not in store.block_states:check any more.
So, if beacon_block_root is not in store.block_states, it will generate a KeyError. Before the change it was a clear GossipReject. It would probably be better to explicitly reject in that case.
There was a problem hiding this comment.
The idea is that the payload envelope will reach the store only if the associated beacon block is valid, so checking for the payload envelope is implicit check that the beacon block is valid and as such it exists in block_states without having to explicitly do the check.
Co-authored-by: Justin Traglia <95511699+jtraglia@users.noreply.github.com>
| if beacon_block_root not in store.payloads: | ||
| raise GossipIgnore("execution proof's payload is unavailable") | ||
|
|
||
| payload_envelope = store.payloads[beacon_block_root] |
There was a problem hiding this comment.
So I disagree here. If those variables were only used within that gossip check, I would agree, but that's not the case. Please see https://github.com/ethereum/consensus-specs/pull/5593/changes#r3971468388 where I suggest something different.
| raise GossipIgnore("execution proof's beacon block has not been seen") | ||
|
|
||
| # [IGNORE] No valid proof is known for this beacon block and proof type | ||
| if proof_envelope.proof_type in store.execution_proofs.get(beacon_block_root, {}): |
There was a problem hiding this comment.
execution_proofs could be DefaultDict.
Description
This PR refines the EIP-8025 spec with the following changes:
ProofDatatype to beByteListwith a size limitProofDataand the container types