Skip to content

Commit

Permalink
Merge pull request #1787 from eqlabs/chris/p2p-starknet-0.13.1
Browse files Browse the repository at this point in the history
p2p starknet 0.13.1
  • Loading branch information
CHr15F0x authored Feb 21, 2024
2 parents c02e019 + dc31aa5 commit 301d4b3
Show file tree
Hide file tree
Showing 13 changed files with 382 additions and 336 deletions.
133 changes: 129 additions & 4 deletions crates/p2p/src/client/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
//!
//! 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,
Expand All @@ -11,10 +14,12 @@ use pathfinder_common::transaction::{
use pathfinder_common::{
AccountDeploymentDataElem, BlockCommitmentSignature, BlockCommitmentSignatureElem, BlockHash,
BlockNumber, BlockTimestamp, CallParam, CasmHash, ClassHash, ConstructorParam, ContractAddress,
ContractAddressSalt, EntryPoint, EventCommitment, EventData, EventKey, Fee, GasPrice,
PaymasterDataElem, SequencerAddress, StarknetVersion, StateCommitment, Tip,
TransactionCommitment, TransactionNonce, TransactionSignatureElem, TransactionVersion,
ContractAddressSalt, EntryPoint, EthereumAddress, EventCommitment, EventData, EventKey, Fee,
GasPrice, L1DataAvailabilityMode, L2ToL1MessagePayloadElem, PaymasterDataElem,
SequencerAddress, StarknetVersion, StateCommitment, Tip, TransactionCommitment,
TransactionHash, TransactionNonce, TransactionSignatureElem, TransactionVersion,
};
use pathfinder_crypto::Felt;

/// 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.
Expand All @@ -32,13 +37,17 @@ pub struct SignedBlockHeader {
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,
pub signature: BlockCommitmentSignature,
}

Expand All @@ -63,14 +72,18 @@ impl TryFrom<p2p_proto::header::SignedBlockHeader> for SignedBlockHeader {
.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: dto.gas_price.into(),
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,
})
}
Expand All @@ -94,18 +107,117 @@ impl
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<Fee>,
pub execution_resources: Option<ExecutionResources>,
pub l2_to_l1_messages: Vec<L2ToL1Message>,
pub execution_status: ExecutionStatus,
pub transaction_hash: TransactionHash,
}

