Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sequencer): v3 transaction request #521

Merged
merged 1 commit into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
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
8 changes: 4 additions & 4 deletions starknet-providers/src/sequencer/models/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,14 +457,14 @@ impl TryFrom<TransactionFinalityStatus> for core::TransactionFinalityStatus {

impl From<core::BroadcastedInvokeTransaction> for InvokeFunctionTransactionRequest {
fn from(value: core::BroadcastedInvokeTransaction) -> Self {
Self {
Self::V1(InvokeFunctionV1TransactionRequest {
sender_address: value.sender_address,
calldata: value.calldata,
signature: value.signature,
max_fee: value.max_fee,
nonce: value.nonce,
is_query: value.is_query,
}
})
}
}

Expand Down Expand Up @@ -513,15 +513,15 @@ impl TryFrom<core::BroadcastedDeclareTransactionV2> for DeclareV2TransactionRequ

impl From<core::BroadcastedDeployAccountTransaction> for DeployAccountTransactionRequest {
fn from(value: core::BroadcastedDeployAccountTransaction) -> Self {
Self {
Self::V1(DeployAccountV1TransactionRequest {
class_hash: value.class_hash,
contract_address_salt: value.contract_address_salt,
constructor_calldata: value.constructor_calldata,
max_fee: value.max_fee,
signature: value.signature,
nonce: value.nonce,
is_query: value.is_query,
}
})
}
}

Expand Down
9 changes: 8 additions & 1 deletion starknet-providers/src/sequencer/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ pub use transaction_request::{
DeclareTransaction as DeclareTransactionRequest,
DeclareV1Transaction as DeclareV1TransactionRequest,
DeclareV2Transaction as DeclareV2TransactionRequest,
DeclareV3Transaction as DeclareV3TransactionRequest,
DeployAccountTransaction as DeployAccountTransactionRequest,
InvokeFunctionTransaction as InvokeFunctionTransactionRequest, TransactionRequest,
DeployAccountV1Transaction as DeployAccountV1TransactionRequest,
DeployAccountV3Transaction as DeployAccountV3TransactionRequest,
InvokeFunctionTransaction as InvokeFunctionTransactionRequest,
InvokeFunctionV1Transaction as InvokeFunctionV1TransactionRequest,
InvokeFunctionV3Transaction as InvokeFunctionV3TransactionRequest, TransactionRequest,
};

mod contract;
Expand All @@ -45,3 +50,5 @@ pub use state_update::StateUpdate;

pub mod trace;
pub use trace::{BlockTraces, TransactionTrace};

pub(crate) mod serde_impls;
120 changes: 120 additions & 0 deletions starknet-providers/src/sequencer/models/serde_impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
pub(crate) mod u64_hex {
use serde::{de::Visitor, Deserialize, Serialize};

struct U64HexVisitor;

pub fn serialize<S>(v: &u64, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&format!("{:#x}", v))
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(U64HexVisitor)
}

impl<'de> Visitor<'de> for U64HexVisitor {
type Value = u64;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "string")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
u64::from_str_radix(v.trim_start_matches("0x"), 16)
.map_err(|err| serde::de::Error::custom(format!("invalid u64 hex string: {err}")))
}
}
}

pub(crate) mod u128_hex {
use serde::{de::Visitor, Deserialize, Serialize};

struct U128HexVisitor;

pub fn serialize<S>(v: &u128, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&format!("{:#x}", v))
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<u128, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(U128HexVisitor)
}

impl<'de> Visitor<'de> for U128HexVisitor {
type Value = u128;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "string")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
u128::from_str_radix(v.trim_start_matches("0x"), 16)
.map_err(|err| serde::de::Error::custom(format!("invalid u128 hex string: {err}")))
}
}
}

pub(crate) mod u64_hex_opt {
use serde::{de::Visitor, Deserialize, Serialize};

struct U64HexOptVisitor;

pub fn serialize<S>(v: &Option<u64>, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match v {
Some(v) => serializer.serialize_str(&format!("{:#x}", v)),
None => serializer.serialize_none(),
}
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(U64HexOptVisitor)
}

impl<'de> Visitor<'de> for U64HexOptVisitor {
type Value = Option<u64>;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "null or string")
}

fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(None)
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Some(
u64::from_str_radix(v.trim_start_matches("0x"), 16).map_err(|err| {
serde::de::Error::custom(format!("invalid u64 hex string: {err}"))
})?,
))
}
}
}
98 changes: 73 additions & 25 deletions starknet-providers/src/sequencer/models/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use serde::Deserialize;
use serde::{de::Visitor, Deserialize, Serialize};
use serde_with::serde_as;
use starknet_core::{
serde::unsigned_field_element::{UfeHex, UfePendingBlockHash},
types::FieldElement,
};

