Skip to content

Commit

Permalink
fix: adding the --starting-from arg back by ignoring ordered state (#245
Browse files Browse the repository at this point in the history
)

Co-authored-by: cchudant <[email protected]>
  • Loading branch information
antiyro and cchudant authored Sep 11, 2024
1 parent 4fb9f37 commit f31bf57
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Next release

- fix: fixed the starting block arg with an ignore_block_order argument
- docs: fixed Docker Compose instructions
- fix: removed unused dependencies with udeps and machete
- feat: add devnet via `--devnet` cli argument
Expand Down
2 changes: 1 addition & 1 deletion crates/client/block_import/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub enum BlockImportError {
#[error("Block hash mismatch: expected {expected:#x}, got {got:#x}")]
BlockHash { got: Felt, expected: Felt },

#[error("Block order mismatch: database expects to import block #{expected}, trying to import #{got}")]
#[error("Block order mismatch: database expects to import block #{expected}, trying to import #{got}. To import a block out of order, use the `ignore_block_order` flag.")]
LatestBlockN { expected: u64, got: u64 },
#[error("Parent hash mismatch: expected {expected:#x}, got {got:#x}")]
ParentHash { got: Felt, expected: Felt },
Expand Down
11 changes: 10 additions & 1 deletion crates/client/block_import/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,21 @@ pub struct BlockValidationContext {
/// If the global state root commitment is missing during import, this will error.
/// This is only intended for full-node syncing without storing the global trie.
pub trust_global_tries: bool,
/// Ignore the order of the blocks to allow starting at some height.
pub ignore_block_order: bool,
/// The chain id of the current block.
pub chain_id: ChainId,
}

impl BlockValidationContext {
pub fn new(chain_id: ChainId) -> Self {
Self { trust_transaction_hashes: false, trust_class_hashes: false, trust_global_tries: false, chain_id }
Self {
trust_transaction_hashes: false,
trust_class_hashes: false,
trust_global_tries: false,
chain_id,
ignore_block_order: false,
}
}
pub fn trust_transaction_hashes(mut self, v: bool) -> Self {
self.trust_transaction_hashes = v;
Expand Down
14 changes: 8 additions & 6 deletions crates/client/block_import/src/verify_apply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub fn verify_apply_inner(
) -> Result<BlockImportResult, BlockImportError> {
// Check block number and block hash against db
let (block_number, parent_block_hash) =
check_parent_hash_and_num(backend, block.header.parent_block_hash, block.unverified_block_number)?;
check_parent_hash_and_num(backend, block.header.parent_block_hash, block.unverified_block_number, &validation)?;

// Update contract and its storage tries
let global_state_root = update_tries(backend, &block, &validation, block_number)?;
Expand Down Expand Up @@ -100,9 +100,10 @@ pub fn verify_apply_inner(
pub fn verify_apply_pending_inner(
backend: &MadaraBackend,
block: PreValidatedPendingBlock,
_validation: BlockValidationContext,
validation: BlockValidationContext,
) -> Result<PendingBlockImportResult, BlockImportError> {
let (_block_number, parent_block_hash) = check_parent_hash_and_num(backend, block.header.parent_block_hash, None)?;
let (_block_number, parent_block_hash) =
check_parent_hash_and_num(backend, block.header.parent_block_hash, None, &validation)?;

let UnverifiedHeader {
parent_block_hash: _,
Expand Down Expand Up @@ -147,6 +148,7 @@ fn check_parent_hash_and_num(
backend: &MadaraBackend,
parent_block_hash: Option<Felt>,
unverified_block_number: Option<u64>,
validation: &BlockValidationContext,
) -> Result<(u64, Felt), BlockImportError> {
let latest_block_info =
backend.get_block_info(&BlockId::Tag(BlockTag::Latest)).map_err(make_db_error("getting latest block info"))?;
Expand All @@ -160,7 +162,7 @@ fn check_parent_hash_and_num(
};

let block_number = if let Some(block_n) = unverified_block_number {
if block_n != expected_block_number {
if block_n != expected_block_number && !validation.ignore_block_order {
return Err(BlockImportError::LatestBlockN { expected: expected_block_number, got: block_n });
}
block_n
Expand All @@ -169,7 +171,7 @@ fn check_parent_hash_and_num(
};

if let Some(parent_block_hash) = parent_block_hash {
if parent_block_hash != expected_parent_block_hash {
if parent_block_hash != expected_parent_block_hash && !validation.ignore_block_order {
return Err(BlockImportError::ParentHash { expected: expected_parent_block_hash, got: parent_block_hash });
}
}
Expand Down Expand Up @@ -284,7 +286,7 @@ fn block_hash(
return Ok((expected, header));
}

if expected != block_hash {
if expected != block_hash && !validation.ignore_block_order {
return Err(BlockImportError::BlockHash { got: block_hash, expected });
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/client/sync/src/fetch/fetchers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ pub struct FetchConfig {
pub chain_id: ChainId,
/// Whether to play a sound when a new block is fetched.
pub sound: bool,
/// Whether to check the root of the state update
/// Whether to check the root of the state update.
pub verify: bool,
/// The optional API_KEY to avoid rate limiting from the sequencer gateway.
pub api_key: Option<String>,
/// Polling interval
/// Polling interval.
pub sync_polling_interval: Option<Duration>,
/// Number of blocks to sync (for testing purposes)
/// Number of blocks to sync (for testing purposes).
pub n_blocks_to_sync: Option<u64>,
}

Expand Down Expand Up @@ -284,7 +284,7 @@ async fn fetch_class_updates(

// for blocks before 2597 on mainnet new classes are not declared in the state update
// https://github.com/madara-alliance/madara/issues/233
let legacy_classes: Vec<_> = if chain_id == MAIN_CHAIN_ID && block_id.block_n() < Some(2597) {
let legacy_classes: Vec<_> = if chain_id == MAIN_CHAIN_ID && block_id.block_n().is_some_and(|id| id < 2597) {
let block_number = block_id.block_n().unwrap(); // Safe to unwrap because of the condition above
MISSED_CLASS_HASHES.get(&block_number).cloned().unwrap_or_default()
} else {
Expand Down
2 changes: 2 additions & 0 deletions crates/client/sync/src/l2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ pub struct L2SyncConfig {
pub sync_polling_interval: Option<Duration>,
pub backup_every_n_blocks: Option<u64>,
pub pending_block_poll_interval: Duration,
pub ignore_block_order: bool,
}

/// Spawns workers to fetch blocks and state updates from the feeder.
Expand Down Expand Up @@ -242,6 +243,7 @@ pub async fn sync(
trust_global_tries: config.verify,
chain_id,
trust_class_hashes: false,
ignore_block_order: config.ignore_block_order,
};

let mut join_set = JoinSet::new();
Expand Down
13 changes: 9 additions & 4 deletions crates/client/sync/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@ pub async fn sync(
telemetry: TelemetryHandle,
pending_block_poll_interval: Duration,
) -> anyhow::Result<()> {
let starting_block = if let Some(starting_block) = starting_block {
starting_block
let (starting_block, ignore_block_order) = if let Some(starting_block) = starting_block {
log::warn!("⚠️ Forcing unordered state. This will most probably break your database.");
(starting_block, true)
} else {
backend
(
backend
.get_block_n(&mp_block::BlockId::Tag(mp_block::BlockTag::Latest))
.context("getting sync tip")?
.map(|block_id| block_id + 1) // next block after the tip
.unwrap_or_default() as _ // or genesis
.unwrap_or_default() as _, // or genesis
false,
)
};

log::info!("⛓️ Starting L2 sync from block {}", starting_block);
Expand All @@ -56,6 +60,7 @@ pub async fn sync(
sync_polling_interval: fetch_config.sync_polling_interval,
backup_every_n_blocks,
pending_block_poll_interval,
ignore_block_order,
},
block_metrics,
db_metrics,
Expand Down
4 changes: 2 additions & 2 deletions crates/node/src/cli/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ pub struct SyncParams {
#[clap(long, alias = "no-sync")]
pub sync_disabled: bool,

/// The block you want to start syncing from.
/// The block you want to start syncing from. This will most probably break your database.
#[clap(long, value_name = "BLOCK NUMBER")]
pub starting_block: Option<u64>,
pub unsafe_starting_block: Option<u64>,

/// This will produce sound interpreted from the block hashes.
#[cfg(feature = "m")]
Expand Down
2 changes: 1 addition & 1 deletion crates/node/src/service/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl SyncService {
Ok(Self {
db_backend: Arc::clone(db.backend()),
fetch_config,
starting_block: config.starting_block,
starting_block: config.unsafe_starting_block,
backup_every_n_blocks: config.backup_every_n_blocks,
block_metrics,
db_metrics,
Expand Down

0 comments on commit f31bf57

Please sign in to comment.