mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: integrate OpPrimitives (#13556)
This commit is contained in:
@ -15,6 +15,7 @@ workspace = true
|
||||
# reth
|
||||
reth-evm.workspace = true
|
||||
reth-primitives.workspace = true
|
||||
reth-primitives-traits.workspace = true
|
||||
reth-provider.workspace = true
|
||||
reth-rpc-eth-api.workspace = true
|
||||
reth-rpc-eth-types.workspace = true
|
||||
|
||||
@ -7,7 +7,9 @@ use op_alloy_rpc_types::OpTransactionReceipt;
|
||||
use reth_chainspec::ChainSpecProvider;
|
||||
use reth_node_api::BlockBody;
|
||||
use reth_optimism_chainspec::OpChainSpec;
|
||||
use reth_primitives::{Receipt, TransactionMeta, TransactionSigned};
|
||||
use reth_optimism_primitives::{OpReceipt, OpTransactionSigned};
|
||||
use reth_primitives::TransactionMeta;
|
||||
use reth_primitives_traits::SignedTransaction;
|
||||
use reth_provider::{BlockReader, HeaderProvider};
|
||||
use reth_rpc_eth_api::{
|
||||
helpers::{EthBlocks, LoadBlock, LoadPendingBlock, LoadReceipt, SpawnBlocking},
|
||||
@ -21,7 +23,7 @@ where
|
||||
Self: LoadBlock<
|
||||
Error = OpEthApiError,
|
||||
NetworkTypes: Network<ReceiptResponse = OpTransactionReceipt>,
|
||||
Provider: BlockReader<Receipt = Receipt, Transaction = TransactionSigned>,
|
||||
Provider: BlockReader<Receipt = OpReceipt, Transaction = OpTransactionSigned>,
|
||||
>,
|
||||
N: OpNodeCore<Provider: ChainSpecProvider<ChainSpec = OpChainSpec> + HeaderProvider>,
|
||||
{
|
||||
@ -50,7 +52,7 @@ where
|
||||
.enumerate()
|
||||
.map(|(idx, (tx, receipt))| -> Result<_, _> {
|
||||
let meta = TransactionMeta {
|
||||
tx_hash: tx.hash(),
|
||||
tx_hash: *tx.tx_hash(),
|
||||
index: idx as u64,
|
||||
block_hash,
|
||||
block_number,
|
||||
|
||||
@ -2,15 +2,18 @@
|
||||
|
||||
use crate::OpEthApi;
|
||||
use alloy_consensus::{
|
||||
constants::EMPTY_WITHDRAWALS, proofs::calculate_transaction_root, Header, EMPTY_OMMER_ROOT_HASH,
|
||||
constants::EMPTY_WITHDRAWALS, proofs::calculate_transaction_root, Eip658Value, Header,
|
||||
Transaction as _, TxReceipt, EMPTY_OMMER_ROOT_HASH,
|
||||
};
|
||||
use alloy_eips::{eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE, BlockNumberOrTag};
|
||||
use alloy_primitives::{B256, U256};
|
||||
use op_alloy_consensus::{OpDepositReceipt, OpTxType};
|
||||
use op_alloy_network::Network;
|
||||
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
||||
use reth_evm::ConfigureEvm;
|
||||
use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism;
|
||||
use reth_primitives::{logs_bloom, BlockBody, Receipt, SealedBlockWithSenders, TransactionSigned};
|
||||
use reth_optimism_primitives::{OpBlock, OpReceipt, OpTransactionSigned};
|
||||
use reth_primitives::{logs_bloom, BlockBody, SealedBlockWithSenders};
|
||||
use reth_provider::{
|
||||
BlockReader, BlockReaderIdExt, ChainSpecProvider, ProviderBlock, ProviderHeader,
|
||||
ProviderReceipt, ProviderTx, ReceiptProvider, StateProviderFactory,
|
||||
@ -33,14 +36,17 @@ where
|
||||
>,
|
||||
N: RpcNodeCore<
|
||||
Provider: BlockReaderIdExt<
|
||||
Transaction = reth_primitives::TransactionSigned,
|
||||
Block = reth_primitives::Block,
|
||||
Receipt = reth_primitives::Receipt,
|
||||
Transaction = OpTransactionSigned,
|
||||
Block = OpBlock,
|
||||
Receipt = OpReceipt,
|
||||
Header = reth_primitives::Header,
|
||||
> + ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
|
||||
+ StateProviderFactory,
|
||||
Pool: TransactionPool<Transaction: PoolTransaction<Consensus = ProviderTx<N::Provider>>>,
|
||||
Evm: ConfigureEvm<Header = Header, Transaction = TransactionSigned>,
|
||||
Evm: ConfigureEvm<
|
||||
Header = ProviderHeader<Self::Provider>,
|
||||
Transaction = ProviderTx<Self::Provider>,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
#[inline]
|
||||
@ -55,7 +61,13 @@ where
|
||||
/// Returns the locally built pending block
|
||||
async fn local_pending_block(
|
||||
&self,
|
||||
) -> Result<Option<(SealedBlockWithSenders, Vec<Receipt>)>, Self::Error> {
|
||||
) -> Result<
|
||||
Option<(
|
||||
SealedBlockWithSenders<ProviderBlock<Self::Provider>>,
|
||||
Vec<ProviderReceipt<Self::Provider>>,
|
||||
)>,
|
||||
Self::Error,
|
||||
> {
|
||||
// See: <https://github.com/ethereum-optimism/op-geth/blob/f2e69450c6eec9c35d56af91389a1c47737206ca/miner/worker.go#L367-L375>
|
||||
let latest = self
|
||||
.provider()
|
||||
@ -97,7 +109,7 @@ where
|
||||
timestamp,
|
||||
);
|
||||
|
||||
let logs_bloom = logs_bloom(receipts.iter().flat_map(|r| &r.logs));
|
||||
let logs_bloom = logs_bloom(receipts.iter().flat_map(|r| r.logs()));
|
||||
let is_cancun = chain_spec.is_cancun_active_at_timestamp(timestamp);
|
||||
let is_prague = chain_spec.is_prague_active_at_timestamp(timestamp);
|
||||
let is_shanghai = chain_spec.is_shanghai_active_at_timestamp(timestamp);
|
||||
@ -118,7 +130,7 @@ where
|
||||
number: block_env.number.to::<u64>(),
|
||||
gas_limit: block_env.gas_limit.to::<u64>(),
|
||||
difficulty: U256::ZERO,
|
||||
gas_used: receipts.last().map(|r| r.cumulative_gas_used).unwrap_or_default(),
|
||||
gas_used: receipts.last().map(|r| r.cumulative_gas_used()).unwrap_or_default() as u64,
|
||||
blob_gas_used: is_cancun.then(|| {
|
||||
transactions.iter().map(|tx| tx.blob_gas_used().unwrap_or_default()).sum::<u64>()
|
||||
}),
|
||||
@ -142,13 +154,22 @@ where
|
||||
result: ExecutionResult,
|
||||
cumulative_gas_used: u64,
|
||||
) -> reth_provider::ProviderReceipt<Self::Provider> {
|
||||
#[allow(clippy::needless_update)]
|
||||
Receipt {
|
||||
tx_type: tx.tx_type(),
|
||||
success: result.is_success(),
|
||||
cumulative_gas_used,
|
||||
let receipt = alloy_consensus::Receipt {
|
||||
status: Eip658Value::Eip658(result.is_success()),
|
||||
cumulative_gas_used: cumulative_gas_used as u128,
|
||||
logs: result.into_logs().into_iter().collect(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
match tx.tx_type() {
|
||||
OpTxType::Legacy => OpReceipt::Legacy(receipt),
|
||||
OpTxType::Eip2930 => OpReceipt::Eip2930(receipt),
|
||||
OpTxType::Eip1559 => OpReceipt::Eip1559(receipt),
|
||||
OpTxType::Eip7702 => OpReceipt::Eip7702(receipt),
|
||||
OpTxType::Deposit => OpReceipt::Deposit(OpDepositReceipt {
|
||||
inner: receipt,
|
||||
deposit_nonce: None,
|
||||
deposit_receipt_version: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,15 +2,14 @@
|
||||
|
||||
use alloy_eips::eip2718::Encodable2718;
|
||||
use alloy_rpc_types_eth::{Log, TransactionReceipt};
|
||||
use op_alloy_consensus::{
|
||||
DepositTransaction, OpDepositReceipt, OpDepositReceiptWithBloom, OpReceiptEnvelope,
|
||||
};
|
||||
use op_alloy_consensus::{OpDepositReceipt, OpDepositReceiptWithBloom, OpReceiptEnvelope};
|
||||
use op_alloy_rpc_types::{L1BlockInfo, OpTransactionReceipt, OpTransactionReceiptFields};
|
||||
use reth_node_api::{FullNodeComponents, NodeTypes};
|
||||
use reth_optimism_chainspec::OpChainSpec;
|
||||
use reth_optimism_evm::RethL1BlockInfo;
|
||||
use reth_optimism_forks::OpHardforks;
|
||||
use reth_primitives::{Receipt, TransactionMeta, TransactionSigned, TxType};
|
||||
use reth_optimism_primitives::{OpReceipt, OpTransactionSigned};
|
||||
use reth_primitives::TransactionMeta;
|
||||
use reth_provider::{ChainSpecProvider, ReceiptProvider, TransactionsProvider};
|
||||
use reth_rpc_eth_api::{helpers::LoadReceipt, FromEthApiError, RpcReceipt};
|
||||
use reth_rpc_eth_types::{receipt::build_receipt, EthApiError};
|
||||
@ -21,14 +20,14 @@ impl<N> LoadReceipt for OpEthApi<N>
|
||||
where
|
||||
Self: Send + Sync,
|
||||
N: FullNodeComponents<Types: NodeTypes<ChainSpec = OpChainSpec>>,
|
||||
Self::Provider:
|
||||
TransactionsProvider<Transaction = TransactionSigned> + ReceiptProvider<Receipt = Receipt>,
|
||||
Self::Provider: TransactionsProvider<Transaction = OpTransactionSigned>
|
||||
+ ReceiptProvider<Receipt = OpReceipt>,
|
||||
{
|
||||
async fn build_transaction_receipt(
|
||||
&self,
|
||||
tx: TransactionSigned,
|
||||
tx: OpTransactionSigned,
|
||||
meta: TransactionMeta,
|
||||
receipt: Receipt,
|
||||
receipt: OpReceipt,
|
||||
) -> Result<RpcReceipt<Self::NetworkTypes>, Self::Error> {
|
||||
let (block, receipts) = self
|
||||
.inner
|
||||
@ -107,7 +106,7 @@ impl OpReceiptFieldsBuilder {
|
||||
pub fn l1_block_info(
|
||||
mut self,
|
||||
chain_spec: &OpChainSpec,
|
||||
tx: &TransactionSigned,
|
||||
tx: &OpTransactionSigned,
|
||||
l1_block_info: revm::L1BlockInfo,
|
||||
) -> Result<Self, OpEthApiError> {
|
||||
let raw_tx = tx.encoded_2718();
|
||||
@ -196,25 +195,21 @@ impl OpReceiptBuilder {
|
||||
/// Returns a new builder.
|
||||
pub fn new(
|
||||
chain_spec: &OpChainSpec,
|
||||
transaction: &TransactionSigned,
|
||||
transaction: &OpTransactionSigned,
|
||||
meta: TransactionMeta,
|
||||
receipt: &Receipt,
|
||||
all_receipts: &[Receipt],
|
||||
receipt: &OpReceipt,
|
||||
all_receipts: &[OpReceipt],
|
||||
l1_block_info: revm::L1BlockInfo,
|
||||
) -> Result<Self, OpEthApiError> {
|
||||
let timestamp = meta.timestamp;
|
||||
let core_receipt =
|
||||
build_receipt(transaction, meta, receipt, all_receipts, |receipt_with_bloom| {
|
||||
match receipt.tx_type {
|
||||
TxType::Legacy => OpReceiptEnvelope::<Log>::Legacy(receipt_with_bloom),
|
||||
TxType::Eip2930 => OpReceiptEnvelope::<Log>::Eip2930(receipt_with_bloom),
|
||||
TxType::Eip1559 => OpReceiptEnvelope::<Log>::Eip1559(receipt_with_bloom),
|
||||
TxType::Eip4844 => {
|
||||
// TODO: unreachable
|
||||
OpReceiptEnvelope::<Log>::Eip1559(receipt_with_bloom)
|
||||
}
|
||||
TxType::Eip7702 => OpReceiptEnvelope::<Log>::Eip7702(receipt_with_bloom),
|
||||
TxType::Deposit => {
|
||||
match receipt {
|
||||
OpReceipt::Legacy(_) => OpReceiptEnvelope::<Log>::Legacy(receipt_with_bloom),
|
||||
OpReceipt::Eip2930(_) => OpReceiptEnvelope::<Log>::Eip2930(receipt_with_bloom),
|
||||
OpReceipt::Eip1559(_) => OpReceiptEnvelope::<Log>::Eip1559(receipt_with_bloom),
|
||||
OpReceipt::Eip7702(_) => OpReceiptEnvelope::<Log>::Eip7702(receipt_with_bloom),
|
||||
OpReceipt::Deposit(receipt) => {
|
||||
OpReceiptEnvelope::<Log>::Deposit(OpDepositReceiptWithBloom::<Log> {
|
||||
receipt: OpDepositReceipt::<Log> {
|
||||
inner: receipt_with_bloom.receipt,
|
||||
@ -229,8 +224,6 @@ impl OpReceiptBuilder {
|
||||
|
||||
let op_receipt_fields = OpReceiptFieldsBuilder::new(timestamp)
|
||||
.l1_block_info(chain_spec, transaction, l1_block_info)?
|
||||
.deposit_nonce(receipt.deposit_nonce)
|
||||
.deposit_version(receipt.deposit_receipt_version)
|
||||
.build();
|
||||
|
||||
Ok(Self { core_receipt, op_receipt_fields })
|
||||
@ -291,13 +284,14 @@ mod test {
|
||||
#[test]
|
||||
fn op_receipt_fields_from_block_and_tx() {
|
||||
// rig
|
||||
let tx_0 = TransactionSigned::decode_2718(
|
||||
let tx_0 = OpTransactionSigned::decode_2718(
|
||||
&mut TX_SET_L1_BLOCK_OP_MAINNET_BLOCK_124665056.as_slice(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let tx_1 = TransactionSigned::decode_2718(&mut TX_1_OP_MAINNET_BLOCK_124665056.as_slice())
|
||||
.unwrap();
|
||||
let tx_1 =
|
||||
OpTransactionSigned::decode_2718(&mut TX_1_OP_MAINNET_BLOCK_124665056.as_slice())
|
||||
.unwrap();
|
||||
|
||||
let block = Block {
|
||||
body: BlockBody { transactions: [tx_0, tx_1.clone()].to_vec(), ..Default::default() },
|
||||
@ -363,7 +357,7 @@ mod test {
|
||||
fn base_receipt_gas_fields() {
|
||||
// https://basescan.org/tx/0x510fd4c47d78ba9f97c91b0f2ace954d5384c169c9545a77a373cf3ef8254e6e
|
||||
let system = hex!("7ef8f8a0389e292420bcbf9330741f72074e39562a09ff5a00fd22e4e9eee7e34b81bca494deaddeaddeaddeaddeaddeaddeaddeaddead00019442000000000000000000000000000000000000158080830f424080b8a4440a5e20000008dd00101c120000000000000004000000006721035b00000000014189960000000000000000000000000000000000000000000000000000000349b4dcdc000000000000000000000000000000000000000000000000000000004ef9325cc5991ce750960f636ca2ffbb6e209bb3ba91412f21dd78c14ff154d1930f1f9a0000000000000000000000005050f69a9786f081509234f1a7f4684b5e5b76c9");
|
||||
let tx_0 = TransactionSigned::decode_2718(&mut &system[..]).unwrap();
|
||||
let tx_0 = OpTransactionSigned::decode_2718(&mut &system[..]).unwrap();
|
||||
|
||||
let block = Block {
|
||||
body: BlockBody { transactions: vec![tx_0], ..Default::default() },
|
||||
@ -374,7 +368,7 @@ mod test {
|
||||
|
||||
// https://basescan.org/tx/0xf9420cbaf66a2dda75a015488d37262cbfd4abd0aad7bb2be8a63e14b1fa7a94
|
||||
let tx = hex!("02f86c8221058034839a4ae283021528942f16386bb37709016023232523ff6d9daf444be380841249c58bc080a001b927eda2af9b00b52a57be0885e0303c39dd2831732e14051c2336470fd468a0681bf120baf562915841a48601c2b54a6742511e535cf8f71c95115af7ff63bd");
|
||||
let tx_1 = TransactionSigned::decode_2718(&mut &tx[..]).unwrap();
|
||||
let tx_1 = OpTransactionSigned::decode_2718(&mut &tx[..]).unwrap();
|
||||
|
||||
let receipt_meta = OpReceiptFieldsBuilder::new(1730216981)
|
||||
.l1_block_info(&BASE_MAINNET, &tx_1, l1_block_info)
|
||||
|
||||
@ -3,10 +3,12 @@
|
||||
use alloy_consensus::{Signed, Transaction as _};
|
||||
use alloy_primitives::{Bytes, PrimitiveSignature as Signature, Sealable, Sealed, B256};
|
||||
use alloy_rpc_types_eth::TransactionInfo;
|
||||
use op_alloy_consensus::OpTxEnvelope;
|
||||
use op_alloy_rpc_types::Transaction;
|
||||
use op_alloy_consensus::{OpTxEnvelope, OpTypedTransaction};
|
||||
use op_alloy_rpc_types::{OpTransactionRequest, Transaction};
|
||||
use reth_node_api::FullNodeComponents;
|
||||
use reth_primitives::{RecoveredTx, TransactionSigned};
|
||||
use reth_optimism_primitives::{OpReceipt, OpTransactionSigned};
|
||||
use reth_primitives::RecoveredTx;
|
||||
use reth_primitives_traits::transaction::signed::SignedTransaction;
|
||||
use reth_provider::{
|
||||
BlockReader, BlockReaderIdExt, ProviderTx, ReceiptProvider, TransactionsProvider,
|
||||
};
|
||||
@ -73,47 +75,40 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> TransactionCompat for OpEthApi<N>
|
||||
impl<N> TransactionCompat<OpTransactionSigned> for OpEthApi<N>
|
||||
where
|
||||
N: FullNodeComponents<Provider: ReceiptProvider<Receipt = reth_primitives::Receipt>>,
|
||||
N: FullNodeComponents<Provider: ReceiptProvider<Receipt = OpReceipt>>,
|
||||
{
|
||||
type Transaction = Transaction;
|
||||
type Error = OpEthApiError;
|
||||
|
||||
fn fill(
|
||||
&self,
|
||||
tx: RecoveredTx,
|
||||
tx: RecoveredTx<OpTransactionSigned>,
|
||||
tx_info: TransactionInfo,
|
||||
) -> Result<Self::Transaction, Self::Error> {
|
||||
let from = tx.signer();
|
||||
let hash = tx.hash();
|
||||
let TransactionSigned { transaction, signature, .. } = tx.into_signed();
|
||||
let hash = *tx.tx_hash();
|
||||
let OpTransactionSigned { transaction, signature, .. } = tx.into_signed();
|
||||
let mut deposit_receipt_version = None;
|
||||
let mut deposit_nonce = None;
|
||||
|
||||
let inner = match transaction {
|
||||
reth_primitives::Transaction::Legacy(tx) => {
|
||||
Signed::new_unchecked(tx, signature, hash).into()
|
||||
}
|
||||
reth_primitives::Transaction::Eip2930(tx) => {
|
||||
Signed::new_unchecked(tx, signature, hash).into()
|
||||
}
|
||||
reth_primitives::Transaction::Eip1559(tx) => {
|
||||
Signed::new_unchecked(tx, signature, hash).into()
|
||||
}
|
||||
reth_primitives::Transaction::Eip4844(_) => unreachable!(),
|
||||
reth_primitives::Transaction::Eip7702(tx) => {
|
||||
Signed::new_unchecked(tx, signature, hash).into()
|
||||
}
|
||||
reth_primitives::Transaction::Deposit(tx) => {
|
||||
OpTypedTransaction::Legacy(tx) => Signed::new_unchecked(tx, signature, hash).into(),
|
||||
OpTypedTransaction::Eip2930(tx) => Signed::new_unchecked(tx, signature, hash).into(),
|
||||
OpTypedTransaction::Eip1559(tx) => Signed::new_unchecked(tx, signature, hash).into(),
|
||||
OpTypedTransaction::Eip7702(tx) => Signed::new_unchecked(tx, signature, hash).into(),
|
||||
OpTypedTransaction::Deposit(tx) => {
|
||||
self.inner
|
||||
.eth_api
|
||||
.provider()
|
||||
.receipt_by_hash(hash)
|
||||
.map_err(Self::Error::from_eth_err)?
|
||||
.inspect(|receipt| {
|
||||
deposit_receipt_version = receipt.deposit_receipt_version;
|
||||
deposit_nonce = receipt.deposit_nonce;
|
||||
if let OpReceipt::Deposit(receipt) = receipt {
|
||||
deposit_receipt_version = receipt.deposit_receipt_version;
|
||||
deposit_nonce = receipt.deposit_nonce;
|
||||
}
|
||||
});
|
||||
|
||||
OpTxEnvelope::Deposit(tx.seal_unchecked(hash))
|
||||
@ -154,14 +149,15 @@ where
|
||||
fn build_simulate_v1_transaction(
|
||||
&self,
|
||||
request: alloy_rpc_types_eth::TransactionRequest,
|
||||
) -> Result<TransactionSigned, Self::Error> {
|
||||
) -> Result<OpTransactionSigned, Self::Error> {
|
||||
let request: OpTransactionRequest = request.into();
|
||||
let Ok(tx) = request.build_typed_tx() else {
|
||||
return Err(OpEthApiError::Eth(EthApiError::TransactionConversionError))
|
||||
};
|
||||
|
||||
// Create an empty signature for the transaction.
|
||||
let signature = Signature::new(Default::default(), Default::default(), false);
|
||||
Ok(TransactionSigned::new_unhashed(tx.into(), signature))
|
||||
Ok(OpTransactionSigned::new_unhashed(tx, signature))
|
||||
}
|
||||
|
||||
fn otterscan_api_truncate_input(tx: &mut Self::Transaction) {
|
||||
|
||||
@ -9,7 +9,8 @@ use reth_chainspec::ChainSpecProvider;
|
||||
use reth_evm::ConfigureEvm;
|
||||
use reth_optimism_chainspec::OpChainSpec;
|
||||
use reth_optimism_payload_builder::OpPayloadBuilder;
|
||||
use reth_primitives::{SealedHeader, TransactionSigned};
|
||||
use reth_optimism_primitives::OpTransactionSigned;
|
||||
use reth_primitives::SealedHeader;
|
||||
use reth_provider::{BlockReaderIdExt, ProviderError, ProviderResult, StateProviderFactory};
|
||||
pub use reth_rpc_api::DebugExecutionWitnessApiServer;
|
||||
use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult};
|
||||
@ -58,7 +59,7 @@ where
|
||||
+ ChainSpecProvider<ChainSpec = OpChainSpec>
|
||||
+ Clone
|
||||
+ 'static,
|
||||
EvmConfig: ConfigureEvm<Header = Header, Transaction = TransactionSigned> + 'static,
|
||||
EvmConfig: ConfigureEvm<Header = Header, Transaction = OpTransactionSigned> + 'static,
|
||||
{
|
||||
async fn execute_payload(
|
||||
&self,
|
||||
|
||||
Reference in New Issue
Block a user