diff --git a/crates/papyrus_protobuf/src/consensus.rs b/crates/papyrus_protobuf/src/consensus.rs index d4156ce270..894b035b5e 100644 --- a/crates/papyrus_protobuf/src/consensus.rs +++ b/crates/papyrus_protobuf/src/consensus.rs @@ -2,7 +2,7 @@ use futures::channel::{mpsc, oneshot}; use starknet_api::block::{BlockHash, BlockNumber}; use starknet_api::core::ContractAddress; use starknet_api::executable_transaction::Transaction as ExecutableTransaction; -use starknet_api::transaction::Transaction; +use starknet_api::transaction::{Transaction, TransactionHash}; use crate::converters::ProtobufConversionError; @@ -78,6 +78,9 @@ pub struct ProposalInit { pub struct TransactionBatch { /// The transactions in the batch. pub transactions: Vec, + // TODO(guyn): remove this once we settle how to convert transactions to ExecutableTransactions + /// The hashes of each transaction. + pub tx_hashes: Vec, } /// The propsal is done when receiving this fin message, which contains the block hash. diff --git a/crates/papyrus_protobuf/src/converters/consensus.rs b/crates/papyrus_protobuf/src/converters/consensus.rs index ad80418e65..178c7c9589 100644 --- a/crates/papyrus_protobuf/src/converters/consensus.rs +++ b/crates/papyrus_protobuf/src/converters/consensus.rs @@ -6,7 +6,8 @@ use std::convert::{TryFrom, TryInto}; use prost::Message; use starknet_api::block::{BlockHash, BlockNumber}; use starknet_api::hash::StarkHash; -use starknet_api::transaction::Transaction; +use starknet_api::transaction::{Transaction, TransactionHash}; +use starknet_types_core::felt::Felt; use crate::consensus::{ ConsensusMessage, @@ -234,14 +235,20 @@ impl TryFrom for TransactionBatch { .into_iter() .map(|tx| tx.try_into()) .collect::, ProtobufConversionError>>()?; - Ok(TransactionBatch { transactions }) + let tx_hashes = value + .tx_hashes + .into_iter() + .map(|x| Felt::try_from(x).map(TransactionHash)) + .collect::>()?; + Ok(TransactionBatch { transactions, tx_hashes }) } } impl From for protobuf::TransactionBatch { fn from(value: TransactionBatch) -> Self { let transactions = value.transactions.into_iter().map(Into::into).collect(); - protobuf::TransactionBatch { transactions } + let tx_hashes = value.tx_hashes.into_iter().map(|hash| hash.0.into()).collect(); + protobuf::TransactionBatch { transactions, tx_hashes } } } diff --git a/crates/papyrus_protobuf/src/converters/test_instances.rs b/crates/papyrus_protobuf/src/converters/test_instances.rs index 742349b973..01c9c1903a 100644 --- a/crates/papyrus_protobuf/src/converters/test_instances.rs +++ b/crates/papyrus_protobuf/src/converters/test_instances.rs @@ -2,7 +2,7 @@ use papyrus_test_utils::{auto_impl_get_test_instance, get_number_of_variants, Ge use rand::Rng; use starknet_api::block::{BlockHash, BlockNumber}; use starknet_api::core::ContractAddress; -use starknet_api::transaction::Transaction; +use starknet_api::transaction::{Transaction, TransactionHash}; use crate::consensus::{ ConsensusMessage, @@ -52,6 +52,7 @@ auto_impl_get_test_instance! { } pub struct TransactionBatch { pub transactions: Vec, + pub tx_hashes: Vec, } pub enum ProposalPart { Init(ProposalInit) = 0, diff --git a/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto b/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto index 8c31067f97..81e5af8d2c 100644 --- a/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto +++ b/crates/papyrus_protobuf/src/proto/p2p/proto/consensus.proto @@ -2,6 +2,7 @@ syntax = "proto3"; import "p2p/proto/transaction.proto"; import "p2p/proto/common.proto"; +// To be deprecated message Proposal { uint64 height = 1; uint32 round = 2; @@ -54,6 +55,8 @@ message ProposalInit { message TransactionBatch { repeated Transaction transactions = 1; + // TODO(guyn): remove this once we know how to calculate hashes + repeated Felt252 tx_hashes = 2; } message ProposalFin { diff --git a/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context.rs b/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context.rs index 54e7a8f750..8ee354a4f9 100644 --- a/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context.rs +++ b/crates/sequencing/papyrus_consensus_orchestrator/src/sequencer_consensus_context.rs @@ -305,6 +305,7 @@ async fn stream_build_proposal( broadcast_client .broadcast_message(ProposalPart::Transactions(TransactionBatch { transactions, + tx_hashes: transaction_hashes, })) .await .expect("Failed to broadcast proposal content"); diff --git a/crates/starknet_api/src/transaction.rs b/crates/starknet_api/src/transaction.rs index 42eeadefad..ac6300cc39 100644 --- a/crates/starknet_api/src/transaction.rs +++ b/crates/starknet_api/src/transaction.rs @@ -775,6 +775,20 @@ impl std::fmt::Display for TransactionHash { } } +// TODO(guyn): this is only used for conversion of transactions->executable transactions +// It should be removed once we integrate a proper way to calculate executable transaction hashes +impl From for Vec { + fn from(tx_hash: TransactionHash) -> Vec { + tx_hash.0.to_bytes_be().to_vec() + } +} +impl From> for TransactionHash { + fn from(bytes: Vec) -> TransactionHash { + let array: [u8; 32] = bytes.try_into().expect("Expected a Vec of length 32"); + TransactionHash(StarkHash::from_bytes_be(&array)) + } +} + /// A transaction version. #[derive( Debug,