Extract warp sync strategy from ChainSync (#2467)

Extract `WarpSync` (and `StateSync` as part of warp sync) from
`ChainSync` as independent syncing strategy called by `SyncingEngine`.
Introduce `SyncingStrategy` enum as a proxy between `SyncingEngine` and
specific syncing strategies.

## Limitations
Gap sync is kept in `ChainSync` for now because it shares the same set
of peers as block syncing implementation in `ChainSync`. Extraction of a
common context responsible for peer management in syncing strategies
able to run in parallel is planned for a follow-up PR.

## Further improvements
A possibility of conversion of `SyncingStartegy` into a trait should be
evaluated. The main stopper for this is that different strategies need
to communicate different actions to `SyncingEngine` and respond to
different events / provide different APIs (e.g., requesting
justifications is only possible via `ChainSync` and not through
`WarpSync`; `SendWarpProofRequest` action is only relevant to
`WarpSync`, etc.)

---------

Co-authored-by: Aaro Altonen <48052676+altonen@users.noreply.github.com>
This commit is contained in:
Dmitry Markin
2024-01-12 17:17:15 +02:00
committed by GitHub
parent 5ed0a75fcd
commit 5208bed7d2
30 changed files with 3227 additions and 1016 deletions
@@ -17,8 +17,9 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::{
chain_sync::{PeerSync, PeerSyncState},
request_metrics::Metrics,
strategy::chain_sync::{PeerSync, PeerSyncState},
LOG_TARGET,
};
use fork_tree::ForkTree;
use libp2p::PeerId;
@@ -102,7 +103,7 @@ impl<B: BlockT> ExtraRequests<B> {
// ignore the `Revert` error.
},
Err(err) => {
debug!(target: "sync", "Failed to insert request {:?} into tree: {}", request, err);
debug!(target: LOG_TARGET, "Failed to insert request {:?} into tree: {}", request, err);
},
_ => (),
}
@@ -126,7 +127,7 @@ impl<B: BlockT> ExtraRequests<B> {
// messages to chain sync.
if let Some(request) = self.active_requests.remove(&who) {
if let Some(r) = resp {
trace!(target: "sync",
trace!(target: LOG_TARGET,
"Queuing import of {} from {:?} for {:?}",
self.request_type_name, who, request,
);
@@ -134,7 +135,7 @@ impl<B: BlockT> ExtraRequests<B> {
self.importing_requests.insert(request);
return Some((who, request.0, request.1, r))
} else {
trace!(target: "sync",
trace!(target: LOG_TARGET,
"Empty {} response from {:?} for {:?}",
self.request_type_name, who, request,
);
@@ -142,7 +143,7 @@ impl<B: BlockT> ExtraRequests<B> {
self.failed_requests.entry(request).or_default().push((who, Instant::now()));
self.pending_requests.push_front(request);
} else {
trace!(target: "sync",
trace!(target: LOG_TARGET,
"No active {} request to {:?}",
self.request_type_name, who,
);
@@ -217,7 +218,7 @@ impl<B: BlockT> ExtraRequests<B> {
};
if self.tree.finalize_root(&finalized_hash).is_none() {
warn!(target: "sync",
warn!(target: LOG_TARGET,
"‼️ Imported {:?} {:?} which isn't a root in the tree: {:?}",
finalized_hash, finalized_number, self.tree.roots().collect::<Vec<_>>()
);
@@ -322,7 +323,7 @@ impl<'a, B: BlockT> Matcher<'a, B> {
}
self.extras.active_requests.insert(*peer, request);
trace!(target: "sync",
trace!(target: LOG_TARGET,
"Sending {} request to {:?} for {:?}",
self.extras.request_type_name, peer, request,
);
@@ -345,7 +346,7 @@ impl<'a, B: BlockT> Matcher<'a, B> {
#[cfg(test)]
mod tests {
use super::*;
use crate::chain_sync::PeerSync;
use crate::strategy::chain_sync::PeerSync;
use quickcheck::{Arbitrary, Gen, QuickCheck};
use sp_blockchain::Error as ClientError;
use sp_test_primitives::{Block, BlockNumber, Hash};