Skip to content

Commit 3b784b0

Browse files
committed
Test is working
1 parent 444f904 commit 3b784b0

File tree

1 file changed

+108
-67
lines changed

1 file changed

+108
-67
lines changed

crates/op-rbuilder/src/integration/integration_test.rs

+108-67
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,22 @@ mod tests {
77
};
88
use alloy_consensus::{Transaction, TxEip1559};
99
use alloy_eips::{eip1559::MIN_PROTOCOL_BASE_FEE, eip2718::Encodable2718};
10+
use alloy_network::TransactionResponse;
1011
use alloy_primitives::hex;
1112
use alloy_provider::{ext::TxPoolApi, Identity, Provider, ProviderBuilder};
12-
use alloy_rpc_types_eth::BlockTransactionsKind;
13-
use futures_util::StreamExt;
1413
use op_alloy_consensus::OpTypedTransaction;
1514
use op_alloy_network::Optimism;
16-
use std::{
17-
cmp::max,
18-
path::PathBuf,
19-
sync::{Arc, Mutex},
20-
time::Duration,
21-
};
22-
use tokio_tungstenite::connect_async;
15+
use std::{cmp::max, path::PathBuf};
2316
use uuid::Uuid;
2417

18+
/// Key used by builder
2519
const BUILDER_PRIVATE_KEY: &str =
2620
"0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
2721

