Skip to content

Commit

Permalink
Allow piece cache to sync before node itself is fully synced
Browse files Browse the repository at this point in the history
  • Loading branch information
nazar-pc committed Jan 31, 2024
1 parent 1483649 commit 0322435
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 14 deletions.
1 change: 1 addition & 0 deletions crates/sc-consensus-subspace-rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ where
FarmerAppInfo {
genesis_hash: self.genesis_hash,
dsn_bootstrap_nodes: self.dsn_bootstrap_nodes.clone(),
syncing: self.sync_oracle.is_major_syncing(),
farming_timeout: chain_constants
.slot_duration()
.as_duration()
Expand Down
2 changes: 1 addition & 1 deletion crates/subspace-farmer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ substrate-bip39 = "0.4.5"
supports-color = "2.1.0"
tempfile = "3.9.0"
thiserror = "1.0.56"
tokio = { version = "1.35.1", features = ["macros", "parking_lot", "rt-multi-thread", "signal"] }
tokio = { version = "1.35.1", features = ["macros", "parking_lot", "rt-multi-thread", "signal", "time"] }
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
ulid = { version = "1.0.0", features = ["serde"] }
Expand Down
43 changes: 30 additions & 13 deletions crates/subspace-farmer/src/piece_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use parking_lot::RwLock;
use std::collections::HashMap;
use std::num::NonZeroU16;
use std::sync::Arc;
use std::time::Duration;
use std::{fmt, mem};
use subspace_core_primitives::{Piece, PieceIndex, SegmentHeader, SegmentIndex};
use subspace_farmer_components::plotting::{PieceGetter, PieceGetterRetryPolicy};
Expand All @@ -30,6 +31,7 @@ const CONCURRENT_PIECES_TO_DOWNLOAD: usize = 1_000;
const INTERMEDIATE_CACHE_UPDATE_INTERVAL: usize = 100;
/// Get piece retry attempts number.
const PIECE_GETTER_RETRY_NUMBER: NonZeroU16 = NonZeroU16::new(4).expect("Not zero; qed");
const INITIAL_SYNC_FARM_INFO_CHECK_INTERVAL: Duration = Duration::from_secs(1);

type HandlerFn<A> = Arc<dyn Fn(&A) + Send + Sync + 'static>;
type Handler<A> = Bag<HandlerFn<A>, A>;
Expand Down Expand Up @@ -303,21 +305,36 @@ where

info!("Synchronizing piece cache");

// TODO: Query from the DSN too such that we don't build outdated cache at start if node is
// not synced fully
let last_segment_index = match self.node_client.farmer_app_info().await {
Ok(farmer_app_info) => farmer_app_info.protocol_info.history_size.segment_index(),
Err(error) => {
error!(
%error,
"Failed to get farmer app info from node, keeping old cache state without \
updates"
);
let last_segment_index = loop {
match self.node_client.farmer_app_info().await {
Ok(farmer_app_info) => {
let last_segment_index =
farmer_app_info.protocol_info.history_size.segment_index();
// Wait for node to be either fully synced or to be aware of non-zero segment
// index, which would indicate it has started DSN sync and knows about
// up-to-date archived history.
//
// While this doesn't account for situations where node was offline for a long
// time and is aware of old segment headers, this is good enough for piece cache
// sync to proceed and should result in better user experience on average.
if last_segment_index > SegmentIndex::ZERO || !farmer_app_info.syncing {
break last_segment_index;
}
}
Err(error) => {
error!(
%error,
"Failed to get farmer app info from node, keeping old cache state without \
updates"
);

// Not the latest, but at least something
*self.caches.write() = caches;
return;
// Not the latest, but at least something
*self.caches.write() = caches;
return;
}
}

tokio::time::sleep(INITIAL_SYNC_FARM_INFO_CHECK_INTERVAL).await;
};

debug!(%last_segment_index, "Identified last segment index");
Expand Down
1 change: 1 addition & 0 deletions crates/subspace-farmer/src/piece_cache/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl NodeClient for MockNodeClient {
Ok(FarmerAppInfo {
genesis_hash: [0; 32],
dsn_bootstrap_nodes: Vec::new(),
syncing: false,
farming_timeout: Duration::default(),
protocol_info: FarmerProtocolInfo {
history_size: HistorySize::from(SegmentIndex::from(
Expand Down
2 changes: 2 additions & 0 deletions crates/subspace-rpc-primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ pub struct FarmerAppInfo {
pub genesis_hash: [u8; 32],
/// Bootstrap nodes for DSN
pub dsn_bootstrap_nodes: Vec<Multiaddr>,
/// Whether node is syncing right now
pub syncing: bool,
/// How much time farmer has to audit sectors and generate a solution
pub farming_timeout: Duration,
/// Protocol info for farmer
Expand Down

0 comments on commit 0322435

Please sign in to comment.