-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Add EIP: eth/70 - partial block receipt lists #9906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
✅ All reviewers have approved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok gave this some thought, mainly some style things. Also did some brainstorming about possible attack scenarios and possibly a way (if we want) to introduce verification of the partial data 😄 👍
EIPS/eip-XXXX.md
Outdated
to defend against malicious servers trying to overload syncing clients, implementations | ||
should perform additional validation for `Receipts` responses: | ||
|
||
- Verify the total number of delivered receipts matches the count of transactions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that only additional checks are necessary if lastBlockIncomplete
is true (1
), and that these checks should only be applied on the final receipts list in the response, right? For all other entries we can perform the original checks (as are done currently (?)): calculating the receiptsRoot
and verify it is correct (and possibly short-circuit this check by first validating if the receipts count equals the transaction count, but this implies we have the block body (from header alone it cannot be derived how much transactions were in the block) which means that the receipts downloader is behind the block body downloader (which is fine))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the text to make this more clear.
EIPS/eip-XXXX.md
Outdated
|
||
- Verify the total number of delivered receipts matches the count of transactions. | ||
- Verify the size of each receipt against the gas limit of the corresponding transaction, | ||
i.e. reject if it is larger than gaslimit/8. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is unclear at this point where the 8
comes from (the reason is introduced in Rationale, absolute minimum cost of this data size in the logs), so should maybe be clarified earlier? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we "need" the transaction for this check, it would also mean we should first download the block body and we can then download the receipts (so cannot be done in parallel).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the restriction on concurrent download is something I need to investigate more during implementation.
EIPS/eip-XXXX.md
Outdated
- Verify the total number of delivered receipts matches the count of transactions. | ||
- Verify the size of each receipt against the gas limit of the corresponding transaction, | ||
i.e. reject if it is larger than gaslimit/8. | ||
- Verify the total downloaded receipts size is no larger than allowed by the block gas limit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we calculate the maximum given the block gas limit? This one is also tricky, since we can effectively spend 20% (due to refund cap of 1/5 https://eips.ethereum.org/EIPS/eip-3529) more than than the reported block gas limit due to refunds. So we have to take into account that the gas limit to calculate this for is 20% more than what is reported in the header.
We know that the max log data size in bytes is block.gasLimit // 8
. But we also have to take into account the status value (1 byte) (or state root of 32 bytes for legacy receipts) and the cumulative block gas used which could at most take N
times the maximum byte size to encode the block gas limit in. So this gives a max size of the receipts, but only for the flat data of the receipts, not the encoded RLP variant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will come up with a more exact formula later when implementing the prototype.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or if you know what to put here, you can also make a PR to the EIP once this is merged. You are co-author and so you can just update.
EIPS/eip-XXXX.md
Outdated
For the first block in the list of requested block hashes, the server should omit receipts | ||
up to the `firstBlockReceiptIndex` from the response. | ||
|
||
Downloading block receipts across multiple messages creates new attack surface. In order |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Downloading block receipts across multiple messages creates new attack surface. In order | |
Downloading block receipts across multiple messages creates new attack surfaces. In order |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'attack surface' is a common term, and it just means the places where it can be attacked. So I'm not changing it to plural.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes upon re-reading it looks correct and should not change. I should also not suggest things regarding grammar/spelling since English is not my main language 😅
EIPS/eip-XXXX.md
Outdated
|
||
- (eth/70): `[request-id: P, firstBlockReceiptIndex: P, [blockhash₁: B_32, blockhash₂: B_32, ...]]` | ||
|
||
For the first block in the list of requested block hashes, the server should omit receipts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the first block in the list of requested block hashes, the server should omit receipts | |
For the first block in the list of requested block hashes, the server must omit receipts |
Since receipts are unique (due to cumulativeGasUsed
) this is technically not a problem, but it would make implementations more complex if we have to deal with the case that the server is sending us receipts which we already have (and thus did not request) 🤔 This also helps to find the position (key) where the receipts should enter the trie, otherwise we have to take all receipts which we have gotten, then sort them by cumulativeGasUsed
and then insert them in the trie to calculate the root.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since receipts are unique (due to
cumulativeGasUsed
) this is technically not a problem, but it would make implementations more complex if we have to deal with the case that the server is sending us receipts which we already have (and thus did not request) 🤔 This also helps to find the position (key) where the receipts should enter the trie, otherwise we have to take all receipts which we have gotten, then sort them bycumulativeGasUsed
and then insert them in the trie to calculate the root.
One thing to note while changing the "should" to "must", it needs to be in capital letters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed the language to make it more clear.
EIPS/eip-XXXX.md
Outdated
|
||
- (eth/69): `[request-id: P, [[receipt₁, receipt₂], ...]]` | ||
|
||
- (eth/70): `[request-id: P, lastBlockIncomplete: {0,1}, [[receipt₁, receipt₂], ...]]` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to spec behavior if the flag is set incorrectly? If it sends all receipts but marks it as "partial" I think we are still fine (?) and do not have to disconnect. But this would then send a request which would thus yield 0 receipts for the first block... 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to document this case in the EIP. Either way I think it's OK to define it more thoroughly in the spec later. For the EIP, it is more important to document the basic idea of the change.
EIPS/eip-XXXX.md
Outdated
|
||
- (eth/69): `[request-id: P, [blockhash₁: B_32, blockhash₂: B_32, ...]]` | ||
|
||
- (eth/70): `[request-id: P, firstBlockReceiptIndex: P, [blockhash₁: B_32, blockhash₂: B_32, ...]]` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we spec behavior if a peer requests firstBlockReceiptIndex
which would yield 0 receipts as response (given that the receiptRoot is not the empty list root)? I can't think of a way how this could be malicious (except wasting resources on the receiver).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use RFC 2119 uppercase keywords where appropriate: MUST, SHOULD, etc.
EIPS/eip-XXXX.md
Outdated
|
||
- (eth/70): `[request-id: P, firstBlockReceiptIndex: P, [blockhash₁: B_32, blockhash₂: B_32, ...]]` | ||
|
||
For the first block in the list of requested block hashes, the server should omit receipts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since receipts are unique (due to
cumulativeGasUsed
) this is technically not a problem, but it would make implementations more complex if we have to deal with the case that the server is sending us receipts which we already have (and thus did not request) 🤔 This also helps to find the position (key) where the receipts should enter the trie, otherwise we have to take all receipts which we have gotten, then sort them bycumulativeGasUsed
and then insert them in the trie to calculate the root.
One thing to note while changing the "should" to "must", it needs to be in capital letters
Co-authored-by: Jochem Brouwer <jochembrouwer96@gmail.com>
EIPS/eip-XXXX.md
Outdated
@@ -0,0 +1,91 @@ | |||
--- | |||
eip: XXX |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
7975
The commit 3f9b7d4 (as a parent of 61c13e8) contains errors. |
@fjl let know when the issues flagged by bots are resolved and EIP is draft ready |
@g11tech it should be good now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All Reviewers Have Approved; Performing Automatic Merge...
No description provided.