From e1e44dffb72d5c4633aa2600ff844467d34e7ab9 Mon Sep 17 00:00:00 2001 From: Daniil Polyakov Date: Wed, 3 Jun 2026 23:50:44 +0300 Subject: [PATCH] feat: add bedrock withdraw events validation --- artifacts/program_methods/bridge.bin | Bin 425196 -> 428948 bytes integration_tests/tests/bridge.rs | 3 + lez/sequencer/core/src/block_publisher.rs | 54 ++-- lez/sequencer/core/src/block_store.rs | 18 ++ lez/sequencer/core/src/lib.rs | 317 ++++++++++++------- lez/sequencer/core/src/mock.rs | 7 +- lez/storage/src/sequencer/mod.rs | 62 +++- lez/storage/src/sequencer/sequencer_cells.rs | 36 ++- 8 files changed, 346 insertions(+), 151 deletions(-) diff --git a/artifacts/program_methods/bridge.bin b/artifacts/program_methods/bridge.bin index 9810c6ac4805b30ad94ec5e3cbe1508f623d2cc7..86c4e1c8242ac4c50a3ea897dc78b1c92f3946f2 100644 GIT binary patch delta 117390 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 delta 113584 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 anyhow::Res observe_result .context("Failed while waiting for finalized withdraw event from zone indexer")?; + // Sleep to observe sequencer log about validated withdraw event + tokio::time::sleep(Duration::from_secs(1)).await; + Ok(()) } diff --git a/lez/sequencer/core/src/block_publisher.rs b/lez/sequencer/core/src/block_publisher.rs index 2cf2dc5b..49b3e0d3 100644 --- a/lez/sequencer/core/src/block_publisher.rs +++ b/lez/sequencer/core/src/block_publisher.rs @@ -3,19 +3,21 @@ use std::{pin::Pin, sync::Arc, time::Duration}; use anyhow::{Context as _, Result}; use common::block::Block; use log::{info, warn}; -use logos_blockchain_core::mantle::{Note, ledger::Outputs, ops::channel::inscribe::Inscription}; +use logos_blockchain_core::mantle::ops::channel::inscribe::Inscription; pub use logos_blockchain_key_management_system_service::keys::{Ed25519Key, ZkKey}; pub use logos_blockchain_zone_sdk::sequencer::SequencerCheckpoint; use logos_blockchain_zone_sdk::{ CommonHttpClient, adapter::NodeHttpClient, - sequencer::{Event, SequencerConfig as ZoneSdkSequencerConfig, SequencerHandle, ZoneSequencer}, - state::{DepositInfo, FinalizedOp, InscriptionInfo}, + sequencer::{ + Event, SequencerConfig as ZoneSdkSequencerConfig, SequencerHandle, WithdrawArg, + ZoneSequencer, + }, + state::{DepositInfo, FinalizedOp, InscriptionInfo, WithdrawInfo}, }; -use num_bigint::BigUint; use tokio::task::JoinHandle; -use crate::{BridgeWithdrawData, config::BedrockConfig}; +use crate::config::BedrockConfig; /// Sink for `Event::Published` checkpoints emitted by the drive task. /// Caller is responsible for persistence (e.g. writing to rocksdb). @@ -30,8 +32,16 @@ pub type FinalizedBlockSink = Box; pub type OnDepositEventSink = Box Pin + Send>> + Send + 'static>; +/// Sink for finalized Bedrock withdraw events. +pub type OnWithdrawEventSink = + Box Pin + Send>> + Send + 'static>; + #[expect(async_fn_in_trait, reason = "We don't care about Send/Sync here")] pub trait BlockPublisherTrait: Clone { + #[expect( + clippy::too_many_arguments, + reason = "Looks better than bundling all those callbacks into a struct" + )] async fn new( config: &BedrockConfig, bedrock_signing_key: Ed25519Key, @@ -40,15 +50,12 @@ pub trait BlockPublisherTrait: Clone { on_checkpoint: CheckpointSink, on_finalized_block: FinalizedBlockSink, on_deposit_event: OnDepositEventSink, + on_withdraw_event: OnWithdrawEventSink, ) -> Result; /// Fire-and-forget publish. Zone-sdk drives the actual submission and /// retries internally; this just hands the payload off. - async fn publish_block( - &self, - block: &Block, - bridge_withdrawals: Vec, - ) -> Result<()>; + async fn publish_block(&self, block: &Block, withdraws: Vec) -> Result<()>; } /// Real block publisher backed by zone-sdk's `ZoneSequencer`. @@ -76,6 +83,7 @@ impl BlockPublisherTrait for ZoneSdkPublisher { on_checkpoint: CheckpointSink, on_finalized_block: FinalizedBlockSink, on_deposit_event: OnDepositEventSink, + on_withdraw_event: OnWithdrawEventSink, ) -> Result { let basic_auth = config.auth.clone().map(Into::into); let node = NodeHttpClient::new(CommonHttpClient::new(basic_auth), config.node_url.clone()); @@ -112,7 +120,9 @@ impl BlockPublisherTrait for ZoneSdkPublisher { FinalizedOp::Deposit(deposit) => { on_deposit_event(deposit).await; } - FinalizedOp::Withdraw(_) => {} + FinalizedOp::Withdraw(withdraw) => { + on_withdraw_event(withdraw).await; + } } } } @@ -132,18 +142,14 @@ impl BlockPublisherTrait for ZoneSdkPublisher { }) } - async fn publish_block( - &self, - block: &Block, - bridge_withdrawals: Vec, - ) -> Result<()> { + async fn publish_block(&self, block: &Block, withdraws: Vec) -> Result<()> { let data = borsh::to_vec(block).context("Failed to serialize block")?; let data_bounded: Inscription = data .try_into() .context("Block data exceeds maximum allowed size")?; let data_byte_size = data_bounded.len(); - if bridge_withdrawals.is_empty() { + if withdraws.is_empty() { self.handle .publish_message(data_bounded) .await @@ -154,20 +160,6 @@ impl BlockPublisherTrait for ZoneSdkPublisher { return Ok(()); } - let withdraws: Vec<_> = bridge_withdrawals - .into_iter() - .map(|withdrawal| { - let recipient_pk = - logos_blockchain_key_management_system_service::keys::ZkPublicKey::from( - BigUint::from_bytes_le(&withdrawal.bedrock_account_pk), - ); - - logos_blockchain_zone_sdk::sequencer::WithdrawArg { - outputs: Outputs::new(Note::new(withdrawal.amount, recipient_pk)), - } - }) - .collect(); - let withdraw_count = withdraws.len(); self.handle .publish_atomic_withdraw(data_bounded, withdraws) diff --git a/lez/sequencer/core/src/block_store.rs b/lez/sequencer/core/src/block_store.rs index 97a23848..473e12f4 100644 --- a/lez/sequencer/core/src/block_store.rs +++ b/lez/sequencer/core/src/block_store.rs @@ -186,6 +186,24 @@ impl SequencerStore { self.dbio .remove_fulfilled_pending_deposit_events_up_to_block(finalized_block_id) } + + pub fn record_unseen_withdraw( + &self, + amount: u64, + bedrock_account_pk: [u8; 32], + ) -> DbResult { + self.dbio + .increment_unseen_withdraw_count(amount, bedrock_account_pk) + } + + pub fn consume_unseen_withdraw( + &self, + amount: u64, + bedrock_account_pk: [u8; 32], + ) -> DbResult { + self.dbio + .consume_unseen_withdraw_count(amount, bedrock_account_pk) + } } pub(crate) fn block_to_transactions_map(block: &Block) -> HashMap { diff --git a/lez/sequencer/core/src/lib.rs b/lez/sequencer/core/src/lib.rs index b7321ba5..ae585447 100644 --- a/lez/sequencer/core/src/lib.rs +++ b/lez/sequencer/core/src/lib.rs @@ -12,11 +12,13 @@ use lee::{AccountId, PublicTransaction, program::Program, public_transaction::Me use lee_core::GENESIS_BLOCK_ID; use log::{error, info, warn}; use logos_blockchain_key_management_system_service::keys::{ED25519_SECRET_KEY_SIZE, Ed25519Key}; +use logos_blockchain_zone_sdk::sequencer::WithdrawArg; use mempool::{MemPool, MemPoolHandle}; #[cfg(feature = "mock")] pub use mock::SequencerCoreWithMockClients; +use num_bigint::BigUint; pub use storage::error::DbError; -use storage::sequencer::sequencer_cells::PendingDepositEventRecord; +use storage::sequencer::{RocksDBIO, sequencer_cells::PendingDepositEventRecord}; use crate::{ block_publisher::{BlockPublisherTrait, ZoneSdkPublisher}, @@ -132,112 +134,18 @@ impl SequencerCore { .expect("Failed to load zone-sdk checkpoint"); let is_fresh_start = initial_checkpoint.is_none(); - let dbio_for_checkpoint = store.dbio(); - let on_checkpoint: block_publisher::CheckpointSink = Box::new(move |cp| { - let bytes = match serde_json::to_vec(&cp) { - Ok(b) => b, - Err(err) => { - error!("Failed to serialize zone-sdk checkpoint: {err:#}"); - return; - } - }; - if let Err(err) = dbio_for_checkpoint.put_zone_sdk_checkpoint_bytes(&bytes) { - error!("Failed to persist zone-sdk checkpoint: {err:#}"); - } - }); - - let dbio_for_finalized = store.dbio(); - let on_finalized_block: block_publisher::FinalizedBlockSink = Box::new(move |block_id| { - // NOTE: Theoretically Zone SDK may report finalization happening multiple times for the - // same block. In practice this is very unlikely to happen. For that to - // happen Sequencer should crash between receiving Finalized and Checkpoint events while - // these events happen very fast (because Checkpoints are generated by Zone SDK - // locally). - - if let Err(err) = dbio_for_finalized.clean_pending_blocks_up_to(block_id) { - error!("Failed to mark pending blocks finalized up to {block_id}: {err:#}"); - } - - match dbio_for_finalized.remove_fulfilled_pending_deposit_events_up_to_block(block_id) { - Ok(0) => {} - Ok(removed) => { - info!( - "Removed {removed} fulfilled pending deposit events up to finalized block {block_id}" - ); - } - Err(err) => { - error!( - "Failed to remove fulfilled pending deposit events up to block {block_id}: {err:#}" - ); - } - } - }); - let (mempool, mempool_handle) = MemPool::new(config.mempool_max_size); - replay_unfulfilled_deposit_events(&store, mempool_handle.clone()); - let mempool_handle_for_deposit = mempool_handle.clone(); - let dbio_for_deposit = store.dbio(); - let on_deposit_event: block_publisher::OnDepositEventSink = Box::new(move |deposit| { - // NOTE: Theoretically Zone SDK may report multiple identical deposits. In practice this - // is very unlikely to happen. For that to happen Sequencer should crash - // between receiving Deposit and Checkpoint events while these events happen - // very fast (because Checkpoints are generated by Zone SDK locally). - - let dbio_for_deposit = Arc::clone(&dbio_for_deposit); - let mempool_handle_for_deposit = mempool_handle_for_deposit.clone(); - Box::pin(async move { - let id_hex = hex::encode(deposit.op_id); - info!("Observed Bedrock Deposit event with id: {id_hex}"); - - let event_record = pending_deposit_event_record(&deposit); - - match dbio_for_deposit.add_pending_deposit_event(event_record.clone()) { - Ok(true) => {} - Ok(false) => { - info!( - "Deposit event {id_hex} already persisted as unfulfilled, skipping duplicate enqueue", - ); - return; - } - Err(err) => { - error!( - "Failed to persist unfulfilled deposit event {id_hex} before enqueue: {err:#}. Deposit will be lost.", - ); - return; - } - } - - let tx = match build_bridge_deposit_tx_from_event(&event_record) { - Ok(tx) => tx, - Err(err) => { - error!( - "Failed to build transaction from Bedrock deposit event {id_hex}: {err:#}. Deposit will be lost.", - ); - return; - } - }; - - if let Err(err) = mempool_handle_for_deposit - .push((TransactionOrigin::Sequencer, tx)) - .await - { - error!( - "Failed to queue sequencer transaction built from finalized Bedrock event: {err:#}. Deposit will be lost." - ); - } - }) - }); - let block_publisher = BP::new( &config.bedrock_config, bedrock_signing_key, config.retry_pending_blocks_timeout, initial_checkpoint, - on_checkpoint, - on_finalized_block, - on_deposit_event, + Self::on_checkpoint(store.dbio()), + Self::on_finalized_block(store.dbio()), + Self::on_deposit_event(store.dbio(), mempool_handle.clone()), + Self::on_withdraw_event(store.dbio()), ) .await .expect("Failed to initialize Block Publisher"); @@ -265,22 +173,164 @@ impl SequencerCore { (sequencer_core, mempool_handle) } + fn on_checkpoint(dbio: Arc) -> block_publisher::CheckpointSink { + Box::new(move |cp| { + let bytes = match serde_json::to_vec(&cp) { + Ok(b) => b, + Err(err) => { + error!("Failed to serialize zone-sdk checkpoint: {err:#}"); + return; + } + }; + if let Err(err) = dbio.put_zone_sdk_checkpoint_bytes(&bytes) { + error!("Failed to persist zone-sdk checkpoint: {err:#}"); + } + }) + } + + fn on_finalized_block(dbio: Arc) -> block_publisher::FinalizedBlockSink { + Box::new(move |block_id| { + // NOTE: Theoretically Zone SDK may report finalization happening multiple times for the + // same block. In practice this is very unlikely to happen. For that to + // happen Sequencer should crash between receiving Finalized and Checkpoint events while + // these events happen very fast (because Checkpoints are generated by Zone SDK + // locally). + + if let Err(err) = dbio.clean_pending_blocks_up_to(block_id) { + error!("Failed to mark pending blocks finalized up to {block_id}: {err:#}"); + } + + match dbio.remove_fulfilled_pending_deposit_events_up_to_block(block_id) { + Ok(0) => {} + Ok(removed) => { + info!( + "Removed {removed} fulfilled pending deposit events up to finalized block {block_id}" + ); + } + Err(err) => { + error!( + "Failed to remove fulfilled pending deposit events up to block {block_id}: {err:#}" + ); + } + } + }) + } + + fn on_deposit_event( + dbio: Arc, + mempool_handle: MemPoolHandle<(TransactionOrigin, LeeTransaction)>, + ) -> block_publisher::OnDepositEventSink { + Box::new(move |deposit| { + // NOTE: Theoretically Zone SDK may report multiple identical deposits. In practice this + // is very unlikely to happen. For that to happen Sequencer should crash + // between receiving Deposit and Checkpoint events while these events happen + // very fast (because Checkpoints are generated by Zone SDK locally). + + let dbio = Arc::clone(&dbio); + let mempool_handle = mempool_handle.clone(); + + Box::pin(async move { + let id_hex = hex::encode(deposit.op_id); + info!("Observed Bedrock Deposit event with id: {id_hex}"); + + let event_record = pending_deposit_event_record(&deposit); + + match dbio.add_pending_deposit_event(event_record.clone()) { + Ok(true) => {} + Ok(false) => { + info!( + "Deposit event {id_hex} already persisted as unfulfilled, skipping duplicate enqueue", + ); + return; + } + Err(err) => { + error!( + "Failed to persist unfulfilled deposit event {id_hex} before enqueue: {err:#}. Deposit will be lost.", + ); + return; + } + } + + let tx = match build_bridge_deposit_tx_from_event(&event_record) { + Ok(tx) => tx, + Err(err) => { + error!( + "Failed to build transaction from Bedrock deposit event {id_hex}: {err:#}. Deposit will be lost.", + ); + return; + } + }; + + if let Err(err) = mempool_handle + .push((TransactionOrigin::Sequencer, tx)) + .await + { + error!( + "Failed to queue sequencer transaction built from finalized Bedrock event: {err:#}. Deposit will be lost." + ); + } + }) + }) + } + + fn on_withdraw_event(dbio: Arc) -> block_publisher::OnWithdrawEventSink { + Box::new(move |withdraw| { + let dbio = Arc::clone(&dbio); + Box::pin(async move { + let hash_encoded = hex::encode(withdraw.tx_hash.as_ref()); + let withdraw_key = match withdraw_event_reconciliation_key(&withdraw.op.outputs) { + Ok(key) => key, + Err(err) => { + error!( + "Failed to build reconciliation key for Bedrock Withdraw event with tx_hash {hash_encoded}: {err:#}" + ); + return; + } + }; + + match dbio.consume_unseen_withdraw_count( + withdraw_key.amount, + withdraw_key.bedrock_account_pk, + ) { + Ok(true) => { + info!("Validated Bedrock Withdraw event with tx_hash: {hash_encoded}"); + } + Ok(false) => warn!( + "Unexpected Bedrock Withdraw event with tx_hash {hash_encoded}: no matching unseen withdraw found" + ), + Err(err) => error!( + "Failed to reconcile Bedrock Withdraw event with tx_hash {hash_encoded}: {err:#}" + ), + } + }) + }) + } + /// Produces a new block from mempool transactions and publishes it via zone-sdk. pub async fn produce_new_block(&mut self) -> Result { let BlockWithMeta { block, deposit_event_ids, - bridge_withdrawals, + withdraws, } = self .build_block_from_mempool() .context("Failed to build block from mempool transactions")?; + for withdraw in &withdraws { + let withdraw_key = withdraw_event_reconciliation_key(&withdraw.outputs) + .context("Failed to derive unseen-withdraw key from withdraw data")?; + + self.store + .record_unseen_withdraw(withdraw_key.amount, withdraw_key.bedrock_account_pk) + .context("Failed to persist unseen withdraw for reconciliation")?; + } + // TODO: Remove msg_id from store.update — it is no longer needed now that // zone-sdk manages L1 settlement state via its own checkpoint. let placeholder_msg_id = [0_u8; 32]; self.block_publisher - .publish_block(&block, bridge_withdrawals) + .publish_block(&block, withdraws) .await .context("Failed to publish block to Bedrock")?; @@ -308,7 +358,7 @@ impl SequencerCore { let mut valid_transactions = Vec::new(); let mut deposit_event_ids = Vec::new(); - let mut bridge_withdrawals = Vec::new(); + let mut withdraws = Vec::new(); let max_block_size = usize::try_from(self.sequencer_config.max_block_size.as_u64()) .expect("`max_block_size` should fit into usize"); @@ -374,7 +424,7 @@ impl SequencerCore { }; if let Some(withdraw_data) = extract_bridge_withdraw_data(&tx) { - bridge_withdrawals.push(withdraw_data); + withdraws.push(withdraw_data); } self.state.apply_state_diff(validated_diff); @@ -437,7 +487,7 @@ impl SequencerCore { Ok(BlockWithMeta { block, deposit_event_ids, - bridge_withdrawals, + withdraws, }) } @@ -497,13 +547,13 @@ impl SequencerCore { struct BlockWithMeta { block: Block, deposit_event_ids: Vec, - bridge_withdrawals: Vec, + withdraws: Vec, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct BridgeWithdrawData { - pub amount: u64, - pub bedrock_account_pk: [u8; 32], +#[derive(Debug, Clone, Copy)] +struct WithdrawReconciliationKey { + amount: u64, + bedrock_account_pk: [u8; 32], } /// Checks the database for any pending deposit events that have not yet been marked as submitted in @@ -694,7 +744,7 @@ fn extract_bridge_deposit_id(tx: &LeeTransaction) -> Option { } #[must_use] -fn extract_bridge_withdraw_data(tx: &LeeTransaction) -> Option { +fn extract_bridge_withdraw_data(tx: &LeeTransaction) -> Option { let LeeTransaction::Public(tx) = tx else { return None; }; @@ -712,16 +762,55 @@ fn extract_bridge_withdraw_data(tx: &LeeTransaction) -> Option Some(BridgeWithdrawData { - amount, - bedrock_account_pk, - }), + } => { + let recipient_pk = + logos_blockchain_key_management_system_service::keys::ZkPublicKey::from( + BigUint::from_bytes_le(&bedrock_account_pk), + ); + + Some(WithdrawArg { + outputs: logos_blockchain_core::mantle::ledger::Outputs::new( + logos_blockchain_core::mantle::Note::new(amount, recipient_pk), + ), + }) + } bridge_core::Instruction::Deposit { .. } => unreachable!( "Deposit instructions from users should never pass validation, and thus should never be seen here" ), } } +fn withdraw_event_reconciliation_key( + outputs: &logos_blockchain_core::mantle::ledger::Outputs, +) -> Result { + let [note] = outputs.as_ref().as_slice() else { + return Err(anyhow!( + "Unsupported withdraw output count for reconciliation: {}", + outputs.len() + )); + }; + + // `extract_bridge_withdraw_data` maps [u8;32] LE -> BigUint -> ZkPublicKey. + // Reconcile by reversing that direction here. + let mut bedrock_account_pk = BigUint::from(note.pk.into_inner()).to_bytes_le(); + if bedrock_account_pk.len() > 32 { + return Err(anyhow!( + "Withdraw recipient public key is too large: {} bytes", + bedrock_account_pk.len() + )); + } + bedrock_account_pk.resize(32, 0); + + let bedrock_account_pk: [u8; 32] = bedrock_account_pk + .try_into() + .expect("Public key bytes were padded/truncated to 32 bytes"); + + Ok(WithdrawReconciliationKey { + amount: note.value, + bedrock_account_pk, + }) +} + /// Load signing key from file or generate a new one if it doesn't exist. fn load_or_create_signing_key(path: &Path) -> Result { if path.exists() { diff --git a/lez/sequencer/core/src/mock.rs b/lez/sequencer/core/src/mock.rs index 0b0024ac..5f2ab8cf 100644 --- a/lez/sequencer/core/src/mock.rs +++ b/lez/sequencer/core/src/mock.rs @@ -3,12 +3,12 @@ use std::time::Duration; use anyhow::Result; use common::block::Block; use logos_blockchain_key_management_system_service::keys::Ed25519Key; +use logos_blockchain_zone_sdk::sequencer::WithdrawArg; use crate::{ - BridgeWithdrawData, block_publisher::{ BlockPublisherTrait, CheckpointSink, FinalizedBlockSink, OnDepositEventSink, - SequencerCheckpoint, + OnWithdrawEventSink, SequencerCheckpoint, }, config::BedrockConfig, }; @@ -27,6 +27,7 @@ impl BlockPublisherTrait for MockBlockPublisher { _on_checkpoint: CheckpointSink, _on_finalized_block: FinalizedBlockSink, _on_deposit_event: OnDepositEventSink, + _on_withdraw_event: OnWithdrawEventSink, ) -> Result { Ok(Self) } @@ -34,7 +35,7 @@ impl BlockPublisherTrait for MockBlockPublisher { async fn publish_block( &self, _block: &Block, - _bridge_withdrawals: Vec, + _bridge_withdrawals: Vec, ) -> Result<()> { Ok(()) } diff --git a/lez/storage/src/sequencer/mod.rs b/lez/storage/src/sequencer/mod.rs index 851dc4ff..e4f44914 100644 --- a/lez/storage/src/sequencer/mod.rs +++ b/lez/storage/src/sequencer/mod.rs @@ -11,12 +11,16 @@ use rocksdb::{ use crate::{ CF_BLOCK_NAME, CF_META_NAME, DB_META_FIRST_BLOCK_IN_DB_KEY, DBIO, DbResult, - cells::shared_cells::{BlockCell, FirstBlockCell, FirstBlockSetCell, LastBlockCell}, + cells::{ + SimpleStorableCell, + shared_cells::{BlockCell, FirstBlockCell, FirstBlockSetCell, LastBlockCell}, + }, error::DbError, sequencer::sequencer_cells::{ LEEStateCellOwned, LEEStateCellRef, LastFinalizedBlockIdCell, LatestBlockMetaCellOwned, LatestBlockMetaCellRef, PendingDepositEventRecord, PendingDepositEventsCellOwned, - PendingDepositEventsCellRef, ZoneSdkCheckpointCellOwned, ZoneSdkCheckpointCellRef, + PendingDepositEventsCellRef, UnseenWithdrawCountCell, ZoneSdkCheckpointCellOwned, + ZoneSdkCheckpointCellRef, }, }; @@ -31,6 +35,8 @@ pub const DB_META_ZONE_SDK_CHECKPOINT_KEY: &str = "zone_sdk_checkpoint"; /// Key base for storing queued deposit events that were not yet /// fulfilled on L2. pub const DB_META_PENDING_DEPOSIT_EVENTS_KEY: &str = "pending_deposit_events"; +/// Key base for counting unseen L2 withdraw intents. +pub const DB_META_UNSEEN_WITHDRAW_COUNT_KEY: &str = "unseen_withdraw_count"; /// Key base for storing the LEE state. pub const DB_LEE_STATE_KEY: &str = "lee_state"; @@ -312,6 +318,58 @@ impl RocksDBIO { Ok(removed) } + pub fn increment_unseen_withdraw_count( + &self, + amount: u64, + bedrock_account_pk: [u8; 32], + ) -> DbResult { + let key_params = (amount, bedrock_account_pk); + + let current = self + .get_opt::(key_params)? + .map_or(0, |cell| cell.0); + + let next = current.checked_add(1).ok_or_else(|| { + DbError::db_interaction_error("Unseen withdraw counter overflow".to_owned()) + })?; + + self.put(&UnseenWithdrawCountCell(next), key_params)?; + + Ok(next) + } + + pub fn consume_unseen_withdraw_count( + &self, + amount: u64, + bedrock_account_pk: [u8; 32], + ) -> DbResult { + let key_params = (amount, bedrock_account_pk); + + let Some(current) = self + .get_opt::(key_params)? + .map(|cell| cell.0) + else { + return Ok(false); + }; + + if let Some(next) = current.checked_sub(1) { + self.put(&UnseenWithdrawCountCell(next), key_params)?; + } else { + let cf_meta = self.meta_column(); + let db_key = + ::key_constructor(key_params)?; + + self.db.delete_cf(&cf_meta, db_key).map_err(|rerr| { + DbError::rocksdb_cast_message( + rerr, + Some("Failed to delete unseen withdraw count".to_owned()), + ) + })?; + } + + Ok(true) + } + pub fn put_block( &self, block: &Block, diff --git a/lez/storage/src/sequencer/sequencer_cells.rs b/lez/storage/src/sequencer/sequencer_cells.rs index 39b6a406..7d9c4609 100644 --- a/lez/storage/src/sequencer/sequencer_cells.rs +++ b/lez/storage/src/sequencer/sequencer_cells.rs @@ -9,7 +9,7 @@ use crate::{ sequencer::{ CF_LEE_STATE_NAME, DB_LEE_STATE_KEY, DB_META_LAST_FINALIZED_BLOCK_ID, DB_META_LATEST_BLOCK_META_KEY, DB_META_PENDING_DEPOSIT_EVENTS_KEY, - DB_META_ZONE_SDK_CHECKPOINT_KEY, + DB_META_UNSEEN_WITHDRAW_COUNT_KEY, DB_META_ZONE_SDK_CHECKPOINT_KEY, }, }; @@ -174,6 +174,40 @@ impl SimpleWritableCell for PendingDepositEventsCellRef<'_> { }) } } +#[derive(Debug, BorshSerialize, BorshDeserialize)] +pub struct UnseenWithdrawCountCell(pub u64); + +impl SimpleStorableCell for UnseenWithdrawCountCell { + type KeyParams = (u64, [u8; 32]); + + const CELL_NAME: &'static str = DB_META_UNSEEN_WITHDRAW_COUNT_KEY; + const CF_NAME: &'static str = CF_META_NAME; + + fn key_constructor((amount, bedrock_account_pk): Self::KeyParams) -> DbResult> { + borsh::to_vec(&(Self::CELL_NAME, amount, bedrock_account_pk)).map_err(|err| { + DbError::borsh_cast_message( + err, + Some(format!( + "Failed to serialize {:?} key params", + Self::CELL_NAME + )), + ) + }) + } +} + +impl SimpleReadableCell for UnseenWithdrawCountCell {} + +impl SimpleWritableCell for UnseenWithdrawCountCell { + fn value_constructor(&self) -> DbResult> { + borsh::to_vec(&self).map_err(|err| { + DbError::borsh_cast_message( + err, + Some("Failed to serialize unseen withdraw count".to_owned()), + ) + }) + } +} #[cfg(test)] mod uniform_tests {