Skip to content

Commit

Permalink
feat: support skip_validate in mempool
Browse files Browse the repository at this point in the history
  • Loading branch information
Yael-Starkware committed Jul 8, 2024
1 parent 871ad40 commit b4e7146
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 0 deletions.
2 changes: 2 additions & 0 deletions crates/mempool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ derive_more.workspace = true
starknet_mempool_infra = { path = "../mempool_infra", version = "0.0" }
starknet_api.workspace = true
starknet_mempool_types = { path = "../mempool_types", version = "0.0" }
starknet-types-core.workspace = true

tokio.workspace = true

[dev-dependencies]
Expand Down
24 changes: 24 additions & 0 deletions crates/mempool/src/mempool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ use std::collections::HashMap;

use starknet_api::core::{ContractAddress, Nonce};
use starknet_api::transaction::{Tip, TransactionHash};
use starknet_mempool_types::errors::MempoolError;
use starknet_mempool_types::mempool_types::{
AccountState, MempoolInput, MempoolResult, ThinTransaction,
};
use starknet_types_core::felt::Felt;

use crate::transaction_pool::TransactionPool;
use crate::transaction_queue::TransactionQueue;
Expand Down Expand Up @@ -78,13 +80,35 @@ impl Mempool {
fn insert_tx(&mut self, input: MempoolInput) -> MempoolResult<()> {
let tx = input.tx;
let tx_reference = TransactionReference::new(&tx);
self.has_deploy_account_tx(&tx, input.account.state.nonce)?;

self.tx_pool.insert(tx)?;
// FIXME: Check nonce before adding!
self.tx_queue.insert(tx_reference);

Ok(())
}

pub fn has_deploy_account_tx(
&self,
tx: &ThinTransaction,
account_nonce: Nonce,
) -> MempoolResult<()> {
// If tx nonce = 1 and account nonce = 0, the gateway have skipped validations and this
// means that the account may not have been deployed yet and we need to check it now.
// TODO(Yael 8/7/2024): This is only relevant for invoke tx, check the type once available.
if tx.nonce == Nonce(Felt::ONE) && account_nonce == Nonce(Felt::ZERO) {
match self.tx_pool.get_by_account(tx.sender_address, Nonce(Felt::ZERO)).is_some() {
true => return Ok(()),
false => {
return Err(MempoolError::UndeployedAccount {
sender_address: tx.sender_address,
});
}
}
}
Ok(())
}
}

/// Provides a lightweight representation of a transaction for mempool usage (e.g., excluding
Expand Down
28 changes: 28 additions & 0 deletions crates/mempool/src/mempool_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use starknet_types_core::felt::Felt;

use crate::mempool::{Mempool, MempoolInput, TransactionReference};

const TEST_SENDER_ADDRESS: u128 = 0x1000;

#[track_caller]
fn add_tx(mempool: &mut Mempool, input: &MempoolInput) {
assert_eq!(mempool.add_tx(input.clone()), Ok(()));
Expand Down Expand Up @@ -168,3 +170,29 @@ fn test_tip_priority_over_tx_hash(mut mempool: Mempool) {
add_tx(&mut mempool, &input_small_tip_big_hash);
check_mempool_txs_eq(&mempool, &[input_big_tip_small_hash.tx, input_small_tip_big_hash.tx])
}

#[rstest]
#[case::empty_mempool(Mempool::empty())]
#[case::mempool_contains_tx_with_nonce_2(
Mempool::new([add_tx_input!(tip: 0, tx_hash: Felt::ONE,
sender_address: TEST_SENDER_ADDRESS,
nonce: 2_u8)]).unwrap()
)]
// TODO(Yael 7/7/2024) - add case for mempool that contains a transaction with nonce 0, and no error
// is received. This case is not available now since the mempool doesn't supoprt multiple nonces per
// account.
fn test_undeployed_account(#[case] mut mempool: Mempool) {
let input = add_tx_input!(
tip: 0,
tx_hash: Felt::ZERO,
sender_address: TEST_SENDER_ADDRESS,
nonce: 1_u8
);
let result = mempool.add_tx(input.clone());

assert_matches!(
result,
Err(MempoolError::UndeployedAccount { sender_address })
if sender_address == input.tx.sender_address
);
}
3 changes: 3 additions & 0 deletions crates/mempool_types/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use starknet_api::core::ContractAddress;
use starknet_api::transaction::TransactionHash;
use thiserror::Error;

#[derive(Clone, Debug, Error, PartialEq, Eq)]
pub enum MempoolError {
#[error("Duplicate transaction, with hash: {tx_hash}")]
DuplicateTransaction { tx_hash: TransactionHash },
#[error("Undeployed account {:?}", sender_address)]
UndeployedAccount { sender_address: ContractAddress },
#[error("Transaction with hash: {tx_hash} not found")]
TransactionNotFound { tx_hash: TransactionHash },
}

0 comments on commit b4e7146

Please sign in to comment.