Skip to content

Commit

Permalink
split receipts and events in common crate
Browse files Browse the repository at this point in the history
  • Loading branch information
sistemd committed Mar 12, 2024
1 parent 8d40ea8 commit 1cd5a2a
Show file tree
Hide file tree
Showing 31 changed files with 434 additions and 237 deletions.
1 change: 0 additions & 1 deletion crates/common/src/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::prelude::*;
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct Receipt {
pub actual_fee: Option<Fee>,
pub events: Vec<crate::event::Event>,
pub execution_resources: ExecutionResources,
pub l2_to_l1_messages: Vec<L2ToL1Message>,
pub execution_status: ExecutionStatus,
Expand Down
128 changes: 86 additions & 42 deletions crates/gateway-types/src/reply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ pub struct Block {
pub status: Status,
pub timestamp: BlockTimestamp,
#[serde_as(as = "Vec<transaction::Receipt>")]
pub transaction_receipts: Vec<pathfinder_common::receipt::Receipt>,
pub transaction_receipts: Vec<(
pathfinder_common::receipt::Receipt,
Vec<pathfinder_common::event::Event>,
)>,
#[serde_as(as = "Vec<transaction::Transaction>")]
pub transactions: Vec<pathfinder_common::transaction::Transaction>,
/// Version metadata introduced in 0.9.1, older blocks will not have it.
Expand Down Expand Up @@ -125,7 +128,10 @@ pub struct PendingBlock {
pub status: Status,
pub timestamp: BlockTimestamp,
#[serde_as(as = "Vec<transaction::Receipt>")]
pub transaction_receipts: Vec<pathfinder_common::receipt::Receipt>,
pub transaction_receipts: Vec<(
pathfinder_common::receipt::Receipt,
Vec<pathfinder_common::event::Event>,
)>,
#[serde_as(as = "Vec<transaction::Transaction>")]
pub transactions: Vec<pathfinder_common::transaction::Transaction>,
/// Version metadata introduced in 0.9.1, older blocks will not have it.
Expand Down Expand Up @@ -593,40 +599,26 @@ pub(crate) mod transaction {
pub revert_error: Option<String>,
}

impl<'de> serde_with::DeserializeAs<'de, pathfinder_common::receipt::Receipt> for Receipt {
fn deserialize_as<D>(
deserializer: D,
) -> Result<pathfinder_common::receipt::Receipt, D::Error>
where
D: serde::Deserializer<'de>,
{
Self::deserialize(deserializer).map(Into::into)
}
}

impl serde_with::SerializeAs<pathfinder_common::receipt::Receipt> for Receipt {
fn serialize_as<S>(
source: &pathfinder_common::receipt::Receipt,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
Self::from(source.clone()).serialize(serializer)
}
}

impl From<pathfinder_common::receipt::Receipt> for Receipt {
fn from(value: pathfinder_common::receipt::Receipt) -> Self {
impl
From<(
pathfinder_common::receipt::Receipt,
Vec<pathfinder_common::event::Event>,
)> for Receipt
{
fn from(
(receipt, events): (
pathfinder_common::receipt::Receipt,
Vec<pathfinder_common::event::Event>,
),
) -> Self {
let pathfinder_common::receipt::Receipt {
actual_fee,
events,
execution_resources,
l2_to_l1_messages,
execution_status,
transaction_hash,
transaction_index,
} = value;
} = receipt;

let (execution_status, revert_error) = match execution_status {
pathfinder_common::receipt::ExecutionStatus::Succeeded => {
Expand All @@ -651,7 +643,57 @@ pub(crate) mod transaction {
}
}

impl From<Receipt> for pathfinder_common::receipt::Receipt {
impl<'de>
serde_with::DeserializeAs<
'de,
(
pathfinder_common::receipt::Receipt,
Vec<pathfinder_common::event::Event>,
),
> for Receipt
{
fn deserialize_as<D>(
deserializer: D,
) -> Result<
(
pathfinder_common::receipt::Receipt,
Vec<pathfinder_common::event::Event>,
),
D::Error,
>
where
D: serde::Deserializer<'de>,
{
Self::deserialize(deserializer).map(Into::into)
}
}

impl
serde_with::SerializeAs<(
pathfinder_common::receipt::Receipt,
Vec<pathfinder_common::event::Event>,
)> for Receipt
{
fn serialize_as<S>(
(receipt, events): &(
pathfinder_common::receipt::Receipt,
Vec<pathfinder_common::event::Event>,
),
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
Self::from((receipt.clone(), events.clone())).serialize(serializer)
}
}

impl From<Receipt>
for (
pathfinder_common::receipt::Receipt,
Vec<pathfinder_common::event::Event>,
)
{
fn from(value: Receipt) -> Self {
use pathfinder_common::receipt as common;

Expand All @@ -668,20 +710,22 @@ pub(crate) mod transaction {
revert_error,
} = value;

common::Receipt {
actual_fee,
events,
execution_resources: execution_resources.unwrap_or_default().into(),
l2_to_l1_messages: l2_to_l1_messages.into_iter().map(Into::into).collect(),
transaction_hash,
transaction_index,
execution_status: match execution_status {
ExecutionStatus::Succeeded => common::ExecutionStatus::Succeeded,
ExecutionStatus::Reverted => common::ExecutionStatus::Reverted {
reason: revert_error.unwrap_or_default(),
(
common::Receipt {
actual_fee,
execution_resources: execution_resources.unwrap_or_default().into(),
l2_to_l1_messages: l2_to_l1_messages.into_iter().map(Into::into).collect(),
transaction_hash,
transaction_index,
execution_status: match execution_status {
ExecutionStatus::Succeeded => common::ExecutionStatus::Succeeded,
ExecutionStatus::Reverted => common::ExecutionStatus::Reverted {
reason: revert_error.unwrap_or_default(),
},
},
},
}
events,
)
}
}

Expand Down
7 changes: 4 additions & 3 deletions crates/p2p/src/client/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,12 @@ impl TryFromDto<p2p_proto::transaction::TransactionVariant> for TransactionVaria
}
}

// TODO Change this: instead of From, have a into_common method that also accepts the transaction
// index
/// ## Important
///
/// This conversion leaves event vector empty and transaction index zeroed.
/// The caller is responsible filling those with correct values after the conversion succeeds.
/// This conversion leaves the transaction index zeroed.
/// The caller is responsible for filling in the correct transaction index after the conversion succeeds.
impl TryFromDto<p2p_proto::receipt::Receipt> for Receipt {
fn try_from_dto(dto: p2p_proto::receipt::Receipt) -> anyhow::Result<Self> {
use p2p_proto::receipt::Receipt::{Declare, Deploy, DeployAccount, Invoke, L1Handler};
Expand Down Expand Up @@ -310,7 +312,6 @@ impl TryFromDto<p2p_proto::receipt::Receipt> for Receipt {
reason: common.revert_reason,
}
},
events: vec![],
transaction_index: TransactionIndex::new_or_panic(0),
}),
}
Expand Down
6 changes: 4 additions & 2 deletions crates/pathfinder/examples/feeder_gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,10 @@ fn resolve_block(
.context("Reading transactions from database")?
.context("Transaction data missing")?;

let (transactions, transaction_receipts): (Vec<_>, Vec<_>) =
transactions_receipts.into_iter().unzip();
let (transactions, transaction_receipts): (Vec<_>, Vec<_>) = transactions_receipts
.into_iter()
.map(|(tx, rx, ev)| (tx, (rx, ev)))
.unzip();

let block_status = tx
.block_is_l1_accepted(header.number.into())
Expand Down
6 changes: 4 additions & 2 deletions crates/pathfinder/examples/re_execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ fn main() -> anyhow::Result<()> {
.unwrap();
drop(transaction);

let (transactions, receipts): (Vec<_>, Vec<_>) =
transactions_and_receipts.into_iter().unzip();
let (transactions, receipts): (Vec<_>, Vec<_>) = transactions_and_receipts
.into_iter()
.map(|(tx, rx, _ev)| (tx, rx))
.unzip();

num_transactions += transactions.len();

Expand Down
6 changes: 4 additions & 2 deletions crates/pathfinder/examples/verify_block_hashes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ fn main() -> anyhow::Result<()> {
drop(tx);

let block_hash = header.hash;
let (transactions, receipts): (Vec<_>, Vec<_>) =
transactions_and_receipts.into_iter().unzip();
let (transactions, receipts): (Vec<_>, Vec<_>) = transactions_and_receipts
.into_iter()
.map(|(tx, rx, ev)| (tx, (rx, ev)))
.unzip();

let block = Block {
block_hash: header.hash,
Expand Down
2 changes: 1 addition & 1 deletion crates/pathfinder/examples/verify_transaction_hashes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn main() -> anyhow::Result<()> {
transactions
.par_iter()
.enumerate()
.for_each(|(i, (txn, _))| {
.for_each(|(i, (txn, _, _))| {
if !txn.verify_hash(chain_id) {
println!("Mismatch: block {block_number} idx {i}. Full_txn\n{txn:?}",);
}
Expand Down
10 changes: 5 additions & 5 deletions crates/pathfinder/src/p2p_network/sync_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ fn get_transactions_for_block(
return Ok(false);
};

for (txn, _) in txn_data {
for (txn, _, _) in txn_data {
tx.blocking_send(TransactionsResponse::Transaction(txn.to_dto()))
.map_err(|_| anyhow::anyhow!("Sending transaction"))?;
}
Expand All @@ -338,8 +338,8 @@ fn get_receipts_for_block(
return Ok(false);
};

for tr in txn_data {
tx.blocking_send(ReceiptsResponse::Receipt(tr.to_dto()))
for (txn, r, _) in txn_data {
tx.blocking_send(ReceiptsResponse::Receipt((txn, r).to_dto()))
.map_err(|_| anyhow::anyhow!("Sending receipt"))?;
}

Expand All @@ -355,8 +355,8 @@ fn get_events_for_block(
return Ok(false);
};

for (_, r) in txn_data {
for event in r.events {
for (_, r, events) in txn_data {
for event in events {
tx.blocking_send(EventsResponse::Event((r.transaction_hash, event).to_dto()))
.map_err(|_| anyhow::anyhow!("Sending event"))?;
}
Expand Down
8 changes: 3 additions & 5 deletions crates/pathfinder/src/p2p_network/sync_handlers/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ mod prop {
// Block number
h.number,
// List of tuples (Transaction hash, Transaction variant)
tr.into_iter().map(|(t, _)| {
tr.into_iter().map(|(t, _, _)| {
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 {
Expand Down Expand Up @@ -423,9 +423,7 @@ mod prop {
// Block number
h.number,
// List of receipts
tr.into_iter().map(|(_, mut r)| {
// P2P receipts don't carry events and transaction index
r.events = vec![];
tr.into_iter().map(|(_, mut r, _)| {
r.transaction_index = TransactionIndex::new_or_panic(0);
r
}).collect::<Vec<_>>()
Expand Down Expand Up @@ -470,7 +468,7 @@ mod prop {
// Block number
h.number,
// List of tuples (Transaction hash, Event)
tr.into_iter().flat_map(|(_, r)| r.events.into_iter().map(move |event| (r.transaction_hash, event)))
tr.into_iter().flat_map(|(_, r, events)| events.into_iter().map(move |event| (r.transaction_hash, event)))
.collect::<Vec<(TransactionHash, Event)>>()
)
).collect::<Vec<_>>();
Expand Down
16 changes: 10 additions & 6 deletions crates/pathfinder/src/state/block_hash.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use anyhow::{Context, Result};
use pathfinder_common::event::Event;
use pathfinder_common::receipt::Receipt;
use pathfinder_common::transaction::{Transaction, TransactionVariant};
use pathfinder_common::{
BlockHash, BlockNumber, BlockTimestamp, Chain, ChainId, EventCommitment, SequencerAddress,
Expand Down Expand Up @@ -53,7 +52,12 @@ pub fn verify_block_hash(
TransactionCommitmentFinalHashType::for_version(&block.starknet_version)?;
let transaction_commitment =
calculate_transaction_commitment(&block.transactions, transaction_final_hash_type)?;
let event_commitment = calculate_event_commitment(&block.transaction_receipts)?;
let events: Vec<_> = block
.transaction_receipts
.iter()
.map(|(_, events)| events.clone())
.collect();
let event_commitment = calculate_event_commitment(&events)?;

let verified = if meta_info.uses_pre_0_7_hash_algorithm(block.block_number) {
anyhow::ensure!(
Expand Down Expand Up @@ -428,15 +432,15 @@ fn calculate_signature_hash(signature: &[TransactionSignatureElem]) -> Felt {
/// The event commitment is the root of the Patricia Merkle tree with height 64
/// constructed by adding the (event_index, event_hash) key-value pairs to the
/// tree and computing the root hash.
pub fn calculate_event_commitment(transaction_receipts: &[Receipt]) -> Result<EventCommitment> {
pub fn calculate_event_commitment(events: &[Vec<Event>]) -> Result<EventCommitment> {
use rayon::prelude::*;

let mut event_hashes = Vec::new();
rayon::scope(|s| {
s.spawn(|_| {
event_hashes = transaction_receipts
event_hashes = events
.par_iter()
.flat_map(|receipt| receipt.events.par_iter())
.flat_map(|events| events.par_iter())
.map(calculate_event_hash)
.collect();
})
Expand Down Expand Up @@ -488,7 +492,7 @@ fn number_of_events_in_block(block: &Block) -> usize {
block
.transaction_receipts
.iter()
.flat_map(|r| r.events.iter())
.flat_map(|(_, events)| events.iter())
.count()
}

Expand Down
11 changes: 9 additions & 2 deletions crates/pathfinder/src/state/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ async fn l2_update(
let event_count = block
.transaction_receipts
.iter()
.map(|r| r.events.len())
.map(|(_, events)| events.len())
.sum();

// Update L2 database. These types shouldn't be options at this level,
Expand Down Expand Up @@ -821,7 +821,14 @@ async fn l2_update(
let transaction_data = block
.transactions
.into_iter()
.zip(block.transaction_receipts.into_iter().map(Some))
.zip(block.transaction_receipts.into_iter())
.map(
|(tx, (receipt, events))| pathfinder_storage::TransactionData {
transaction: tx,
receipt: Some(receipt),
events: Some(events),
},
)
.collect::<Vec<_>>();

transaction
Expand Down
6 changes: 5 additions & 1 deletion crates/pathfinder/src/sync/p2p/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ pub(super) async fn persist(
block.number,
&transactions
.into_iter()
.map(|tx| (tx, None))
.map(|tx| pathfinder_storage::TransactionData {
transaction: tx,
receipt: None,
events: None,
})
.collect::<Vec<_>>(),
)
.context("Inserting transactions")?;
Expand Down
Loading

0 comments on commit 1cd5a2a

Please sign in to comment.