use super::{
serde_impls::{u128_hex, u64_hex, u64_hex_opt},
transaction_receipt::{TransactionExecutionStatus, TransactionFinalityStatus},
TransactionStatus,
};
Expand Down Expand Up @@ -102,12 +103,11 @@ pub struct DeclareTransaction {
pub transaction_hash: FieldElement,
#[serde_as(deserialize_as = "Vec<UfeHex>")]
pub signature: Vec<FieldElement>,
pub nonce_data_availability_mode: Option<u32>,
pub fee_data_availability_mode: Option<u32>,
pub nonce_data_availability_mode: Option<DataAvailabilityMode>,
pub fee_data_availability_mode: Option<DataAvailabilityMode>,
pub resource_bounds: Option<ResourceBoundsMapping>,
#[serde(default)]
#[serde_as(as = "Option<UfeHex>")]
pub tip: Option<FieldElement>,
#[serde(default, with = "u64_hex_opt")]
pub tip: Option<u64>,
#[serde_as(as = "Option<Vec<UfeHex>>")]
pub paymaster_data: Option<Vec<FieldElement>>,
#[serde_as(deserialize_as = "Option<Vec<UfeHex>>")]
Expand Down Expand Up @@ -156,12 +156,11 @@ pub struct DeployAccountTransaction {
#[serde(default)]
#[serde_as(as = "Option<UfeHex>")]
pub max_fee: Option<FieldElement>,
pub nonce_data_availability_mode: Option<u32>,
pub fee_data_availability_mode: Option<u32>,
pub nonce_data_availability_mode: Option<DataAvailabilityMode>,
pub fee_data_availability_mode: Option<DataAvailabilityMode>,
pub resource_bounds: Option<ResourceBoundsMapping>,
#[serde(default)]
#[serde_as(as = "Option<UfeHex>")]
pub tip: Option<FieldElement>,
#[serde(default, with = "u64_hex_opt")]
pub tip: Option<u64>,
#[serde_as(as = "Option<Vec<UfeHex>>")]
pub paymaster_data: Option<Vec<FieldElement>>,
#[serde(default)]
Expand Down Expand Up @@ -190,12 +189,11 @@ pub struct InvokeFunctionTransaction {
pub max_fee: Option<FieldElement>,
#[serde_as(as = "Option<UfeHex>")]
pub nonce: Option<FieldElement>,
pub nonce_data_availability_mode: Option<u32>,
pub fee_data_availability_mode: Option<u32>,
pub nonce_data_availability_mode: Option<DataAvailabilityMode>,
pub fee_data_availability_mode: Option<DataAvailabilityMode>,
pub resource_bounds: Option<ResourceBoundsMapping>,
#[serde(default)]
#[serde_as(as = "Option<UfeHex>")]
pub tip: Option<FieldElement>,
#[serde(default, with = "u64_hex_opt")]
pub tip: Option<u64>,
#[serde_as(as = "Option<Vec<UfeHex>>")]
pub paymaster_data: Option<Vec<FieldElement>>,
#[serde_as(deserialize_as = "Option<Vec<UfeHex>>")]
Expand All @@ -222,24 +220,31 @@ pub struct L1HandlerTransaction {
pub version: FieldElement,
}

#[derive(Debug, Deserialize)]
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub struct ResourceBoundsMapping {
l1_gas: ResourceBounds,
l2_gas: ResourceBounds,
pub l1_gas: ResourceBounds,
pub l2_gas: ResourceBounds,
}

#[serde_as]
#[derive(Debug, Deserialize)]
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))]
pub struct ResourceBounds {
#[serde_as(as = "UfeHex")]
pub max_amount: FieldElement,
#[serde_as(as = "UfeHex")]
pub max_price_per_unit: FieldElement,
#[serde(with = "u64_hex")]
pub max_amount: u64,
#[serde(with = "u128_hex")]
pub max_price_per_unit: u128,
}

#[derive(Debug)]
pub enum DataAvailabilityMode {
L1,
L2,
}

struct DataAvailabilityModeVisitor;

impl TransactionType {
pub fn transaction_hash(&self) -> FieldElement {
match self {
Expand All @@ -252,6 +257,49 @@ impl TransactionType {
}
}

impl Serialize for DataAvailabilityMode {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u32(match self {
Self::L1 => 0,
Self::L2 => 1,
})
}
}

impl<'de> Deserialize<'de> for DataAvailabilityMode {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(DataAvailabilityModeVisitor)
}
}

impl<'de> Visitor<'de> for DataAvailabilityModeVisitor {
type Value = DataAvailabilityMode;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "integer")
}

fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match v {
0 => Ok(DataAvailabilityMode::L1),
1 => Ok(DataAvailabilityMode::L2),
_ => Err(serde::de::Error::invalid_value(
serde::de::Unexpected::Unsigned(v),
&"0 or 1",
)),
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pub struct BuiltinInstanceCounter {
pub ec_op_builtin: Option<u64>,
pub poseidon_builtin: Option<u64>,
pub keccak_builtin: Option<u64>,
pub segment_arena_builtin: Option<u64>,
}

#[serde_as]
Expand Down
Loading
Loading