From 70b31856e9a86cc8655dcbae1553466e0aa84eff Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Mon, 28 Jul 2025 15:21:35 -0300 Subject: [PATCH] wip --- sequencer_core/src/lib.rs | 47 +++++++++++++++++-- .../src/sequencer_store/accounts_store.rs | 26 +++++++++- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index bfde1f6..ad4d551 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -262,15 +262,15 @@ impl SequencerCore { self.store.block_store.put_block_at_id(block)?; - self.chain_height += 1; + self.chain_height = new_block_height; - Ok(self.chain_height - 1) + Ok(self.chain_height) } } #[cfg(test)] mod tests { - use crate::config::AccountInitialData; + use crate::{config::AccountInitialData, sequencer_store::accounts_store}; use super::*; use std::path::PathBuf; @@ -521,6 +521,7 @@ mod tests { fn test_produce_new_block_with_mempool_transactions() { let config = setup_sequencer_config(); let mut sequencer = SequencerCore::start_from_config(config); + let genesis_height = sequencer.chain_height; let tx = create_dummy_transaction(vec![[94; 32]], vec![[7; 32]], vec![[8; 32]]); let tx_mempool = MempoolTransaction { @@ -530,6 +531,44 @@ mod tests { let block_id = sequencer.produce_new_block_with_mempool_transactions(); assert!(block_id.is_ok()); - assert_eq!(block_id.unwrap(), 1); + assert_eq!(block_id.unwrap(), genesis_height + 1); + } + + #[test] + fn test_replay_transactions_are_rejected() { + let config = setup_sequencer_config(); + let mut sequencer = SequencerCore::start_from_config(config); + + let tx = create_dummy_transaction(vec![[94; 32]], vec![[7; 32]], vec![[8; 32]]); + + // The transaction should be included the first time + let tx_mempool_original = MempoolTransaction { + auth_tx: tx.clone().into_authenticated().unwrap(), + }; + sequencer.mempool.push_item(tx_mempool_original); + let current_height = sequencer + .produce_new_block_with_mempool_transactions() + .unwrap(); + let block = sequencer + .store + .block_store + .get_block_at_id(current_height) + .unwrap(); + assert_eq!(block.transactions, vec![tx.clone()]); + + // Add same transaction should fail + let tx_mempool_replay = MempoolTransaction { + auth_tx: tx.into_authenticated().unwrap(), + }; + sequencer.mempool.push_item(tx_mempool_replay); + let current_height = sequencer + .produce_new_block_with_mempool_transactions() + .unwrap(); + let block = sequencer + .store + .block_store + .get_block_at_id(current_height) + .unwrap(); + assert!(block.transactions.is_empty()); } } diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs index 7d64491..e955a9f 100644 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ b/sequencer_core/src/sequencer_store/accounts_store.rs @@ -7,18 +7,28 @@ use std::collections::HashMap; pub(crate) struct AccountPublicData { pub balance: u64, pub address: AccountAddress, + nonce: u64, } impl AccountPublicData { pub fn new(address: AccountAddress) -> Self { Self { balance: 0, + nonce: 0, address, } } fn new_with_balance(address: AccountAddress, balance: u64) -> Self { - Self { balance, address } + Self { + balance, + address, + nonce: 0, + } + } + + fn nonce(&self) -> u64 { + self.nonce } } @@ -110,6 +120,13 @@ mod tests { assert_eq!(new_acc.address, [1; 32]); } + #[test] + fn test_zero_nonce_account_data_creation() { + let new_acc = AccountPublicData::new([1; 32]); + + assert_eq!(new_acc.nonce, 0); + } + #[test] fn test_non_zero_balance_account_data_creation() { let new_acc = AccountPublicData::new_with_balance([1; 32], 10); @@ -118,6 +135,13 @@ mod tests { assert_eq!(new_acc.address, [1; 32]); } + #[test] + fn test_zero_nonce_account_data_creation_with_balance() { + let new_acc = AccountPublicData::new_with_balance([1; 32], 10); + + assert_eq!(new_acc.nonce, 0); + } + #[test] fn default_account_sequencer_store() { let seq_acc_store = SequencerAccountsStore::default();