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

chore(mempool): add transaction queue content #886

Closed
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
8 changes: 7 additions & 1 deletion crates/mempool/src/transaction_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ use starknet_api::transaction::{

use crate::mempool::TransactionReference;

#[cfg(test)]
#[path = "transaction_queue_test_utils.rs"]
pub mod transaction_queue_test_utils;

type AddressToTransactionReference = HashMap<ContractAddress, TransactionReference>;

// A queue holding the transaction that with nonces that match account nonces.
// Note: the derived comparison functionality considers the order guaranteed by the data structures
// used.
Expand All @@ -23,7 +29,7 @@ pub struct TransactionQueue {
// Transactions with gas price below gas price threshold (sorted by price).
pending_queue: BTreeSet<PendingTransaction>,
// Set of account addresses for efficient existence checks.
address_to_tx: HashMap<ContractAddress, TransactionReference>,
address_to_tx: AddressToTransactionReference,
}

impl TransactionQueue {
Expand Down
108 changes: 108 additions & 0 deletions crates/mempool/src/transaction_queue_test_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use std::collections::{BTreeSet, HashMap};

use pretty_assertions::assert_eq;

use crate::mempool::TransactionReference;
use crate::transaction_queue::{
AddressToTransactionReference,
PendingTransaction,
PriorityTransaction,
TransactionQueue,
};

/// Represents the internal content of the transaction queue.
/// Enables customized (and potentially inconsistent) creation for unit testing.
/// Note: gas price threshold is only used for builing the queue (non-test) struct.
#[derive(Debug, Default)]
pub struct TransactionQueueContent {
priority_queue: Option<BTreeSet<PriorityTransaction>>,
pending_queue: Option<BTreeSet<PendingTransaction>>,
address_to_tx: Option<AddressToTransactionReference>,
gas_price_threshold: Option<u128>,
}

impl TransactionQueueContent {
pub fn _assert_eq_priority_queue_and_pending_queue_content(&self, tx_queue: &TransactionQueue) {
assert_eq!(self.priority_queue.as_ref().unwrap(), &tx_queue.priority_queue);
assert_eq!(self.pending_queue.as_ref().unwrap(), &tx_queue.pending_queue);
assert_eq!(self.address_to_tx.as_ref().unwrap(), &tx_queue.address_to_tx);
}

pub fn _assert_eq_priority_queue_content(&self, tx_queue: &TransactionQueue) {
assert_eq!(self.priority_queue.as_ref().unwrap(), &tx_queue.priority_queue);
assert_eq!(self.address_to_tx.as_ref().unwrap(), &tx_queue.address_to_tx);
}

pub fn _assert_eq_pending_queue_content(&self, tx_queue: &TransactionQueue) {
assert_eq!(self.pending_queue.as_ref().unwrap(), &tx_queue.pending_queue);
assert_eq!(self.address_to_tx.as_ref().unwrap(), &tx_queue.address_to_tx);
}
}

#[derive(Debug, Default)]
pub struct TransactionQueueContentBuilder {
_priority_queue: Option<BTreeSet<PriorityTransaction>>,
_pending_queue: Option<BTreeSet<PendingTransaction>>,
_address_to_tx: Option<AddressToTransactionReference>,
_gas_price_threshold: Option<u128>,
}

impl TransactionQueueContentBuilder {
pub fn _with_priority<P>(mut self, priority_txs: P) -> Self
where
P: IntoIterator<Item = TransactionReference>,
{
let priority_txs: Vec<TransactionReference> = priority_txs.into_iter().collect();

self._address_to_tx.get_or_insert_with(HashMap::new).extend(
priority_txs.iter().map(|tx_reference| (tx_reference.sender_address, *tx_reference)),
);
self._priority_queue =
Some(priority_txs.into_iter().map(PriorityTransaction::from).collect());
self
}

pub fn _with_pending<P>(mut self, pending_txs: P) -> Self
where
P: IntoIterator<Item = TransactionReference>,
{
let pending_txs: Vec<TransactionReference> = pending_txs.into_iter().collect();

self._address_to_tx.get_or_insert_with(HashMap::new).extend(
pending_txs.iter().map(|tx_reference| (tx_reference.sender_address, *tx_reference)),
);
self._pending_queue = Some(pending_txs.into_iter().map(PendingTransaction::from).collect());
self
}

pub fn _with_gas_price_threshold(mut self, gas_price_threshold: u128) -> Self {
self._gas_price_threshold = Some(gas_price_threshold);
self
}

pub fn _build(self) -> TransactionQueueContent {
TransactionQueueContent {
priority_queue: self._priority_queue,
pending_queue: self._pending_queue,
address_to_tx: self._address_to_tx,
gas_price_threshold: self._gas_price_threshold,
}
}
}

impl From<TransactionQueueContent> for TransactionQueue {
fn from(tx_queue_content: TransactionQueueContent) -> Self {
let TransactionQueueContent {
priority_queue,
pending_queue,
address_to_tx,
gas_price_threshold,
} = tx_queue_content;
TransactionQueue {
priority_queue: priority_queue.unwrap_or_default(),
pending_queue: pending_queue.unwrap_or_default(),
address_to_tx: address_to_tx.unwrap_or_default(),
gas_price_threshold: gas_price_threshold.unwrap_or_default(),
}
}
}
Loading