-
Notifications
You must be signed in to change notification settings - Fork 973
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
Clarification on get_pow_block
#2636
Comments
EDIT: I disagree with myself based on discord discussion
|
Some relevant discussion on discord We need to specify what the consensus and execution layer do when the consensus re-orgs from a transitioned chain to an non-transitioned chain. @paulhauner suggests sending In a 1:1 consensus to execution relationship, I do think that this clears up the ambiguity in the spec around item (3). That is, you would never be trying to build an initial execution payload on an execution-layer that thought PoS blocks were in the canonical chain. That said, this does not support many:1 consesnsu to execution, but our general set fork choice construction in the API and specs already does not support this. |
This is likely tangential, but we'll need to consider mechanisms on the APIs to lock to 1:1 if that's how we're going to specify. |
Trying to understand whether handling this edge case worth an additional trigger in the execution-layer fork choice. Suppose, there is a beacon block For simplicity, let's assume that a halve of nodes has observed Under the assumption that In an exceptional case we could have several non-transition blocks built on top of Considering the above (I hope my analysis does make sense) the options are as follows:
I agree to rename |
What do you mean the "mechanisms"? Could we explicitly say that Engine API spec we have is designed to handle 1:1 case and not every part of it might work in many-to-one relationship? A rough idea of handling many-to-one use case is outlined in the Shared execution client section of the Engine API design space doc. The exercise was to consider this use case in the API design and if possible avoid decisions in the design that could restrict the many-to-one use case and it seems that the fork choice state concurrently updated by multiple consensus clients is a problem. I haven't thought much of it but I'd prefer implementations decide on how to handle the many-to-one use case as long as the API allows for it. I'd be happy to discuss many-to-one use case in a separate thread. |
Off the main issue of this PR, should we clarify the error handling of this function? i.e., if block with given Option 1.
Option 2.
|
Actually, with this change #2595 |
Actually, I am not quite right on the above and there is a normal case which |
A nitpicking question around In def get_pow_block_at_terminal_total_difficulty(pow_chain: Sequence[PowBlock]) -> Optional[PowBlock]:
# `pow_chain` abstractly represents all blocks in the PoW chain
for block in pow_chain:
parent = get_pow_block(block.parent_hash)
... If the validator already maintains all blocks, do they really have to call Can we just query in the given query = [pow_block for pow_block in pow_chain if pow_block.block_hash == block.parent_hash]
parent = query[0] if query else None It seems we touched the line between pseudo-code and reality. Reusing |
I see what you mean. Re-using |
@mkalinin Another option is creating another abstract helper |
I think client implementations override |
addressed in #2694 |
Reopen it because I think the original problem of this issue hasn't been solved yet? @mkalinin's comment: #2636 (comment) |
Thanks @hwwhww! Getting back to the original problem. In the event when a valid transition block isn't accepted by the network, do we want a subsequent proposer to pick a transition PoW block according to the total difficulty rule. Or are we OK that the proposer will pick the same transition PoW block as the previous proposer picked if it has imported the previous transition block by a chance and switched its fork choice rule to the PoS? |
Closing this issue without any follow-ups to the spec. Switching fork choice rule back and force doesn't seem to be valuable enough to take the implementation and design complexity it introduces. The only real case that is affected by not doing the switch back to TD rule seems to be the case when the valid transition block isn't accepted by the network and the validator that has accepted this block is proposing yet another transition block. The choice of a terminal block in this pretty rare case will happen according to the new fork choice rule rather than to the TD rule which doesn't seem vulnerable to any kind of attack as long as a terminal block satisfies the corresponding conditions. The latter must always be true, otherwise, the previous transition block must have not been accepted by the node. |
## Issue Addressed NA ## Proposed Changes Removes three types of TODOs: 1. `execution_layer/src/lib.rs`: It was [determined](ethereum/consensus-specs#2636 (comment)) that there is no action required here. 2. `beacon_processor/worker/gossip_methods.rs`: Removed TODOs relating to peer scoring that have already been addressed via `epe.penalize_peer()`. - It seems `cargo fmt` wanted to adjust some things here as well 🤷 3. `proto_array_fork_choice.rs`: it would be nice to remove that useless `bool` for cleanliness, but I don't think it's something we need to do and the TODO just makes things look messier IMO. ## Additional Info There should be no functional changes to the code in this PR. There are still some TODOs lingering, those ones require actual changes or more thought.
The spec defines a
get_pow_block
function which returns aPoWBlock
structure. In practice, I expectget_pow_block
to map to theeth_getBlockByHash
JSON-RPC call.Assuming we use
eth_getBlockByHash
, doesget_pow_block
filter the result so that it only contains pre-merge, non-PoS blocks?From the naming, I think it should apply the filter.
However, if we look at
get_block_at_terminal_total_difficulty
, we can see it iterates through the entirepow_chain
. This communicates that there might be multiple blocks inpow_chain
whereblock.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
. This conflicts with EIP-3675 which states:I raise this for the following reasons:
get_block_at_terminal_total_difficulty
can perform. When doing recursive look-ups to a remote server it's desirable to clearly understand the properties of that recursion.get_pow_block
to avoid differences in implementation.get_pow_block
also returns PoS blocks, then it seems like it needs a different name.On a side note, if
get_pow_block
should filter the results, how does it do that? I assume there's some simple way, but I haven't seen it in the API docs I've been looking at.The text was updated successfully, but these errors were encountered: