From d147e1c3245f4533e9282022edc9ca102997f152 Mon Sep 17 00:00:00 2001 From: Esad Yusuf Atik Date: Tue, 14 May 2024 14:49:11 +0300 Subject: [PATCH] Fix l1 fee rate selection and error handling in sequencer (#565) * fix l1 fee rate selection and error handling in sequencer * Update crates/soft-confirmation-rule-enforcer/src/query.rs Co-authored-by: Roman * Refactor + clamp --------- Co-authored-by: Roman Co-authored-by: otaliptus --- Cargo.lock | 1 + bin/citrea/tests/e2e/mod.rs | 2 +- crates/sequencer/Cargo.toml | 7 +++-- crates/sequencer/src/sequencer.rs | 22 +++++++++++++++ .../src/query.rs | 28 +++++++++++++++++++ 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08a413b59..d902bd034 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1705,6 +1705,7 @@ dependencies = [ "serde", "serde_json", "shared-backup-db", + "soft-confirmation-rule-enforcer", "sov-accounts", "sov-db", "sov-mock-da", diff --git a/bin/citrea/tests/e2e/mod.rs b/bin/citrea/tests/e2e/mod.rs index c51f2f457..0317cd324 100644 --- a/bin/citrea/tests/e2e/mod.rs +++ b/bin/citrea/tests/e2e/mod.rs @@ -1843,7 +1843,7 @@ async fn sequencer_crash_and_replace_full_node() -> Result<(), anyhow::Error> { #[tokio::test] async fn transaction_failing_on_l1_is_removed_from_mempool() -> Result<(), anyhow::Error> { - citrea::initialize_logging(); + // citrea::initialize_logging(); let (seq_test_client, full_node_test_client, seq_task, full_node_task, _) = initialize_test(Default::default()).await; diff --git a/crates/sequencer/Cargo.toml b/crates/sequencer/Cargo.toml index 253acf953..881b3a5c6 100644 --- a/crates/sequencer/Cargo.toml +++ b/crates/sequencer/Cargo.toml @@ -45,7 +45,7 @@ schnellru = "0.2.1" sov-rollup-interface = { path = "../sovereign-sdk/rollup-interface", features = [ "native", ] } -citrea-evm = { path = "../evm" } +citrea-evm = { path = "../evm", features = ["native"] } sov-db = { path = "../sovereign-sdk/full-node/db/sov-db", version = "0.3" } sov-stf-runner = { path = "../sovereign-sdk/full-node/sov-stf-runner" } @@ -57,6 +57,10 @@ sov-modules-api = { path = "../sovereign-sdk/module-system/sov-modules-api", def sov-accounts = { path = "../sovereign-sdk/module-system/module-implementations/sov-accounts", default-features = false } sov-state = { path = "../sovereign-sdk/module-system/sov-state" } sov-mock-da = { path = "../sovereign-sdk/adapters/mock-da", default-features = false } +soft-confirmation-rule-enforcer = { path = "../soft-confirmation-rule-enforcer", features = [ + "native", +] } + hex = { workspace = true } shared-backup-db = { path = "../shared-backup-db" } @@ -68,4 +72,3 @@ tempfile = { workspace = true } [features] default = [] local = [] -native = ["citrea-stf/native", "citrea-evm/native"] diff --git a/crates/sequencer/src/sequencer.rs b/crates/sequencer/src/sequencer.rs index 9275d7ba3..b5922191c 100644 --- a/crates/sequencer/src/sequencer.rs +++ b/crates/sequencer/src/sequencer.rs @@ -18,6 +18,7 @@ use reth_primitives::{FromRecoveredPooledTransaction, IntoRecoveredTransaction}; use reth_provider::BlockReaderIdExt; use reth_transaction_pool::{BestTransactionsAttributes, EthPooledTransaction, PoolTransaction}; use shared_backup_db::{CommitmentStatus, PostgresConnector, SharedBackupDbConfig}; +use soft_confirmation_rule_enforcer::SoftConfirmationRuleEnforcer; use sov_accounts::Accounts; use sov_accounts::Response::{AccountEmpty, AccountExists}; use sov_db::ledger_db::{LedgerDB, SlotCommit}; @@ -74,6 +75,7 @@ where state_root: StateRoot, sequencer_pub_key: Vec, rpc_config: RpcConfig, + soft_confirmation_rule_enforcer: SoftConfirmationRuleEnforcer, } enum L2BlockMode { @@ -138,6 +140,9 @@ where let sov_tx_signer_priv_key = C::PrivateKey::try_from(&hex::decode(&config.private_key).unwrap()).unwrap(); + let soft_confirmation_rule_enforcer = + SoftConfirmationRuleEnforcer::::Spec>::default(); + Ok(Self { da_service, mempool: Arc::new(pool), @@ -154,6 +159,7 @@ where state_root: prev_state_root, sequencer_pub_key: public_keys.sequencer_public_key, rpc_config, + soft_confirmation_rule_enforcer, }) } @@ -424,6 +430,10 @@ where err ); batch_workspace.revert(); + return Err(anyhow!( + "Failed to apply begin soft confirmation hook: {:?}", + err + )); } } Ok(()) @@ -464,12 +474,16 @@ where last_finalized_height ); + let fee_rate_range = self.get_l1_fee_rate_range()?; + let l1_fee_rate = self .da_service .get_fee_rate() .await .map_err(|e| anyhow!(e))?; + let l1_fee_rate = l1_fee_rate.clamp(*fee_rate_range.start(), *fee_rate_range.end()); + let new_da_block = match last_finalized_height.cmp(&prev_l1_height) { Ordering::Less => { panic!("DA L1 height is less than Ledger finalized height"); @@ -862,4 +876,12 @@ where None => Ok(()), } } + + fn get_l1_fee_rate_range(&self) -> Result, anyhow::Error> { + let mut working_set = WorkingSet::::new(self.storage.clone()); + + self.soft_confirmation_rule_enforcer + .get_next_min_max_l1_fee_rate(&mut working_set) + .map_err(|e| anyhow::anyhow!("Error reading min max l1 fee rate: {}", e)) + } } diff --git a/crates/soft-confirmation-rule-enforcer/src/query.rs b/crates/soft-confirmation-rule-enforcer/src/query.rs index aed8306a7..ea0d1ea39 100644 --- a/crates/soft-confirmation-rule-enforcer/src/query.rs +++ b/crates/soft-confirmation-rule-enforcer/src/query.rs @@ -1,3 +1,5 @@ +use std::ops::RangeInclusive; + use jsonrpsee::core::RpcResult; use sov_modules_api::macros::rpc_gen; use sov_modules_api::{Context, DaSpec, StateMapAccessor, StateValueAccessor, WorkingSet}; @@ -52,4 +54,30 @@ impl SoftConfirmationRuleEnforcer { pub fn get_last_timestamp(&self, working_set: &mut WorkingSet) -> RpcResult { Ok(self.last_timestamp.get(working_set).unwrap_or(0)) } + + /// function to get min and max for next L1 fee rate + pub fn get_next_min_max_l1_fee_rate( + &self, + working_set: &mut WorkingSet, + ) -> RpcResult> { + let last_l1_fee_rate = self.last_l1_fee_rate.get(working_set).unwrap_or(0); + + if last_l1_fee_rate == 0 { + // on the first soft confirmation, we don't have a last fee rate + return Ok(0..=u128::MAX); + } + + let l1_fee_rate_change_percentage = self + .l1_fee_rate_change_percentage + .get(working_set) + .expect("L1 fee rate change should be set"); + + let min = last_l1_fee_rate + .saturating_sub((last_l1_fee_rate * l1_fee_rate_change_percentage) / 100); + + let max = last_l1_fee_rate + .saturating_add((last_l1_fee_rate * l1_fee_rate_change_percentage) / 100); + + Ok(min..=max) + } }