diff --git a/chain/ethereum/src/codec.rs b/chain/ethereum/src/codec.rs index a3bfb75ad49..8a73ce83136 100644 --- a/chain/ethereum/src/codec.rs +++ b/chain/ethereum/src/codec.rs @@ -8,7 +8,9 @@ use graph::{ blockchain::{ self, Block as BlockchainBlock, BlockPtr, BlockTime, ChainStoreBlock, ChainStoreData, }, - components::ethereum::{AnyBlock, AnyHeader, AnyRpcHeader, AnyRpcTransaction, AnyTxEnvelope}, + components::ethereum::{ + AnyBlock, AnyHeader, AnyRpcHeader, AnyTransactionReceiptBare, AnyTxEnvelope, + }, prelude::{ alloy::{ self, @@ -16,7 +18,6 @@ use graph::{ network::AnyReceiptEnvelope, primitives::{aliases::B2048, Address, Bloom, Bytes, LogData, B256, U256}, rpc::types::{self as alloy_rpc_types, AccessList, AccessListItem, Transaction}, - serde::WithOtherFields, }, BlockNumber, Error, EthereumBlock, EthereumBlockWithCalls, EthereumCall, LightEthereumBlock, @@ -556,19 +557,12 @@ impl TryInto for &Block { let any_header: AnyRpcHeader = rpc_header.map(AnyHeader::from); - let any_transactions: Vec = transactions - .into_iter() - .map(|tx| AnyRpcTransaction::new(WithOtherFields::new(tx))) - .collect(); - - let any_block = Block { + Ok(Block { header: any_header, - transactions: alloy::rpc::types::BlockTransactions::Full(any_transactions), + transactions: alloy::rpc::types::BlockTransactions::Full(transactions), uncles, withdrawals: None, - }; - - Ok(AnyBlock::new(WithOtherFields::new(any_block))) + }) } } @@ -619,7 +613,7 @@ impl TryInto for &Block { fn transaction_trace_to_alloy_txn_reciept( t: &TransactionTrace, block: &Block, -) -> Result, Error> { +) -> Result, Error> { use alloy::consensus::{Eip658Value, Receipt}; let r = t.receipt.as_ref(); @@ -719,7 +713,7 @@ fn transaction_trace_to_alloy_txn_reciept( inner: any_envelope, }; - Ok(Some(WithOtherFields::new(receipt))) + Ok(Some(receipt)) } impl BlockHeader { @@ -1014,7 +1008,7 @@ mod test { let receipt = receipt_opt.unwrap(); - assert_eq!(receipt.inner.inner.r#type, 126); + assert_eq!(receipt.inner.r#type, 126); assert_eq!(receipt.gas_used, 21000); assert_eq!(receipt.transaction_index, Some(0)); } diff --git a/chain/ethereum/src/data_source.rs b/chain/ethereum/src/data_source.rs index cd945d00c62..b2303b6d053 100644 --- a/chain/ethereum/src/data_source.rs +++ b/chain/ethereum/src/data_source.rs @@ -444,7 +444,6 @@ fn create_dummy_transaction( transaction_index: Option, transaction_hash: Option, ) -> Result { - use alloy::serde::WithOtherFields; use graph::components::ethereum::AnyTxEnvelope; use graph::prelude::alloy::{ consensus::transaction::Recovered, consensus::Signed, primitives::Signature, @@ -465,15 +464,13 @@ fn create_dummy_transaction( let recovered = Recovered::new_unchecked(any_envelope, Address::ZERO); - let inner_tx = Transaction { + Ok(Transaction { inner: recovered, block_hash: Some(block_hash), block_number: Some(block_number), transaction_index, effective_gas_price: None, - }; - - Ok(AnyTransaction::new(WithOtherFields::new(inner_tx))) + }) } impl DataSource { @@ -812,7 +809,7 @@ impl DataSource { let logging_extras = Arc::new(o! { "signature" => event_handler.event.to_string(), "address" => format!("{}", &log.address()), - "transaction" => format!("{}", &transaction.inner.tx_hash()), + "transaction" => format!("{}", &transaction.tx_hash()), }); let handler = event_handler.handler.clone(); let calls = DeclaredCall::from_log_trigger_with_event( @@ -921,7 +918,7 @@ impl DataSource { let logging_extras = Arc::new(o! { "function" => handler.function.to_string(), "to" => format!("{}", &call.to), - "transaction" => format!("{}", &transaction.inner.tx_hash()), + "transaction" => format!("{}", &transaction.tx_hash()), }); Ok(Some(TriggerWithHandler::::new_with_logging_extras( MappingTrigger::Call { diff --git a/chain/ethereum/src/ethereum_adapter.rs b/chain/ethereum/src/ethereum_adapter.rs index 5bc0b285d51..5d9b78118a0 100644 --- a/chain/ethereum/src/ethereum_adapter.rs +++ b/chain/ethereum/src/ethereum_adapter.rs @@ -25,7 +25,7 @@ use graph::futures03::{ use graph::prelude::{ alloy::{ self, - network::{AnyNetwork, TransactionResponse}, + network::TransactionResponse, primitives::{Address, B256}, providers::{ ext::TraceApi, @@ -86,8 +86,8 @@ type AlloyProvider = FillProvider< Identity, JoinFill>>, >, - RootProvider, - AnyNetwork, + RootProvider, + AnyNetworkBare, >; #[derive(Clone)] @@ -167,22 +167,22 @@ impl EthereumAdapter { ) -> Self { let alloy = match &transport { Transport::RPC(client) => Arc::new( - alloy::providers::ProviderBuilder::<_, _, AnyNetwork>::default() - .network::() + alloy::providers::ProviderBuilder::<_, _, AnyNetworkBare>::default() + .network::() .with_recommended_fillers() .connect_client(client.clone()), ), Transport::IPC(ipc_connect) => Arc::new( - alloy::providers::ProviderBuilder::<_, _, AnyNetwork>::default() - .network::() + alloy::providers::ProviderBuilder::<_, _, AnyNetworkBare>::default() + .network::() .with_recommended_fillers() .connect_ipc(ipc_connect.clone()) .await .expect("Failed to connect to Ethereum IPC"), ), Transport::WS(ws_connect) => Arc::new( - alloy::providers::ProviderBuilder::<_, _, AnyNetwork>::default() - .network::() + alloy::providers::ProviderBuilder::<_, _, AnyNetworkBare>::default() + .network::() .with_recommended_fillers() .connect_ws(ws_connect.clone()) .await @@ -2062,7 +2062,7 @@ pub(crate) fn parse_block_triggers( async fn fetch_receipt_from_ethereum_client( eth: &EthereumAdapter, transaction_hash: B256, -) -> anyhow::Result { +) -> anyhow::Result { match eth.alloy.get_transaction_receipt(transaction_hash).await { Ok(Some(receipt)) => Ok(receipt), Ok(None) => bail!("Could not find transaction receipt"), @@ -2215,7 +2215,7 @@ async fn fetch_transaction_receipts_in_batch_with_retry( hashes: Vec, block_hash: B256, logger: ProviderLogger, -) -> Result>, IngestorError> { +) -> Result>, IngestorError> { let retry_log_message = format!( "batch eth_getTransactionReceipt RPC call for block {:?}", block_hash @@ -2241,7 +2241,7 @@ async fn fetch_transaction_receipts_in_batch( hashes: Vec, block_hash: B256, logger: ProviderLogger, -) -> Result>, IngestorError> { +) -> Result>, IngestorError> { // Use the batch method to get all receipts at once let receipts = batch_get_transaction_receipts(alloy, hashes.clone()) .await @@ -2270,17 +2270,16 @@ async fn fetch_transaction_receipts_in_batch( async fn batch_get_transaction_receipts( provider: Arc, tx_hashes: Vec, -) -> Result>, Box> { +) -> Result>, Box> { let mut batch = alloy::rpc::client::BatchRequest::new(provider.client()); let mut receipt_futures = Vec::new(); // Add all receipt requests to batch for tx_hash in &tx_hashes { - let receipt_future = batch - .add_call::<(B256,), Option>( - "eth_getTransactionReceipt", - &(*tx_hash,), - )?; + let receipt_future = batch.add_call::<(B256,), Option>( + "eth_getTransactionReceipt", + &(*tx_hash,), + )?; receipt_futures.push(receipt_future); } @@ -2332,7 +2331,7 @@ async fn fetch_receipts_with_retry( block_hash: B256, logger: ProviderLogger, supports_block_receipts: bool, -) -> Result>, IngestorError> { +) -> Result>, IngestorError> { if supports_block_receipts { return fetch_block_receipts_with_retry(alloy, hashes, block_hash, logger).await; } @@ -2345,7 +2344,7 @@ async fn fetch_individual_receipts_with_retry( hashes: Vec, block_hash: B256, logger: ProviderLogger, -) -> Result>, IngestorError> { +) -> Result>, IngestorError> { if ENV_VARS.fetch_receipts_in_batches { return fetch_transaction_receipts_in_batch_with_retry(alloy, hashes, block_hash, logger) .await; @@ -2364,9 +2363,9 @@ async fn fetch_individual_receipts_with_retry( }) .buffered(ENV_VARS.block_ingestor_max_concurrent_json_rpc_calls); - tokio_stream::StreamExt::collect::< - Result>, IngestorError>, - >(receipt_stream) + tokio_stream::StreamExt::collect::>, IngestorError>>( + receipt_stream, + ) .await } @@ -2376,7 +2375,7 @@ async fn fetch_block_receipts_with_retry( hashes: Vec, block_hash: B256, logger: ProviderLogger, -) -> Result>, IngestorError> { +) -> Result>, IngestorError> { use graph::prelude::alloy::rpc::types::BlockId; let retry_log_message = format!("eth_getBlockReceipts RPC call for block {:?}", block_hash); @@ -2420,7 +2419,7 @@ async fn fetch_transaction_receipt_with_retry( transaction_hash: B256, block_hash: B256, logger: ProviderLogger, -) -> Result, IngestorError> { +) -> Result, IngestorError> { let retry_log_message = format!( "eth_getTransactionReceipt RPC call for transaction {:?}", transaction_hash @@ -2443,11 +2442,11 @@ async fn fetch_transaction_receipt_with_retry( } fn resolve_transaction_receipt( - transaction_receipt: Option, + transaction_receipt: Option, transaction_hash: B256, block_hash: B256, logger: ProviderLogger, -) -> Result { +) -> Result { match transaction_receipt { // A receipt might be missing because the block was uncled, and the transaction never // made it back into the main chain. @@ -2580,11 +2579,10 @@ async fn get_transaction_receipts_for_transaction_hashes( transaction_hashes_by_block: &HashMap>, subgraph_metrics: Arc, logger: ProviderLogger, -) -> Result>, anyhow::Error> { +) -> Result>, anyhow::Error> { use std::collections::hash_map::Entry::Vacant; - let mut receipts_by_hash: HashMap> = - HashMap::new(); + let mut receipts_by_hash: HashMap> = HashMap::new(); // Return early if input set is empty if transaction_hashes_by_block.is_empty() { @@ -2665,8 +2663,7 @@ mod tests { EthereumBlockWithCalls, }; use graph::blockchain::BlockPtr; - use graph::components::ethereum::AnyBlock; - use graph::prelude::alloy::network::AnyNetwork; + use graph::components::ethereum::AnyNetworkBare; use graph::prelude::alloy::primitives::{Address, Bytes, B256}; use graph::prelude::alloy::providers::mock::Asserter; use graph::prelude::alloy::providers::ProviderBuilder; @@ -2682,7 +2679,7 @@ mod tests { let block = EthereumBlockWithCalls { ethereum_block: EthereumBlock { - block: Arc::new(LightEthereumBlock::new(AnyBlock::from(block))), + block: Arc::new(LightEthereumBlock::new(block)), ..Default::default() }, calls: Some(vec![EthereumCall { @@ -2743,8 +2740,8 @@ mod tests { let json_value: Value = serde_json::from_str(json_response).unwrap(); let asserter = Asserter::new(); - let provider = ProviderBuilder::<_, _, AnyNetwork>::default() - .network::() + let provider = ProviderBuilder::<_, _, AnyNetworkBare>::default() + .network::() .with_recommended_fillers() .connect_mocked_client(asserter.clone()); @@ -2827,7 +2824,7 @@ mod tests { #[allow(unreachable_code)] let block = EthereumBlockWithCalls { ethereum_block: EthereumBlock { - block: Arc::new(LightEthereumBlock::new(AnyBlock::from(block))), + block: Arc::new(LightEthereumBlock::new(block)), ..Default::default() }, calls: Some(vec![EthereumCall { @@ -2858,7 +2855,7 @@ mod tests { #[allow(unreachable_code)] let block = EthereumBlockWithCalls { ethereum_block: EthereumBlock { - block: Arc::new(LightEthereumBlock::new(AnyBlock::from(block))), + block: Arc::new(LightEthereumBlock::new(block)), ..Default::default() }, calls: Some(vec![EthereumCall { diff --git a/chain/ethereum/src/runtime/abi.rs b/chain/ethereum/src/runtime/abi.rs index 7ac13752671..8f85866b3d4 100644 --- a/chain/ethereum/src/runtime/abi.rs +++ b/chain/ethereum/src/runtime/abi.rs @@ -9,7 +9,6 @@ use graph::prelude::alloy; use graph::prelude::alloy::consensus::TxReceipt; use graph::prelude::alloy::network::ReceiptResponse; use graph::prelude::alloy::rpc::types::{Log, TransactionReceipt}; -use graph::prelude::alloy::serde::WithOtherFields; use graph::{ prelude::BigInt, runtime::{ @@ -587,10 +586,7 @@ where #[async_trait] impl<'a, T, B, Inner> ToAscObj> - for ( - EthereumEventData<'a>, - Option<&WithOtherFields>>, - ) + for (EthereumEventData<'a>, Option<&TransactionReceipt>) where T: AscType + AscIndexId + Send, B: AscType + AscIndexId + Send, @@ -615,7 +611,7 @@ where params, } = event_data.to_asc_obj(heap, gas).await?; let receipt = if let Some(receipt_data) = optional_receipt { - asc_new(heap, &receipt_data.inner(), gas).await? + asc_new(heap, receipt_data, gas).await? } else { AscPtr::null() }; diff --git a/chain/ethereum/src/trigger.rs b/chain/ethereum/src/trigger.rs index f969fa7063c..6a5e1503073 100644 --- a/chain/ethereum/src/trigger.rs +++ b/chain/ethereum/src/trigger.rs @@ -3,12 +3,12 @@ use graph::abi; use graph::blockchain::MappingTriggerTrait; use graph::blockchain::TriggerData; use graph::components::ethereum::AnyTransaction; +use graph::components::ethereum::AnyTransactionReceiptBare as AlloyTransactionReceipt; use graph::data::subgraph::API_VERSION_0_0_2; use graph::data::subgraph::API_VERSION_0_0_6; use graph::data::subgraph::API_VERSION_0_0_7; use graph::data_source::common::DeclaredCall; use graph::prelude::alloy::consensus::Transaction as TransactionTrait; -use graph::prelude::alloy::network::AnyTransactionReceipt as AlloyTransactionReceipt; use graph::prelude::alloy::network::TransactionResponse; use graph::prelude::alloy::primitives::{Address, B256, U256}; use graph::prelude::alloy::rpc::types::Log; diff --git a/graph/src/components/ethereum/mod.rs b/graph/src/components/ethereum/mod.rs index 0c068c24dee..1fe8d2ac0d3 100644 --- a/graph/src/components/ethereum/mod.rs +++ b/graph/src/components/ethereum/mod.rs @@ -1,9 +1,11 @@ +mod network; mod types; +pub use self::network::AnyNetworkBare; pub use self::types::{ - AnyBlock, AnyTransaction, EthereumBlock, EthereumBlockWithCalls, EthereumCall, - LightEthereumBlock, LightEthereumBlockExt, + AnyBlock, AnyTransaction, AnyTransactionReceiptBare, EthereumBlock, EthereumBlockWithCalls, + EthereumCall, LightEthereumBlock, LightEthereumBlockExt, }; // Re-export Alloy network types for convenience -pub use alloy::network::{AnyHeader, AnyRpcBlock, AnyRpcHeader, AnyRpcTransaction, AnyTxEnvelope}; +pub use alloy::network::{AnyHeader, AnyRpcHeader, AnyTxEnvelope}; diff --git a/graph/src/components/ethereum/network.rs b/graph/src/components/ethereum/network.rs new file mode 100644 index 00000000000..e2407cc8e23 --- /dev/null +++ b/graph/src/components/ethereum/network.rs @@ -0,0 +1,212 @@ +use alloy::network::{ + AnyHeader, AnyReceiptEnvelope, AnyTxEnvelope, AnyTxType, AnyTypedTransaction, BuildResult, + Network, NetworkWallet, TransactionBuilder, TransactionBuilderError, +}; +use alloy::primitives::{Address, Bytes, ChainId, TxKind, U256}; +use alloy::providers::fillers::{ + BlobGasFiller, ChainIdFiller, GasFiller, JoinFill, NonceFiller, RecommendedFillers, +}; +use alloy::rpc::types::{ + AccessList, Block, Header, Log, TransactionInputKind, TransactionReceipt, TransactionRequest, +}; +use alloy::serde::WithOtherFields; +use std::ops::{Deref, DerefMut}; + +use super::types::AnyTransaction; + +/// Like alloy's [`AnyNetwork`] but without [`WithOtherFields`] on response types. +/// +/// `AnyNetwork` wraps every response (block, transaction, receipt) in `WithOtherFields`, +/// which captures unknown JSON keys into a `BTreeMap`. This requires `#[serde(flatten)]`, +/// forcing serde to buffer entire JSON objects into intermediate `Value` maps and +/// re-serialize them to diff keys — on every block and every transaction. +/// graph-node never uses these extra fields, so we define a bare network that deserializes +/// directly into the inner types. +/// +/// Uses `AnyTxEnvelope` (not `TxEnvelope`) to support non-standard transaction types from +/// L2s and sidechains. `TransactionRequest` retains `WithOtherFields` because upstream +/// `From` impls for `AnyTxEnvelope` only exist on `WithOtherFields`. +/// +/// [`AnyNetwork`]: alloy::network::AnyNetwork +/// [`WithOtherFields`]: alloy::serde::WithOtherFields +#[derive(Clone, Copy, Debug)] +pub struct AnyNetworkBare; + +impl Network for AnyNetworkBare { + type TxType = AnyTxType; + type TxEnvelope = AnyTxEnvelope; + type UnsignedTx = AnyTypedTransaction; + type ReceiptEnvelope = AnyReceiptEnvelope; + type Header = AnyHeader; + + type TransactionRequest = WithOtherFields; + type TransactionResponse = AnyTransaction; + type ReceiptResponse = TransactionReceipt>; + type HeaderResponse = Header; + type BlockResponse = Block>; +} + +impl RecommendedFillers for AnyNetworkBare { + type RecommendedFillers = + JoinFill>>; + + fn recommended_fillers() -> Self::RecommendedFillers { + Default::default() + } +} + +impl TransactionBuilder for WithOtherFields { + fn chain_id(&self) -> Option { + self.deref().chain_id() + } + + fn set_chain_id(&mut self, chain_id: ChainId) { + self.deref_mut().set_chain_id(chain_id) + } + + fn nonce(&self) -> Option { + self.deref().nonce() + } + + fn set_nonce(&mut self, nonce: u64) { + self.deref_mut().set_nonce(nonce) + } + + fn take_nonce(&mut self) -> Option { + self.deref_mut().nonce.take() + } + + fn input(&self) -> Option<&Bytes> { + self.deref().input() + } + + fn set_input>(&mut self, input: T) { + self.deref_mut().set_input(input); + } + + fn set_input_kind>(&mut self, input: T, kind: TransactionInputKind) { + self.deref_mut().set_input_kind(input, kind) + } + + fn from(&self) -> Option
{ + self.deref().from() + } + + fn set_from(&mut self, from: Address) { + self.deref_mut().set_from(from); + } + + fn kind(&self) -> Option { + self.deref().kind() + } + + fn clear_kind(&mut self) { + self.deref_mut().clear_kind() + } + + fn set_kind(&mut self, kind: TxKind) { + self.deref_mut().set_kind(kind) + } + + fn value(&self) -> Option { + self.deref().value() + } + + fn set_value(&mut self, value: U256) { + self.deref_mut().set_value(value) + } + + fn gas_price(&self) -> Option { + self.deref().gas_price() + } + + fn set_gas_price(&mut self, gas_price: u128) { + self.deref_mut().set_gas_price(gas_price); + } + + fn max_fee_per_gas(&self) -> Option { + self.deref().max_fee_per_gas() + } + + fn set_max_fee_per_gas(&mut self, max_fee_per_gas: u128) { + self.deref_mut().set_max_fee_per_gas(max_fee_per_gas); + } + + fn max_priority_fee_per_gas(&self) -> Option { + self.deref().max_priority_fee_per_gas() + } + + fn set_max_priority_fee_per_gas(&mut self, max_priority_fee_per_gas: u128) { + self.deref_mut() + .set_max_priority_fee_per_gas(max_priority_fee_per_gas); + } + + fn gas_limit(&self) -> Option { + self.deref().gas_limit() + } + + fn set_gas_limit(&mut self, gas_limit: u64) { + self.deref_mut().set_gas_limit(gas_limit); + } + + fn access_list(&self) -> Option<&AccessList> { + self.deref().access_list() + } + + fn set_access_list(&mut self, access_list: AccessList) { + self.deref_mut().set_access_list(access_list) + } + + fn complete_type( + &self, + ty: ::TxType, + ) -> Result<(), Vec<&'static str>> { + self.deref() + .complete_type(ty.try_into().map_err(|_| vec!["supported tx type"])?) + } + + fn can_submit(&self) -> bool { + self.deref().can_submit() + } + + fn can_build(&self) -> bool { + self.deref().can_build() + } + + fn output_tx_type(&self) -> ::TxType { + self.deref().output_tx_type().into() + } + + fn output_tx_type_checked(&self) -> Option<::TxType> { + self.deref().output_tx_type_checked().map(Into::into) + } + + fn prep_for_submission(&mut self) { + self.deref_mut().prep_for_submission() + } + + fn build_unsigned( + self, + ) -> BuildResult<::UnsignedTx, AnyNetworkBare> { + if let Err((tx_type, missing)) = self.missing_keys() { + return Err(TransactionBuilderError::InvalidTransactionRequest( + tx_type.into(), + missing, + ) + .into_unbuilt(self)); + } + Ok(self + .inner + .build_typed_tx() + .expect("checked by missing_keys") + .into()) + } + + async fn build>( + self, + wallet: &W, + ) -> Result<::TxEnvelope, TransactionBuilderError> + { + Ok(wallet.sign_request(self).await?) + } +} diff --git a/graph/src/components/ethereum/types.rs b/graph/src/components/ethereum/types.rs index a6c21aacb8a..70db118d312 100644 --- a/graph/src/components/ethereum/types.rs +++ b/graph/src/components/ethereum/types.rs @@ -1,9 +1,12 @@ use alloy::{ - network::{AnyRpcBlock, AnyRpcHeader, AnyRpcTransaction, ReceiptResponse, TransactionResponse}, + network::{ + AnyHeader, AnyReceiptEnvelope, AnyRpcHeader, AnyTxEnvelope, ReceiptResponse, + TransactionResponse, + }, primitives::{Address, Bytes, B256, U256}, rpc::types::{ trace::parity::{Action, LocalizedTransactionTrace, TraceOutput}, - Log, + Block, Header, Log, Transaction, TransactionReceipt, }, }; use serde::{Deserialize, Serialize}; @@ -14,9 +17,11 @@ use crate::{ prelude::BlockNumber, }; -// Use Alloy's official types for handling any transaction type -pub type AnyTransaction = AnyRpcTransaction; -pub type AnyBlock = AnyRpcBlock; +pub type AnyTransaction = Transaction; +pub type AnyBlock = Block>; +/// Like alloy's `AnyTransactionReceipt` but without the `WithOtherFields` wrapper, +/// avoiding `#[serde(flatten)]` overhead during deserialization. +pub type AnyTransactionReceiptBare = TransactionReceipt>; #[allow(dead_code)] #[derive(Debug, Deserialize, Serialize)] @@ -24,16 +29,14 @@ pub struct LightEthereumBlock(AnyBlock); impl Default for LightEthereumBlock { fn default() -> Self { - use alloy::rpc::types::{Block, BlockTransactions}; - use alloy::serde::WithOtherFields; + use alloy::rpc::types::BlockTransactions; - let default_block = Block { + Self(Block { header: AnyRpcHeader::default(), transactions: BlockTransactions::Full(vec![]), uncles: vec![], withdrawals: None, - }; - Self(AnyBlock::new(WithOtherFields::new(default_block))) + }) } } @@ -186,7 +189,7 @@ impl EthereumBlockWithCalls { #[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct EthereumBlock { pub block: Arc, - pub transaction_receipts: Vec>, + pub transaction_receipts: Vec>, } #[derive(Debug, Default, Clone, PartialEq, Eq)] diff --git a/graph/src/components/transaction_receipt.rs b/graph/src/components/transaction_receipt.rs index 526a0487180..52d3730ddc0 100644 --- a/graph/src/components/transaction_receipt.rs +++ b/graph/src/components/transaction_receipt.rs @@ -16,8 +16,8 @@ pub struct LightTransactionReceipt { pub status: bool, } -impl From for LightTransactionReceipt { - fn from(receipt: alloy::network::AnyTransactionReceipt) -> Self { +impl From for LightTransactionReceipt { + fn from(receipt: super::ethereum::AnyTransactionReceiptBare) -> Self { LightTransactionReceipt { transaction_hash: receipt.transaction_hash, transaction_index: receipt.transaction_index.unwrap(), // unwrap is safe because its None only for pending transactions, graph-node does not ingest pending transactions diff --git a/graph/src/util/test_utils.rs b/graph/src/util/test_utils.rs index d5240e21faa..2375f411b33 100644 --- a/graph/src/util/test_utils.rs +++ b/graph/src/util/test_utils.rs @@ -1,41 +1,41 @@ -use alloy::consensus::{TxEnvelope, TxLegacy}; +use alloy::consensus::TxLegacy; use alloy::primitives::Address; use alloy::rpc::types::Transaction; +use crate::components::ethereum::{AnyBlock, AnyHeader, AnyTransaction, AnyTxEnvelope}; use crate::prelude::alloy::consensus::Header as ConsensusHeader; use crate::prelude::alloy::primitives::B256; use crate::prelude::alloy::rpc::types::{Block, Header}; /// Creates a minimal Alloy Block for testing purposes. -pub fn create_minimal_block_for_test(block_number: u64, block_hash: B256) -> Block { +pub fn create_minimal_block_for_test(block_number: u64, block_hash: B256) -> AnyBlock { // Create consensus header with defaults, but set the specific number let consensus_header = ConsensusHeader { number: block_number, ..Default::default() }; - // Create RPC header with the specific hash + // Create RPC header with the specific hash and wrap in AnyHeader let rpc_header = Header { hash: block_hash, - inner: consensus_header, + inner: AnyHeader::from(consensus_header), total_difficulty: None, size: None, }; - // Create an empty block with this header Block::empty(rpc_header) } -/// Generic function that creates a mock legacy Transaction from ANY log +/// Generic function that creates a mock legacy Transaction for testing pub fn create_dummy_transaction( block_number: u64, block_hash: B256, transaction_index: Option, transaction_hash: B256, -) -> Transaction { +) -> AnyTransaction { use alloy::{ consensus::transaction::Recovered, - consensus::Signed, + consensus::{Signed, TxEnvelope}, primitives::{Signature, U256}, }; @@ -46,8 +46,9 @@ pub fn create_dummy_transaction( let signed_tx = Signed::new_unchecked(tx, signature, transaction_hash); let envelope = TxEnvelope::Legacy(signed_tx); + let any_envelope = AnyTxEnvelope::Ethereum(envelope); - let recovered = Recovered::new_unchecked(envelope, Address::ZERO); + let recovered = Recovered::new_unchecked(any_envelope, Address::ZERO); Transaction { inner: recovered, diff --git a/store/test-store/src/block_store.rs b/store/test-store/src/block_store.rs index 77bacf0ae53..c0ca494688c 100644 --- a/store/test-store/src/block_store.rs +++ b/store/test-store/src/block_store.rs @@ -117,7 +117,7 @@ impl FakeBlock { let rpc_header = Header { hash: block_hash, - inner: consensus_header, + inner: graph::components::ethereum::AnyHeader::from(consensus_header), total_difficulty: None, size: None, }; @@ -125,7 +125,7 @@ impl FakeBlock { let block = Block::empty(rpc_header); EthereumBlock { - block: Arc::new(LightEthereumBlock::new(block.into())), + block: Arc::new(LightEthereumBlock::new(block)), transaction_receipts: Vec::new(), } } diff --git a/tests/src/fixture/ethereum.rs b/tests/src/fixture/ethereum.rs index 713df0af40f..fa8468d164d 100644 --- a/tests/src/fixture/ethereum.rs +++ b/tests/src/fixture/ethereum.rs @@ -84,7 +84,7 @@ pub fn genesis() -> BlockWithTriggers { let block = create_minimal_block_for_test(ptr.number as u64, ptr.hash.as_b256()); BlockWithTriggers:: { - block: BlockFinality::Final(Arc::new(LightEthereumBlock::new(block.into()))), + block: BlockFinality::Final(Arc::new(LightEthereumBlock::new(block))), trigger_data: vec![Trigger::Chain(EthereumTrigger::Block( ptr, EthereumBlockTriggerType::End, @@ -128,7 +128,7 @@ pub fn empty_block(parent_ptr: BlockPtr, ptr: BlockPtr) -> BlockWithTriggers { - block: BlockFinality::Final(Arc::new(LightEthereumBlock::new(alloy_block.into()))), + block: BlockFinality::Final(Arc::new(LightEthereumBlock::new(alloy_block))), trigger_data: vec![Trigger::Chain(EthereumTrigger::Block( ptr, EthereumBlockTriggerType::End, diff --git a/tests/tests/runner_tests.rs b/tests/tests/runner_tests.rs index b3778c109b4..f1dbda62c41 100644 --- a/tests/tests/runner_tests.rs +++ b/tests/tests/runner_tests.rs @@ -1219,7 +1219,7 @@ async fn aggregation_current_bucket() { .with_transactions(transactions); BlockWithTriggers:: { - block: BlockFinality::Final(Arc::new(LightEthereumBlock::new(alloy_block.into()))), + block: BlockFinality::Final(Arc::new(LightEthereumBlock::new(alloy_block))), trigger_data: vec![Trigger::Chain(EthereumTrigger::Block( ptr, EthereumBlockTriggerType::End,