impl From<pathfinder_common::receipt::Receipt> 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<p2p_proto::receipt::Receipt> for Receipt {
type Error = anyhow::Error;

fn try_from(proto: p2p_proto::receipt::Receipt) -> anyhow::Result<Self>
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, .. }) => {
let data_availability = (common.execution_resources.l1_gas != Felt::ZERO
|| common.execution_resources.l1_data_gas != Felt::ZERO)
.then_some(ExecutionDataAvailability {
l1_gas: GasPrice::from(common.execution_resources.l1_gas).0,
l1_data_gas: GasPrice::from(common.execution_resources.l1_data_gas).0,
});
Ok(Self {
transaction_hash: TransactionHash(common.transaction_hash.0),
actual_fee: Some(Fee(common.actual_fee)),
execution_resources: Some(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,
}),
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 {
Expand Down Expand Up @@ -473,3 +585,16 @@ impl TryFromDto<String> for DataAvailabilityMode {
}
}
}

impl TryFromDto<p2p_proto::common::L1DataAvailabilityMode> for L1DataAvailabilityMode {
fn try_from_dto(dto: p2p_proto::common::L1DataAvailabilityMode) -> anyhow::Result<Self>
where
Self: Sized,
{
use p2p_proto::common::L1DataAvailabilityMode::{Blob, Calldata};
Ok(match dto {
Calldata => Self::Calldata,
Blob => Self::Blob,
})
}
}
12 changes: 11 additions & 1 deletion crates/p2p_proto/proto/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,18 @@ message PeerID {
bytes id = 1;
}

message Uint128 {
uint64 low = 1;
uint64 high = 2;
}

message ConsensusSignature {
Felt252 r = 1;
Felt252 s = 2;
}

message Merkle {
uint32 n_leaves = 1; // needed to know the height, so as to how many nodes to expect in a proof.
uint64 n_leaves = 1; // needed to know the height, so as to how many nodes to expect in a proof.
// and also when receiving all leaves, how many to expect
Hash root = 2;
}
Expand All @@ -43,6 +48,11 @@ message BlockID {
Hash header = 2;
}

enum L1DataAvailabilityMode {
Calldata = 0;
Blob = 1;
}

message Iteration {
enum Direction {
Forward = 0;
Expand Down
38 changes: 21 additions & 17 deletions crates/p2p_proto/proto/header.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,30 @@ package starknet.header;
// Note: commitments may change to be for the previous blocks like comet/tendermint
// hash of block header sent to L1
message SignedBlockHeader {
starknet.common.Hash block_hash = 1; // For the structure of the block hash, see https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/header/#block_hash
starknet.common.Hash parent_hash = 2;
uint64 number = 3;
uint64 time = 4; // Encoded in Unix time.
starknet.common.Address sequencer_address = 5;
starknet.common.Hash state_diff_commitment = 6; // The state diff commitment returned by the Starknet Feeder Gateway.
starknet.common.Hash block_hash = 1; // For the structure of the block hash, see https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/header/#block_hash
starknet.common.Hash parent_hash = 2;
uint64 number = 3;
uint64 time = 4; // Encoded in Unix time.
starknet.common.Address sequencer_address = 5;
starknet.common.Hash state_diff_commitment = 6; // The state diff commitment returned by the Starknet Feeder Gateway.
// For more info, see https://community.starknet.io/t/introducing-p2p-authentication-and-mismatch-resolution-in-v0-12-2/97993
starknet.common.Patricia state = 7; // hash of contract and class patricia tries. Same as in L1. Later more trees will be included
starknet.common.Patricia state = 7; // hash of contract and class patricia tries. Same as in L1. Later more trees will be included
// The following merkles can be built on the fly while sequencing/validating txs.
starknet.common.Merkle transactions = 8; // By order of execution. TBD: required? the client can execute (powerful machine) and match state diff
starknet.common.Merkle events = 9; // By order of issuance. TBD: in receipts?
starknet.common.Merkle receipts = 10; // By order of issuance.
string protocol_version = 11; // Starknet version
starknet.common.Felt252 gas_price = 12;
uint64 num_storage_diffs = 13;
uint64 num_nonce_updates = 14;
uint64 num_declared_classes = 15; // Includes both Cairo 0 and Cairo 1.
uint64 num_deployed_contracts = 16; // This includes the replaced classes too.
starknet.common.Merkle transactions = 8; // By order of execution. TBD: required? the client can execute (powerful machine) and match state diff
starknet.common.Merkle events = 9; // By order of issuance. TBD: in receipts?
starknet.common.Merkle receipts = 10; // By order of issuance.
string protocol_version = 11; // Starknet version
starknet.common.Uint128 gas_price_fri = 12;
starknet.common.Uint128 gas_price_wei = 13;
starknet.common.Uint128 data_gas_price_fri = 14;
starknet.common.Uint128 data_gas_price_wei = 15;
starknet.common.L1DataAvailabilityMode l1_data_availability_mode = 16;
uint64 num_storage_diffs = 17;
uint64 num_nonce_updates = 18;
uint64 num_declared_classes = 19; // Includes both Cairo 0 and Cairo 1.
uint64 num_deployed_contracts = 20; // This includes the replaced classes too.
// for now, we assume a small consensus, so this fits in 1M. Else, these will be repeated and extracted from this message.
repeated starknet.common.ConsensusSignature signatures = 17; //
repeated starknet.common.ConsensusSignature signatures = 21;
// can be more explicit here about the signature structure as this is not part of account abstraction
}

Expand Down
8 changes: 5 additions & 3 deletions crates/p2p_proto/proto/receipt.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ message Receipt {
uint32 output = 8;
}

BuiltinCounter builtins = 1;
uint32 steps = 2;
uint32 memory_holes = 3;
BuiltinCounter builtins = 1;
uint32 steps = 2;
uint32 memory_holes = 3;
starknet.common.Felt252 l1_gas = 4;
starknet.common.Felt252 l1_data_gas = 5;
}

message Common {
Expand Down
46 changes: 45 additions & 1 deletion crates/p2p_proto/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct ConsensusSignature {
#[derive(Debug, Copy, Clone, PartialEq, Eq, ToProtobuf, TryFromProtobuf, Dummy, Default)]
#[protobuf(name = "crate::proto::common::Merkle")]
pub struct Merkle {
pub n_leaves: u32,
pub n_leaves: u64,
pub root: Hash,
}

Expand All @@ -48,6 +48,12 @@ pub struct BlockId {
pub hash: Hash,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Dummy)]
pub enum L1DataAvailabilityMode {
Calldata,
Blob,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, ToProtobuf, TryFromProtobuf, Dummy)]
#[protobuf(name = "crate::proto::common::Iteration")]
pub struct Iteration {
Expand Down Expand Up @@ -154,6 +160,26 @@ impl Display for BlockId {
}
}

impl ToProtobuf<i32> for L1DataAvailabilityMode {
fn to_protobuf(self) -> i32 {
use proto::common::L1DataAvailabilityMode::{Blob, Calldata};
match self {
L1DataAvailabilityMode::Calldata => Calldata as i32,
L1DataAvailabilityMode::Blob => Blob as i32,
}
}
}

impl TryFromProtobuf<i32> for L1DataAvailabilityMode {
fn try_from_protobuf(input: i32, _: &'static str) -> Result<Self, std::io::Error> {
use proto::common::L1DataAvailabilityMode::{Blob, Calldata};
Ok(match TryFrom::try_from(input)? {
Calldata => L1DataAvailabilityMode::Calldata,
Blob => L1DataAvailabilityMode::Blob,
})
}
}

impl ToProtobuf<proto::common::PeerId> for PeerId {
fn to_protobuf(self) -> proto::common::PeerId {
proto::common::PeerId {
Expand All @@ -177,6 +203,24 @@ impl TryFromProtobuf<proto::common::PeerId> for PeerId {
}
}

impl ToProtobuf<proto::common::Uint128> for u128 {
fn to_protobuf(self) -> proto::common::Uint128 {
proto::common::Uint128 {
low: (self & 0xFFFF_FFFF_FFFF_FFFF) as u64,
high: (self >> 64) as u64,
}
}
}

impl TryFromProtobuf<proto::common::Uint128> for u128 {
fn try_from_protobuf(
input: proto::common::Uint128,
_: &'static str,
) -> Result<Self, std::io::Error> {
Ok((input.high as u128) << 64 | input.low as u128)
}
}

impl From<u64> for BlockNumberOrHash {
fn from(x: u64) -> Self {
Self::Number(x)
Expand Down
Loading

0 comments on commit 301d4b3

Please sign in to comment.