Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions prdoc/pr_10223.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
title: Removed dependency to `sp-consensus-grandpa` from `sc-network-sync`
doc:
- audience: Node Dev
description: |-
Refactored warp sync to remove the dependency on GRANDPA consensus primitives from the network sync module.
Instead of directly verifying proofs with GRANDPA-specific parameters, warp sync now uses a more generic
verifier pattern. This makes the warp sync implementation independent of any specific consensus mechanism,
allowing it to work with different consensus algorithms in the future.

crates:
- name: sc-consensus-grandpa
bump: major
- name: sc-network-sync
bump: major
104 changes: 69 additions & 35 deletions substrate/client/consensus/grandpa/src/warp_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ use crate::{
BlockNumberOps, GrandpaJustification, SharedAuthoritySet,
};
use sc_client_api::Backend as ClientBackend;
use sc_network_sync::strategy::warp::{EncodedProof, VerificationResult, WarpSyncProvider};
use sc_network_sync::strategy::warp::{
EncodedProof, VerificationResult, Verifier, WarpSyncProvider,
};
use sp_blockchain::{Backend as BlockchainBackend, HeaderBackend};
use sp_consensus_grandpa::{AuthorityList, SetId, GRANDPA_ENGINE_ID};
use sp_runtime::{
Expand Down Expand Up @@ -278,29 +280,26 @@ where
}
}

impl<Block: BlockT, Backend: ClientBackend<Block>> WarpSyncProvider<Block>
for NetworkProvider<Block, Backend>
/// Verifier state for GRANDPA warp sync.
struct VerifierState<Block: BlockT> {
set_id: SetId,
authorities: AuthorityList,
next_proof_context: Block::Hash,
}

/// Verifier implementation for GRANDPA warp sync.
struct GrandpaVerifier<Block: BlockT> {
state: VerifierState<Block>,
hard_forks: HashMap<(Block::Hash, NumberFor<Block>), (SetId, AuthorityList)>,
}

impl<Block: BlockT> Verifier<Block> for GrandpaVerifier<Block>
where
NumberFor<Block>: BlockNumberOps,
{
fn generate(
&self,
start: Block::Hash,
) -> Result<EncodedProof, Box<dyn std::error::Error + Send + Sync>> {
let proof = WarpSyncProof::<Block>::generate(
&*self.backend,
start,
&self.authority_set.authority_set_changes(),
)
.map_err(Box::new)?;
Ok(EncodedProof(proof.encode()))
}

fn verify(
&self,
&mut self,
proof: &EncodedProof,
set_id: SetId,
authorities: AuthorityList,
) -> Result<VerificationResult<Block>, Box<dyn std::error::Error + Send + Sync>> {
let EncodedProof(proof) = proof;
let proof = WarpSyncProof::<Block>::decode_all(&mut proof.as_slice())
Expand All @@ -310,8 +309,20 @@ where
.last()
.map(|p| p.header.clone())
.ok_or_else(|| "Empty proof".to_string())?;
let (next_set_id, next_authorities) =
proof.verify(set_id, authorities, &self.hard_forks).map_err(Box::new)?;

let (current_set_id, current_authorities) =
(self.state.set_id, self.state.authorities.clone());

let (next_set_id, next_authorities) = proof
.verify(current_set_id, current_authorities, &self.hard_forks)
.map_err(Box::new)?;

self.state = VerifierState {
set_id: next_set_id,
authorities: next_authorities,
next_proof_context: last_header.hash(),
};

let justifications = proof
.proofs
.into_iter()
Expand All @@ -321,25 +332,48 @@ where
(p.header, justifications)
})
.collect::<Vec<_>>();

if proof.is_finished {
Ok(VerificationResult::<Block>::Complete(
next_set_id,
next_authorities,
last_header,
justifications,
))
Ok(VerificationResult::Complete(last_header, justifications))
} else {
Ok(VerificationResult::<Block>::Partial(
next_set_id,
next_authorities,
last_header.hash(),
justifications,
))
Ok(VerificationResult::Partial(justifications))
}
}

fn current_authorities(&self) -> AuthorityList {
self.authority_set.inner().current_authorities.clone()
fn next_proof_context(&self) -> Block::Hash {
self.state.next_proof_context
}
}

impl<Block: BlockT, Backend: ClientBackend<Block>> WarpSyncProvider<Block>
for NetworkProvider<Block, Backend>
where
NumberFor<Block>: BlockNumberOps,
{
fn generate(
&self,
start: Block::Hash,
) -> Result<EncodedProof, Box<dyn std::error::Error + Send + Sync>> {
let proof = WarpSyncProof::<Block>::generate(
&*self.backend,
start,
&self.authority_set.authority_set_changes(),
)
.map_err(Box::new)?;
Ok(EncodedProof(proof.encode()))
}

fn create_verifier(&self) -> Box<dyn Verifier<Block>> {
let authority_set = self.authority_set.inner();
let genesis_hash = self.backend.blockchain().info().genesis_hash;
Box::new(GrandpaVerifier {
state: VerifierState {
set_id: authority_set.set_id,
authorities: authority_set.current_authorities.clone(),
next_proof_context: genesis_hash,
},
hard_forks: self.hard_forks.clone(),
})
}
}

Expand Down
1 change: 0 additions & 1 deletion substrate/client/network/sync/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ smallvec = { workspace = true, default-features = true }
sp-arithmetic = { workspace = true, default-features = true }
sp-blockchain = { workspace = true, default-features = true }
sp-consensus = { workspace = true, default-features = true }
sp-consensus-grandpa = { workspace = true, default-features = true }
sp-core = { workspace = true, default-features = true }
sp-runtime = { workspace = true, default-features = true }
thiserror = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions substrate/client/network/sync/src/strategy/polkadot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub struct PolkadotSyncingStrategy<B: BlockT, Client> {
/// Client used by syncing strategies.
client: Arc<Client>,
/// Warp strategy.
warp: Option<WarpSync<B, Client>>,
warp: Option<WarpSync<B>>,
/// State strategy.
state: Option<StateStrategy<B>>,
/// `ChainSync` strategy.`
Expand Down Expand Up @@ -207,7 +207,7 @@ where
);
debug_assert!(false);
},
WarpSync::<B, Client>::STRATEGY_KEY =>
WarpSync::<B>::STRATEGY_KEY =>
if let Some(warp) = &mut self.warp {
warp.on_generic_response(peer_id, protocol_name, response);
} else {
Expand Down
Loading
Loading