Repository navigation
Phase3 trusted block root #9917
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
base: unstable
Are you sure you want to change the base?
Changes from 12 commits
bf8af5d
59ae21a
a6c6b28
414eaf7
e349980
c9f2b29
c244567
cd37d05
2051be6
a2dac20
91d369b
171d024
79dc568
d7aa59d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -452,6 +452,21 @@ where | |
| })? | ||
| .ok_or("Finalized block missing from remote, it returned 404")?; | ||
| let block_root = block.canonical_root(); | ||
| // If --wss-checkpoint was provided, verify the downloaded block root matches it | ||
| // before initializing the chain from the checkpoint state. | ||
| if let Some(wss_checkpoint) = config.chain.weak_subjectivity_checkpoint { | ||
| if block_root != wss_checkpoint.root { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, given that --wss-checkpoint was already used before, is this compatible with its earlier use? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, in PR description --checkpoint-sync-url is mentioned, is that still applicable?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No Im still using --wss-checkpoint as the source of the root, that part’s unchanged. The gap is in how I compare it: so my check does flat equality against the freshest downloaded block, so it would reject a checkpoint that’s slightly older than the tip, something the existing verify_weak_subjectivity_checkpoint already tolerates by walking backward through block roots when the checkpoint’s epoch is older than the current finalized one. I’ll rework the comparison to match that existing backward-walk behavior instead of a flat equality check. |
||
| return Err(format!( | ||
| "Checkpoint sync block root mismatch. Expected (from --wss-checkpoint): {:?}, \ | ||
| Downloaded: {:?}. The checkpoint provider may be serving a different chain.", | ||
| wss_checkpoint.root, block_root | ||
| )); | ||
| } | ||
| info!( | ||
| block_root = ?block_root, | ||
| "Verified checkpoint block root matches --wss-checkpoint" | ||
| ); | ||
| } | ||
|
|
||
| debug!("Downloaded finalized block"); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| use serde::{Deserialize, Serialize}; | ||
| use ssz_derive::{Decode, Encode}; | ||
| use ssz_types::ProgressiveVariableList; | ||
| use tree_hash_derive::TreeHash; | ||
|
|
||
| use crate::core::Hash256; | ||
|
|
||
| /// One fetchable slice of state data, returned by `beacon_state_parts_by_range`: the chunk's | ||
| /// index, its raw bytes, and a Merkle proof (`branch`) tying it to an already-verified | ||
| /// [`super::BeaconStateSnapshot`] summary root. Different chunks can be fetched from different, | ||
| /// mutually untrusting peers and verified independently. | ||
| #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] | ||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash)] | ||
| #[serde(deny_unknown_fields)] | ||
| pub struct BeaconStatePart { | ||
| #[serde(with = "serde_utils::quoted_u64")] | ||
| pub chunk_index: u64, | ||
| pub data: ProgressiveVariableList<u8>, | ||
| pub branch: ProgressiveVariableList<Hash256>, | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| ssz_and_tree_hash_tests!(BeaconStatePart); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| use serde::{Deserialize, Serialize}; | ||
| use ssz_derive::{Decode, Encode}; | ||
| use ssz_types::ProgressiveVariableList; | ||
| use tree_hash_derive::TreeHash; | ||
|
|
||
| use crate::{beacon_state_summary::BeaconStateSummary, core::EthSpec, core::Hash256}; | ||
|
|
||
| /// Response to a `beacon_state_summary` request: a [`BeaconStateSummary`] plus a Merkle proof | ||
| /// (`state_branch`) tying its root to the already-trusted block root the requester started from. | ||
| #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] | ||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash)] | ||
| #[serde(bound = "E: EthSpec", deny_unknown_fields)] | ||
| #[cfg_attr(feature = "arbitrary", arbitrary(bound = "E: EthSpec"))] | ||
| pub struct BeaconStateSnapshot<E: EthSpec> { | ||
| pub summary: BeaconStateSummary<E>, | ||
| pub state_branch: ProgressiveVariableList<Hash256>, | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
| use crate::MinimalEthSpec; | ||
|
|
||
| ssz_and_tree_hash_tests!(BeaconStateSnapshot<MinimalEthSpec>); | ||
| } |
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.
The checkpoint state also has to be validated. i.e., have to verify that the block header's state_root matches the state's root, and that both of them are referring to the same slot / block.
Given that you only add new logic here, I wonder if this is a problem related to the PR, or already there before.
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.
Yeah thats checked, this predates the PR. The state and block are fetched independently a few lines above with no cross-check between them already there. My change only adds the root-vs---wss-checkpoint comparison after that, I didn’t touch the fetch logic itself. It's definitely worth fixing, but it’s a separate, existing gap, not something I introduced. Happy to pick it up as a follow-up, or fold it into this PR if you’d rather bundle it.