ethereum / consensus-specs

Ethereum Proof-of-Stake Consensus Specifications

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Serving blocks and blob_sidecars in RPC byRoot right after they passed gossip validation

tbenr opened this issue · comments

Assuming a node has not received via gossip a block that has been imported by the majority of the network.

Before Deneb, a node can be aware of that block's root when:

  • it sees an attestation voting for it
  • it sees the next block building on top of it

In both cases it is likely that the node can lookup the block byRoot since both events signals that the block has been imported (probably) by the majority of the network.

After Deneb, there will be a third condition:

  • it sees a valid blob_sidecar carrying the block header.

This third event happens way before the the other two, probably before most of the nodes has successfully imported the block.
And this applies to blob_sidecars too.

Thus, while pre-Deneb, serving only fully imported blocks seems good enough for client missing them, in Deneb seems not be the case anymore.

Should we let clients serve byRoot requests for blocks and blob_sidecars that have passed gossip but has not yet fully imported to allow early byRoot recovery?

I believe we are dealing with two types of blocks in this scenario:

1.) Blocks that pass gossip validation but are yet to undergo the state transition function.
2.) Blocks that have successfully passed the state transition function but have not yet been imported into the fork choice.

While these considerations apply to both types, focusing primarily on the second type might be safer. However, it's important to note that after passing through gossip validation, the block will possess a valid signature and proposer index. Consequently, a malicious node would need to either sacrifice a block or risk being slashed to successfully execute any kind of attack

@terencechain right. But to get the most benefit we should go for 1). Not sure if doing it only 2) is worth the change in terms of gained timing, and seems to me that 1) won't introduce any additional risks.
But it would be nice to hear from others.

Re: @terencechain's conditions, I have a bit mixed thoughts. Only allowing (2) seems "safe", but it might be just as safe as gossip to allow (1) and then remove if (2) fails. Essentially, if it's something that can be forwarded on gossip, then it's something that can/will get to you independent of the full validation. So if you see something (sidecar) with it as a dependency, I think it's okay to get it actively (req/resp) upon the same condition you are expecting it passively (gossip) which is the gossip conditions being validated

Agree with the above. I'm convinced 1.) is the way to go. I initially said 2.) because most clients verify consensus check in parallel with execution check, and the only difference is ~50ms for Prysm to verify state transition as soon as a block passes gossip. Which might still matter in the grand scheme of things

So if you see something (sidecar) with it as a dependency, I think it's okay to get it actively (req/resp) upon the same condition you are expecting it passively (gossip) which is the gossip conditions being validated

My point on the call was that if you observed a sidecar as a dependency and not yet received the block, it is very likely that peers that you’re connected to have not yet received a block either (otherwise, they would gossip you the block); in this case if BlockByRoot is sent shortly after receiving a sidecar would likely not help to resolve the dependency.

But in some cases when a remote peer receives a block e.g. 3.5 seconds into a slot and a local node requests it, additional time to wait for the execution of this block before serving it back can result in the node missing the attestation deadline as after receiving the block it will have to be executed as well. From this perspective run only gossip validation before serving a block makes sense to me