Warp sync part II (#9284)

* Gap sync

* Gap epoch test

* Simplified network requests

* Update client/db/src/utils.rs

Co-authored-by: cheme <emericchevalier.pro@gmail.com>

* Fixed v1 migration and added some comments

* Next epoch is always regular

* Removed fork tree change

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Added a comment and converted assert to error

Co-authored-by: cheme <emericchevalier.pro@gmail.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Arkadiy Paronyan
2021-10-07 11:31:39 +02:00
committed by GitHub
parent 9f1c3acb7d
commit e6ff531d0b
29 changed files with 800 additions and 169 deletions
@@ -31,7 +31,7 @@ use sp_runtime::{
traits::{Block as BlockT, Header as HeaderT, NumberFor, One},
};
use std::sync::Arc;
use std::{collections::HashMap, sync::Arc};
/// Warp proof processing error.
#[derive(Debug, derive_more::Display, derive_more::From)]
@@ -194,6 +194,7 @@ impl<Block: BlockT> WarpSyncProof<Block> {
&self,
set_id: SetId,
authorities: AuthorityList,
hard_forks: &HashMap<(Block::Hash, NumberFor<Block>), (SetId, AuthorityList)>,
) -> Result<(SetId, AuthorityList), Error>
where
NumberFor<Block>: BlockNumberOps,
@@ -202,26 +203,34 @@ impl<Block: BlockT> WarpSyncProof<Block> {
let mut current_authorities = authorities;
for (fragment_num, proof) in self.proofs.iter().enumerate() {
proof
.justification
.verify(current_set_id, &current_authorities)
.map_err(|err| Error::InvalidProof(err.to_string()))?;
let hash = proof.header.hash();
let number = *proof.header.number();
if proof.justification.target().1 != proof.header.hash() {
return Err(Error::InvalidProof(
"Mismatch between header and justification".to_owned(),
))
}
if let Some((set_id, list)) = hard_forks.get(&(hash.clone(), number)) {
current_set_id = *set_id;
current_authorities = list.clone();
} else {
proof
.justification
.verify(current_set_id, &current_authorities)
.map_err(|err| Error::InvalidProof(err.to_string()))?;
if let Some(scheduled_change) = find_scheduled_change::<Block>(&proof.header) {
current_authorities = scheduled_change.next_authorities;
current_set_id += 1;
} else if fragment_num != self.proofs.len() - 1 || !self.is_finished {
// Only the last fragment of the last proof message is allowed to be missing
// the authority set change.
return Err(Error::InvalidProof(
"Header is missing authority set change digest".to_string(),
))
if proof.justification.target().1 != hash {
return Err(Error::InvalidProof(
"Mismatch between header and justification".to_owned(),
))
}
if let Some(scheduled_change) = find_scheduled_change::<Block>(&proof.header) {
current_authorities = scheduled_change.next_authorities;
current_set_id += 1;
} else if fragment_num != self.proofs.len() - 1 || !self.is_finished {
// Only the last fragment of the last proof message is allowed to be missing the
// authority set change.
return Err(Error::InvalidProof(
"Header is missing authority set change digest".to_string(),
))
}
}
}
Ok((current_set_id, current_authorities))
@@ -235,6 +244,7 @@ where
{
backend: Arc<Backend>,
authority_set: SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
hard_forks: HashMap<(Block::Hash, NumberFor<Block>), (SetId, AuthorityList)>,
}
impl<Block: BlockT, Backend: ClientBackend<Block>> NetworkProvider<Block, Backend>
@@ -245,8 +255,13 @@ where
pub fn new(
backend: Arc<Backend>,
authority_set: SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
hard_forks: Vec<(SetId, (Block::Hash, NumberFor<Block>), AuthorityList)>,
) -> Self {
NetworkProvider { backend, authority_set }
NetworkProvider {
backend,
authority_set,
hard_forks: hard_forks.into_iter().map(|(s, hn, list)| (hn, (s, list))).collect(),
}
}
}
@@ -283,7 +298,7 @@ where
.map(|p| p.header.clone())
.ok_or_else(|| "Empty proof".to_string())?;
let (next_set_id, next_authorities) =
proof.verify(set_id, authorities).map_err(Box::new)?;
proof.verify(set_id, authorities, &self.hard_forks).map_err(Box::new)?;
if proof.is_finished {
Ok(VerificationResult::<Block>::Complete(next_set_id, next_authorities, last_header))
} else {
@@ -417,7 +432,8 @@ mod tests {
WarpSyncProof::generate(&*backend, genesis_hash, &authority_set_changes).unwrap();
// verifying the proof should yield the last set id and authorities
let (new_set_id, new_authorities) = warp_sync_proof.verify(0, genesis_authorities).unwrap();
let (new_set_id, new_authorities) =
warp_sync_proof.verify(0, genesis_authorities, &Default::default()).unwrap();
let expected_authorities = current_authorities
.iter()