Skip to content

Commit

Permalink
fix test_out_of_order_mempool
Browse files Browse the repository at this point in the history
  • Loading branch information
LePremierHomme committed Jan 13, 2025
1 parent d841316 commit 034c799
Showing 1 changed file with 96 additions and 99 deletions.
195 changes: 96 additions & 99 deletions fendermint/testing/materializer/tests/docker_tests/standalone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0, MIT
use crate::make_testnet;
use anyhow::{bail, Context};
use ethers::prelude::transaction::eip2718::TypedTransaction;
use ethers::{
core::k256::ecdsa::SigningKey,
middleware::SignerMiddleware,
Expand All @@ -10,6 +11,7 @@ use ethers::{
types::{Eip1559TransactionRequest, H160},
};
use fendermint_materializer::{manifest::Rootnet, materials::DefaultAccount, HasEthApi};
use std::time::{Duration, Instant};

const MANIFEST: &str = "standalone.yaml";

Expand Down Expand Up @@ -90,102 +92,97 @@ async fn test_sent_tx_found_in_mempool() -> Result<(), anyhow::Error> {
res
}

// /// Test that transactions sent out-of-order with regards to the nonce are not rejected,
// /// but rather get included in block eventually, their submission managed by the ethereum
// /// API facade.
// #[serial_test::serial]
// #[tokio::test]
// async fn test_out_of_order_mempool() {
// const MAX_WAIT_TIME: Duration = Duration::from_secs(10);
// const SLEEP_TIME: Duration = Duration::from_secs(1);
//
// with_testnet(
// MANIFEST,
// None,
// |_| {},
// |_, _, testnet, _| {
// let test = async move {
// let bob = testnet.account("bob")?;
// let charlie = testnet.account("charlie")?;
//
// let pangea = testnet.node(&testnet.root().node("pangea"))?;
// let provider = pangea
// .ethapi_http_provider()?
// .expect("ethapi should be enabled");
//
// let middleware = make_middleware(provider, bob)
// .await
// .context("failed to set up middleware")?;
//
// // Create the simplest transaction possible: send tokens between accounts.
// let to: H160 = charlie.eth_addr().into();
// let tx = Eip1559TransactionRequest::new().to(to).value(1);
// let mut tx: TypedTransaction = tx.into();
//
// // Fill out the nonce, gas, etc.
// middleware
// .fill_transaction(&mut tx, None)
// .await
// .context("failed to fill tx")?;
//
// // Create a few more transactions to be sent out-of-order.
// let mut txs = vec![tx];
//
// for i in 1..5 {
// let mut tx = txs[0].clone();
// let nonce = tx.nonce().expect("fill_transaction filled the nonce");
// tx.set_nonce(nonce.saturating_add(i.into()));
// txs.push(tx)
// }
//
// let mut pending_txs = Vec::new();
//
// // Submit transactions in opposite order.
// for (i, tx) in txs.iter().enumerate().rev() {
// let sig = middleware
// .signer()
// .sign_transaction(tx)
// .await
// .context("failed to sign tx")?;
//
// let rlp = tx.rlp_signed(&sig);
//
// let pending_tx: PendingTransaction<_> = middleware
// .send_raw_transaction(rlp)
// .await
// .with_context(|| format!("failed to send tx {i}"))?;
//
// pending_txs.push(pending_tx)
// }
//
// // Check that they eventually get included.
// let start = Instant::now();
// 'pending: loop {
// for tx in pending_txs.iter() {
// let receipt = middleware
// .get_transaction_receipt(tx.tx_hash())
// .await
// .context("failed to get receipt")?;
//
// if receipt.is_none() {
// if start.elapsed() > MAX_WAIT_TIME {
// bail!("some transactions are still not executed")
// } else {
// tokio::time::sleep(SLEEP_TIME).await;
// continue 'pending;
// }
// }
// }
// // All of them have receipt.
// break 'pending;
// }
//
// Ok(())
// };
//
// test.boxed()
// },
// )
// .await
// .unwrap()
// }
/// Test that transactions sent out-of-order with regards to the nonce are not rejected,
/// but rather get included in block eventually, their submission managed by the ethereum
/// API facade.
#[serial_test::serial]
#[tokio::test]
async fn test_out_of_order_mempool() {
const MAX_WAIT_TIME: Duration = Duration::from_secs(10);
const SLEEP_TIME: Duration = Duration::from_secs(1);

let (testnet, cleanup) = make_testnet(MANIFEST, |_| {}).await.unwrap();

let res = async {
let bob = testnet.account("bob")?;
let charlie = testnet.account("charlie")?;

let pangea = testnet.node(&testnet.root().node("pangea"))?;
let provider = pangea
.ethapi_http_provider()?
.expect("ethapi should be enabled");

let middleware = make_middleware(provider, bob)
.await
.context("failed to set up middleware")?;

// Create the simplest transaction possible: send tokens between accounts.
let to: H160 = charlie.eth_addr().into();
let tx = Eip1559TransactionRequest::new().to(to).value(1);
let mut tx: TypedTransaction = tx.into();

// Fill out the nonce, gas, etc.
middleware
.fill_transaction(&mut tx, None)
.await
.context("failed to fill tx")?;

// Create a few more transactions to be sent out-of-order.
let mut txs = vec![tx];

for i in 1..5 {
let mut tx = txs[0].clone();
let nonce = tx.nonce().expect("fill_transaction filled the nonce");
tx.set_nonce(nonce.saturating_add(i.into()));
txs.push(tx)
}

let mut pending_txs = Vec::new();

// Submit transactions in opposite order.
for (i, tx) in txs.iter().enumerate().rev() {
let sig = middleware
.signer()
.sign_transaction(tx)
.await
.context("failed to sign tx")?;

let rlp = tx.rlp_signed(&sig);

let pending_tx: PendingTransaction<_> = middleware
.send_raw_transaction(rlp)
.await
.with_context(|| format!("failed to send tx {i}"))?;

pending_txs.push(pending_tx)
}

// Check that they eventually get included.
let start = Instant::now();
'pending: loop {
for tx in pending_txs.iter() {
let receipt = middleware
.get_transaction_receipt(tx.tx_hash())
.await
.context("failed to get receipt")?;

if receipt.is_none() {
if start.elapsed() > MAX_WAIT_TIME {
bail!("some transactions are still not executed")
} else {
tokio::time::sleep(SLEEP_TIME).await;
continue 'pending;
}
}
}
// All of them have receipt.
break 'pending;
}

Ok(())
};

let res = res.await;
cleanup(res.is_err(), testnet).await;
res.unwrap()
}

0 comments on commit 034c799

Please sign in to comment.