diff --git a/prover/src/continuation.rs b/prover/src/continuation.rs index 2fcce9cda..15b56a1e0 100644 --- a/prover/src/continuation.rs +++ b/prover/src/continuation.rs @@ -662,6 +662,18 @@ pub fn prove_continuation( if executor.pc() == 0 { break; } + // The cross-epoch ordering check (IsB20 on `fini_epoch - 1 - init_epoch`) + // only spans `local_to_global::MAX_EPOCHS` epochs. Beyond that the IsB20 bus + // cannot balance, so an honest proof is impossible — fail fast with a clear + // error instead of building an unprovable trace. The verifier already + // rejects any such proof; this is a prover-side guard for a clean message. + if index >= local_to_global::MAX_EPOCHS { + return Err(Error::InvalidContinuationEpochSize(format!( + "execution needs more than {} continuation epochs (the IsB20 cross-epoch \ + ordering range); use a larger epoch size", + local_to_global::MAX_EPOCHS + ))); + } let register_init: Vec = if index == 0 { register::register_init_from_entry_point(elf.entry_point) } else { diff --git a/prover/src/tables/local_to_global.rs b/prover/src/tables/local_to_global.rs index eb91b36f3..3f9221d57 100644 --- a/prover/src/tables/local_to_global.rs +++ b/prover/src/tables/local_to_global.rs @@ -72,6 +72,16 @@ type Provenance = PagedMem<(u64, u64, u64)>; /// (1-based) epoch label, so `init_epoch < fini_epoch` holds for genesis cells. pub const GENESIS_EPOCH: u64 = 0; +/// Maximum number of epochs a continuation run may have. +/// +/// The cross-epoch ordering check proves `init_epoch < fini_epoch` via an `IsB20` +/// (20-bit) lookup on `fini_epoch - 1 - init_epoch`. A genesis-sourced cell +/// finalized in epoch `index` (0-based) has gap `index`, so every epoch must +/// satisfy `index < 2^20`. A run needing more epochs cannot be proved — the +/// IsB20 bus would not balance — so the driver rejects it up front (see +/// `prove_continuation`). +pub const MAX_EPOCHS: u64 = 1 << 20; + /// A cell's state when an epoch first touches it. #[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct InitClaim { @@ -462,7 +472,7 @@ pub fn collect_bitwise_from_l2g(boundaries: &[CellBoundary]) -> Vec> 8) & 0xFF) as u8,