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

feat: support skip_validate in mempool #376

Closed
wants to merge 1 commit into from
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
1 change: 1 addition & 0 deletions crates/mempool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ 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::{
Account, AccountState, MempoolInput, MempoolResult, ThinTransaction,
};
use starknet_types_core::felt::Felt;

use crate::transaction_pool::TransactionPool;
use crate::transaction_queue::TransactionQueue;
Expand Down Expand Up @@ -61,6 +63,9 @@ impl Mempool {
/// TODO: support fee escalation and transactions with future nonces.
/// TODO: check Account nonce and balance.
pub fn add_tx(&mut self, input: MempoolInput) -> MempoolResult<()> {
// TODO(Yael 8/7/2024): Consider removing this check and instead add an API for the gateway
// to check if the deploy_account tx exists.
self.should_insert(&input)?;
self.insert_tx(input)
}

Expand Down Expand Up @@ -88,6 +93,25 @@ impl Mempool {
Ok(())
}

pub fn should_insert(&self, input: &MempoolInput) -> MempoolResult<()> {
// If the tx nonce is 1 and the account nonce is 0, the account was not deployed yet and the
// gateway has skipped validations. In this case, we need to verify that a deploy_account
// transaction exists for this account. It is suficient to check if the account exists in
// the mempool since it means that either it has a deploy_account transaction or
// transactions with future nonces that passed validations.
// TODO(Yael 8/7/2024): Consider instead of checking the nonces, get a value from the
// gateway that indicates that the mempool needs to check the deploy_account existence.
if input.tx.nonce == Nonce(Felt::ONE)
&& input.account.state.nonce == Nonce(Felt::ZERO)
&& !self.tx_pool.contains_address(input.tx.sender_address)
{
return Err(MempoolError::UndeployedAccount {
sender_address: input.tx.sender_address,
});
}
Ok(())
}

#[cfg(test)]
pub(crate) fn _tx_pool(&self) -> &TransactionPool {
&self.tx_pool
Expand Down
29 changes: 29 additions & 0 deletions crates/mempool/src/mempool_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ impl FromIterator<TransactionReference> for TransactionQueue {
}
}

const TEST_SENDER_ADDRESS: u8 = 0x1;

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

#[rstest]
#[case::empty_mempool(Mempool::empty())]
#[case::mempool_contains_another_address(Mempool::new([
add_tx_input!(tip: 0, tx_hash: 1, sender_address: 0x2345_u16, tx_nonce: 2_u8, account_nonce: 0_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: 0,
sender_address: TEST_SENDER_ADDRESS,
tx_nonce: 1_u8,
account_nonce: 0_u8
);
let result = mempool.add_tx(input.clone());

assert_eq!(
result,
Err(MempoolError::UndeployedAccount {
sender_address: contract_address!(TEST_SENDER_ADDRESS)
})
);
}
12 changes: 4 additions & 8 deletions crates/mempool/src/transaction_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,8 @@ impl TransactionPool {
self.tx_pool.get(&tx_hash).ok_or(MempoolError::TransactionNotFound { tx_hash })
}

pub fn get_by_address_and_nonce(
&self,
address: ContractAddress,
nonce: Nonce,
) -> Option<&TransactionReference> {
self.txs_by_account.get(address, nonce)
pub fn contains_address(&self, address: ContractAddress) -> bool {
self.txs_by_account.contains(address)
}

#[cfg(test)]
Expand Down Expand Up @@ -101,7 +97,7 @@ impl AccountTransactionIndex {
removed_tx
}

fn get(&self, address: ContractAddress, nonce: Nonce) -> Option<&TransactionReference> {
self.0.get(&address)?.get(&nonce)
fn contains(&self, address: ContractAddress) -> bool {
self.0.contains_key(&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 },
}
Loading