Skip to content

Commit 8c87a6c

Browse files
committed
add AccountInfoLookup trait + fix check latest nonce
1 parent 4f8afcb commit 8c87a6c

File tree

1 file changed

+31
-8
lines changed

1 file changed

+31
-8
lines changed

crates/ingress-rpc/src/service.rs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use alloy_consensus::Typed2718;
22
use alloy_consensus::constants::KECCAK_EMPTY;
33
use alloy_consensus::{Transaction, transaction::SignerRecoverable};
4-
use alloy_primitives::{Address, B256, Bytes, address};
4+
use alloy_primitives::{Address, B256, Bytes, U256, address};
55
use alloy_provider::network::eip2718::Decodable2718;
66
use alloy_provider::{Provider, RootProvider};
77
use alloy_rpc_types_mev::{EthBundleHash, EthCancelBundle, EthSendBundle};
@@ -22,6 +22,27 @@ use crate::queue::QueuePublisher;
2222
// reference: https://github.com/paradigmxyz/reth/blob/bdc59799d0651133d8b191bbad62746cb5036595/crates/optimism/txpool/src/supervisor/access_list.rs#L39
2323
const CROSS_L2_INBOX_ADDRESS: Address = address!("0x4200000000000000000000000000000000000022");
2424

25+
pub struct AccountInfo {
26+
pub balance: U256,
27+
pub nonce: u64,
28+
pub code_hash: B256,
29+
}
30+
31+
pub trait AccountInfoLookup {
32+
async fn fetch_account_info(&self, address: Address) -> Result<AccountInfo>;
33+
}
34+
35+
impl AccountInfoLookup for RootProvider<Optimism> {
36+
async fn fetch_account_info(&self, address: Address) -> Result<AccountInfo> {
37+
let account = self.get_account(address).await?;
38+
Ok(AccountInfo {
39+
balance: account.balance,
40+
nonce: account.nonce,
41+
code_hash: account.code_hash,
42+
})
43+
}
44+
}
45+
2546
#[rpc(server, namespace = "eth")]
2647
pub trait IngressApi {
2748
/// `eth_sendBundle` can be used to send your bundles to the builder.
@@ -54,7 +75,7 @@ impl<Queue> IngressService<Queue> {
5475

5576
async fn validate_tx(&self, envelope: &OpTxEnvelope) -> Result<()> {
5677
let sender = envelope.recover_signer().unwrap_or_default();
57-
let account = self.provider.get_account(sender).await.unwrap_or_default();
78+
let account = self.provider.fetch_account_info(sender).await?;
5879

5980
// skip eip4844 transactions
6081
if envelope.is_eip4844() {
@@ -73,22 +94,24 @@ impl<Queue> IngressService<Queue> {
7394
}
7495
}
7596

76-
// check account bytecode to see if the account is 7702 then is the tx 7702
77-
if account.code_hash != KECCAK_EMPTY && envelope.is_eip7702() {
97+
// error if account is 7702 but tx is not 7702
98+
if account.code_hash != KECCAK_EMPTY && !envelope.is_eip7702() {
7899
return Err(anyhow::anyhow!(
79100
"Account is a 7702 account but transaction is not EIP-7702"
80101
));
81102
}
82103

83-
// check if nonce is the latest
84-
if account.nonce < envelope.nonce() {
104+
// error if tx nonce is not the latest
105+
if envelope.nonce() != account.nonce - 1 {
85106
return Err(anyhow::anyhow!("Nonce is not the latest"));
86107
}
87108

88-
// check if execution cost <= balance
89-
if account.balance < envelope.value() {
109+
// error if execution cost costs more than balance
110+
if envelope.value() > account.balance {
90111
return Err(anyhow::anyhow!("Insufficient funds"));
91112
}
113+
114+
// TODO: op-checks (l1 block info, l1 balance > execution + DA fee)
92115
Ok(())
93116
}
94117
}

0 commit comments

Comments
 (0)