-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Fast sync #8884
Fast sync #8884
Changes from all commits
c7d1ad8
224ec1f
eeda74e
1722f9b
c3e378c
e755467
e610196
783e794
b02b515
d22f27e
4895459
4d4a05a
753d412
22462f3
0e99e07
dff08a4
c6a263a
2eb647b
5f97da2
fb4926f
c287be3
e8df4ac
bad1124
730d619
7a8e682
4d665f3
4b34885
bf21352
2f07284
5a99ef1
13a68e4
08079f4
fb882d4
21c8c35
6e5b91c
47583d9
7ff27dd
fe1d210
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 |
|---|---|---|
|
|
@@ -347,6 +347,11 @@ impl<Block: BlockT> HeaderBackend<Block> for Blockchain<Block> { | |
| genesis_hash: storage.genesis_hash, | ||
| finalized_hash: storage.finalized_hash, | ||
| finalized_number: storage.finalized_number, | ||
| finalized_state: if storage.finalized_hash != Default::default() { | ||
|
cheme marked this conversation as resolved.
|
||
| Some((storage.finalized_hash.clone(), storage.finalized_number)) | ||
| } else { | ||
| None | ||
| }, | ||
| number_leaves: storage.leaves.count() | ||
| } | ||
| } | ||
|
|
@@ -528,6 +533,32 @@ pub struct BlockImportOperation<Block: BlockT> { | |
| set_head: Option<BlockId<Block>>, | ||
| } | ||
|
|
||
| impl<Block: BlockT> BlockImportOperation<Block> where | ||
| Block::Hash: Ord, | ||
| { | ||
| fn apply_storage(&mut self, storage: Storage, commit: bool) -> sp_blockchain::Result<Block::Hash> { | ||
| check_genesis_storage(&storage)?; | ||
|
|
||
| let child_delta = storage.children_default.iter() | ||
| .map(|(_storage_key, child_content)| | ||
| ( | ||
| &child_content.child_info, | ||
| child_content.data.iter().map(|(k, v)| (k.as_ref(), Some(v.as_ref()))) | ||
| ) | ||
| ); | ||
|
|
||
| let (root, transaction) = self.old_state.full_storage_root( | ||
| storage.top.iter().map(|(k, v)| (k.as_ref(), Some(v.as_ref()))), | ||
| child_delta, | ||
| ); | ||
|
|
||
| if commit { | ||
| self.new_state = Some(transaction); | ||
| } | ||
| Ok(root) | ||
| } | ||
| } | ||
|
|
||
| impl<Block: BlockT> backend::BlockImportOperation<Block> for BlockImportOperation<Block> where | ||
| Block::Hash: Ord, | ||
| { | ||
|
|
@@ -569,24 +600,12 @@ impl<Block: BlockT> backend::BlockImportOperation<Block> for BlockImportOperatio | |
| Ok(()) | ||
| } | ||
|
|
||
| fn reset_storage(&mut self, storage: Storage) -> sp_blockchain::Result<Block::Hash> { | ||
| check_genesis_storage(&storage)?; | ||
|
|
||
| let child_delta = storage.children_default.iter() | ||
| .map(|(_storage_key, child_content)| | ||
| ( | ||
| &child_content.child_info, | ||
| child_content.data.iter().map(|(k, v)| (k.as_ref(), Some(v.as_ref()))) | ||
| ) | ||
| ); | ||
|
|
||
| let (root, transaction) = self.old_state.full_storage_root( | ||
| storage.top.iter().map(|(k, v)| (k.as_ref(), Some(v.as_ref()))), | ||
| child_delta, | ||
| ); | ||
| fn set_genesis_state(&mut self, storage: Storage, commit: bool) -> sp_blockchain::Result<Block::Hash> { | ||
| self.apply_storage(storage, commit) | ||
| } | ||
|
|
||
| self.new_state = Some(transaction); | ||
| Ok(root) | ||
| fn reset_storage(&mut self, storage: Storage) -> sp_blockchain::Result<Block::Hash> { | ||
| self.apply_storage(storage, true) | ||
| } | ||
|
Comment on lines
+607
to
609
Member
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. Did we ever used this for something different than setting the genesis state? Why do we now need 2 methods doing almost the same?
Member
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.
One is used for setting genesis, another for resetting state in fast sync mode. There's a difference in behaviour and purpose here, so I've introduced a separate method to make it more explicit. |
||
|
|
||
| fn insert_aux<I>(&mut self, ops: I) -> sp_blockchain::Result<()> | ||
|
|
@@ -806,12 +825,12 @@ impl<Block: BlockT> backend::RemoteBackend<Block> for Backend<Block> where Block | |
| /// Check that genesis storage is valid. | ||
| pub fn check_genesis_storage(storage: &Storage) -> sp_blockchain::Result<()> { | ||
| if storage.top.iter().any(|(k, _)| well_known_keys::is_child_storage_key(k)) { | ||
| return Err(sp_blockchain::Error::GenesisInvalid.into()); | ||
| return Err(sp_blockchain::Error::InvalidState.into()); | ||
| } | ||
|
|
||
| if storage.children_default.keys() | ||
| .any(|child_key| !well_known_keys::is_child_storage_key(&child_key)) { | ||
| return Err(sp_blockchain::Error::GenesisInvalid.into()); | ||
| return Err(sp_blockchain::Error::InvalidState.into()); | ||
| } | ||
|
|
||
| Ok(()) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,4 +70,31 @@ pub trait ProofProvider<Block: BlockT> { | |
| storage_key: Option<&PrefixedStorageKey>, | ||
| key: &StorageKey, | ||
| ) -> sp_blockchain::Result<ChangesProof<Block::Header>>; | ||
|
|
||
|
cheme marked this conversation as resolved.
|
||
| /// Given a `BlockId` iterate over all storage values starting at `start_key` exclusively, | ||
| /// building proofs until size limit is reached. Returns combined proof and the number of collected keys. | ||
| fn read_proof_collection( | ||
| &self, | ||
| id: &BlockId<Block>, | ||
| start_key: &[u8], | ||
| size_limit: usize, | ||
| ) -> sp_blockchain::Result<(StorageProof, u32)>; | ||
|
|
||
| /// Given a `BlockId` iterate over all storage values starting at `start_key`. | ||
|
Member
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. Do we now start with
Member
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. First after. I'll update the comment. |
||
| /// Returns collected keys and values. | ||
| fn storage_collection( | ||
| &self, | ||
| id: &BlockId<Block>, | ||
| start_key: &[u8], | ||
| size_limit: usize, | ||
| ) -> sp_blockchain::Result<Vec<(Vec<u8>, Vec<u8>)>>; | ||
|
|
||
| /// Verify read storage proof for a set of keys. | ||
| /// Returns collected key-value pairs and a flag indicating if iteration is complete. | ||
| fn verify_range_proof( | ||
| &self, | ||
| root: Block::Hash, | ||
| proof: StorageProof, | ||
| start_key: &[u8], | ||
|
Contributor
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. On #8237 I verify with the
Member
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.
Could you explain this a bit? I'd consider the reply to be good as long as it iterates over at least a single value. The network protocol does not impose that the size limit needs to be upheld exactly. The server is free to send any number of values in the proof up to the limit.
Contributor
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. For instance if you run a reputation system, you can see if the peer replies fully to your request. |
||
| ) -> sp_blockchain::Result<(Vec<(Vec<u8>, Vec<u8>)>, bool)>; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -232,6 +232,30 @@ arg_enum! { | |
| } | ||
| } | ||
|
|
||
| arg_enum! { | ||
| /// Syncing mode. | ||
| #[allow(missing_docs)] | ||
| #[derive(Debug, Clone, Copy)] | ||
| pub enum SyncMode { | ||
| // Full sync. Donwnload end verify all blocks. | ||
| Full, | ||
| // Download blocks without executing them. Download latest state with proofs. | ||
| Fast, | ||
| // Download blocks without executing them. Download latest state without proofs. | ||
| FastUnsafe, | ||
|
cheme marked this conversation as resolved.
Member
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. While it doesn't support doc comments, you can just add some code comment explaining what this does. |
||
| } | ||
| } | ||
|
|
||
| impl Into<sc_network::config::SyncMode> for SyncMode { | ||
| fn into(self) -> sc_network::config::SyncMode { | ||
| match self { | ||
| SyncMode::Full => sc_network::config::SyncMode::Full, | ||
| SyncMode::Fast => sc_network::config::SyncMode::Fast { skip_proofs: false }, | ||
| SyncMode::FastUnsafe => sc_network::config::SyncMode::Fast { skip_proofs: true }, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Default value for the `--execution-syncing` parameter. | ||
| pub const DEFAULT_EXECUTION_SYNCING: ExecutionStrategy = ExecutionStrategy::NativeElseWasm; | ||
| /// Default value for the `--execution-import-block` parameter. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ | |
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
|
|
||
| use crate::params::node_key_params::NodeKeyParams; | ||
| use crate::arg_enums::SyncMode; | ||
| use sc_network::{ | ||
| config::{NetworkConfiguration, NodeKeyConfig, NonReservedPeerMode, SetConfig, TransportConfig}, | ||
| multiaddr::Protocol, | ||
|
|
@@ -125,6 +126,13 @@ pub struct NetworkParams { | |
| /// Join the IPFS network and serve transactions over bitswap protocol. | ||
| #[structopt(long)] | ||
| pub ipfs_server: bool, | ||
|
|
||
| /// Blockchain syncing mode. | ||
|
Member
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. Or add some docs here about the variants. So, that the user can understand them |
||
| /// Full - Download and validate full blockchain history (Default). | ||
| /// Fast - Download blocks and the latest state only. | ||
| /// FastUnsafe - Same as Fast, but do skips downloading state proofs. | ||
| #[structopt(long, default_value = "Full")] | ||
| pub sync: SyncMode, | ||
| } | ||
|
|
||
| impl NetworkParams { | ||
|
|
@@ -218,6 +226,7 @@ impl NetworkParams { | |
| kademlia_disjoint_query_paths: self.kademlia_disjoint_query_paths, | ||
| yamux_window_size: None, | ||
| ipfs_server: self.ipfs_server, | ||
| sync_mode: self.sync.into(), | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.