mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 08:47:57 +00:00
Network sync refactoring (part 1) (#11303)
* Remove unnecessary imports, move one internal re-export into where it is actually used, make one import explicit * Move a few data structures down into modules * Use generic parameters in `sc-network` instead of `chain::Client` trait * Remove unnecessary bound
This commit is contained in:
@@ -39,9 +39,10 @@ use extra_requests::ExtraRequests;
|
||||
use futures::{stream::FuturesUnordered, task::Poll, Future, FutureExt, StreamExt};
|
||||
use libp2p::PeerId;
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use sc_client_api::{BlockBackend, ProofProvider};
|
||||
use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock};
|
||||
use sp_arithmetic::traits::Saturating;
|
||||
use sp_blockchain::{Error as ClientError, HeaderMetadata};
|
||||
use sp_blockchain::{Error as ClientError, HeaderBackend, HeaderMetadata};
|
||||
use sp_consensus::{
|
||||
block_validation::{BlockAnnounceValidator, Validation},
|
||||
BlockOrigin, BlockStatus,
|
||||
@@ -54,6 +55,7 @@ use sp_runtime::{
|
||||
},
|
||||
EncodedJustification, Justifications,
|
||||
};
|
||||
pub use state::StateDownloadProgress;
|
||||
use state::StateSync;
|
||||
use std::{
|
||||
collections::{hash_map::Entry, HashMap, HashSet},
|
||||
@@ -63,6 +65,7 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
use warp::{WarpProofRequest, WarpSync, WarpSyncProvider};
|
||||
pub use warp::{WarpSyncPhase, WarpSyncProgress};
|
||||
|
||||
mod blocks;
|
||||
mod extra_requests;
|
||||
@@ -194,9 +197,9 @@ struct GapSync<B: BlockT> {
|
||||
|
||||
/// The main data structure which contains all the state for a chains
|
||||
/// active syncing strategy.
|
||||
pub struct ChainSync<B: BlockT> {
|
||||
pub struct ChainSync<B: BlockT, Client> {
|
||||
/// Chain client.
|
||||
client: Arc<dyn crate::chain::Client<B>>,
|
||||
client: Arc<Client>,
|
||||
/// The active peers that we are using to sync and their PeerSync status
|
||||
peers: HashMap<PeerId, PeerSync<B>>,
|
||||
/// A `BlockCollection` of blocks that are being downloaded from peers
|
||||
@@ -228,9 +231,9 @@ pub struct ChainSync<B: BlockT> {
|
||||
/// Stats per peer about the number of concurrent block announce validations.
|
||||
block_announce_validation_per_peer_stats: HashMap<PeerId, usize>,
|
||||
/// State sync in progress, if any.
|
||||
state_sync: Option<StateSync<B>>,
|
||||
state_sync: Option<StateSync<B, Client>>,
|
||||
/// Warp sync in progress, if any.
|
||||
warp_sync: Option<WarpSync<B>>,
|
||||
warp_sync: Option<WarpSync<B, Client>>,
|
||||
/// Warp sync provider.
|
||||
warp_sync_provider: Option<Arc<dyn WarpSyncProvider<B>>>,
|
||||
/// Enable importing existing blocks. This is used used after the state download to
|
||||
@@ -329,30 +332,6 @@ pub enum SyncState {
|
||||
Downloading,
|
||||
}
|
||||
|
||||
/// Reported state download progress.
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub struct StateDownloadProgress {
|
||||
/// Estimated download percentage.
|
||||
pub percentage: u32,
|
||||
/// Total state size in bytes downloaded so far.
|
||||
pub size: u64,
|
||||
}
|
||||
|
||||
/// Reported warp sync phase.
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub enum WarpSyncPhase<B: BlockT> {
|
||||
/// Waiting for peers to connect.
|
||||
AwaitingPeers,
|
||||
/// Downloading and verifying grandpa warp proofs.
|
||||
DownloadingWarpProofs,
|
||||
/// Downloading state data.
|
||||
DownloadingState,
|
||||
/// Importing state.
|
||||
ImportingState,
|
||||
/// Downloading block history.
|
||||
DownloadingBlocks(NumberFor<B>),
|
||||
}
|
||||
|
||||
impl<B: BlockT> fmt::Display for WarpSyncPhase<B> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
@@ -365,15 +344,6 @@ impl<B: BlockT> fmt::Display for WarpSyncPhase<B> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Reported warp sync progress.
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub struct WarpSyncProgress<B: BlockT> {
|
||||
/// Estimated download percentage.
|
||||
pub phase: WarpSyncPhase<B>,
|
||||
/// Total bytes downloaded so far.
|
||||
pub total_bytes: u64,
|
||||
}
|
||||
|
||||
/// Syncing status and statistics.
|
||||
#[derive(Clone)]
|
||||
pub struct Status<B: BlockT> {
|
||||
@@ -534,11 +504,21 @@ enum HasSlotForBlockAnnounceValidation {
|
||||
MaximumPeerSlotsReached,
|
||||
}
|
||||
|
||||
impl<B: BlockT> ChainSync<B> {
|
||||
impl<B, Client> ChainSync<B, Client>
|
||||
where
|
||||
B: BlockT,
|
||||
Client: HeaderBackend<B>
|
||||
+ BlockBackend<B>
|
||||
+ HeaderMetadata<B, Error = sp_blockchain::Error>
|
||||
+ ProofProvider<B>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
{
|
||||
/// Create a new instance.
|
||||
pub fn new(
|
||||
mode: SyncMode,
|
||||
client: Arc<dyn crate::chain::Client<B>>,
|
||||
client: Arc<Client>,
|
||||
block_announce_validator: Box<dyn BlockAnnounceValidator<B> + Send>,
|
||||
max_parallel_downloads: u32,
|
||||
warp_sync_provider: Option<Arc<dyn WarpSyncProvider<B>>>,
|
||||
@@ -2741,7 +2721,11 @@ mod test {
|
||||
}
|
||||
|
||||
/// Send a block annoucnement for the given `header`.
|
||||
fn send_block_announce(header: Header, peer_id: &PeerId, sync: &mut ChainSync<Block>) {
|
||||
fn send_block_announce(
|
||||
header: Header,
|
||||
peer_id: &PeerId,
|
||||
sync: &mut ChainSync<Block, TestClient>,
|
||||
) {
|
||||
let block_annnounce = BlockAnnounce {
|
||||
header: header.clone(),
|
||||
state: Some(BlockState::Best),
|
||||
@@ -2780,7 +2764,7 @@ mod test {
|
||||
|
||||
/// Get a block request from `sync` and check that is matches the expected request.
|
||||
fn get_block_request(
|
||||
sync: &mut ChainSync<Block>,
|
||||
sync: &mut ChainSync<Block, TestClient>,
|
||||
from: FromBlock<Hash, u64>,
|
||||
max: u32,
|
||||
peer: &PeerId,
|
||||
|
||||
@@ -16,14 +16,11 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::StateDownloadProgress;
|
||||
use crate::{
|
||||
chain::{Client, ImportedState},
|
||||
schema::v1::{StateEntry, StateRequest, StateResponse},
|
||||
};
|
||||
use crate::schema::v1::{StateEntry, StateRequest, StateResponse};
|
||||
use codec::{Decode, Encode};
|
||||
use log::debug;
|
||||
use sc_client_api::CompactProof;
|
||||
use sc_client_api::{CompactProof, ProofProvider};
|
||||
use sc_consensus::ImportedState;
|
||||
use smallvec::SmallVec;
|
||||
use sp_core::storage::well_known_keys;
|
||||
use sp_runtime::traits::{Block as BlockT, Header, NumberFor};
|
||||
@@ -33,18 +30,27 @@ use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
/// State sync state machine. Accumulates partial state data until it
|
||||
/// is ready to be imported.
|
||||
pub struct StateSync<B: BlockT> {
|
||||
pub struct StateSync<B: BlockT, Client> {
|
||||
target_block: B::Hash,
|
||||
target_header: B::Header,
|
||||
target_root: B::Hash,
|
||||
last_key: SmallVec<[Vec<u8>; 2]>,
|
||||
state: HashMap<Vec<u8>, (Vec<(Vec<u8>, Vec<u8>)>, Vec<Vec<u8>>)>,
|
||||
complete: bool,
|
||||
client: Arc<dyn Client<B>>,
|
||||
client: Arc<Client>,
|
||||
imported_bytes: u64,
|
||||
skip_proof: bool,
|
||||
}
|
||||
|
||||
/// Reported state download progress.
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub struct StateDownloadProgress {
|
||||
/// Estimated download percentage.
|
||||
pub percentage: u32,
|
||||
/// Total state size in bytes downloaded so far.
|
||||
pub size: u64,
|
||||
}
|
||||
|
||||
/// Import state chunk result.
|
||||
pub enum ImportResult<B: BlockT> {
|
||||
/// State is complete and ready for import.
|
||||
@@ -55,9 +61,13 @@ pub enum ImportResult<B: BlockT> {
|
||||
BadResponse,
|
||||
}
|
||||
|
||||
impl<B: BlockT> StateSync<B> {
|
||||
impl<B, Client> StateSync<B, Client>
|
||||
where
|
||||
B: BlockT,
|
||||
Client: ProofProvider<B> + Send + Sync + 'static,
|
||||
{
|
||||
/// Create a new instance.
|
||||
pub fn new(client: Arc<dyn Client<B>>, target: B::Header, skip_proof: bool) -> Self {
|
||||
pub fn new(client: Arc<Client>, target: B::Header, skip_proof: bool) -> Self {
|
||||
Self {
|
||||
client,
|
||||
target_block: target.hash(),
|
||||
@@ -71,7 +81,7 @@ impl<B: BlockT> StateSync<B> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Validate and import a state reponse.
|
||||
/// Validate and import a state response.
|
||||
pub fn import(&mut self, response: StateResponse) -> ImportResult<B> {
|
||||
if response.entries.is_empty() && response.proof.is_empty() {
|
||||
debug!(target: "sync", "Bad state response");
|
||||
|
||||
@@ -17,23 +17,44 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
///! Warp sync support.
|
||||
pub use super::state::ImportResult;
|
||||
use super::state::StateSync;
|
||||
use super::state::{ImportResult, StateSync};
|
||||
use crate::schema::v1::{StateRequest, StateResponse};
|
||||
pub use crate::warp_request_handler::{
|
||||
EncodedProof, Request as WarpProofRequest, VerificationResult, WarpSyncProvider,
|
||||
};
|
||||
use crate::{
|
||||
chain::Client,
|
||||
schema::v1::{StateRequest, StateResponse},
|
||||
WarpSyncPhase, WarpSyncProgress,
|
||||
};
|
||||
use sc_client_api::ProofProvider;
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_finality_grandpa::{AuthorityList, SetId};
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor, Zero};
|
||||
use std::sync::Arc;
|
||||
|
||||
enum Phase<B: BlockT> {
|
||||
enum Phase<B: BlockT, Client> {
|
||||
WarpProof { set_id: SetId, authorities: AuthorityList, last_hash: B::Hash },
|
||||
State(StateSync<B>),
|
||||
State(StateSync<B, Client>),
|
||||
}
|
||||
|
||||
/// Reported warp sync phase.
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub enum WarpSyncPhase<B: BlockT> {
|
||||
/// Waiting for peers to connect.
|
||||
AwaitingPeers,
|
||||
/// Downloading and verifying grandpa warp proofs.
|
||||
DownloadingWarpProofs,
|
||||
/// Downloading state data.
|
||||
DownloadingState,
|
||||
/// Importing state.
|
||||
ImportingState,
|
||||
/// Downloading block history.
|
||||
DownloadingBlocks(NumberFor<B>),
|
||||
}
|
||||
|
||||
/// Reported warp sync progress.
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub struct WarpSyncProgress<B: BlockT> {
|
||||
/// Estimated download percentage.
|
||||
pub phase: WarpSyncPhase<B>,
|
||||
/// Total bytes downloaded so far.
|
||||
pub total_bytes: u64,
|
||||
}
|
||||
|
||||
/// Import warp proof result.
|
||||
@@ -45,19 +66,20 @@ pub enum WarpProofImportResult {
|
||||
}
|
||||
|
||||
/// Warp sync state machine. Accumulates warp proofs and state.
|
||||
pub struct WarpSync<B: BlockT> {
|
||||
phase: Phase<B>,
|
||||
client: Arc<dyn Client<B>>,
|
||||
pub struct WarpSync<B: BlockT, Client> {
|
||||
phase: Phase<B, Client>,
|
||||
client: Arc<Client>,
|
||||
warp_sync_provider: Arc<dyn WarpSyncProvider<B>>,
|
||||
total_proof_bytes: u64,
|
||||
}
|
||||
|
||||
impl<B: BlockT> WarpSync<B> {
|
||||
impl<B, Client> WarpSync<B, Client>
|
||||
where
|
||||
B: BlockT,
|
||||
Client: HeaderBackend<B> + ProofProvider<B> + 'static,
|
||||
{
|
||||
/// Create a new instance.
|
||||
pub fn new(
|
||||
client: Arc<dyn Client<B>>,
|
||||
warp_sync_provider: Arc<dyn WarpSyncProvider<B>>,
|
||||
) -> Self {
|
||||
pub fn new(client: Arc<Client>, warp_sync_provider: Arc<dyn WarpSyncProvider<B>>) -> Self {
|
||||
let last_hash = client.hash(Zero::zero()).unwrap().expect("Genesis header always exists");
|
||||
let phase = Phase::WarpProof {
|
||||
set_id: 0,
|
||||
|
||||
Reference in New Issue
Block a user