diff --git a/rollup/src/address.rs b/rollup/src/address.rs index da98ed1..26f1c8c 100644 --- a/rollup/src/address.rs +++ b/rollup/src/address.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; /// A newtype wrapper around an Ethereum address. /// Allows conversion from a public key. -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] pub struct Address(AlloyAddress); impl From for Address { diff --git a/rollup/src/block.rs b/rollup/src/block.rs index 35d50fc..e335d39 100644 --- a/rollup/src/block.rs +++ b/rollup/src/block.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use crate::{Address, Signature, SignedTransaction, Signer}; /// A block header containing metadata about the block. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub struct BlockHeader { /// The address of the sequencer that sealed the block. pub sequencer: Address, @@ -30,7 +30,7 @@ impl BlockHeader { } /// A signed block header containing a block header and a signature. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub struct SignedBlockHeader { header: BlockHeader, signature: Signature, @@ -45,10 +45,10 @@ impl SignedBlockHeader { } /// A block containing a header and a list of transactions. -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, Eq, PartialEq)] pub struct Block { pub(crate) signed: SignedBlockHeader, - transactions: Vec, + pub(crate) transactions: Vec, } impl std::fmt::Debug for Block { diff --git a/rollup/src/blockchain.rs b/rollup/src/blockchain.rs index 1c25c06..7af2695 100644 --- a/rollup/src/blockchain.rs +++ b/rollup/src/blockchain.rs @@ -22,8 +22,8 @@ impl Default for Blockchain { impl Blockchain { /// Returns the head block of the blockchain. - pub(crate) fn head(&self) -> Option<&Block> { - self.blocks.last() + pub(crate) fn head(&self) -> Option { + self.blocks.last().cloned() } /// Returns the height of the blockchain. diff --git a/rollup/src/sequencer.rs b/rollup/src/sequencer.rs index d80703f..81a95c0 100644 --- a/rollup/src/sequencer.rs +++ b/rollup/src/sequencer.rs @@ -83,7 +83,7 @@ impl Sequencer { } /// Returns the head block of the blockchain. - pub fn head(&self) -> Option<&Block> { + pub fn head(&self) -> Option { self.blockchain.head() } } @@ -120,3 +120,32 @@ impl Future for ArcSequencer { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_sequencer() { + // Create a sequencer. + let signer = Signer::random(); + let sequencer = ArcSequencer::new(signer); + let mut sequencer = sequencer.lock().await; + + // Add a transaction to the sequencer. + let transaction = SignedTransaction::new( + Transaction::dynamic(sequencer.signer.address, 100), + &sequencer.signer, + ); + sequencer.add_transaction(transaction.clone()); + + // Seal the block. + let block = sequencer.seal(); + + // Validate the block. + assert_eq!(block.transactions.len(), 1); + assert_eq!(block.transactions[0], transaction); + assert_eq!(sequencer.head().unwrap(), block); + assert!(block.verify()); + } +} diff --git a/rollup/src/signer.rs b/rollup/src/signer.rs index 3c2997b..77aa2b8 100644 --- a/rollup/src/signer.rs +++ b/rollup/src/signer.rs @@ -10,7 +10,7 @@ use std::str::FromStr; use crate::Address; /// A recoverable seckp256k1 signature. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub struct Signature { /// The r component of the signature. pub r: U256, diff --git a/rollup/src/transaction.rs b/rollup/src/transaction.rs index 2a6b8c8..6067f7c 100644 --- a/rollup/src/transaction.rs +++ b/rollup/src/transaction.rs @@ -6,7 +6,7 @@ use crate::signer::{Signature, Signer}; use crate::{Address, CHAIN_ID}; /// A transaction header containing metadata about the transaction. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub struct TransactionHeader { /// The identifier of the chain on which the transaction was intended to be executed. chain_id: u64, @@ -19,7 +19,7 @@ pub struct TransactionHeader { } /// A dynamic transaction containing a transaction header and dynamic fee data. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub struct DynamicTxData { /// The transaction header. header: TransactionHeader, @@ -38,7 +38,7 @@ impl DynamicTxData { } /// A withdrawal transaction containing a transaction header and destination. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub struct WithdrawalTxData { /// The transaction header. header: TransactionHeader, @@ -55,7 +55,7 @@ impl WithdrawalTxData { } /// A transaction containing either dynamic or withdrawal transaction data. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub enum Transaction { Dynamic(DynamicTxData), Withdrawal(WithdrawalTxData), @@ -109,7 +109,7 @@ impl Transaction { } /// A signed transaction containing a transaction and signature. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub struct SignedTransaction { pub transaction: Transaction, pub signature: Signature,