Skip to content

Commit b8642ce

Browse files
authored
feat(sequencer): v3 transaction request (#521)
1 parent 95d50ac commit b8642ce

File tree

6 files changed

+436
-34
lines changed

6 files changed

+436
-34
lines changed

starknet-providers/src/sequencer/models/conversions.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,14 +457,14 @@ impl TryFrom<TransactionFinalityStatus> for core::TransactionFinalityStatus {
457457

458458
impl From<core::BroadcastedInvokeTransaction> for InvokeFunctionTransactionRequest {
459459
fn from(value: core::BroadcastedInvokeTransaction) -> Self {
460-
Self {
460+
Self::V1(InvokeFunctionV1TransactionRequest {
461461
sender_address: value.sender_address,
462462
calldata: value.calldata,
463463
signature: value.signature,
464464
max_fee: value.max_fee,
465465
nonce: value.nonce,
466466
is_query: value.is_query,
467-
}
467+
})
468468
}
469469
}
470470

@@ -513,15 +513,15 @@ impl TryFrom<core::BroadcastedDeclareTransactionV2> for DeclareV2TransactionRequ
513513

514514
impl From<core::BroadcastedDeployAccountTransaction> for DeployAccountTransactionRequest {
515515
fn from(value: core::BroadcastedDeployAccountTransaction) -> Self {
516-
Self {
516+
Self::V1(DeployAccountV1TransactionRequest {
517517
class_hash: value.class_hash,
518518
contract_address_salt: value.contract_address_salt,
519519
constructor_calldata: value.constructor_calldata,
520520
max_fee: value.max_fee,
521521
signature: value.signature,
522522
nonce: value.nonce,
523523
is_query: value.is_query,
524-
}
524+
})
525525
}
526526
}
527527

starknet-providers/src/sequencer/models/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,13 @@ pub use transaction_request::{
3333
DeclareTransaction as DeclareTransactionRequest,
3434
DeclareV1Transaction as DeclareV1TransactionRequest,
3535
DeclareV2Transaction as DeclareV2TransactionRequest,
36+
DeclareV3Transaction as DeclareV3TransactionRequest,
3637
DeployAccountTransaction as DeployAccountTransactionRequest,
37-
InvokeFunctionTransaction as InvokeFunctionTransactionRequest, TransactionRequest,
38+
DeployAccountV1Transaction as DeployAccountV1TransactionRequest,
39+
DeployAccountV3Transaction as DeployAccountV3TransactionRequest,
40+
InvokeFunctionTransaction as InvokeFunctionTransactionRequest,
41+
InvokeFunctionV1Transaction as InvokeFunctionV1TransactionRequest,
42+
InvokeFunctionV3Transaction as InvokeFunctionV3TransactionRequest, TransactionRequest,
3843
};
3944

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

4651
pub mod trace;
4752
pub use trace::{BlockTraces, TransactionTrace};
53+
54+
pub(crate) mod serde_impls;
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
pub(crate) mod u64_hex {
2+
use serde::{de::Visitor, Deserialize, Serialize};
3+
4+
struct U64HexVisitor;
5+
6+
pub fn serialize<S>(v: &u64, serializer: S) -> Result<S::Ok, S::Error>
7+
where
8+
S: serde::Serializer,
9+
{
10+
serializer.serialize_str(&format!("{:#x}", v))
11+
}
12+
13+
pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
14+
where
15+
D: serde::Deserializer<'de>,
16+
{
17+
deserializer.deserialize_any(U64HexVisitor)
18+
}
19+
20+
impl<'de> Visitor<'de> for U64HexVisitor {
21+
type Value = u64;
22+
23+
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
24+
write!(formatter, "string")
25+
}
26+
27+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
28+
where
29+
E: serde::de::Error,
30+
{
31+
u64::from_str_radix(v.trim_start_matches("0x"), 16)
32+
.map_err(|err| serde::de::Error::custom(format!("invalid u64 hex string: {err}")))
33+
}
34+
}
35+
}
36+
37+
pub(crate) mod u128_hex {
38+
use serde::{de::Visitor, Deserialize, Serialize};
39+
40+
struct U128HexVisitor;
41+
42+
pub fn serialize<S>(v: &u128, serializer: S) -> Result<S::Ok, S::Error>
43+
where
44+
S: serde::Serializer,
45+
{
46+
serializer.serialize_str(&format!("{:#x}", v))
47+
}
48+
49+
pub fn deserialize<'de, D>(deserializer: D) -> Result<u128, D::Error>
50+
where
51+
D: serde::Deserializer<'de>,
52+
{
53+
deserializer.deserialize_any(U128HexVisitor)
54+
}
55+
56+
impl<'de> Visitor<'de> for U128HexVisitor {
57+
type Value = u128;
58+
59+
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
60+
write!(formatter, "string")
61+
}
62+
63+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
64+
where
65+
E: serde::de::Error,
66+
{
67+
u128::from_str_radix(v.trim_start_matches("0x"), 16)
68+
.map_err(|err| serde::de::Error::custom(format!("invalid u128 hex string: {err}")))
69+
}
70+
}
71+
}
72+
73+
pub(crate) mod u64_hex_opt {
74+
use serde::{de::Visitor, Deserialize, Serialize};
75+
76+
struct U64HexOptVisitor;
77+
78+
pub fn serialize<S>(v: &Option<u64>, serializer: S) -> Result<S::Ok, S::Error>
79+
where
80+
S: serde::Serializer,
81+
{
82+
match v {
83+
Some(v) => serializer.serialize_str(&format!("{:#x}", v)),
84+
None => serializer.serialize_none(),
85+
}
86+
}
87+
88+
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
89+
where
90+
D: serde::Deserializer<'de>,
91+
{
92+
deserializer.deserialize_any(U64HexOptVisitor)
93+
}
94+
95+
impl<'de> Visitor<'de> for U64HexOptVisitor {
96+
type Value = Option<u64>;
97+
98+
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
99+
write!(formatter, "null or string")
100+
}
101+
102+
fn visit_none<E>(self) -> Result<Self::Value, E>
103+
where
104+
E: serde::de::Error,
105+
{
106+
Ok(None)
107+
}
108+
109+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
110+
where
111+
E: serde::de::Error,
112+
{
113+
Ok(Some(
114+
u64::from_str_radix(v.trim_start_matches("0x"), 16).map_err(|err| {
115+
serde::de::Error::custom(format!("invalid u64 hex string: {err}"))
116+
})?,
117+
))
118+
}
119+
}
120+
}

