Skip to content

Commit

Permalink
feat(light-node): cold boot with all history
Browse files Browse the repository at this point in the history
  • Loading branch information
pashinov authored and Rexagon committed Feb 6, 2025
1 parent d554742 commit e164e05
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 27 deletions.
2 changes: 1 addition & 1 deletion cli/src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ impl Node {
self.zerostate,
self.starter_config.clone(),
)
.cold_boot(zerostates.map(FileZerostateProvider))
.cold_boot(zerostates.map(FileZerostateProvider), false)
.await?
}
};
Expand Down
54 changes: 35 additions & 19 deletions core/src/block_strider/starter/cold_boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,50 @@ use crate::proto::blockchain::KeyBlockProof;

impl StarterInner {
#[tracing::instrument(skip_all)]
pub async fn cold_boot<P>(&self, zerostates: Option<P>) -> Result<BlockId>
pub async fn cold_boot<P>(
&self,
zerostates: Option<P>,
sync_from_genesis: bool,
) -> Result<BlockId>
where
P: ZerostateProvider,
{
tracing::info!("started");

// Find the last known key block (or zerostate)
// from which we can start downloading other key blocks
let init_block = self.prepare_init_block(zerostates).await?;

// Ensure that all key blocks until now (with some offset) are downloaded
self.download_key_blocks(init_block).await?;

// Choose the latest key block with persistent state
let last_key_block = self.choose_key_block()?;
let last_mc_block_id = match sync_from_genesis {
true => {
let zerostates = zerostates.context("zerostate should be present")?;
let (handle, _) = self.import_zerostates(zerostates).await?;
*handle.id()
}
false => {
// Find the last known key block (or zerostate)
// from which we can start downloading other key blocks
let init_block = self.prepare_init_block(zerostates).await?;

// Ensure that all key blocks until now (with some offset) are downloaded
self.download_key_blocks(init_block).await?;

// Choose the latest key block with persistent state
let last_key_block = self.choose_key_block()?;

if last_key_block.id().seqno != 0 {
// If the last suitable key block is not zerostate, we must download all blocks
// with their states from shards for that
self.download_start_blocks_and_states(last_key_block.id())
.await?;
}

if last_key_block.id().seqno != 0 {
// If the last suitable key block is not zerostate, we must download all blocks
// with their states from shards for that
self.download_start_blocks_and_states(last_key_block.id())
.await?;
}
*last_key_block.id()
}
};

self.storage
.node_state()
.store_last_mc_block_id(last_key_block.id());
tracing::info!(last_mc_block_id = %last_key_block.id(), "finished");
Ok(*last_key_block.id())
.store_last_mc_block_id(&last_mc_block_id);
tracing::info!(last_mc_block_id = %last_mc_block_id, "finished");

Ok(last_mc_block_id)
}

// === Sync steps ===
Expand Down
10 changes: 8 additions & 2 deletions core/src/block_strider/starter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,17 @@ impl Starter {
/// Boot type when the node has not yet started syncing
///
/// Returns the last masterchain key block id.
pub async fn cold_boot<P>(&self, zerostate_provider: Option<P>) -> Result<BlockId>
pub async fn cold_boot<P>(
&self,
zerostate_provider: Option<P>,
sync_from_genesis: bool,
) -> Result<BlockId>
where
P: ZerostateProvider,
{
self.inner.cold_boot(zerostate_provider).await
self.inner
.cold_boot(zerostate_provider, sync_from_genesis)
.await
}
}

Expand Down
2 changes: 1 addition & 1 deletion light-node/examples/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async fn main() -> anyhow::Result<()> {
tycho_light_node::NodeConfig::from_file(args.node.config.as_ref().context("no config")?)?;

let mut node = args.node.create(config).await?;
let init_block_id = node.init(import_zerostate).await?;
let init_block_id = node.init(import_zerostate, false).await?;
node.update_validator_set(&init_block_id).await?;
node.run(PrintSubscriber).await?;

Expand Down
16 changes: 12 additions & 4 deletions light-node/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,15 @@ impl<C> Node<C> {
})
}

pub async fn init(&self, import_zerostate: Option<Vec<PathBuf>>) -> Result<BlockId> {
pub async fn init(
&self,
import_zerostate: Option<Vec<PathBuf>>,
sync_from_genesis: bool,
) -> Result<BlockId> {
self.wait_for_neighbours().await;

let init_block_id = self
.boot(import_zerostate)
.boot(import_zerostate, sync_from_genesis)
.await
.context("failed to init node")?;

Expand All @@ -259,7 +263,11 @@ impl<C> Node<C> {
}

/// Initialize the node and return the init block id.
async fn boot(&self, zerostates: Option<Vec<PathBuf>>) -> Result<BlockId> {
async fn boot(
&self,
zerostates: Option<Vec<PathBuf>>,
sync_from_genesis: bool,
) -> Result<BlockId> {
let node_state = self.storage.node_state();

let last_mc_block_id = match node_state.load_last_mc_block_id() {
Expand All @@ -271,7 +279,7 @@ impl<C> Node<C> {
self.zerostate,
self.starter_config.clone(),
)
.cold_boot(zerostates.map(FileZerostateProvider))
.cold_boot(zerostates.map(FileZerostateProvider), sync_from_genesis)
.await?
}
};
Expand Down

0 comments on commit e164e05

Please sign in to comment.