Re-enable optimistic sync for Gloas payload envelopes - #9934
Conversation
105919b to
142e3f1
Compare
|
Yes we can force a resync for all Gloas nodes |
142e3f1 to
9bc89e2
Compare
9bc89e2 to
8d1aa2a
Compare
|
I think we can easily force resync devnet nodes. Not an issue. Halfway through the review. Will complete tomorrow |
| // The payload is revealed later, in an envelope. | ||
| execution_status: ExecutionStatus::Irrelevant(false), |
There was a problem hiding this comment.
Almost need another variant (like NotYetRevealed or Pending) for the Gloas case?
There was a problem hiding this comment.
Added NotYetRevealed
| // Execution status tracking only exists on V17 (pre-Gloas) nodes. | ||
| if let Ok(v17) = parent.as_v17() | ||
| && v17.execution_status.is_invalid() | ||
| { | ||
| return Err(Error::ParentExecutionStatusIsInvalid { | ||
| block_root: block.root, | ||
| parent_root: parent.root(), | ||
| }); | ||
| } |
There was a problem hiding this comment.
Out of date. Probably need to handle parent payload status here to know if the parent's invalidity affects this new block (if we build on the empty variant of a parent whose payload is invalid, that's ok).
-> Good test case.
| // If the node has an invalid execution payload, reduce its weight to zero. | ||
| 0_i64 | ||
| .checked_sub(node.weight() as i64) | ||
| .ok_or(Error::InvalidExecutionDeltaOverflow(node_index))? |
There was a problem hiding this comment.
I think we need to not do this for Gloas. I think we should just do it for the full weight?
| // Invalid nodes always have a weight of 0. | ||
| *node.weight_mut() = 0; |
There was a problem hiding this comment.
I think we need to tweak this for Gloas too.
| && matches!(block.execution_status, ExecutionStatus::Valid(_)) | ||
| { | ||
| self.propagate_execution_payload_validation_by_index(parent_index)?; | ||
| let parent_status = node.parent_payload_status().unwrap_or(PayloadStatus::Full); |
There was a problem hiding this comment.
Conflicting convention with get_parent_payload_status:
Maybe we should be consistent and treat pre-Gloas blocks as Empty? Or add a new enum with a pre-Gloas status to this codepath.
There was a problem hiding this comment.
Added ParentPayloadStatus and removed all defaults
| PayloadStatus::Empty | PayloadStatus::Pending => self | ||
| .proto_array | ||
| .empty_node_execution_status(*block_root) | ||
| .ok(), |
There was a problem hiding this comment.
Nit: probably shouldn't swallow this error (we don't expect this to error, I imagine?)
| } | ||
| Ok(ExecutionStatus::Irrelevant(_)) => break, | ||
| Err(_) => break, | ||
| ExecutionStatus::Irrelevant(_) => break, |
There was a problem hiding this comment.
Once we add the new status, can probably return an error for that variant (we should not be able to invalidate a head block with an unrevealed payload, and the block should not have any Full ancestors with unrevealed payloads)
| } | ||
|
|
||
| if let Some(parent_index) = node.parent() { | ||
| status = node.parent_payload_status().unwrap_or(PayloadStatus::Full); |
There was a problem hiding this comment.
To exercise this path, need a test case for the first payload after the Gloas fork being invalid
There was a problem hiding this comment.
Could simplify this loop using ProtoArray::children field
| // A Gloas descendant becomes invalid only when it built on the payload of the | ||
| // ancestor. A descendant that took the `EMPTY` edge stays viable. | ||
| if let ProtoNode::V29(gloas_node) = node | ||
| && gloas_node.parent_payload_status != PayloadStatus::Full | ||
| { | ||
| continue; | ||
| } |
There was a problem hiding this comment.
It's incorrect to continue here. A block (node) with parent_payload_status Empty could descend from some other Full block which is invalid because it descends from the latest valid hash.
| // In Gloas this means only that the payload is not revealed yet. The block did | ||
| // commit to the invalid ancestry. Pre-Gloas this state is a contradiction. | ||
| match node { | ||
| ProtoNode::V29(gloas_node) => { | ||
| gloas_node.execution_status = ExecutionStatus::Invalid( | ||
| gloas_node.execution_payload_block_hash, | ||
| ); | ||
| } |
There was a problem hiding this comment.
Looks like a good use for the separate variant
There was a problem hiding this comment.
Added NotYetRevealed
700056b to
8d1aa2a
Compare
| proto_block.execution_status.is_optimistic_or_invalid(); | ||
| let new_head_is_optimistic = fork_choice | ||
| .get_node_execution_status(&block_root, head_payload_status) | ||
| .is_some_and(|status| status.is_optimistic_or_invalid()); |
There was a problem hiding this comment.
Needs to walk backwards to find the first full ancestor which is the head's payload status
| // The payload is revealed later, in an envelope. | ||
| execution_status: ExecutionStatus::Irrelevant(false), |
There was a problem hiding this comment.
Added NotYetRevealed
| && matches!(block.execution_status, ExecutionStatus::Valid(_)) | ||
| { | ||
| self.propagate_execution_payload_validation_by_index(parent_index)?; | ||
| let parent_status = node.parent_payload_status().unwrap_or(PayloadStatus::Full); |
There was a problem hiding this comment.
Added ParentPayloadStatus and removed all defaults
| // In Gloas this means only that the payload is not revealed yet. The block did | ||
| // commit to the invalid ancestry. Pre-Gloas this state is a contradiction. | ||
| match node { | ||
| ProtoNode::V29(gloas_node) => { | ||
| gloas_node.execution_status = ExecutionStatus::Invalid( | ||
| gloas_node.execution_payload_block_hash, | ||
| ); | ||
| } |
There was a problem hiding this comment.
Added NotYetRevealed
| // A Gloas descendant becomes invalid only when it built on the payload of the | ||
| // ancestor. A descendant that took the `EMPTY` edge stays viable. | ||
| if let ProtoNode::V29(gloas_node) = node | ||
| && gloas_node.parent_payload_status != PayloadStatus::Full | ||
| { | ||
| continue; | ||
| } |
Breaking change
Can we force existing Gloas nodes to resync when updating to this new version? Then we can simplify the migrations as the property
execution_statushas continuity in mainnet from Fulu to Gloas. Otherwise there's an awkward partial disappearance between v29 and v30.Issue Addressed
Re-enable optimistic sync for Gloas payload envelopes
Proposed Changes
Track the status of the payload (FULL) node in ProtoNode::execution_status