22+
/// Key used in tests, so builder txs won't affect them
23+
const CUSTOM_PRIVATE_KEY: &str =
24+
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
25+
2826
#[tokio::test]
2927
#[cfg(not(feature = "flashblocks"))]
3028
async fn integration_test_chain_produces_blocks() -> eyre::Result<()> {
@@ -97,6 +95,7 @@ mod tests {
9795
Ok(())
9896
}
9997

98+
/// Caution: this test could be brittle to change because of queued pool checks
10099
#[tokio::test]
101100
#[cfg(not(feature = "flashblocks"))]
102101
async fn integration_test_revert_protection() -> eyre::Result<()> {
@@ -149,86 +148,128 @@ mod tests {
149148
MIN_PROTOCOL_BASE_FEE,
150149
);
151150
for _ in 0..10 {
151+
// We check queued pool to see if it already has tx we sent earlier
152+
// We do this in the beginning, because once we insert valid tx the queued tx would move
153+
// to pending pool, because nonce gap would be fixed.
154+
let mut queued_hash = None;
155+
let mut pool_content = provider.txpool_content().await?;
156+
if !pool_content.queued.is_empty() {
157+
// We are on the non-first, so we have 1 tx in queue pool
158+
assert_eq!(
159+
pool_content.queued.len(),
160+
1,
161+
"Queued pool should contain only 1 transaction"
162+
);
163+
queued_hash = Some(
164+
pool_content
165+
.queued
166+
.pop_first()
167+
.unwrap()
168+
.1
169+
.pop_first()
170+
.unwrap()
171+
.1
172+
.tx_hash(),
173+
);
174+
}
175+
176+
let known_wallet = Signer::try_from_secret(CUSTOM_PRIVATE_KEY.parse()?)?;
152177
// Get builder's address
153-
let known_wallet = Signer::try_from_secret(BUILDER_PRIVATE_KEY.parse()?)?;
154-
let builder_address = known_wallet.address;
178+
let custom_address = known_wallet.address;
155179
// Get current nonce from chain
156-
let nonce = provider.get_transaction_count(builder_address).await?;
157-
// Transaction from builder should succeed
158-
let tx_request = OpTypedTransaction::Eip1559(TxEip1559 {
159-
chain_id: 901,
160-
nonce,
161-
gas_limit: 210000,
162-
max_fee_per_gas: base_fee.into(),
163-
..Default::default()
164-
});
165-
let signed_tx = known_wallet.sign_tx(tx_request)?;
166-
let known_tx = provider
167-
.send_raw_transaction(signed_tx.encoded_2718().as_slice())
168-
.await?;
169-
170-
// Create a reverting transaction
171-
let tx_request = OpTypedTransaction::Eip1559(TxEip1559 {
172-
chain_id: 901,
173-
nonce: nonce + 1,
174-
gas_limit: 300000,
175-
max_fee_per_gas: base_fee.into(),
176-
input: hex!("60006000fd").into(), // PUSH1 0x00 PUSH1 0x00 REVERT
177-
..Default::default()
178-
});
179-
let signed_tx = known_wallet.sign_tx(tx_request)?;
180-
let reverting_tx = provider
181-
.send_raw_transaction(signed_tx.encoded_2718().as_slice())
182-
.await?;
183-
184-
// Create a second reverting transaction
185-
let tx_request = OpTypedTransaction::Eip1559(TxEip1559 {
186-
chain_id: 901,
187-
nonce: nonce + 2,
188-
gas_limit: 300000,
189-
max_fee_per_gas: base_fee.into(),
190-
input: hex!("60006000fd").into(), // PUSH1 0x00 PUSH1 0x00 REVERT
191-
..Default::default()
192-
});
193-
let signed_tx = known_wallet.sign_tx(tx_request)?;
194-
let reverting_tx_2 = provider
195-
.send_raw_transaction(signed_tx.encoded_2718().as_slice())
196-
.await?;
197-
198-
// Before block we should have 3 txs in pool, because they all valid
180+
let nonce = provider.get_transaction_count(custom_address).await?;
181+
182+
// Send valid tx that must be included in the block
183+
let valid_tx = {
184+
let tx_request = OpTypedTransaction::Eip1559(TxEip1559 {
185+
chain_id: 901,
186+
nonce,
187+
gas_limit: 210000,
188+
max_fee_per_gas: base_fee.into(),
189+
..Default::default()
190+
});
191+
let signed_tx = known_wallet.sign_tx(tx_request)?;
192+
let known_tx = provider
193+
.send_raw_transaction(signed_tx.encoded_2718().as_slice())
194+
.await?;
195+
known_tx.tx_hash().to_owned()
196+
};
197+
198+
// If we don't have reverting tx in the queued pool we send one. This send occurs only
199+
// on first cycle iteration
200+
let revert_tx_1 = if queued_hash.is_none() {
201+
// Reverting tx that would be removed
202+
let tx_request = OpTypedTransaction::Eip1559(TxEip1559 {
203+
chain_id: 901,
204+
nonce: nonce + 1,
205+
gas_limit: 300000,
206+
max_fee_per_gas: base_fee.into(),
207+
input: hex!("60006000fd").into(), // PUSH1 0x00 PUSH1 0x00 REVERT
208+
..Default::default()
209+
});
210+
let signed_tx = known_wallet.sign_tx(tx_request)?;
211+
let reverting_tx = provider
212+
.send_raw_transaction(signed_tx.encoded_2718().as_slice())
213+
.await?;
214+
reverting_tx.tx_hash().to_owned()
215+
} else {
216+
queued_hash.unwrap()
217+
};
218+
219+
// We send second reverting tx
220+
let revert_tx_2 = {
221+
// Reverting tx that would be places in queue pool, then it would be placed in the
222+
// pending pool in the next interation (after the nonce gap is fixed be sending
223+
// valid tx) and removed
224+
let tx_request = OpTypedTransaction::Eip1559(TxEip1559 {
225+
chain_id: 901,
226+
nonce: nonce + 2,
227+
gas_limit: 300000,
228+
max_fee_per_gas: base_fee.into(),
229+
input: hex!("60006000fd").into(), // PUSH1 0x00 PUSH1 0x00 REVERT
230+
..Default::default()
231+
});
232+
let signed_tx = known_wallet.sign_tx(tx_request)?;
233+
let reverting_tx_2 = provider
234+
.send_raw_transaction(signed_tx.encoded_2718().as_slice())
235+
.await?;
236+
reverting_tx_2.tx_hash().to_owned()
237+
};
238+
239+
// All txs should be in pending pool.
240+
// 2 cases:
241+
// - we sent all 3 txs
242+
// - we sent 2 txs and one got promoted from queue pool
199243
let pool = provider.txpool_status().await?;
200244
assert_eq!(pool.pending, 3, "all txs should be in pending pool");
201245
assert_eq!(pool.queued, 0, "queued pool should be empty");
202246

203247
let block_hash = generator.generate_block().await?;
204248

205-
// TODO: uncomment once reth issue is addressed https://github.com/paradigmxyz/reth/issues/15973
206249
// After block is produced we will remove one of the reverting txs and place another
207250
// in queue pool because we have nonce gap
208-
// let pool = provider.txpool_status().await?;
209-
// assert_eq!(pool.pending, 0, "pending pool should be empty");
210-
// assert_eq!(pool.queued, 1, "queued pool should contain 1 tx");
251+
let pool = provider.txpool_status().await?;
252+
assert_eq!(pool.pending, 0, "pending pool should be empty");
253+
assert_eq!(pool.queued, 1, "queued pool should contain 1 tx");
211254

212255
// query the block and the transactions inside the block
213256
let block = provider
214257
.get_block_by_hash(block_hash)
215258
.await?
216259
.expect("block");
217260

218-
// Verify known transaction is included
261+
// Verify valid transaction is included
219262
assert!(
220-
block
221-
.transactions
222-
.hashes()
223-
.any(|hash| hash == *known_tx.tx_hash()),
263+
block.transactions.hashes().any(|hash| hash == *valid_tx),
224264
"successful transaction missing from block"
225265
);
226266

227-
// Verify reverted transactions are NOT included
267+
// Verify reverting transactions are NOT included
228268
assert!(
229-
!block.transactions.hashes().any(
230-
|hash| hash == *reverting_tx.tx_hash() || hash == *reverting_tx_2.tx_hash()
231-
),
269+
!block
270+
.transactions
271+
.hashes()
272+
.any(|hash| hash == *revert_tx_1 || hash == *revert_tx_2),
232273
"reverted transaction unexpectedly included in block"
233274
);
234275
for hash in block.transactions.hashes() {

0 commit comments

Comments
 (0)