Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(derive): Holocene Activation #574

Merged
merged 7 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
run: cargo generate-lockfile
- name: cargo llvm-cov
run: |
cargo llvm-cov nextest --locked --workspace --lcov --output-path lcov.info --features test-utils --profile ci && \
RUST_MIN_STACK=33554432 cargo llvm-cov nextest --locked --workspace --lcov --output-path lcov.info --features test-utils --profile ci && \
mv ./target/nextest/ci/junit.xml ./junit.xml
- name: Record Rust version
run: echo "RUST=$(rustc --version)" >> "$GITHUB_ENV"
Expand Down
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 36 additions & 2 deletions crates/derive/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl PipelineError {
}

/// A reset error
#[derive(Error, Debug, Eq, PartialEq)]
#[derive(Error, Clone, Debug, Eq, PartialEq)]
pub enum ResetError {
/// The batch has a bad parent hash.
/// The first argument is the expected parent hash, and the second argument is the actual
Expand All @@ -127,6 +127,16 @@ pub enum ResetError {
/// Attributes builder error variant, with [BuilderError].
#[error("Attributes builder error: {0}")]
AttributesBuilder(#[from] BuilderError),
/// A Holocene activation temporary error.
#[error("Holocene activation reset")]
HoloceneActivation,
}

impl ResetError {
/// Wrap [self] as a [PipelineErrorKind::Reset].
pub const fn reset(self) -> PipelineErrorKind {
PipelineErrorKind::Reset(self)
}
}

/// A decoding error.
Expand Down Expand Up @@ -159,7 +169,7 @@ pub enum BatchDecompressionError {
/// An [AttributesBuilder] Error.
///
/// [AttributesBuilder]: crate::traits::AttributesBuilder
#[derive(Error, Debug, PartialEq, Eq)]
#[derive(Error, Clone, Debug, PartialEq, Eq)]
pub enum BuilderError {
/// Mismatched blocks.
#[error("Block mismatch. Expected {0:?}, got {1:?}")]
Expand Down Expand Up @@ -199,3 +209,27 @@ pub enum BlobProviderError {
#[error("{0}")]
Backend(String),
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_reset_error_kinds() {
let reset_errors = [
ResetError::BadParentHash(Default::default(), Default::default()),
ResetError::BadTimestamp(0, 0),
ResetError::L1OriginMismatch(0, 0),
ResetError::ReorgDetected(Default::default(), Default::default()),
ResetError::AttributesBuilder(BuilderError::BlockMismatch(
Default::default(),
Default::default(),
)),
ResetError::HoloceneActivation,
];
for error in reset_errors.into_iter() {
let expected = PipelineErrorKind::Reset(error.clone());
assert_eq!(error.reset(), expected);
}
}
}
12 changes: 12 additions & 0 deletions crates/derive/src/stages/l1_traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,20 @@
}

crate::set!(ORIGIN_GAUGE, next_l1_origin.number as i64);

let prev_block_holocene = self.rollup_config.is_holocene_active(block.timestamp);
let next_block_holocene = self.rollup_config.is_holocene_active(next_l1_origin.timestamp);

// Update the block origin regardless of if a holocene activation is required.
self.block = Some(next_l1_origin);
self.done = false;

// If the prev block is not holocene, but the next is, we need to flag this
// so the pipeline driver will reset the pipeline for holocene activation.
if !prev_block_holocene && next_block_holocene {
return Err(ResetError::HoloceneActivation.reset());

Check warning on line 122 in crates/derive/src/stages/l1_traversal.rs

View check run for this annotation

Codecov / codecov/patch

crates/derive/src/stages/l1_traversal.rs#L122

Added line #L122 was not covered by tests
}

Ok(())
}
}
Expand Down
56 changes: 32 additions & 24 deletions examples/trusted-sync/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,32 +214,40 @@ async fn sync(cli: cli::Cli) -> Result<()> {
metrics::PIPELINE_STEPS.with_label_values(&["origin_advance"]).inc();
trace!(target: "loop", "Advanced origin");
}
StepResult::OriginAdvanceErr(e) => {
metrics::PIPELINE_STEPS.with_label_values(&["origin_advance_failure"]).inc();
warn!(target: "loop", "Could not advance origin: {:?}", e);
}
StepResult::StepFailed(e) => match e {
PipelineErrorKind::Temporary(e) => {
if matches!(e, PipelineError::NotEnoughData) {
metrics::PIPELINE_STEPS.with_label_values(&["not_enough_data"]).inc();
debug!(target: "loop", "Not enough data to step derivation pipeline");
}
}
PipelineErrorKind::Reset(_) => {
metrics::PIPELINE_STEPS.with_label_values(&["reset"]).inc();
warn!(target: "loop", "Resetting pipeline: {:?}", e);
pipeline
.reset(
cursor.block_info,
pipeline.origin().ok_or(anyhow::anyhow!("Missing origin"))?,
)
.await?;
sr => {
if let StepResult::OriginAdvanceErr(ref e) = sr {
metrics::PIPELINE_STEPS.with_label_values(&["origin_advance_failure"]).inc();
warn!(target: "loop", "Could not advance origin: {:?}", e);
}
_ => {
metrics::PIPELINE_STEPS.with_label_values(&["failure"]).inc();
error!(target: "loop", "Error stepping derivation pipeline: {:?}", e);

match sr {
StepResult::PreparedAttributes | StepResult::AdvancedOrigin => {}
StepResult::OriginAdvanceErr(e) | StepResult::StepFailed(e) => match e {
PipelineErrorKind::Temporary(e) => {
if matches!(e, PipelineError::NotEnoughData) {
metrics::PIPELINE_STEPS
.with_label_values(&["not_enough_data"])
.inc();
debug!(target: "loop", "Not enough data to step derivation pipeline");
}
}
PipelineErrorKind::Reset(_) => {
metrics::PIPELINE_STEPS.with_label_values(&["reset"]).inc();
warn!(target: "loop", "Resetting pipeline: {:?}", e);
pipeline
.reset(
cursor.block_info,
pipeline.origin().ok_or(anyhow::anyhow!("Missing origin"))?,
)
.await?;
}
PipelineErrorKind::Critical(_) => {
metrics::PIPELINE_STEPS.with_label_values(&["failure"]).inc();
error!(target: "loop", "Error stepping derivation pipeline: {:?}", e);
}
},
}
},
}
}

// Peek at the next prepared attributes and validate them.
Expand Down