Skip to content
This repository has been archived by the owner on Dec 26, 2024. It is now read-only.

feat(network): add conversions from protobuf to transaction outputs #2053

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 108 additions & 32 deletions crates/papyrus_network/src/converters/protobuf_conversion/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ use starknet_api::core::{ContractAddress, EthAddress, PatriciaKey};
use starknet_api::hash::StarkFelt;
use starknet_api::transaction::{
Builtin,
DeclareTransactionOutput,
DeployAccountTransactionOutput,
DeployTransactionOutput,
ExecutionResources,
Fee,
InvokeTransactionOutput,
L1HandlerTransactionOutput,
L2ToL1Payload,
MessageToL1,
RevertedTransactionExecutionStatus,
Expand All @@ -21,33 +25,46 @@ use crate::protobuf_messages::protobuf::{self};
impl TryFrom<protobuf::receipt::DeployAccount> for DeployAccountTransactionOutput {
type Error = ProtobufConversionError;
fn try_from(value: protobuf::receipt::DeployAccount) -> Result<Self, Self::Error> {
let common = value.common.ok_or(ProtobufConversionError::MissingField {
field_description: "DeployAccount::common",
})?;
let (actual_fee, messages_sent, execution_status, execution_resources) =
parse_common_receipt_fields(value.common)?;

let actual_fee_felt = StarkFelt::try_from(common.actual_fee.ok_or(
ProtobufConversionError::MissingField {
field_description: "DeployAccount::common.actual_fee",
},
)?)?;
let actual_fee = Fee(try_from_starkfelt_to_u128(actual_fee_felt).map_err(|_| {
let events = vec![];

let contract_address =
value.contract_address.ok_or(ProtobufConversionError::MissingField {
field_description: "DeployAccount::contract_address",
})?;
let felt = StarkFelt::try_from(contract_address)?;
let contract_address = ContractAddress(PatriciaKey::try_from(felt).map_err(|_| {
ProtobufConversionError::OutOfRangeValue {
type_description: "u128",
value_as_str: format!("{actual_fee_felt:?}"),
type_description: "PatriciaKey",
value_as_str: format!("{felt:?}"),
}
})?);

let messages_sent = common
.messages_sent
.into_iter()
.map(MessageToL1::try_from)
.collect::<Result<Vec<_>, _>>()?;
Ok(Self {
actual_fee,
messages_sent,
events,
contract_address,
execution_status,
execution_resources,
})
}
}

// The output will have an empty events vec
impl TryFrom<protobuf::receipt::Deploy> for DeployTransactionOutput {
type Error = ProtobufConversionError;
fn try_from(value: protobuf::receipt::Deploy) -> Result<Self, Self::Error> {
let (actual_fee, messages_sent, execution_status, execution_resources) =
parse_common_receipt_fields(value.common)?;

let events = vec![];

let contract_address =
value.contract_address.ok_or(ProtobufConversionError::MissingField {
field_description: "DeployAccount::contract_address",
field_description: "Deploy::contract_address",
})?;
let felt = StarkFelt::try_from(contract_address)?;
let contract_address = ContractAddress(PatriciaKey::try_from(felt).map_err(|_| {
Expand All @@ -57,21 +74,6 @@ impl TryFrom<protobuf::receipt::DeployAccount> for DeployAccountTransactionOutpu
}
})?);

let execution_status = common.revert_reason.map_or_else(
|| TransactionExecutionStatus::Succeeded,
|revert_reason| {
TransactionExecutionStatus::Reverted(RevertedTransactionExecutionStatus {
revert_reason,
})
},
);

let execution_resources = ExecutionResources::try_from(common.execution_resources.ok_or(
ProtobufConversionError::MissingField {
field_description: "DeployAccount::common.execution_resources",
},
)?)?;

Ok(Self {
actual_fee,
messages_sent,
Expand All @@ -83,6 +85,45 @@ impl TryFrom<protobuf::receipt::DeployAccount> for DeployAccountTransactionOutpu
}
}

// The output will have an empty events vec
impl TryFrom<protobuf::receipt::Declare> for DeclareTransactionOutput {
type Error = ProtobufConversionError;
fn try_from(value: protobuf::receipt::Declare) -> Result<Self, Self::Error> {
let (actual_fee, messages_sent, execution_status, execution_resources) =
parse_common_receipt_fields(value.common)?;

let events = vec![];

Ok(Self { actual_fee, messages_sent, events, execution_status, execution_resources })
}
}

// The output will have an empty events vec
impl TryFrom<protobuf::receipt::Invoke> for InvokeTransactionOutput {
type Error = ProtobufConversionError;
fn try_from(value: protobuf::receipt::Invoke) -> Result<Self, Self::Error> {
let (actual_fee, messages_sent, execution_status, execution_resources) =
parse_common_receipt_fields(value.common)?;

let events = vec![];

Ok(Self { actual_fee, messages_sent, events, execution_status, execution_resources })
}
}

// The output will have an empty events vec
impl TryFrom<protobuf::receipt::L1Handler> for L1HandlerTransactionOutput {
type Error = ProtobufConversionError;
fn try_from(value: protobuf::receipt::L1Handler) -> Result<Self, Self::Error> {
let (actual_fee, messages_sent, execution_status, execution_resources) =
parse_common_receipt_fields(value.common)?;

let events = vec![];

Ok(Self { actual_fee, messages_sent, events, execution_status, execution_resources })
}
}

type ProtobufBuiltinCounter = protobuf::receipt::execution_resources::BuiltinCounter;

impl TryFrom<ProtobufBuiltinCounter> for HashMap<Builtin, u64> {
Expand Down Expand Up @@ -245,3 +286,38 @@ impl From<MessageToL1> for protobuf::MessageToL1 {
}
}
}

fn parse_common_receipt_fields(
common: Option<protobuf::receipt::Common>,
) -> Result<
(Fee, Vec<MessageToL1>, TransactionExecutionStatus, ExecutionResources),
ProtobufConversionError,
> {
let common =
common.ok_or(ProtobufConversionError::MissingField { field_description: "Common" })?;
let actual_fee_felt =
StarkFelt::try_from(common.actual_fee.ok_or(ProtobufConversionError::MissingField {
field_description: "Common::actual_fee",
})?)?;
let actual_fee = Fee(try_from_starkfelt_to_u128(actual_fee_felt).map_err(|_| {
ProtobufConversionError::OutOfRangeValue {
type_description: "u128",
value_as_str: format!("{actual_fee_felt:?}"),
}
})?);
let messages_sent = common
.messages_sent
.into_iter()
.map(MessageToL1::try_from)
.collect::<Result<Vec<_>, _>>()?;
let execution_status =
common.revert_reason.map_or(TransactionExecutionStatus::Succeeded, |revert_reason| {
TransactionExecutionStatus::Reverted(RevertedTransactionExecutionStatus {
revert_reason,
})
});
let execution_resources = ExecutionResources::try_from(common.execution_resources.ok_or(
ProtobufConversionError::MissingField { field_description: "Common::execution_resources" },
)?)?;
Ok((actual_fee, messages_sent, execution_status, execution_resources))
}
Loading