feat: integrate OpPrimitives (#13556)

This commit is contained in:
Arsenii Kulikov
2024-12-27 18:11:11 +03:00
committed by GitHub
parent c35fe4ac54
commit 4994cdf0b0
44 changed files with 524 additions and 506 deletions

View File

@ -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

View File

@ -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,

View File

@ -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,
}),
}
}
}

View File

@ -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)

View File

@ -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) {

View File

@ -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,