From 65965823823596551cf09b8ccec3c8b7478408cc Mon Sep 17 00:00:00 2001 From: Krzysztof Lis Date: Thu, 22 Feb 2024 14:48:25 +0100 Subject: [PATCH] fix(p2p): drop partial types --- crates/common/src/lib.rs | 13 +- crates/p2p/src/client.rs | 2 +- crates/p2p/src/client/conv.rs | 367 +++++++++++ crates/p2p/src/client/peer_agnostic.rs | 80 +-- crates/p2p/src/client/types.rs | 613 ------------------ .../src/p2p_network/sync_handlers/tests.rs | 44 +- crates/pathfinder/src/sync/p2p/headers.rs | 6 +- 7 files changed, 419 insertions(+), 706 deletions(-) create mode 100644 crates/p2p/src/client/conv.rs delete mode 100644 crates/p2p/src/client/types.rs diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index 60a2fe0bf0..5a10413bf5 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -335,11 +335,18 @@ impl From for GasPrice { } } -impl From for GasPrice { - fn from(src: Felt) -> Self { +impl TryFrom for GasPrice { + type Error = anyhow::Error; + + fn try_from(src: Felt) -> Result { + anyhow::ensure!( + src.as_be_bytes()[0..16] == [0; 16], + "Gas price fits into u128" + ); + let mut bytes = [0u8; 16]; bytes.copy_from_slice(&src.as_be_bytes()[16..]); - Self(u128::from_be_bytes(bytes)) + Ok(Self(u128::from_be_bytes(bytes))) } } diff --git a/crates/p2p/src/client.rs b/crates/p2p/src/client.rs index 1965005c6b..f7f50c70ed 100644 --- a/crates/p2p/src/client.rs +++ b/crates/p2p/src/client.rs @@ -1,3 +1,3 @@ +pub mod conv; pub mod peer_agnostic; pub mod peer_aware; -pub mod types; diff --git a/crates/p2p/src/client/conv.rs b/crates/p2p/src/client/conv.rs new file mode 100644 index 0000000000..421c2b1470 --- /dev/null +++ b/crates/p2p/src/client/conv.rs @@ -0,0 +1,367 @@ +use pathfinder_common::{ + receipt::{ + BuiltinCounters, ExecutionDataAvailability, ExecutionResources, ExecutionStatus, + L2ToL1Message, Receipt, + }, + transaction::{ + DataAvailabilityMode, DeclareTransactionV0V1, DeclareTransactionV2, DeclareTransactionV3, + DeployAccountTransactionV0V1, DeployAccountTransactionV3, DeployTransaction, + InvokeTransactionV0, InvokeTransactionV1, InvokeTransactionV3, L1HandlerTransaction, + ResourceBound, ResourceBounds, TransactionVariant, + }, + AccountDeploymentDataElem, BlockCommitmentSignature, BlockCommitmentSignatureElem, BlockHash, + BlockHeader, BlockNumber, BlockTimestamp, CallParam, CasmHash, ClassCommitment, ClassHash, + ConstructorParam, ContractAddress, ContractAddressSalt, EntryPoint, EthereumAddress, + EventCommitment, EventData, EventKey, Fee, GasPrice, L1DataAvailabilityMode, + L2ToL1MessagePayloadElem, SequencerAddress, SignedBlockHeader, StateCommitment, + StorageCommitment, TransactionCommitment, TransactionHash, TransactionIndex, TransactionNonce, + TransactionSignatureElem, TransactionVersion, +}; + +/// We don't want to introduce circular dependencies between crates +/// and we need to work around for the orphan rule - implement conversion fns for types ourside our crate. +pub trait TryFromDto { + fn try_from_dto(dto: T) -> anyhow::Result + where + Self: Sized; +} + +impl TryFromDto for SignedBlockHeader { + /// ## Important + /// + /// This conversion leaves `class_commitment` and `storage_commitment` fields zeroed. + /// The caller must make sure to fill them with the correct values after the conversion succeeds. + fn try_from_dto(dto: p2p_proto::header::SignedBlockHeader) -> anyhow::Result { + anyhow::ensure!(dto.signatures.len() == 1, "expected exactly one signature"); + let signature = dto + .signatures + .into_iter() + .map(|sig| BlockCommitmentSignature { + r: BlockCommitmentSignatureElem(sig.r), + s: BlockCommitmentSignatureElem(sig.s), + }) + .next() + .expect("exactly one element"); + Ok(SignedBlockHeader { + header: BlockHeader { + hash: BlockHash(dto.block_hash.0), + parent_hash: BlockHash(dto.parent_hash.0), + number: BlockNumber::new(dto.number) + .ok_or(anyhow::anyhow!("block number > i64::MAX"))?, + timestamp: BlockTimestamp::new(dto.time) + .ok_or(anyhow::anyhow!("block timestamp > i64::MAX"))?, + eth_l1_gas_price: GasPrice(dto.gas_price_wei), + strk_l1_gas_price: GasPrice(dto.gas_price_fri), + eth_l1_data_gas_price: GasPrice(dto.data_gas_price_wei), + strk_l1_data_gas_price: GasPrice(dto.data_gas_price_fri), + sequencer_address: SequencerAddress(dto.sequencer_address.0), + starknet_version: dto.protocol_version.into(), + class_commitment: ClassCommitment::ZERO, + event_commitment: EventCommitment(dto.events.root.0), + state_commitment: StateCommitment(dto.state.root.0), + storage_commitment: StorageCommitment::ZERO, + transaction_commitment: TransactionCommitment(dto.transactions.root.0), + transaction_count: dto.transactions.n_leaves.try_into()?, + event_count: dto.events.n_leaves.try_into()?, + l1_da_mode: TryFromDto::try_from_dto(dto.l1_data_availability_mode)?, + }, + signature, + }) + } +} + +impl TryFromDto for TransactionVariant { + /// ## Important + /// + /// This conversion does not compute deployed contract address for deploy account transactions + /// ([`TransactionVariant::DeployAccountV0V1`] and [`TransactionVariant::DeployAccountV3`]), + /// filling it with a zero address instead. The caller is responsible for performing the computation after the conversion succeeds. + fn try_from_dto(dto: p2p_proto::transaction::TransactionVariant) -> anyhow::Result + where + Self: Sized, + { + use p2p_proto::transaction::TransactionVariant::{ + DeclareV0, DeclareV1, DeclareV2, DeclareV3, Deploy, DeployAccountV1, DeployAccountV3, + InvokeV0, InvokeV1, InvokeV3, L1HandlerV0, + }; + Ok(match dto { + DeclareV0(x) => Self::DeclareV0(DeclareTransactionV0V1 { + class_hash: ClassHash(x.class_hash.0), + max_fee: Fee(x.max_fee), + nonce: TransactionNonce::ZERO, + sender_address: ContractAddress(x.sender.0), + signature: x + .signature + .parts + .into_iter() + .map(TransactionSignatureElem) + .collect(), + }), + DeclareV1(x) => Self::DeclareV1(DeclareTransactionV0V1 { + class_hash: ClassHash(x.class_hash.0), + max_fee: Fee(x.max_fee), + nonce: TransactionNonce(x.nonce), + sender_address: ContractAddress(x.sender.0), + signature: x + .signature + .parts + .into_iter() + .map(TransactionSignatureElem) + .collect(), + }), + DeclareV2(x) => Self::DeclareV2(DeclareTransactionV2 { + class_hash: ClassHash(x.class_hash.0), + max_fee: Fee(x.max_fee), + nonce: TransactionNonce(x.nonce), + sender_address: ContractAddress(x.sender.0), + signature: x + .signature + .parts + .into_iter() + .map(TransactionSignatureElem) + .collect(), + compiled_class_hash: CasmHash(x.compiled_class_hash), + }), + DeclareV3(x) => Self::DeclareV3(DeclareTransactionV3 { + class_hash: ClassHash(x.class_hash.0), + nonce: TransactionNonce(x.nonce), + nonce_data_availability_mode: DataAvailabilityMode::try_from_dto(x.nonce_domain)?, + fee_data_availability_mode: DataAvailabilityMode::try_from_dto(x.fee_domain)?, + resource_bounds: ResourceBounds::try_from_dto(x.resource_bounds)?, + tip: pathfinder_common::Tip(x.tip.try_into()?), + paymaster_data: vec![pathfinder_common::PaymasterDataElem(x.paymaster_data.0)], + signature: x + .signature + .parts + .into_iter() + .map(TransactionSignatureElem) + .collect(), + account_deployment_data: vec![AccountDeploymentDataElem( + x.account_deployment_data.0, + )], + sender_address: ContractAddress(x.sender.0), + compiled_class_hash: CasmHash(x.compiled_class_hash), + }), + Deploy(x) => Self::Deploy(DeployTransaction { + contract_address: ContractAddress::ZERO, + contract_address_salt: ContractAddressSalt(x.address_salt), + class_hash: ClassHash(x.class_hash.0), + constructor_calldata: x.calldata.into_iter().map(ConstructorParam).collect(), + version: match x.version { + 0 => TransactionVersion::ZERO, + 1 => TransactionVersion::ONE, + _ => anyhow::bail!("Invalid deploy transaction version"), + }, + }), + DeployAccountV1(x) => Self::DeployAccountV0V1(DeployAccountTransactionV0V1 { + contract_address: ContractAddress::ZERO, + max_fee: Fee(x.max_fee), + version: TransactionVersion::ONE, + signature: x + .signature + .parts + .into_iter() + .map(TransactionSignatureElem) + .collect(), + nonce: TransactionNonce(x.nonce), + contract_address_salt: ContractAddressSalt(x.address_salt), + constructor_calldata: x.calldata.into_iter().map(CallParam).collect(), + class_hash: ClassHash(x.class_hash.0), + }), + DeployAccountV3(x) => Self::DeployAccountV3(DeployAccountTransactionV3 { + contract_address: ContractAddress::ZERO, + signature: x + .signature + .parts + .into_iter() + .map(TransactionSignatureElem) + .collect(), + nonce: TransactionNonce(x.nonce), + nonce_data_availability_mode: DataAvailabilityMode::try_from_dto(x.nonce_domain)?, + fee_data_availability_mode: DataAvailabilityMode::try_from_dto(x.fee_domain)?, + resource_bounds: ResourceBounds::try_from_dto(x.resource_bounds)?, + tip: pathfinder_common::Tip(x.tip.try_into()?), + paymaster_data: vec![pathfinder_common::PaymasterDataElem(x.paymaster_data.0)], + contract_address_salt: ContractAddressSalt(x.address_salt), + constructor_calldata: x.calldata.into_iter().map(CallParam).collect(), + class_hash: ClassHash(x.class_hash.0), + }), + InvokeV0(x) => Self::InvokeV0(InvokeTransactionV0 { + calldata: x.calldata.into_iter().map(CallParam).collect(), + sender_address: ContractAddress(x.address.0), + entry_point_selector: EntryPoint(x.entry_point_selector), + entry_point_type: None, + max_fee: Fee(x.max_fee), + signature: x + .signature + .parts + .into_iter() + .map(TransactionSignatureElem) + .collect(), + }), + InvokeV1(x) => Self::InvokeV1(InvokeTransactionV1 { + calldata: x.calldata.into_iter().map(CallParam).collect(), + sender_address: ContractAddress(x.sender.0), + max_fee: Fee(x.max_fee), + signature: x + .signature + .parts + .into_iter() + .map(TransactionSignatureElem) + .collect(), + nonce: TransactionNonce(x.nonce), + }), + InvokeV3(x) => Self::InvokeV3(InvokeTransactionV3 { + signature: x + .signature + .parts + .into_iter() + .map(TransactionSignatureElem) + .collect(), + nonce: TransactionNonce(x.nonce), + nonce_data_availability_mode: DataAvailabilityMode::try_from_dto(x.nonce_domain)?, + fee_data_availability_mode: DataAvailabilityMode::try_from_dto(x.fee_domain)?, + resource_bounds: ResourceBounds::try_from_dto(x.resource_bounds)?, + tip: pathfinder_common::Tip(x.tip.try_into()?), + paymaster_data: vec![pathfinder_common::PaymasterDataElem(x.paymaster_data.0)], + account_deployment_data: vec![AccountDeploymentDataElem( + x.account_deployment_data.0, + )], + calldata: x.calldata.into_iter().map(CallParam).collect(), + sender_address: ContractAddress(x.sender.0), + }), + L1HandlerV0(x) => Self::L1Handler(L1HandlerTransaction { + contract_address: ContractAddress(x.address.0), + entry_point_selector: EntryPoint(x.entry_point_selector), + nonce: TransactionNonce(x.nonce), + calldata: x.calldata.into_iter().map(CallParam).collect(), + }), + }) + } +} + +/// ## Important +/// +/// This conversion leaves event vector empty and transaction index zeroed. +/// The caller is responsible filling those with correct values after the conversion succeeds. +impl TryFromDto for Receipt { + fn try_from_dto(dto: p2p_proto::receipt::Receipt) -> anyhow::Result { + use p2p_proto::receipt::Receipt::{Declare, Deploy, DeployAccount, Invoke, L1Handler}; + use p2p_proto::receipt::{ + DeclareTransactionReceipt, DeployAccountTransactionReceipt, DeployTransactionReceipt, + InvokeTransactionReceipt, L1HandlerTransactionReceipt, + }; + match dto { + Invoke(InvokeTransactionReceipt { common }) + | Declare(DeclareTransactionReceipt { common }) + | L1Handler(L1HandlerTransactionReceipt { common, .. }) + | Deploy(DeployTransactionReceipt { common, .. }) + | DeployAccount(DeployAccountTransactionReceipt { common, .. }) => Ok(Self { + transaction_hash: TransactionHash(common.transaction_hash.0), + actual_fee: Some(Fee(common.actual_fee)), + execution_resources: ExecutionResources { + builtin_instance_counter: BuiltinCounters { + output_builtin: common.execution_resources.builtins.output.into(), + pedersen_builtin: common.execution_resources.builtins.pedersen.into(), + range_check_builtin: common.execution_resources.builtins.range_check.into(), + ecdsa_builtin: common.execution_resources.builtins.ecdsa.into(), + bitwise_builtin: common.execution_resources.builtins.bitwise.into(), + ec_op_builtin: common.execution_resources.builtins.ec_op.into(), + keccak_builtin: common.execution_resources.builtins.keccak.into(), + poseidon_builtin: common.execution_resources.builtins.poseidon.into(), + segment_arena_builtin: 0, + }, + n_steps: common.execution_resources.steps.into(), + n_memory_holes: common.execution_resources.memory_holes.into(), + data_availability: ExecutionDataAvailability { + l1_gas: GasPrice::try_from(common.execution_resources.l1_gas)?.0, + l1_data_gas: GasPrice::try_from(common.execution_resources.l1_data_gas)?.0, + }, + }, + l2_to_l1_messages: common + .messages_sent + .into_iter() + .map(|x| L2ToL1Message { + from_address: ContractAddress(x.from_address), + payload: x + .payload + .into_iter() + .map(L2ToL1MessagePayloadElem) + .collect(), + to_address: EthereumAddress(x.to_address.0), + }) + .collect(), + execution_status: if common.revert_reason.is_empty() { + ExecutionStatus::Succeeded + } else { + ExecutionStatus::Reverted { + reason: common.revert_reason, + } + }, + events: vec![], + transaction_index: TransactionIndex::new_or_panic(0), + }), + } + } +} + +impl TryFromDto for ResourceBounds { + fn try_from_dto(dto: p2p_proto::transaction::ResourceBounds) -> anyhow::Result + where + Self: Sized, + { + Ok(Self { + l1_gas: ResourceBound { + max_amount: pathfinder_common::ResourceAmount(dto.l1_gas.max_amount.try_into()?), + max_price_per_unit: pathfinder_common::ResourcePricePerUnit( + dto.l1_gas.max_price_per_unit.try_into()?, + ), + }, + l2_gas: ResourceBound { + max_amount: pathfinder_common::ResourceAmount(dto.l2_gas.max_amount.try_into()?), + max_price_per_unit: pathfinder_common::ResourcePricePerUnit( + dto.l2_gas.max_price_per_unit.try_into()?, + ), + }, + }) + } +} + +impl TryFromDto for DataAvailabilityMode { + fn try_from_dto(dto: String) -> anyhow::Result + where + Self: Sized, + { + match dto.as_str() { + "L1" => Ok(Self::L1), + "L2" => Ok(Self::L2), + _ => anyhow::bail!("Invalid data availability mode"), + } + } +} + +impl TryFromDto for pathfinder_common::event::Event { + fn try_from_dto(proto: p2p_proto::event::Event) -> anyhow::Result + where + Self: Sized, + { + Ok(Self { + from_address: ContractAddress(proto.from_address), + keys: proto.keys.into_iter().map(EventKey).collect(), + data: proto.data.into_iter().map(EventData).collect(), + }) + } +} + +impl TryFromDto for L1DataAvailabilityMode { + fn try_from_dto(dto: p2p_proto::common::L1DataAvailabilityMode) -> anyhow::Result + where + Self: Sized, + { + use p2p_proto::common::L1DataAvailabilityMode::{Blob, Calldata}; + Ok(match dto { + Calldata => Self::Calldata, + Blob => Self::Blob, + }) + } +} diff --git a/crates/p2p/src/client/peer_agnostic.rs b/crates/p2p/src/client/peer_agnostic.rs index 439f6396a0..085b89903f 100644 --- a/crates/p2p/src/client/peer_agnostic.rs +++ b/crates/p2p/src/client/peer_agnostic.rs @@ -6,22 +6,14 @@ use std::{ time::Duration, }; -use anyhow::Context; use futures::StreamExt; use libp2p::PeerId; use p2p_proto::common::{Direction, Iteration}; use p2p_proto::header::{BlockHeadersRequest, BlockHeadersResponse}; -use pathfinder_common::{ - transaction::{DeployAccountTransactionV0V1, DeployAccountTransactionV3, TransactionVariant}, - BlockNumber, -}; -use pathfinder_common::{BlockHash, ContractAddress}; - -use rayon::prelude::{IntoParallelIterator, ParallelIterator}; +use pathfinder_common::{BlockNumber, SignedBlockHeader}; use tokio::sync::RwLock; -use crate::client::peer_aware; -use crate::client::types::{RawDeployAccountTransaction, SignedBlockHeader}; +use crate::client::{conv::TryFromDto, peer_aware}; use crate::sync::protocol; /// Data received from a specific peer. @@ -145,7 +137,8 @@ impl Client { while let Some(signed_header) = responses.next().await { let signed_header = match signed_header { - BlockHeadersResponse::Header(hdr) => match SignedBlockHeader::try_from(*hdr) { + BlockHeadersResponse::Header(hdr) => + match SignedBlockHeader::try_from_dto(*hdr) { Ok(hdr) => hdr, Err(error) => { tracing::debug!(%peer, %error, "Header stream failed"); @@ -175,71 +168,6 @@ impl Client { } } -// TODO -/// Does not block the current thread. -async fn _compute_contract_addresses( - deploy_account: HashMap>, -) -> anyhow::Result)>> { - let jh = tokio::task::spawn_blocking(move || { - // Now we can compute the missing addresses - let computed: Vec<_> = deploy_account - .into_par_iter() - .map(|(block_hash, transactions)| { - ( - block_hash, - transactions - .into_par_iter() - .map(|t| match t { - RawDeployAccountTransaction::DeployAccountV0V1(x) => { - let contract_address = ContractAddress::deployed_contract_address( - x.constructor_calldata.iter().copied(), - &x.contract_address_salt, - &x.class_hash, - ); - TransactionVariant::DeployAccountV0V1( - DeployAccountTransactionV0V1 { - contract_address, - max_fee: x.max_fee, - version: x.version, - signature: x.signature, - nonce: x.nonce, - contract_address_salt: x.contract_address_salt, - constructor_calldata: x.constructor_calldata, - class_hash: x.class_hash, - }, - ) - } - RawDeployAccountTransaction::DeployAccountV3(x) => { - let contract_address = ContractAddress::deployed_contract_address( - x.constructor_calldata.iter().copied(), - &x.contract_address_salt, - &x.class_hash, - ); - TransactionVariant::DeployAccountV3(DeployAccountTransactionV3 { - contract_address, - signature: x.signature, - nonce: x.nonce, - nonce_data_availability_mode: x.nonce_data_availability_mode, - fee_data_availability_mode: x.fee_data_availability_mode, - resource_bounds: x.resource_bounds, - tip: x.tip, - paymaster_data: x.paymaster_data, - contract_address_salt: x.contract_address_salt, - constructor_calldata: x.constructor_calldata, - class_hash: x.class_hash, - }) - } - }) - .collect::>(), - ) - }) - .collect(); - computed - }); - let computed = jh.await.context("task ended unexpectedly")?; - Ok(computed) -} - #[derive(Clone, Debug)] struct PeersWithCapability { set: HashMap>, diff --git a/crates/p2p/src/client/types.rs b/crates/p2p/src/client/types.rs deleted file mode 100644 index b08acf800c..0000000000 --- a/crates/p2p/src/client/types.rs +++ /dev/null @@ -1,613 +0,0 @@ -//! Conversions between DTOs and common types. -//! -//! Also includes some "bridging" types which should eventually be removed -use pathfinder_common::event::Event; -use pathfinder_common::receipt::{ - BuiltinCounters, ExecutionDataAvailability, ExecutionResources, ExecutionStatus, L2ToL1Message, -}; -use pathfinder_common::transaction::{ - DataAvailabilityMode, DeclareTransactionV0V1, DeclareTransactionV2, DeclareTransactionV3, - DeployAccountTransactionV0V1, DeployAccountTransactionV3, DeployTransaction, - InvokeTransactionV0, InvokeTransactionV1, InvokeTransactionV3, L1HandlerTransaction, - ResourceBound, ResourceBounds, TransactionVariant, -}; -use pathfinder_common::{ - AccountDeploymentDataElem, BlockCommitmentSignature, BlockCommitmentSignatureElem, BlockHash, - BlockNumber, BlockTimestamp, CallParam, CasmHash, ClassHash, ConstructorParam, ContractAddress, - ContractAddressSalt, EntryPoint, EthereumAddress, EventCommitment, EventData, EventKey, Fee, - GasPrice, L1DataAvailabilityMode, L2ToL1MessagePayloadElem, PaymasterDataElem, - SequencerAddress, StarknetVersion, StateCommitment, Tip, TransactionCommitment, - TransactionHash, TransactionNonce, TransactionSignatureElem, TransactionVersion, -}; - -/// We don't want to introduce circular dependencies between crates -/// and we need to work around for the orphan rule - implement conversion fns for types ourside our crate. -pub trait TryFromDto { - fn try_from_dto(dto: T) -> anyhow::Result - where - Self: Sized; -} - -/// Represents a simplified [`pathfinder_common::SignedBlockHeader`], ie. excluding class commitment and storage commitment. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct SignedBlockHeader { - pub header: BlockHeader, - pub signature: BlockCommitmentSignature, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct BlockHeader { - pub hash: BlockHash, - pub parent_hash: BlockHash, - pub number: BlockNumber, - pub timestamp: BlockTimestamp, - pub eth_l1_gas_price: GasPrice, - pub strk_l1_gas_price: GasPrice, - pub eth_l1_data_gas_price: GasPrice, - pub strk_l1_data_gas_price: GasPrice, - pub sequencer_address: SequencerAddress, - pub starknet_version: StarknetVersion, - pub event_commitment: EventCommitment, - pub state_commitment: StateCommitment, - pub transaction_commitment: TransactionCommitment, - pub transaction_count: usize, - pub event_count: usize, - pub l1_da_mode: L1DataAvailabilityMode, -} - -impl SignedBlockHeader { - pub fn verify_signature(&self) -> bool { - // TODO - true - } -} - -impl BlockHeader { - pub fn verify_hash(&self) -> bool { - // TODO - true - } -} - -impl TryFrom for SignedBlockHeader { - type Error = anyhow::Error; - - fn try_from(dto: p2p_proto::header::SignedBlockHeader) -> Result { - anyhow::ensure!(dto.signatures.len() == 1, "expected exactly one signature"); - let signature = dto - .signatures - .into_iter() - .map(|sig| BlockCommitmentSignature { - r: BlockCommitmentSignatureElem(sig.r), - s: BlockCommitmentSignatureElem(sig.s), - }) - .next() - .expect("exactly one element"); - Ok(SignedBlockHeader { - header: BlockHeader { - hash: BlockHash(dto.block_hash.0), - parent_hash: BlockHash(dto.parent_hash.0), - number: BlockNumber::new(dto.number) - .ok_or(anyhow::anyhow!("block number > i64::MAX"))?, - timestamp: BlockTimestamp::new(dto.time) - .ok_or(anyhow::anyhow!("block timestamp > i64::MAX"))?, - eth_l1_gas_price: GasPrice(dto.gas_price_wei), - strk_l1_gas_price: GasPrice(dto.gas_price_fri), - eth_l1_data_gas_price: GasPrice(dto.data_gas_price_wei), - strk_l1_data_gas_price: GasPrice(dto.data_gas_price_fri), - sequencer_address: SequencerAddress(dto.sequencer_address.0), - starknet_version: dto.protocol_version.into(), - event_commitment: EventCommitment(dto.events.root.0), - state_commitment: StateCommitment(dto.state.root.0), - transaction_commitment: TransactionCommitment(dto.transactions.root.0), - transaction_count: dto.transactions.n_leaves.try_into()?, - event_count: dto.events.n_leaves.try_into()?, - l1_da_mode: TryFromDto::try_from_dto(dto.l1_data_availability_mode)?, - }, - signature, - }) - } -} - -impl - From<( - pathfinder_common::BlockHeader, - pathfinder_common::BlockCommitmentSignature, - )> for SignedBlockHeader -{ - fn from( - (header, signature): ( - pathfinder_common::BlockHeader, - pathfinder_common::BlockCommitmentSignature, - ), - ) -> Self { - Self { - header: BlockHeader { - hash: header.hash, - parent_hash: header.parent_hash, - number: header.number, - timestamp: header.timestamp, - eth_l1_gas_price: header.eth_l1_gas_price, - strk_l1_gas_price: header.strk_l1_gas_price, - eth_l1_data_gas_price: header.eth_l1_data_gas_price, - strk_l1_data_gas_price: header.strk_l1_data_gas_price, - sequencer_address: header.sequencer_address, - starknet_version: header.starknet_version, - event_commitment: header.event_commitment, - state_commitment: header.state_commitment, - transaction_commitment: header.transaction_commitment, - transaction_count: header.transaction_count, - event_count: header.event_count, - l1_da_mode: header.l1_da_mode, - }, - signature, - } - } -} - -/// Represents a simplified [`pathfinder_common::receipt::Receipt`] (events and transaction index excluded). -#[derive(Clone, Default, Debug, PartialEq)] -pub struct Receipt { - pub actual_fee: Option, - pub execution_resources: ExecutionResources, - pub l2_to_l1_messages: Vec, - pub execution_status: ExecutionStatus, - pub transaction_hash: TransactionHash, -} - -impl From for Receipt { - fn from(x: pathfinder_common::receipt::Receipt) -> Self { - Self { - transaction_hash: x.transaction_hash, - actual_fee: x.actual_fee, - execution_resources: x.execution_resources, - l2_to_l1_messages: x.l2_to_l1_messages, - execution_status: x.execution_status, - } - } -} - -impl TryFrom for Receipt { - type Error = anyhow::Error; - - fn try_from(proto: p2p_proto::receipt::Receipt) -> anyhow::Result - where - Self: Sized, - { - use p2p_proto::receipt::Receipt::{Declare, Deploy, DeployAccount, Invoke, L1Handler}; - use p2p_proto::receipt::{ - DeclareTransactionReceipt, DeployAccountTransactionReceipt, DeployTransactionReceipt, - InvokeTransactionReceipt, L1HandlerTransactionReceipt, - }; - match proto { - Invoke(InvokeTransactionReceipt { common }) - | Declare(DeclareTransactionReceipt { common }) - | L1Handler(L1HandlerTransactionReceipt { common, .. }) - | Deploy(DeployTransactionReceipt { common, .. }) - | DeployAccount(DeployAccountTransactionReceipt { common, .. }) => Ok(Self { - transaction_hash: TransactionHash(common.transaction_hash.0), - actual_fee: Some(Fee(common.actual_fee)), - execution_resources: ExecutionResources { - builtin_instance_counter: BuiltinCounters { - output_builtin: common.execution_resources.builtins.output.into(), - pedersen_builtin: common.execution_resources.builtins.pedersen.into(), - range_check_builtin: common.execution_resources.builtins.range_check.into(), - ecdsa_builtin: common.execution_resources.builtins.ecdsa.into(), - bitwise_builtin: common.execution_resources.builtins.bitwise.into(), - ec_op_builtin: common.execution_resources.builtins.ec_op.into(), - keccak_builtin: common.execution_resources.builtins.keccak.into(), - poseidon_builtin: common.execution_resources.builtins.poseidon.into(), - segment_arena_builtin: 0, - }, - n_steps: common.execution_resources.steps.into(), - n_memory_holes: common.execution_resources.memory_holes.into(), - data_availability: ExecutionDataAvailability { - l1_gas: GasPrice::from(common.execution_resources.l1_gas).0, - l1_data_gas: GasPrice::from(common.execution_resources.l1_data_gas).0, - }, - }, - l2_to_l1_messages: common - .messages_sent - .into_iter() - .map(|x| L2ToL1Message { - from_address: ContractAddress(x.from_address), - payload: x - .payload - .into_iter() - .map(L2ToL1MessagePayloadElem) - .collect(), - to_address: EthereumAddress(x.to_address.0), - }) - .collect(), - execution_status: if common.revert_reason.is_empty() { - ExecutionStatus::Succeeded - } else { - ExecutionStatus::Reverted { - reason: common.revert_reason, - } - }, - }), - } - } -} - -/// Deployed contract address has not been computed for deploy account transactions. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum RawTransactionVariant { - DeployAccount(RawDeployAccountTransaction), - NonDeployAccount(NonDeployAccountTransaction), -} - -/// Deployed contract address has not been computed. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum RawDeployAccountTransaction { - DeployAccountV0V1(RawDeployAccountTransactionV0V1), - DeployAccountV3(RawDeployAccountTransactionV3), -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum NonDeployAccountTransaction { - DeclareV0(DeclareTransactionV0V1), - DeclareV1(DeclareTransactionV0V1), - DeclareV2(DeclareTransactionV2), - DeclareV3(DeclareTransactionV3), - // Regenesis: deploy is a legacy variant and can be removed after regenesis. - Deploy(DeployTransaction), - InvokeV0(InvokeTransactionV0), - InvokeV1(InvokeTransactionV1), - InvokeV3(InvokeTransactionV3), - L1Handler(L1HandlerTransaction), -} - -/// Deployed contract address has not been computed. -#[derive(Clone, Default, Debug, PartialEq, Eq)] -pub struct RawDeployAccountTransactionV0V1 { - pub max_fee: Fee, - pub version: TransactionVersion, - pub signature: Vec, - pub nonce: TransactionNonce, - pub contract_address_salt: ContractAddressSalt, - pub constructor_calldata: Vec, - pub class_hash: ClassHash, -} - -/// Deployed contract address has not been computed. -#[derive(Clone, Default, Debug, PartialEq, Eq)] -pub struct RawDeployAccountTransactionV3 { - pub signature: Vec, - pub nonce: TransactionNonce, - pub nonce_data_availability_mode: DataAvailabilityMode, - pub fee_data_availability_mode: DataAvailabilityMode, - pub resource_bounds: ResourceBounds, - pub tip: Tip, - pub paymaster_data: Vec, - pub contract_address_salt: ContractAddressSalt, - pub constructor_calldata: Vec, - pub class_hash: ClassHash, -} - -impl NonDeployAccountTransaction { - pub fn into_variant(self) -> TransactionVariant { - use NonDeployAccountTransaction::*; - match self { - DeclareV0(x) => TransactionVariant::DeclareV0(x), - DeclareV1(x) => TransactionVariant::DeclareV1(x), - DeclareV2(x) => TransactionVariant::DeclareV2(x), - DeclareV3(x) => TransactionVariant::DeclareV3(x), - Deploy(x) => TransactionVariant::Deploy(x), - InvokeV0(x) => TransactionVariant::InvokeV0(x), - InvokeV1(x) => TransactionVariant::InvokeV1(x), - InvokeV3(x) => TransactionVariant::InvokeV3(x), - L1Handler(x) => TransactionVariant::L1Handler(x), - } - } -} - -impl From for RawTransactionVariant { - fn from(x: TransactionVariant) -> Self { - use TransactionVariant::*; - match x { - DeclareV0(x) => Self::NonDeployAccount(NonDeployAccountTransaction::DeclareV0(x)), - DeclareV1(x) => Self::NonDeployAccount(NonDeployAccountTransaction::DeclareV1(x)), - DeclareV2(x) => Self::NonDeployAccount(NonDeployAccountTransaction::DeclareV2(x)), - DeclareV3(x) => Self::NonDeployAccount(NonDeployAccountTransaction::DeclareV3(x)), - Deploy(x) => Self::NonDeployAccount(NonDeployAccountTransaction::Deploy(x)), - InvokeV0(x) => Self::NonDeployAccount(NonDeployAccountTransaction::InvokeV0(x)), - InvokeV1(x) => Self::NonDeployAccount(NonDeployAccountTransaction::InvokeV1(x)), - InvokeV3(x) => Self::NonDeployAccount(NonDeployAccountTransaction::InvokeV3(x)), - L1Handler(x) => Self::NonDeployAccount(NonDeployAccountTransaction::L1Handler(x)), - DeployAccountV0V1(x) => { - Self::DeployAccount(RawDeployAccountTransaction::DeployAccountV0V1(x.into())) - } - DeployAccountV3(x) => { - Self::DeployAccount(RawDeployAccountTransaction::DeployAccountV3(x.into())) - } - } - } -} - -impl From for RawDeployAccountTransactionV0V1 { - fn from(x: DeployAccountTransactionV0V1) -> Self { - Self { - max_fee: x.max_fee, - version: x.version, - signature: x.signature, - nonce: x.nonce, - contract_address_salt: x.contract_address_salt, - constructor_calldata: x.constructor_calldata, - class_hash: x.class_hash, - } - } -} - -impl From for RawDeployAccountTransactionV3 { - fn from(x: DeployAccountTransactionV3) -> Self { - Self { - signature: x.signature, - nonce: x.nonce, - nonce_data_availability_mode: x.nonce_data_availability_mode, - fee_data_availability_mode: x.fee_data_availability_mode, - resource_bounds: x.resource_bounds, - tip: x.tip, - paymaster_data: x.paymaster_data, - contract_address_salt: x.contract_address_salt, - constructor_calldata: x.constructor_calldata, - class_hash: x.class_hash, - } - } -} - -impl TryFromDto for RawTransactionVariant { - /// ## Important - /// - /// This conversion does not compute deployed contract address for deploy account transactions - /// ([`TransactionVariant::DeployAccountV0V1`] and [`TransactionVariant::DeployAccountV3`]), - /// filling it with a zero address instead. The caller is responsible for performing the computation after the conversion succeeds. - fn try_from_dto(dto: p2p_proto::transaction::TransactionVariant) -> anyhow::Result - where - Self: Sized, - { - use p2p_proto::transaction::TransactionVariant::*; - - Ok(match dto { - DeclareV0(x) => RawTransactionVariant::NonDeployAccount( - NonDeployAccountTransaction::DeclareV0(DeclareTransactionV0V1 { - class_hash: ClassHash(x.class_hash.0), - max_fee: Fee(x.max_fee), - nonce: TransactionNonce::ZERO, - sender_address: ContractAddress(x.sender.0), - signature: x - .signature - .parts - .into_iter() - .map(TransactionSignatureElem) - .collect(), - }), - ), - DeclareV1(x) => RawTransactionVariant::NonDeployAccount( - NonDeployAccountTransaction::DeclareV1(DeclareTransactionV0V1 { - class_hash: ClassHash(x.class_hash.0), - max_fee: Fee(x.max_fee), - nonce: TransactionNonce(x.nonce), - sender_address: ContractAddress(x.sender.0), - signature: x - .signature - .parts - .into_iter() - .map(TransactionSignatureElem) - .collect(), - }), - ), - DeclareV2(x) => RawTransactionVariant::NonDeployAccount( - NonDeployAccountTransaction::DeclareV2(DeclareTransactionV2 { - class_hash: ClassHash(x.class_hash.0), - max_fee: Fee(x.max_fee), - nonce: TransactionNonce(x.nonce), - sender_address: ContractAddress(x.sender.0), - signature: x - .signature - .parts - .into_iter() - .map(TransactionSignatureElem) - .collect(), - compiled_class_hash: CasmHash(x.compiled_class_hash), - }), - ), - DeclareV3(x) => RawTransactionVariant::NonDeployAccount( - NonDeployAccountTransaction::DeclareV3(DeclareTransactionV3 { - class_hash: ClassHash(x.class_hash.0), - nonce: TransactionNonce(x.nonce), - nonce_data_availability_mode: DataAvailabilityMode::try_from_dto( - x.nonce_domain, - )?, - fee_data_availability_mode: DataAvailabilityMode::try_from_dto(x.fee_domain)?, - resource_bounds: ResourceBounds::try_from_dto(x.resource_bounds)?, - tip: pathfinder_common::Tip(x.tip.try_into()?), - paymaster_data: vec![pathfinder_common::PaymasterDataElem(x.paymaster_data.0)], - signature: x - .signature - .parts - .into_iter() - .map(TransactionSignatureElem) - .collect(), - account_deployment_data: vec![AccountDeploymentDataElem( - x.account_deployment_data.0, - )], - sender_address: ContractAddress(x.sender.0), - compiled_class_hash: CasmHash(x.compiled_class_hash), - }), - ), - Deploy(x) => RawTransactionVariant::NonDeployAccount( - NonDeployAccountTransaction::Deploy(DeployTransaction { - contract_address: ContractAddress::ZERO, // FIXME: compute deployed contract address - contract_address_salt: ContractAddressSalt(x.address_salt), - class_hash: ClassHash(x.class_hash.0), - constructor_calldata: x.calldata.into_iter().map(ConstructorParam).collect(), - version: match x.version { - 0 => TransactionVersion::ZERO, - 1 => TransactionVersion::ONE, - _ => anyhow::bail!("Invalid deploy transaction version"), - }, - }), - ), - DeployAccountV1(x) => RawTransactionVariant::DeployAccount( - RawDeployAccountTransaction::DeployAccountV0V1(RawDeployAccountTransactionV0V1 { - max_fee: Fee(x.max_fee), - version: TransactionVersion::ONE, - signature: x - .signature - .parts - .into_iter() - .map(TransactionSignatureElem) - .collect(), - nonce: TransactionNonce(x.nonce), - contract_address_salt: ContractAddressSalt(x.address_salt), - constructor_calldata: x.calldata.into_iter().map(CallParam).collect(), - class_hash: ClassHash(x.class_hash.0), - }), - ), - DeployAccountV3(x) => RawTransactionVariant::DeployAccount( - RawDeployAccountTransaction::DeployAccountV3(RawDeployAccountTransactionV3 { - signature: x - .signature - .parts - .into_iter() - .map(TransactionSignatureElem) - .collect(), - nonce: TransactionNonce(x.nonce), - nonce_data_availability_mode: DataAvailabilityMode::try_from_dto( - x.nonce_domain, - )?, - fee_data_availability_mode: DataAvailabilityMode::try_from_dto(x.fee_domain)?, - resource_bounds: ResourceBounds::try_from_dto(x.resource_bounds)?, - tip: pathfinder_common::Tip(x.tip.try_into()?), - paymaster_data: vec![pathfinder_common::PaymasterDataElem(x.paymaster_data.0)], - contract_address_salt: ContractAddressSalt(x.address_salt), - constructor_calldata: x.calldata.into_iter().map(CallParam).collect(), - class_hash: ClassHash(x.class_hash.0), - }), - ), - InvokeV0(x) => RawTransactionVariant::NonDeployAccount( - NonDeployAccountTransaction::InvokeV0(InvokeTransactionV0 { - calldata: x.calldata.into_iter().map(CallParam).collect(), - sender_address: ContractAddress(x.address.0), - entry_point_selector: EntryPoint(x.entry_point_selector), - entry_point_type: None, - max_fee: Fee(x.max_fee), - signature: x - .signature - .parts - .into_iter() - .map(TransactionSignatureElem) - .collect(), - }), - ), - InvokeV1(x) => RawTransactionVariant::NonDeployAccount( - NonDeployAccountTransaction::InvokeV1(InvokeTransactionV1 { - calldata: x.calldata.into_iter().map(CallParam).collect(), - sender_address: ContractAddress(x.sender.0), - max_fee: Fee(x.max_fee), - signature: x - .signature - .parts - .into_iter() - .map(TransactionSignatureElem) - .collect(), - nonce: TransactionNonce(x.nonce), - }), - ), - InvokeV3(x) => RawTransactionVariant::NonDeployAccount( - NonDeployAccountTransaction::InvokeV3(InvokeTransactionV3 { - signature: x - .signature - .parts - .into_iter() - .map(TransactionSignatureElem) - .collect(), - nonce: TransactionNonce(x.nonce), - nonce_data_availability_mode: DataAvailabilityMode::try_from_dto( - x.nonce_domain, - )?, - fee_data_availability_mode: DataAvailabilityMode::try_from_dto(x.fee_domain)?, - resource_bounds: ResourceBounds::try_from_dto(x.resource_bounds)?, - tip: pathfinder_common::Tip(x.tip.try_into()?), - paymaster_data: vec![pathfinder_common::PaymasterDataElem(x.paymaster_data.0)], - account_deployment_data: vec![AccountDeploymentDataElem( - x.account_deployment_data.0, - )], - calldata: x.calldata.into_iter().map(CallParam).collect(), - sender_address: ContractAddress(x.sender.0), - }), - ), - L1HandlerV0(x) => RawTransactionVariant::NonDeployAccount( - NonDeployAccountTransaction::L1Handler(L1HandlerTransaction { - contract_address: ContractAddress(x.address.0), - entry_point_selector: EntryPoint(x.entry_point_selector), - nonce: TransactionNonce(x.nonce), - calldata: x.calldata.into_iter().map(CallParam).collect(), - }), - ), - }) - } -} - -impl TryFromDto for ResourceBounds { - fn try_from_dto(dto: p2p_proto::transaction::ResourceBounds) -> anyhow::Result - where - Self: Sized, - { - Ok(Self { - l1_gas: ResourceBound { - max_amount: pathfinder_common::ResourceAmount(dto.l1_gas.max_amount.try_into()?), - max_price_per_unit: pathfinder_common::ResourcePricePerUnit( - dto.l1_gas.max_price_per_unit.try_into()?, - ), - }, - l2_gas: ResourceBound { - max_amount: pathfinder_common::ResourceAmount(dto.l2_gas.max_amount.try_into()?), - max_price_per_unit: pathfinder_common::ResourcePricePerUnit( - dto.l2_gas.max_price_per_unit.try_into()?, - ), - }, - }) - } -} - -impl TryFromDto for Event { - fn try_from_dto(proto: p2p_proto::event::Event) -> anyhow::Result - where - Self: Sized, - { - Ok(Self { - from_address: ContractAddress(proto.from_address), - keys: proto.keys.into_iter().map(EventKey).collect(), - data: proto.data.into_iter().map(EventData).collect(), - }) - } -} - -impl TryFromDto for DataAvailabilityMode { - fn try_from_dto(dto: String) -> anyhow::Result - where - Self: Sized, - { - match dto.as_str() { - "L1" => Ok(Self::L1), - "L2" => Ok(Self::L2), - _ => anyhow::bail!("Invalid data availability mode"), - } - } -} - -impl TryFromDto for L1DataAvailabilityMode { - fn try_from_dto(dto: p2p_proto::common::L1DataAvailabilityMode) -> anyhow::Result - where - Self: Sized, - { - use p2p_proto::common::L1DataAvailabilityMode::{Blob, Calldata}; - Ok(match dto { - Calldata => Self::Calldata, - Blob => Self::Blob, - }) - } -} diff --git a/crates/pathfinder/src/p2p_network/sync_handlers/tests.rs b/crates/pathfinder/src/p2p_network/sync_handlers/tests.rs index 900bbff2b8..fc5153b279 100644 --- a/crates/pathfinder/src/p2p_network/sync_handlers/tests.rs +++ b/crates/pathfinder/src/p2p_network/sync_handlers/tests.rs @@ -99,7 +99,7 @@ mod prop { use crate::p2p_network::sync_handlers; use futures::channel::mpsc; use futures::StreamExt; - use p2p::client::types::{RawTransactionVariant, Receipt, SignedBlockHeader, TryFromDto}; + use p2p::client::conv::TryFromDto; use p2p_proto::class::{Class, ClassesRequest, ClassesResponse}; use p2p_proto::common::{BlockNumberOrHash, Iteration}; use p2p_proto::event::{EventsRequest, EventsResponse}; @@ -110,12 +110,14 @@ mod prop { }; use p2p_proto::transaction::{TransactionsRequest, TransactionsResponse}; use pathfinder_common::event::Event; + use pathfinder_common::receipt::Receipt; use pathfinder_common::state_update::{ ContractClassUpdate, ContractUpdate, SystemContractUpdate, }; + use pathfinder_common::transaction::TransactionVariant; use pathfinder_common::{ - ClassHash, ContractAddress, ContractNonce, SierraHash, StorageAddress, StorageValue, - TransactionHash, + ClassCommitment, ClassHash, ContractAddress, ContractNonce, SierraHash, SignedBlockHeader, + StorageAddress, StorageCommitment, StorageValue, TransactionHash, TransactionIndex, }; use pathfinder_crypto::Felt; use proptest::prelude::*; @@ -160,7 +162,14 @@ mod prop { // Compute the overlapping set between the db and the request // These are the headers that we expect to be read from the db let expected = overlapping::get(in_db, start_block, limit, step, num_blocks, direction) - .into_iter().map(|(h, s, _, _, _, _)| SignedBlockHeader::from((h, s)) ).collect::>(); + .into_iter().map(|(mut h, s, _, _, _, _)| { + // P2P headers don't carry class commitment and storage commitment, so zero them just like `try_from_dto` does + h.class_commitment = ClassCommitment::ZERO; + h.storage_commitment = StorageCommitment::ZERO; + SignedBlockHeader{ + header: h, + signature: s, + }}).collect::>(); // Run the handler let request = BlockHeadersRequest { iteration: Iteration { start: BlockNumberOrHash::Number(start_block), limit, step, direction, } }; let mut responses = Runtime::new().unwrap().block_on(async { @@ -179,7 +188,7 @@ mod prop { // Check the rest let actual = responses.into_iter().map(|response| match response { - BlockHeadersResponse::Header(hdr) => SignedBlockHeader::try_from(*hdr).unwrap(), + BlockHeadersResponse::Header(hdr) => SignedBlockHeader::try_from_dto(*hdr).unwrap(), _ => panic!("unexpected response"), }).collect::>(); @@ -261,6 +270,7 @@ mod prop { } proptest! { + #![proptest_config(ProptestConfig::with_cases(50))] #[test] fn get_classes((num_blocks, seed, start_block, limit, step, direction) in strategy::composite()) { // Fake storage with a given number of blocks @@ -360,10 +370,17 @@ mod prop { ( // Block number h.number, - // List of tuples (Transaction hash, Raw transaction variant) + // List of tuples (Transaction hash, Transaction variant) tr.into_iter().map(|(t, _)| { - let txn = workaround::for_legacy_l1_handlers(t); - (txn.hash, RawTransactionVariant::from(txn.variant)) + let mut txn = workaround::for_legacy_l1_handlers(t); + // P2P transactions don't carry contract address, so zero them just like `try_from_dto` does + match &mut txn.variant { + TransactionVariant::Deploy(x) => x.contract_address = ContractAddress::ZERO, + TransactionVariant::DeployAccountV0V1(x) => x.contract_address = ContractAddress::ZERO, + TransactionVariant::DeployAccountV3(x) => x.contract_address = ContractAddress::ZERO, + _ => {} + }; + (txn.hash, txn.variant) }).collect::>() ) ).collect::>(); @@ -381,7 +398,7 @@ mod prop { // Check the rest let mut actual = responses.into_iter().map(|response| match response { - TransactionsResponse::Transaction(txn) => (TransactionHash(txn.hash.0), RawTransactionVariant::try_from_dto(txn.variant).unwrap()), + TransactionsResponse::Transaction(txn) => (TransactionHash(txn.hash.0), TransactionVariant::try_from_dto(txn.variant).unwrap()), _ => panic!("unexpected response"), }).collect::>(); @@ -406,7 +423,12 @@ mod prop { // Block number h.number, // List of receipts - tr.into_iter().map(|(_, r)| Receipt::from(r)).collect::>() + tr.into_iter().map(|(_, mut r)| { + // P2P receipts don't carry events and transaction index + r.events = vec![]; + r.transaction_index = TransactionIndex::new_or_panic(0); + r + }).collect::>() ) ).collect::>(); // Run the handler @@ -423,7 +445,7 @@ mod prop { // Check the rest let mut actual = responses.into_iter().map(|response| match response { - ReceiptsResponse::Receipt(receipt) => Receipt::try_from(receipt).unwrap(), + ReceiptsResponse::Receipt(receipt) => Receipt::try_from_dto(receipt).unwrap(), _ => panic!("unexpected response"), }).collect::>(); diff --git a/crates/pathfinder/src/sync/p2p/headers.rs b/crates/pathfinder/src/sync/p2p/headers.rs index 268a54f921..6eb5b0caf8 100644 --- a/crates/pathfinder/src/sync/p2p/headers.rs +++ b/crates/pathfinder/src/sync/p2p/headers.rs @@ -1,7 +1,9 @@ #![allow(dead_code, unused_variables)] use anyhow::Context; -use p2p::{client::types::SignedBlockHeader, PeerData}; -use pathfinder_common::{BlockHash, BlockNumber, ClassCommitment, StorageCommitment}; +use p2p::PeerData; +use pathfinder_common::{ + BlockHash, BlockNumber, ClassCommitment, SignedBlockHeader, StorageCommitment, +}; use pathfinder_storage::Storage; use tokio::task::spawn_blocking;