starknet-providers/src/sequencer/models/transaction.rs

Lines changed: 73 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use serde::Deserialize;
1+
use serde::{de::Visitor, Deserialize, Serialize};
22
use serde_with::serde_as;
33
use starknet_core::{
44
serde::unsigned_field_element::{UfeHex, UfePendingBlockHash},
55
types::FieldElement,
66
};
77

88
use super::{
9+
serde_impls::{u128_hex, u64_hex, u64_hex_opt},
910
transaction_receipt::{TransactionExecutionStatus, TransactionFinalityStatus},
1011
TransactionStatus,
1112
};
@@ -102,12 +103,11 @@ pub struct DeclareTransaction {
102103
pub transaction_hash: FieldElement,
103104
#[serde_as(deserialize_as = "Vec<UfeHex>")]
104105
pub signature: Vec<FieldElement>,
105-
pub nonce_data_availability_mode: Option<u32>,
106-
pub fee_data_availability_mode: Option<u32>,
106+
pub nonce_data_availability_mode: Option<DataAvailabilityMode>,
107+
pub fee_data_availability_mode: Option<DataAvailabilityMode>,
107108
pub resource_bounds: Option<ResourceBoundsMapping>,
108-
#[serde(default)]
109-
#[serde_as(as = "Option<UfeHex>")]
110-
pub tip: Option<FieldElement>,
109+
#[serde(default, with = "u64_hex_opt")]
110+
pub tip: Option<u64>,
111111
#[serde_as(as = "Option<Vec<UfeHex>>")]
112112
pub paymaster_data: Option<Vec<FieldElement>>,
113113
#[serde_as(deserialize_as = "Option<Vec<UfeHex>>")]
@@ -156,12 +156,11 @@ pub struct DeployAccountTransaction {
156156
#[serde(default)]
157157
#[serde_as(as = "Option<UfeHex>")]
158158
pub max_fee: Option<FieldElement>,
159-
pub nonce_data_availability_mode: Option<u32>,
160-
pub fee_data_availability_mode: Option<u32>,
159+
pub nonce_data_availability_mode: Option<DataAvailabilityMode>,
160+
pub fee_data_availability_mode: Option<DataAvailabilityMode>,
161161
pub resource_bounds: Option<ResourceBoundsMapping>,
162-
#[serde(default)]
163-
#[serde_as(as = "Option<UfeHex>")]
164-
pub tip: Option<FieldElement>,
162+
#[serde(default, with = "u64_hex_opt")]
163+
pub tip: Option<u64>,
165164
#[serde_as(as = "Option<Vec<UfeHex>>")]
166165
pub paymaster_data: Option<Vec<FieldElement>>,
167166
#[serde(default)]
@@ -190,12 +189,11 @@ pub struct InvokeFunctionTransaction {
190189
pub max_fee: Option<FieldElement>,
191190
#[serde_as(as = "Option<UfeHex>")]
192191
pub nonce: Option<FieldElement>,
193-
pub nonce_data_availability_mode: Option<u32>,
194-
pub fee_data_availability_mode: Option<u32>,
192+
pub nonce_data_availability_mode: Option<DataAvailabilityMode>,
193+
pub fee_data_availability_mode: Option<DataAvailabilityMode>,
195194
pub resource_bounds: Option<ResourceBoundsMapping>,
196-
#[serde(default)]
197-
#[serde_as(as = "Option<UfeHex>")]
198-
pub tip: Option<FieldElement>,
195+
#[serde(default, with = "u64_hex_opt")]
196+
pub tip: Option<u64>,
199197
#[serde_as(as = "Option<Vec<UfeHex>>")]
200198
pub paymaster_data: Option<Vec<FieldElement>>,
201199
#[serde_as(deserialize_as = "Option<Vec<UfeHex>>")]
@@ -222,24 +220,31 @@ pub struct L1HandlerTransaction {
222220
pub version: FieldElement,
223221
}
224222

225-
#[derive(Debug, Deserialize)]
223+
#[derive(Debug, Serialize, Deserialize)]
226224
#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))]
227225
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
228226
pub struct ResourceBoundsMapping {
229-
l1_gas: ResourceBounds,
230-
l2_gas: ResourceBounds,
227+
pub l1_gas: ResourceBounds,
228+
pub l2_gas: ResourceBounds,
231229
}
232230

233-
#[serde_as]
234-
#[derive(Debug, Deserialize)]
231+
#[derive(Debug, Serialize, Deserialize)]
235232
#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))]
236233
pub struct ResourceBounds {
237-
#[serde_as(as = "UfeHex")]
238-
pub max_amount: FieldElement,
239-
#[serde_as(as = "UfeHex")]
240-
pub max_price_per_unit: FieldElement,
234+
#[serde(with = "u64_hex")]
235+
pub max_amount: u64,
236+
#[serde(with = "u128_hex")]
237+
pub max_price_per_unit: u128,
241238
}
242239

240+
#[derive(Debug)]
241+
pub enum DataAvailabilityMode {
242+
L1,
243+
L2,
244+
}
245+
246+
struct DataAvailabilityModeVisitor;
247+
243248
impl TransactionType {
244249
pub fn transaction_hash(&self) -> FieldElement {
245250
match self {
@@ -252,6 +257,49 @@ impl TransactionType {
252257
}
253258
}
254259

260+
impl Serialize for DataAvailabilityMode {
261+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
262+
where
263+
S: serde::Serializer,
264+
{
265+
serializer.serialize_u32(match self {
266+
Self::L1 => 0,
267+
Self::L2 => 1,
268+
})
269+
}
270+
}
271+
272+
impl<'de> Deserialize<'de> for DataAvailabilityMode {
273+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
274+
where
275+
D: serde::Deserializer<'de>,
276+
{
277+
deserializer.deserialize_any(DataAvailabilityModeVisitor)
278+
}
279+
}
280+
281+
impl<'de> Visitor<'de> for DataAvailabilityModeVisitor {
282+
type Value = DataAvailabilityMode;
283+
284+
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
285+
write!(formatter, "integer")
286+
}
287+
288+
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
289+
where
290+
E: serde::de::Error,
291+
{
292+
match v {
293+
0 => Ok(DataAvailabilityMode::L1),
294+
1 => Ok(DataAvailabilityMode::L2),
295+
_ => Err(serde::de::Error::invalid_value(
296+
serde::de::Unexpected::Unsigned(v),
297+
&"0 or 1",
298+
)),
299+
}
300+
}
301+
}
302+
255303
#[cfg(test)]
256304
mod tests {
257305
use super::*;

starknet-providers/src/sequencer/models/transaction_receipt.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ pub struct BuiltinInstanceCounter {
8787
pub ec_op_builtin: Option<u64>,
8888
pub poseidon_builtin: Option<u64>,
8989
pub keccak_builtin: Option<u64>,
90+
pub segment_arena_builtin: Option<u64>,
9091
}
9192

9293
#[serde_as]

0 commit comments

Comments
 (0)