From 66f1d5935a2ff5924488bbc16993b838059110b4 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Fri, 3 Nov 2023 16:54:51 +0000 Subject: [PATCH] feat(jsonrpc): switch to spec 0.5.1 --- README.md | 2 +- .../tests/single_owner_account.rs | 2 +- .../tests/contract_deployment.rs | 2 +- starknet-core/src/types/codegen.rs | 867 +++++++++++++----- starknet-core/src/types/mod.rs | 49 +- starknet-core/src/types/requests.rs | 7 +- starknet-core/src/types/serde_impls.rs | 66 +- starknet-providers/src/any.rs | 59 +- starknet-providers/src/jsonrpc/mod.rs | 64 +- starknet-providers/src/provider.rs | 23 +- .../src/sequencer/models/conversions.rs | 304 +++--- .../sequencer/models/transaction_receipt.rs | 2 + starknet-providers/src/sequencer/provider.rs | 114 ++- starknet-providers/tests/jsonrpc.rs | 105 ++- 14 files changed, 1180 insertions(+), 486 deletions(-) diff --git a/README.md b/README.md index 4e803253..f0282f94 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ **Complete Starknet library in Rust[™](https://www.reddit.com/r/rust/comments/12e7tdb/rust_trademark_policy_feedback_form/)** ![starknet-version-v0.12.1](https://img.shields.io/badge/Starknet_Version-v0.12.1-2ea44f?logo=ethereum) -[![jsonrpc-spec-v0.4.0](https://img.shields.io/badge/JSON--RPC-v0.4.0-2ea44f?logo=ethereum)](https://github.com/starkware-libs/starknet-specs/tree/v0.3.0) +[![jsonrpc-spec-v0.5.1](https://img.shields.io/badge/JSON--RPC-v0.5.1-2ea44f?logo=ethereum)](https://github.com/starkware-libs/starknet-specs/tree/v0.5.1) [![linting-badge](https://github.com/xJonathanLEI/starknet-rs/actions/workflows/lint.yaml/badge.svg?branch=master)](https://github.com/xJonathanLEI/starknet-rs/actions/workflows/lint.yaml) [![crates-badge](https://img.shields.io/crates/v/starknet.svg)](https://crates.io/crates/starknet) diff --git a/starknet-accounts/tests/single_owner_account.rs b/starknet-accounts/tests/single_owner_account.rs index 4152bed8..ab0acef6 100644 --- a/starknet-accounts/tests/single_owner_account.rs +++ b/starknet-accounts/tests/single_owner_account.rs @@ -24,7 +24,7 @@ fn create_sequencer_client() -> SequencerGatewayProvider { fn create_jsonrpc_client() -> JsonRpcClient { let rpc_url = - std::env::var("STARKNET_RPC").unwrap_or("https://rpc-goerli-1.starknet.rs/rpc/v0.4".into()); + std::env::var("STARKNET_RPC").unwrap_or("https://rpc-goerli-1.starknet.rs/rpc/v0.5".into()); JsonRpcClient::new(HttpTransport::new(url::Url::parse(&rpc_url).unwrap())) } diff --git a/starknet-contract/tests/contract_deployment.rs b/starknet-contract/tests/contract_deployment.rs index 4b9dfa47..b1543290 100644 --- a/starknet-contract/tests/contract_deployment.rs +++ b/starknet-contract/tests/contract_deployment.rs @@ -12,7 +12,7 @@ use url::Url; #[tokio::test] async fn can_deploy_contract_to_alpha_goerli() { let rpc_url = - std::env::var("STARKNET_RPC").unwrap_or("https://rpc-goerli-1.starknet.rs/rpc/v0.4".into()); + std::env::var("STARKNET_RPC").unwrap_or("https://rpc-goerli-1.starknet.rs/rpc/v0.5".into()); let provider = JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())); let signer = LocalWallet::from(SigningKey::from_secret_scalar( FieldElement::from_hex_be( diff --git a/starknet-core/src/types/codegen.rs b/starknet-core/src/types/codegen.rs index 2b177d80..6b1bcd8d 100644 --- a/starknet-core/src/types/codegen.rs +++ b/starknet-core/src/types/codegen.rs @@ -94,6 +94,10 @@ pub struct BlockWithTxHashes { /// The Starknet identity of the sequencer submitting this block #[serde_as(as = "UfeHex")] pub sequencer_address: FieldElement, + /// The price of L1 gas in the block + pub l1_gas_price: ResourcePrice, + /// Semver of the current Starknet protocol + pub starknet_version: String, /// The hashes of the transactions included in this block #[serde_as(as = "Vec")] pub transactions: Vec, @@ -124,17 +128,17 @@ pub struct BlockWithTxs { /// The Starknet identity of the sequencer submitting this block #[serde_as(as = "UfeHex")] pub sequencer_address: FieldElement, + /// The price of L1 gas in the block + pub l1_gas_price: ResourcePrice, + /// Semver of the current Starknet protocol + pub starknet_version: String, /// The transactions in this block pub transactions: Vec, } -/// Broadcasted declare transaction v1. -/// -/// Mempool representation of a declare transaction. +/// Broadcasted declare contract transaction v1. #[derive(Debug, Clone, PartialEq, Eq)] pub struct BroadcastedDeclareTransactionV1 { - /// The class to be declared - pub contract_class: OwnedPtr, /// The address of the account contract sending the declaration transaction pub sender_address: FieldElement, /// The maximal fee that can be charged for including the transaction @@ -143,17 +147,17 @@ pub struct BroadcastedDeclareTransactionV1 { pub signature: Vec, /// Nonce pub nonce: FieldElement, + /// The class to be declared + pub contract_class: OwnedPtr, /// If set to `true`, uses a query-only transaction version that's invalid for execution pub is_query: bool, } /// Broadcasted declare transaction v2. /// -/// Mempool representation of a declare transaction v2. +/// Broadcasted declare contract transaction v2. #[derive(Debug, Clone, PartialEq, Eq)] pub struct BroadcastedDeclareTransactionV2 { - /// The class to be declared - pub contract_class: OwnedPtr, /// The address of the account contract sending the declaration transaction pub sender_address: FieldElement, /// The hash of the cairo assembly resulting from the sierra compilation @@ -164,13 +168,15 @@ pub struct BroadcastedDeclareTransactionV2 { pub signature: Vec, /// Nonce pub nonce: FieldElement, + /// The class to be declared + pub contract_class: OwnedPtr, /// If set to `true`, uses a query-only transaction version that's invalid for execution pub is_query: bool, } -/// Broadcasted deploy account transaction. +/// Deploy account transaction. /// -/// Mempool representation of a deploy account transaction. +/// Deploys an account contract, charges fee from the pre-funded account addresses. #[derive(Debug, Clone, PartialEq, Eq)] pub struct BroadcastedDeployAccountTransaction { /// The maximal fee that can be charged for including the transaction @@ -211,6 +217,8 @@ pub struct BroadcastedInvokeTransaction { #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum CallType { + #[serde(rename = "DELEGATE")] + Delegate, #[serde(rename = "LIBRARY_CALL")] LibraryCall, #[serde(rename = "CALL")] @@ -226,6 +234,7 @@ pub struct CompressedLegacyContractClass { /// A base64 representation of the compressed program code #[serde(with = "base64")] pub program: Vec, + /// Deprecated entry points by type pub entry_points_by_type: LegacyEntryPointsByType, /// Contract abi #[serde(skip_serializing_if = "Option::is_none")] @@ -244,6 +253,18 @@ pub struct ContractStorageDiffItem { pub storage_entries: Vec, } +/// Da mode. +/// +/// Specifies a storage domain in Starknet. Each domain has different gurantess regarding +/// availability. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum DataAvailabilityMode { + #[serde(rename = "L1")] + L1, + #[serde(rename = "L2")] + L2, +} + /// Declare transaction receipt. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareTransactionReceipt { @@ -261,18 +282,19 @@ pub struct DeclareTransactionReceipt { pub messages_sent: Vec, /// The events emitted as part of this transaction pub events: Vec, + /// The resources consumed by the transaction + pub execution_resources: ExecutionResources, /// Transaction execution result pub execution_result: ExecutionResult, } /// The execution trace of a declare transaction. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareTransactionTrace { - #[serde(skip_serializing_if = "Option::is_none")] pub validate_invocation: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub fee_transfer_invocation: Option, + /// The state diffs induced by the transaction + pub state_diff: Option, } /// Declare contract transaction v0. @@ -280,16 +302,16 @@ pub struct DeclareTransactionTrace { /// Declare contract transaction v0. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareTransactionV0 { - /// The hash identifying the transaction + /// Transaction hash pub transaction_hash: FieldElement, - /// The hash of the declared class - pub class_hash: FieldElement, /// The address of the account contract sending the declaration transaction pub sender_address: FieldElement, /// The maximal fee that can be charged for including the transaction pub max_fee: FieldElement, /// Signature pub signature: Vec, + /// The hash of the declared class + pub class_hash: FieldElement, } /// Declare contract transaction v1. @@ -297,10 +319,8 @@ pub struct DeclareTransactionV0 { /// Declare contract transaction v1. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareTransactionV1 { - /// The hash identifying the transaction + /// Transaction hash pub transaction_hash: FieldElement, - /// The hash of the declared class - pub class_hash: FieldElement, /// The address of the account contract sending the declaration transaction pub sender_address: FieldElement, /// The maximal fee that can be charged for including the transaction @@ -309,6 +329,8 @@ pub struct DeclareTransactionV1 { pub signature: Vec, /// Nonce pub nonce: FieldElement, + /// The hash of the declared class + pub class_hash: FieldElement, } /// Declare transaction v2. @@ -316,10 +338,8 @@ pub struct DeclareTransactionV1 { /// Declare contract transaction v2. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeclareTransactionV2 { - /// The hash identifying the transaction + /// Transaction hash pub transaction_hash: FieldElement, - /// The hash of the declared class - pub class_hash: FieldElement, /// The address of the account contract sending the declaration transaction pub sender_address: FieldElement, /// The hash of the cairo assembly resulting from the sierra compilation @@ -330,8 +350,12 @@ pub struct DeclareTransactionV2 { pub signature: Vec, /// Nonce pub nonce: FieldElement, + /// The hash of the declared class + pub class_hash: FieldElement, } +/// New classes. +/// /// The declared class hash and compiled class hash. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -350,7 +374,7 @@ pub struct DeclaredClassItem { /// Deploys an account contract, charges fee from the pre-funded account addresses. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeployAccountTransaction { - /// The hash identifying the transaction + /// Transaction hash pub transaction_hash: FieldElement, /// The maximal fee that can be charged for including the transaction pub max_fee: FieldElement, @@ -383,6 +407,8 @@ pub struct DeployAccountTransactionReceipt { pub messages_sent: Vec, /// The events emitted as part of this transaction pub events: Vec, + /// The resources consumed by the transaction + pub execution_resources: ExecutionResources, /// Transaction execution result pub execution_result: ExecutionResult, /// The address of the deployed contract @@ -390,16 +416,15 @@ pub struct DeployAccountTransactionReceipt { } /// The execution trace of a deploy account transaction. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct DeployAccountTransactionTrace { - #[serde(skip_serializing_if = "Option::is_none")] pub validate_invocation: Option, /// The trace of the __execute__ call or constructor call, depending on the transaction type /// (none for declare transactions) pub constructor_invocation: FunctionInvocation, - #[serde(skip_serializing_if = "Option::is_none")] pub fee_transfer_invocation: Option, + /// The state diffs induced by the transaction + pub state_diff: Option, } /// Deploy contract transaction. @@ -408,7 +433,7 @@ pub struct DeployAccountTransactionTrace { /// longer be supported in future versions. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeployTransaction { - /// The hash identifying the transaction + /// Transaction hash pub transaction_hash: FieldElement, /// Version of the transaction scheme pub version: u64, @@ -437,6 +462,8 @@ pub struct DeployTransactionReceipt { pub messages_sent: Vec, /// The events emitted as part of this transaction pub events: Vec, + /// The resources consumed by the transaction + pub execution_resources: ExecutionResources, /// Transaction execution result pub execution_result: ExecutionResult, /// The address of the deployed contract @@ -493,6 +520,7 @@ pub enum EntryPointType { Constructor, } +/// Entry points by type. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct EntryPointsByType { @@ -525,21 +553,6 @@ pub struct Event { pub data: Vec, } -/// Event content. -/// -/// The content of an event. -#[serde_as] -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] -pub struct EventContent { - /// Keys - #[serde_as(as = "Vec")] - pub keys: Vec, - /// Data - #[serde_as(as = "Vec")] - pub data: Vec, -} - /// Event filter. /// /// An event filter/query. @@ -563,6 +576,7 @@ pub struct EventFilter { pub keys: Option>>, } +/// Events request. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] pub struct EventFilterWithPage { @@ -584,6 +598,43 @@ pub struct EventsChunk { pub continuation_token: Option, } +/// Execution resources. +/// +/// The resources consumed by the transaction. +#[serde_as] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +pub struct ExecutionResources { + /// The number of cairo steps used + #[serde_as(as = "NumAsHex")] + pub steps: u64, + /// The number of unused memory cells (each cell is roughly equivalent to a step) + #[serde(skip_serializing_if = "Option::is_none")] + #[serde_as(as = "Option")] + pub memory_holes: Option, + /// The number of range_check builtin instances + #[serde_as(as = "NumAsHex")] + pub range_check_builtin_applications: u64, + /// The number of pedersen builtin instances + #[serde_as(as = "NumAsHex")] + pub pedersen_builtin_applications: u64, + /// The number of poseidon builtin instances + #[serde_as(as = "NumAsHex")] + pub poseidon_builtin_applications: u64, + /// The number of ec_op builtin instances + #[serde_as(as = "NumAsHex")] + pub ec_op_builtin_applications: u64, + /// The number of ecdsa builtin instances + #[serde_as(as = "NumAsHex")] + pub ecdsa_builtin_applications: u64, + /// The number of bitwise builtin instances + #[serde_as(as = "NumAsHex")] + pub bitwise_builtin_applications: u64, + /// The number of keccak builtin instances + #[serde_as(as = "NumAsHex")] + pub keccak_builtin_applications: u64, +} + /// Fee estimation. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -662,9 +713,9 @@ pub struct FunctionInvocation { /// The calls made by this invocation pub calls: Vec, /// The events emitted in this invocation - pub events: Vec, + pub events: Vec, /// The messages sent by this invocation to L1 - pub messages: Vec, + pub messages: Vec, } /// Function state mutability type. @@ -691,19 +742,20 @@ pub struct InvokeTransactionReceipt { pub messages_sent: Vec, /// The events emitted as part of this transaction pub events: Vec, + /// The resources consumed by the transaction + pub execution_resources: ExecutionResources, /// Transaction execution result pub execution_result: ExecutionResult, } /// The execution trace of an invoke transaction. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeTransactionTrace { - #[serde(skip_serializing_if = "Option::is_none")] pub validate_invocation: Option, pub execute_invocation: ExecuteInvocation, - #[serde(skip_serializing_if = "Option::is_none")] pub fee_transfer_invocation: Option, + /// The state diffs induced by the transaction + pub state_diff: Option, } /// Invoke transaction v0. @@ -711,7 +763,7 @@ pub struct InvokeTransactionTrace { /// Invokes a specific function in the desired contract (not necessarily an account). #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeTransactionV0 { - /// The hash identifying the transaction + /// Transaction hash pub transaction_hash: FieldElement, /// The maximal fee that can be charged for including the transaction pub max_fee: FieldElement, @@ -730,7 +782,7 @@ pub struct InvokeTransactionV0 { /// Initiates a transaction from a given account. #[derive(Debug, Clone, PartialEq, Eq)] pub struct InvokeTransactionV1 { - /// The hash identifying the transaction + /// Transaction hash pub transaction_hash: FieldElement, /// Sender address pub sender_address: FieldElement, @@ -748,7 +800,7 @@ pub struct InvokeTransactionV1 { /// L1 handler transaction. #[derive(Debug, Clone, PartialEq, Eq)] pub struct L1HandlerTransaction { - /// The hash identifying the transaction + /// Transaction hash pub transaction_hash: FieldElement, /// Version of the transaction scheme pub version: u64, @@ -768,6 +820,8 @@ pub struct L1HandlerTransaction { /// Receipt for L1 handler transaction. #[derive(Debug, Clone, PartialEq, Eq)] pub struct L1HandlerTransactionReceipt { + /// The message hash as it appears on the L1 core contract + pub message_hash: Hash256, /// The hash identifying the transaction pub transaction_hash: FieldElement, /// The fee that was charged by the sequencer @@ -782,17 +836,20 @@ pub struct L1HandlerTransactionReceipt { pub messages_sent: Vec, /// The events emitted as part of this transaction pub events: Vec, + /// The resources consumed by the transaction + pub execution_resources: ExecutionResources, /// Transaction execution result pub execution_result: ExecutionResult, } /// The execution trace of an L1 handler transaction. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct L1HandlerTransactionTrace { /// The trace of the __execute__ call or constructor call, depending on the transaction type /// (none for declare transactions) pub function_invocation: FunctionInvocation, + /// The state diffs induced by the transaction + pub state_diff: Option, } /// Deprecated cairo entry point. @@ -950,6 +1007,9 @@ pub struct MsgToL1 { pub payload: Vec, } +/// Nonce update. +/// +/// The updated nonce per contract address. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] @@ -962,6 +1022,43 @@ pub struct NonceUpdate { pub nonce: FieldElement, } +/// Orderedevent. +/// +/// An event alongside its order within the transaction. +#[serde_as] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +pub struct OrderedEvent { + /// The order of the event within the transaction + pub order: u64, + /// Keys + #[serde_as(as = "Vec")] + pub keys: Vec, + /// Data + #[serde_as(as = "Vec")] + pub data: Vec, +} + +/// Orderedmessage. +/// +/// A message alongside its order within the transaction. +#[serde_as] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +pub struct OrderedMessage { + /// The order of the message within the transaction + pub order: u64, + /// The address of the L2 contract sending the message + #[serde_as(as = "UfeHex")] + pub from_address: FieldElement, + /// The target L1 address the message is sent to + #[serde_as(as = "UfeHex")] + pub to_address: FieldElement, + /// The payload of the message + #[serde_as(as = "Vec")] + pub payload: Vec, +} + /// Pending block with transaction hashes. /// /// The dynamic block being constructed by the sequencer. Note that this object will be deprecated @@ -973,14 +1070,18 @@ pub struct PendingBlockWithTxHashes { /// The hashes of the transactions included in this block #[serde_as(as = "Vec")] pub transactions: Vec, + /// The hash of this block's parent + #[serde_as(as = "UfeHex")] + pub parent_hash: FieldElement, /// The time in which the block was created, encoded in Unix time pub timestamp: u64, /// The Starknet identity of the sequencer submitting this block #[serde_as(as = "UfeHex")] pub sequencer_address: FieldElement, - /// The hash of this block's parent - #[serde_as(as = "UfeHex")] - pub parent_hash: FieldElement, + /// The price of L1 gas in the block + pub l1_gas_price: ResourcePrice, + /// Semver of the current Starknet protocol + pub starknet_version: String, } /// Pending block with transactions. @@ -993,17 +1094,21 @@ pub struct PendingBlockWithTxHashes { pub struct PendingBlockWithTxs { /// The transactions in this block pub transactions: Vec, + /// The hash of this block's parent + #[serde_as(as = "UfeHex")] + pub parent_hash: FieldElement, /// The time in which the block was created, encoded in Unix time pub timestamp: u64, /// The Starknet identity of the sequencer submitting this block #[serde_as(as = "UfeHex")] pub sequencer_address: FieldElement, - /// The hash of this block's parent - #[serde_as(as = "UfeHex")] - pub parent_hash: FieldElement, + /// The price of L1 gas in the block + pub l1_gas_price: ResourcePrice, + /// Semver of the current Starknet protocol + pub starknet_version: String, } -/// Pending declare transaction receipt. +/// Declare transaction receipt. #[derive(Debug, Clone, PartialEq, Eq)] pub struct PendingDeclareTransactionReceipt { /// The hash identifying the transaction @@ -1014,11 +1119,13 @@ pub struct PendingDeclareTransactionReceipt { pub messages_sent: Vec, /// The events emitted as part of this transaction pub events: Vec, + /// The resources consumed by the transaction + pub execution_resources: ExecutionResources, /// Transaction execution result pub execution_result: ExecutionResult, } -/// Pending deploy account transaction receipt. +/// Deploy account transaction receipt. #[derive(Debug, Clone, PartialEq, Eq)] pub struct PendingDeployAccountTransactionReceipt { /// The hash identifying the transaction @@ -1029,28 +1136,15 @@ pub struct PendingDeployAccountTransactionReceipt { pub messages_sent: Vec, /// The events emitted as part of this transaction pub events: Vec, - /// Transaction execution result - pub execution_result: ExecutionResult, -} - -/// Pending deploy transaction receipt. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct PendingDeployTransactionReceipt { - /// The hash identifying the transaction - pub transaction_hash: FieldElement, - /// The fee that was charged by the sequencer - pub actual_fee: FieldElement, - /// Messages sent - pub messages_sent: Vec, - /// The events emitted as part of this transaction - pub events: Vec, + /// The resources consumed by the transaction + pub execution_resources: ExecutionResources, /// Transaction execution result pub execution_result: ExecutionResult, /// The address of the deployed contract pub contract_address: FieldElement, } -/// Pending invoke transaction receipt. +/// Invoke transaction receipt. #[derive(Debug, Clone, PartialEq, Eq)] pub struct PendingInvokeTransactionReceipt { /// The hash identifying the transaction @@ -1061,13 +1155,19 @@ pub struct PendingInvokeTransactionReceipt { pub messages_sent: Vec, /// The events emitted as part of this transaction pub events: Vec, + /// The resources consumed by the transaction + pub execution_resources: ExecutionResources, /// Transaction execution result pub execution_result: ExecutionResult, } -/// Pending receipt for L1 handler transaction. +/// L1 handler transaction receipt. +/// +/// Receipt for L1 handler transaction. #[derive(Debug, Clone, PartialEq, Eq)] pub struct PendingL1HandlerTransactionReceipt { + /// The message hash as it appears on the L1 core contract + pub message_hash: Hash256, /// The hash identifying the transaction pub transaction_hash: FieldElement, /// The fee that was charged by the sequencer @@ -1076,6 +1176,8 @@ pub struct PendingL1HandlerTransactionReceipt { pub messages_sent: Vec, /// The events emitted as part of this transaction pub events: Vec, + /// The resources consumed by the transaction + pub execution_resources: ExecutionResources, /// Transaction execution result pub execution_result: ExecutionResult, } @@ -1090,11 +1192,13 @@ pub struct PendingStateUpdate { /// The previous global state root #[serde_as(as = "UfeHex")] pub old_root: FieldElement, - /// The change in state applied in this block, given as a mapping of addresses to the new values - /// and/or new contracts + /// State diff pub state_diff: StateDiff, } +/// Replaced class. +/// +/// The list of contracts whose class was replaced. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] @@ -1107,6 +1211,31 @@ pub struct ReplacedClassItem { pub class_hash: FieldElement, } +#[serde_as] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +pub struct ResourceLimits { + /// The max amount of the resource that can be used in the tx + #[serde_as(as = "NumAsHex")] + pub max_amount: u64, + /// The max price per unit of this resource for this tx + #[serde_as(as = "NumAsHex")] + pub max_price_per_unit: u64, +} + +#[serde_as] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] +pub struct ResourcePrice { + /// The price of one unit of the given resource, denominated in strk + #[serde(skip_serializing_if = "Option::is_none")] + #[serde_as(as = "Option")] + pub price_in_strk: Option, + /// The price of one unit of the given resource, denominated in wei + #[serde_as(as = "NumAsHex")] + pub price_in_wei: u64, +} + /// Result page request. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] @@ -1126,6 +1255,22 @@ pub struct RevertedInvocation { pub revert_reason: String, } +/// Transaction status. +/// +/// The finality status of the transaction, including the case the txn is still in the mempool or +/// failed validation during the block construction phase. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum SequencerTransactionStatus { + #[serde(rename = "RECEIVED")] + Received, + #[serde(rename = "REJECTED")] + Rejected, + #[serde(rename = "ACCEPTED_ON_L2")] + AcceptedOnL2, + #[serde(rename = "ACCEPTED_ON_L1")] + AcceptedOnL1, +} + /// Sierra entry point. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -1208,14 +1353,12 @@ pub enum StarknetError { UnsupportedTxVersion, /// the contract class version is not supported UnsupportedContractClassVersion, - /// An unexpected error occured + /// An unexpected error occurred UnexpectedError, /// No trace available for transaction NoTraceAvailable, /// Invalid transaction hash InvalidTransactionHash, - /// Invalid block hash - InvalidBlockHash, } #[cfg(feature = "std")] @@ -1250,11 +1393,12 @@ impl core::fmt::Display for StarknetError { Self::UnexpectedError => write!(f, "UnexpectedError"), Self::NoTraceAvailable => write!(f, "NoTraceAvailable"), Self::InvalidTransactionHash => write!(f, "InvalidTransactionHash"), - Self::InvalidBlockHash => write!(f, "InvalidBlockHash"), } } } +/// The change in state applied in this block, given as a mapping of addresses to the new values +/// and/or new contracts. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] @@ -1282,17 +1426,17 @@ pub struct StateUpdate { /// Block hash #[serde_as(as = "UfeHex")] pub block_hash: FieldElement, - /// The new global state root - #[serde_as(as = "UfeHex")] - pub new_root: FieldElement, /// The previous global state root #[serde_as(as = "UfeHex")] pub old_root: FieldElement, - /// The change in state applied in this block, given as a mapping of addresses to the new values - /// and/or new contracts + /// The new global state root + #[serde_as(as = "UfeHex")] + pub new_root: FieldElement, + /// State diff pub state_diff: StateDiff, } +/// Storage diff item. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] @@ -1647,9 +1791,17 @@ pub struct GetTransactionReceiptRequestRef<'a> { pub transaction_hash: &'a FieldElement, } -/// Request for method starknet_pendingTransactions +/// Request for method starknet_getTransactionStatus #[derive(Debug, Clone, PartialEq, Eq)] -pub struct PendingTransactionsRequest; +pub struct GetTransactionStatusRequest { + pub transaction_hash: FieldElement, +} + +/// Reference version of [GetTransactionStatusRequest]. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct GetTransactionStatusRequestRef<'a> { + pub transaction_hash: &'a FieldElement, +} /// Request for method starknet_simulateTransactions #[derive(Debug, Clone, PartialEq, Eq)] @@ -1671,6 +1823,10 @@ pub struct SimulateTransactionsRequestRef<'a> { pub simulation_flags: &'a [SimulationFlag], } +/// Request for method starknet_specVersion +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct SpecVersionRequest; + /// Request for method starknet_syncing #[derive(Debug, Clone, PartialEq, Eq)] pub struct SyncingRequest; @@ -1678,13 +1834,14 @@ pub struct SyncingRequest; /// Request for method starknet_traceBlockTransactions #[derive(Debug, Clone, PartialEq, Eq)] pub struct TraceBlockTransactionsRequest { - pub block_hash: FieldElement, + /// The hash of the requested block, or number (height) of the requested block, or a block tag + pub block_id: BlockId, } /// Reference version of [TraceBlockTransactionsRequest]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct TraceBlockTransactionsRequestRef<'a> { - pub block_hash: &'a FieldElement, + pub block_id: &'a BlockId, } /// Request for method starknet_traceTransaction @@ -1705,7 +1862,6 @@ impl Serialize for BroadcastedDeclareTransactionV1 { #[derive(Serialize)] struct Tagged<'a> { pub r#type: &'a str, - pub contract_class: &'a CompressedLegacyContractClass, #[serde_as(as = "UfeHex")] pub sender_address: &'a FieldElement, #[serde_as(as = "UfeHex")] @@ -1716,6 +1872,7 @@ impl Serialize for BroadcastedDeclareTransactionV1 { pub signature: &'a [FieldElement], #[serde_as(as = "UfeHex")] pub nonce: &'a FieldElement, + pub contract_class: &'a CompressedLegacyContractClass, } let r#type = "DECLARE"; @@ -1728,12 +1885,12 @@ impl Serialize for BroadcastedDeclareTransactionV1 { let tagged = Tagged { r#type, - contract_class: &self.contract_class, sender_address: &self.sender_address, max_fee: &self.max_fee, version, signature: &self.signature, nonce: &self.nonce, + contract_class: &self.contract_class, }; Tagged::serialize(&tagged, serializer) @@ -1747,7 +1904,6 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV1 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { pub r#type: Option, - pub contract_class: CompressedLegacyContractClass, #[serde_as(as = "UfeHex")] pub sender_address: FieldElement, #[serde_as(as = "UfeHex")] @@ -1758,6 +1914,7 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV1 { pub signature: Vec, #[serde_as(as = "UfeHex")] pub nonce: FieldElement, + pub contract_class: CompressedLegacyContractClass, } let tagged = Tagged::deserialize(deserializer)?; @@ -1777,11 +1934,11 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV1 { }; Ok(Self { - contract_class: OwnedPtr::new(tagged.contract_class), sender_address: tagged.sender_address, max_fee: tagged.max_fee, signature: tagged.signature, nonce: tagged.nonce, + contract_class: OwnedPtr::new(tagged.contract_class), is_query, }) } @@ -1793,7 +1950,6 @@ impl Serialize for BroadcastedDeclareTransactionV2 { #[derive(Serialize)] struct Tagged<'a> { pub r#type: &'a str, - pub contract_class: &'a FlattenedSierraClass, #[serde_as(as = "UfeHex")] pub sender_address: &'a FieldElement, #[serde_as(as = "UfeHex")] @@ -1806,6 +1962,7 @@ impl Serialize for BroadcastedDeclareTransactionV2 { pub signature: &'a [FieldElement], #[serde_as(as = "UfeHex")] pub nonce: &'a FieldElement, + pub contract_class: &'a FlattenedSierraClass, } let r#type = "DECLARE"; @@ -1818,13 +1975,13 @@ impl Serialize for BroadcastedDeclareTransactionV2 { let tagged = Tagged { r#type, - contract_class: &self.contract_class, sender_address: &self.sender_address, compiled_class_hash: &self.compiled_class_hash, max_fee: &self.max_fee, version, signature: &self.signature, nonce: &self.nonce, + contract_class: &self.contract_class, }; Tagged::serialize(&tagged, serializer) @@ -1838,7 +1995,6 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV2 { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { pub r#type: Option, - pub contract_class: FlattenedSierraClass, #[serde_as(as = "UfeHex")] pub sender_address: FieldElement, #[serde_as(as = "UfeHex")] @@ -1851,6 +2007,7 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV2 { pub signature: Vec, #[serde_as(as = "UfeHex")] pub nonce: FieldElement, + pub contract_class: FlattenedSierraClass, } let tagged = Tagged::deserialize(deserializer)?; @@ -1870,12 +2027,12 @@ impl<'de> Deserialize<'de> for BroadcastedDeclareTransactionV2 { }; Ok(Self { - contract_class: OwnedPtr::new(tagged.contract_class), sender_address: tagged.sender_address, compiled_class_hash: tagged.compiled_class_hash, max_fee: tagged.max_fee, signature: tagged.signature, nonce: tagged.nonce, + contract_class: OwnedPtr::new(tagged.contract_class), is_query, }) } @@ -2083,6 +2240,7 @@ impl Serialize for DeclareTransactionReceipt { pub block_number: &'a u64, pub messages_sent: &'a [MsgToL1], pub events: &'a [Event], + pub execution_resources: &'a ExecutionResources, #[serde(flatten)] pub execution_result: &'a ExecutionResult, } @@ -2098,6 +2256,7 @@ impl Serialize for DeclareTransactionReceipt { block_number: &self.block_number, messages_sent: &self.messages_sent, events: &self.events, + execution_resources: &self.execution_resources, execution_result: &self.execution_result, }; @@ -2122,6 +2281,7 @@ impl<'de> Deserialize<'de> for DeclareTransactionReceipt { pub block_number: u64, pub messages_sent: Vec, pub events: Vec, + pub execution_resources: ExecutionResources, #[serde(flatten)] pub execution_result: ExecutionResult, } @@ -2142,11 +2302,68 @@ impl<'de> Deserialize<'de> for DeclareTransactionReceipt { block_number: tagged.block_number, messages_sent: tagged.messages_sent, events: tagged.events, + execution_resources: tagged.execution_resources, execution_result: tagged.execution_result, }) } } +impl Serialize for DeclareTransactionTrace { + fn serialize(&self, serializer: S) -> Result { + #[derive(Serialize)] + struct Tagged<'a> { + #[serde(skip_serializing_if = "Option::is_none")] + pub validate_invocation: &'a Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_transfer_invocation: &'a Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub state_diff: &'a Option, + pub r#type: &'a str, + } + + let r#type = "DECLARE"; + + let tagged = Tagged { + validate_invocation: &self.validate_invocation, + fee_transfer_invocation: &self.fee_transfer_invocation, + state_diff: &self.state_diff, + r#type, + }; + + Tagged::serialize(&tagged, serializer) + } +} + +impl<'de> Deserialize<'de> for DeclareTransactionTrace { + fn deserialize>(deserializer: D) -> Result { + #[derive(Deserialize)] + #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] + struct Tagged { + #[serde(skip_serializing_if = "Option::is_none")] + pub validate_invocation: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_transfer_invocation: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub state_diff: Option, + pub r#type: Option, + } + + let tagged = Tagged::deserialize(deserializer)?; + + if let Some(tag_field) = &tagged.r#type { + if tag_field != "DECLARE" { + return Err(serde::de::Error::custom("invalid `type` value")); + } + } + + Ok(Self { + validate_invocation: tagged.validate_invocation, + fee_transfer_invocation: tagged.fee_transfer_invocation, + state_diff: tagged.state_diff, + }) + } +} + impl Serialize for DeclareTransactionV0 { fn serialize(&self, serializer: S) -> Result { #[serde_as] @@ -2156,8 +2373,6 @@ impl Serialize for DeclareTransactionV0 { pub transaction_hash: &'a FieldElement, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, - #[serde_as(as = "UfeHex")] pub sender_address: &'a FieldElement, #[serde_as(as = "UfeHex")] pub max_fee: &'a FieldElement, @@ -2165,6 +2380,8 @@ impl Serialize for DeclareTransactionV0 { pub version: &'a u64, #[serde_as(as = "[UfeHex]")] pub signature: &'a [FieldElement], + #[serde_as(as = "UfeHex")] + pub class_hash: &'a FieldElement, } let r#type = "DECLARE"; @@ -2174,11 +2391,11 @@ impl Serialize for DeclareTransactionV0 { let tagged = Tagged { transaction_hash: &self.transaction_hash, r#type, - class_hash: &self.class_hash, sender_address: &self.sender_address, max_fee: &self.max_fee, version, signature: &self.signature, + class_hash: &self.class_hash, }; Tagged::serialize(&tagged, serializer) @@ -2195,8 +2412,6 @@ impl<'de> Deserialize<'de> for DeclareTransactionV0 { pub transaction_hash: FieldElement, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, - #[serde_as(as = "UfeHex")] pub sender_address: FieldElement, #[serde_as(as = "UfeHex")] pub max_fee: FieldElement, @@ -2204,6 +2419,8 @@ impl<'de> Deserialize<'de> for DeclareTransactionV0 { pub version: Option, #[serde_as(as = "Vec")] pub signature: Vec, + #[serde_as(as = "UfeHex")] + pub class_hash: FieldElement, } let tagged = Tagged::deserialize(deserializer)?; @@ -2222,10 +2439,10 @@ impl<'de> Deserialize<'de> for DeclareTransactionV0 { Ok(Self { transaction_hash: tagged.transaction_hash, - class_hash: tagged.class_hash, sender_address: tagged.sender_address, max_fee: tagged.max_fee, signature: tagged.signature, + class_hash: tagged.class_hash, }) } } @@ -2239,8 +2456,6 @@ impl Serialize for DeclareTransactionV1 { pub transaction_hash: &'a FieldElement, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, - #[serde_as(as = "UfeHex")] pub sender_address: &'a FieldElement, #[serde_as(as = "UfeHex")] pub max_fee: &'a FieldElement, @@ -2250,6 +2465,8 @@ impl Serialize for DeclareTransactionV1 { pub signature: &'a [FieldElement], #[serde_as(as = "UfeHex")] pub nonce: &'a FieldElement, + #[serde_as(as = "UfeHex")] + pub class_hash: &'a FieldElement, } let r#type = "DECLARE"; @@ -2259,12 +2476,12 @@ impl Serialize for DeclareTransactionV1 { let tagged = Tagged { transaction_hash: &self.transaction_hash, r#type, - class_hash: &self.class_hash, sender_address: &self.sender_address, max_fee: &self.max_fee, version, signature: &self.signature, nonce: &self.nonce, + class_hash: &self.class_hash, }; Tagged::serialize(&tagged, serializer) @@ -2281,8 +2498,6 @@ impl<'de> Deserialize<'de> for DeclareTransactionV1 { pub transaction_hash: FieldElement, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, - #[serde_as(as = "UfeHex")] pub sender_address: FieldElement, #[serde_as(as = "UfeHex")] pub max_fee: FieldElement, @@ -2292,6 +2507,8 @@ impl<'de> Deserialize<'de> for DeclareTransactionV1 { pub signature: Vec, #[serde_as(as = "UfeHex")] pub nonce: FieldElement, + #[serde_as(as = "UfeHex")] + pub class_hash: FieldElement, } let tagged = Tagged::deserialize(deserializer)?; @@ -2310,11 +2527,11 @@ impl<'de> Deserialize<'de> for DeclareTransactionV1 { Ok(Self { transaction_hash: tagged.transaction_hash, - class_hash: tagged.class_hash, sender_address: tagged.sender_address, max_fee: tagged.max_fee, signature: tagged.signature, nonce: tagged.nonce, + class_hash: tagged.class_hash, }) } } @@ -2328,8 +2545,6 @@ impl Serialize for DeclareTransactionV2 { pub transaction_hash: &'a FieldElement, pub r#type: &'a str, #[serde_as(as = "UfeHex")] - pub class_hash: &'a FieldElement, - #[serde_as(as = "UfeHex")] pub sender_address: &'a FieldElement, #[serde_as(as = "UfeHex")] pub compiled_class_hash: &'a FieldElement, @@ -2341,6 +2556,8 @@ impl Serialize for DeclareTransactionV2 { pub signature: &'a [FieldElement], #[serde_as(as = "UfeHex")] pub nonce: &'a FieldElement, + #[serde_as(as = "UfeHex")] + pub class_hash: &'a FieldElement, } let r#type = "DECLARE"; @@ -2350,13 +2567,13 @@ impl Serialize for DeclareTransactionV2 { let tagged = Tagged { transaction_hash: &self.transaction_hash, r#type, - class_hash: &self.class_hash, sender_address: &self.sender_address, compiled_class_hash: &self.compiled_class_hash, max_fee: &self.max_fee, version, signature: &self.signature, nonce: &self.nonce, + class_hash: &self.class_hash, }; Tagged::serialize(&tagged, serializer) @@ -2373,8 +2590,6 @@ impl<'de> Deserialize<'de> for DeclareTransactionV2 { pub transaction_hash: FieldElement, pub r#type: Option, #[serde_as(as = "UfeHex")] - pub class_hash: FieldElement, - #[serde_as(as = "UfeHex")] pub sender_address: FieldElement, #[serde_as(as = "UfeHex")] pub compiled_class_hash: FieldElement, @@ -2386,6 +2601,8 @@ impl<'de> Deserialize<'de> for DeclareTransactionV2 { pub signature: Vec, #[serde_as(as = "UfeHex")] pub nonce: FieldElement, + #[serde_as(as = "UfeHex")] + pub class_hash: FieldElement, } let tagged = Tagged::deserialize(deserializer)?; @@ -2404,12 +2621,12 @@ impl<'de> Deserialize<'de> for DeclareTransactionV2 { Ok(Self { transaction_hash: tagged.transaction_hash, - class_hash: tagged.class_hash, sender_address: tagged.sender_address, compiled_class_hash: tagged.compiled_class_hash, max_fee: tagged.max_fee, signature: tagged.signature, nonce: tagged.nonce, + class_hash: tagged.class_hash, }) } } @@ -2524,6 +2741,7 @@ impl Serialize for DeployAccountTransactionReceipt { pub block_number: &'a u64, pub messages_sent: &'a [MsgToL1], pub events: &'a [Event], + pub execution_resources: &'a ExecutionResources, #[serde(flatten)] pub execution_result: &'a ExecutionResult, pub r#type: &'a str, @@ -2541,6 +2759,7 @@ impl Serialize for DeployAccountTransactionReceipt { block_number: &self.block_number, messages_sent: &self.messages_sent, events: &self.events, + execution_resources: &self.execution_resources, execution_result: &self.execution_result, r#type, contract_address: &self.contract_address, @@ -2566,11 +2785,78 @@ impl<'de> Deserialize<'de> for DeployAccountTransactionReceipt { pub block_number: u64, pub messages_sent: Vec, pub events: Vec, + pub execution_resources: ExecutionResources, #[serde(flatten)] pub execution_result: ExecutionResult, pub r#type: Option, - #[serde_as(as = "UfeHex")] - pub contract_address: FieldElement, + #[serde_as(as = "UfeHex")] + pub contract_address: FieldElement, + } + + let tagged = Tagged::deserialize(deserializer)?; + + if let Some(tag_field) = &tagged.r#type { + if tag_field != "DEPLOY_ACCOUNT" { + return Err(serde::de::Error::custom("invalid `type` value")); + } + } + + Ok(Self { + transaction_hash: tagged.transaction_hash, + actual_fee: tagged.actual_fee, + finality_status: tagged.finality_status, + block_hash: tagged.block_hash, + block_number: tagged.block_number, + messages_sent: tagged.messages_sent, + events: tagged.events, + execution_resources: tagged.execution_resources, + execution_result: tagged.execution_result, + contract_address: tagged.contract_address, + }) + } +} + +impl Serialize for DeployAccountTransactionTrace { + fn serialize(&self, serializer: S) -> Result { + #[derive(Serialize)] + struct Tagged<'a> { + #[serde(skip_serializing_if = "Option::is_none")] + pub validate_invocation: &'a Option, + pub constructor_invocation: &'a FunctionInvocation, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_transfer_invocation: &'a Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub state_diff: &'a Option, + pub r#type: &'a str, + } + + let r#type = "DEPLOY_ACCOUNT"; + + let tagged = Tagged { + validate_invocation: &self.validate_invocation, + constructor_invocation: &self.constructor_invocation, + fee_transfer_invocation: &self.fee_transfer_invocation, + state_diff: &self.state_diff, + r#type, + }; + + Tagged::serialize(&tagged, serializer) + } +} + +impl<'de> Deserialize<'de> for DeployAccountTransactionTrace { + fn deserialize>(deserializer: D) -> Result { + #[derive(Deserialize)] + #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] + struct Tagged { + #[serde(skip_serializing_if = "Option::is_none")] + pub validate_invocation: Option, + pub constructor_invocation: FunctionInvocation, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_transfer_invocation: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub state_diff: Option, + pub r#type: Option, } let tagged = Tagged::deserialize(deserializer)?; @@ -2582,15 +2868,10 @@ impl<'de> Deserialize<'de> for DeployAccountTransactionReceipt { } Ok(Self { - transaction_hash: tagged.transaction_hash, - actual_fee: tagged.actual_fee, - finality_status: tagged.finality_status, - block_hash: tagged.block_hash, - block_number: tagged.block_number, - messages_sent: tagged.messages_sent, - events: tagged.events, - execution_result: tagged.execution_result, - contract_address: tagged.contract_address, + validate_invocation: tagged.validate_invocation, + constructor_invocation: tagged.constructor_invocation, + fee_transfer_invocation: tagged.fee_transfer_invocation, + state_diff: tagged.state_diff, }) } } @@ -2680,6 +2961,7 @@ impl Serialize for DeployTransactionReceipt { pub block_number: &'a u64, pub messages_sent: &'a [MsgToL1], pub events: &'a [Event], + pub execution_resources: &'a ExecutionResources, #[serde(flatten)] pub execution_result: &'a ExecutionResult, pub r#type: &'a str, @@ -2697,6 +2979,7 @@ impl Serialize for DeployTransactionReceipt { block_number: &self.block_number, messages_sent: &self.messages_sent, events: &self.events, + execution_resources: &self.execution_resources, execution_result: &self.execution_result, r#type, contract_address: &self.contract_address, @@ -2722,6 +3005,7 @@ impl<'de> Deserialize<'de> for DeployTransactionReceipt { pub block_number: u64, pub messages_sent: Vec, pub events: Vec, + pub execution_resources: ExecutionResources, #[serde(flatten)] pub execution_result: ExecutionResult, pub r#type: Option, @@ -2745,6 +3029,7 @@ impl<'de> Deserialize<'de> for DeployTransactionReceipt { block_number: tagged.block_number, messages_sent: tagged.messages_sent, events: tagged.events, + execution_resources: tagged.execution_resources, execution_result: tagged.execution_result, contract_address: tagged.contract_address, }) @@ -2767,6 +3052,7 @@ impl Serialize for InvokeTransactionReceipt { pub block_number: &'a u64, pub messages_sent: &'a [MsgToL1], pub events: &'a [Event], + pub execution_resources: &'a ExecutionResources, #[serde(flatten)] pub execution_result: &'a ExecutionResult, } @@ -2782,6 +3068,7 @@ impl Serialize for InvokeTransactionReceipt { block_number: &self.block_number, messages_sent: &self.messages_sent, events: &self.events, + execution_resources: &self.execution_resources, execution_result: &self.execution_result, }; @@ -2806,6 +3093,7 @@ impl<'de> Deserialize<'de> for InvokeTransactionReceipt { pub block_number: u64, pub messages_sent: Vec, pub events: Vec, + pub execution_resources: ExecutionResources, #[serde(flatten)] pub execution_result: ExecutionResult, } @@ -2826,11 +3114,72 @@ impl<'de> Deserialize<'de> for InvokeTransactionReceipt { block_number: tagged.block_number, messages_sent: tagged.messages_sent, events: tagged.events, + execution_resources: tagged.execution_resources, execution_result: tagged.execution_result, }) } } +impl Serialize for InvokeTransactionTrace { + fn serialize(&self, serializer: S) -> Result { + #[derive(Serialize)] + struct Tagged<'a> { + #[serde(skip_serializing_if = "Option::is_none")] + pub validate_invocation: &'a Option, + pub execute_invocation: &'a ExecuteInvocation, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_transfer_invocation: &'a Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub state_diff: &'a Option, + pub r#type: &'a str, + } + + let r#type = "INVOKE"; + + let tagged = Tagged { + validate_invocation: &self.validate_invocation, + execute_invocation: &self.execute_invocation, + fee_transfer_invocation: &self.fee_transfer_invocation, + state_diff: &self.state_diff, + r#type, + }; + + Tagged::serialize(&tagged, serializer) + } +} + +impl<'de> Deserialize<'de> for InvokeTransactionTrace { + fn deserialize>(deserializer: D) -> Result { + #[derive(Deserialize)] + #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] + struct Tagged { + #[serde(skip_serializing_if = "Option::is_none")] + pub validate_invocation: Option, + pub execute_invocation: ExecuteInvocation, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_transfer_invocation: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub state_diff: Option, + pub r#type: Option, + } + + let tagged = Tagged::deserialize(deserializer)?; + + if let Some(tag_field) = &tagged.r#type { + if tag_field != "INVOKE" { + return Err(serde::de::Error::custom("invalid `type` value")); + } + } + + Ok(Self { + validate_invocation: tagged.validate_invocation, + execute_invocation: tagged.execute_invocation, + fee_transfer_invocation: tagged.fee_transfer_invocation, + state_diff: tagged.state_diff, + }) + } +} + impl Serialize for InvokeTransactionV0 { fn serialize(&self, serializer: S) -> Result { #[serde_as] @@ -3091,6 +3440,7 @@ impl Serialize for L1HandlerTransactionReceipt { #[derive(Serialize)] struct Tagged<'a> { pub r#type: &'a str, + pub message_hash: &'a Hash256, #[serde_as(as = "UfeHex")] pub transaction_hash: &'a FieldElement, #[serde_as(as = "UfeHex")] @@ -3101,6 +3451,7 @@ impl Serialize for L1HandlerTransactionReceipt { pub block_number: &'a u64, pub messages_sent: &'a [MsgToL1], pub events: &'a [Event], + pub execution_resources: &'a ExecutionResources, #[serde(flatten)] pub execution_result: &'a ExecutionResult, } @@ -3109,6 +3460,7 @@ impl Serialize for L1HandlerTransactionReceipt { let tagged = Tagged { r#type, + message_hash: &self.message_hash, transaction_hash: &self.transaction_hash, actual_fee: &self.actual_fee, finality_status: &self.finality_status, @@ -3116,6 +3468,7 @@ impl Serialize for L1HandlerTransactionReceipt { block_number: &self.block_number, messages_sent: &self.messages_sent, events: &self.events, + execution_resources: &self.execution_resources, execution_result: &self.execution_result, }; @@ -3130,6 +3483,7 @@ impl<'de> Deserialize<'de> for L1HandlerTransactionReceipt { #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { pub r#type: Option, + pub message_hash: Hash256, #[serde_as(as = "UfeHex")] pub transaction_hash: FieldElement, #[serde_as(as = "UfeHex")] @@ -3140,6 +3494,7 @@ impl<'de> Deserialize<'de> for L1HandlerTransactionReceipt { pub block_number: u64, pub messages_sent: Vec, pub events: Vec, + pub execution_resources: ExecutionResources, #[serde(flatten)] pub execution_result: ExecutionResult, } @@ -3153,6 +3508,7 @@ impl<'de> Deserialize<'de> for L1HandlerTransactionReceipt { } Ok(Self { + message_hash: tagged.message_hash, transaction_hash: tagged.transaction_hash, actual_fee: tagged.actual_fee, finality_status: tagged.finality_status, @@ -3160,114 +3516,90 @@ impl<'de> Deserialize<'de> for L1HandlerTransactionReceipt { block_number: tagged.block_number, messages_sent: tagged.messages_sent, events: tagged.events, + execution_resources: tagged.execution_resources, execution_result: tagged.execution_result, }) } } -impl Serialize for PendingDeclareTransactionReceipt { +impl Serialize for L1HandlerTransactionTrace { fn serialize(&self, serializer: S) -> Result { - #[serde_as] #[derive(Serialize)] struct Tagged<'a> { - #[serde_as(as = "UfeHex")] - pub transaction_hash: &'a FieldElement, - #[serde_as(as = "UfeHex")] - pub actual_fee: &'a FieldElement, + pub function_invocation: &'a FunctionInvocation, + #[serde(skip_serializing_if = "Option::is_none")] + pub state_diff: &'a Option, pub r#type: &'a str, - pub messages_sent: &'a [MsgToL1], - pub events: &'a [Event], - pub finality_status: &'a TransactionFinalityStatus, - #[serde(flatten)] - pub execution_result: &'a ExecutionResult, } - let r#type = "DECLARE"; - - let finality_status = &TransactionFinalityStatus::AcceptedOnL2; + let r#type = "L1_HANDLER"; let tagged = Tagged { - transaction_hash: &self.transaction_hash, - actual_fee: &self.actual_fee, + function_invocation: &self.function_invocation, + state_diff: &self.state_diff, r#type, - messages_sent: &self.messages_sent, - events: &self.events, - finality_status, - execution_result: &self.execution_result, }; Tagged::serialize(&tagged, serializer) } } -impl<'de> Deserialize<'de> for PendingDeclareTransactionReceipt { +impl<'de> Deserialize<'de> for L1HandlerTransactionTrace { fn deserialize>(deserializer: D) -> Result { - #[serde_as] #[derive(Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { - #[serde_as(as = "UfeHex")] - pub transaction_hash: FieldElement, - #[serde_as(as = "UfeHex")] - pub actual_fee: FieldElement, + pub function_invocation: FunctionInvocation, + #[serde(skip_serializing_if = "Option::is_none")] + pub state_diff: Option, pub r#type: Option, - pub messages_sent: Vec, - pub events: Vec, - pub finality_status: TransactionFinalityStatus, - #[serde(flatten)] - pub execution_result: ExecutionResult, } let tagged = Tagged::deserialize(deserializer)?; if let Some(tag_field) = &tagged.r#type { - if tag_field != "DECLARE" { + if tag_field != "L1_HANDLER" { return Err(serde::de::Error::custom("invalid `type` value")); } } - if tagged.finality_status != TransactionFinalityStatus::AcceptedOnL2 { - return Err(serde::de::Error::custom("invalid `finality_status` value")); - } - Ok(Self { - transaction_hash: tagged.transaction_hash, - actual_fee: tagged.actual_fee, - messages_sent: tagged.messages_sent, - events: tagged.events, - execution_result: tagged.execution_result, + function_invocation: tagged.function_invocation, + state_diff: tagged.state_diff, }) } } -impl Serialize for PendingDeployAccountTransactionReceipt { +impl Serialize for PendingDeclareTransactionReceipt { fn serialize(&self, serializer: S) -> Result { #[serde_as] #[derive(Serialize)] struct Tagged<'a> { + pub r#type: &'a str, #[serde_as(as = "UfeHex")] pub transaction_hash: &'a FieldElement, #[serde_as(as = "UfeHex")] pub actual_fee: &'a FieldElement, - pub r#type: &'a str, pub messages_sent: &'a [MsgToL1], pub events: &'a [Event], pub finality_status: &'a TransactionFinalityStatus, + pub execution_resources: &'a ExecutionResources, #[serde(flatten)] pub execution_result: &'a ExecutionResult, } - let r#type = "DEPLOY_ACCOUNT"; + let r#type = "DECLARE"; let finality_status = &TransactionFinalityStatus::AcceptedOnL2; let tagged = Tagged { + r#type, transaction_hash: &self.transaction_hash, actual_fee: &self.actual_fee, - r#type, messages_sent: &self.messages_sent, events: &self.events, finality_status, + execution_resources: &self.execution_resources, execution_result: &self.execution_result, }; @@ -3275,20 +3607,21 @@ impl Serialize for PendingDeployAccountTransactionReceipt { } } -impl<'de> Deserialize<'de> for PendingDeployAccountTransactionReceipt { +impl<'de> Deserialize<'de> for PendingDeclareTransactionReceipt { fn deserialize>(deserializer: D) -> Result { #[serde_as] #[derive(Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { + pub r#type: Option, #[serde_as(as = "UfeHex")] pub transaction_hash: FieldElement, #[serde_as(as = "UfeHex")] pub actual_fee: FieldElement, - pub r#type: Option, pub messages_sent: Vec, pub events: Vec, pub finality_status: TransactionFinalityStatus, + pub execution_resources: ExecutionResources, #[serde(flatten)] pub execution_result: ExecutionResult, } @@ -3296,7 +3629,7 @@ impl<'de> Deserialize<'de> for PendingDeployAccountTransactionReceipt { let tagged = Tagged::deserialize(deserializer)?; if let Some(tag_field) = &tagged.r#type { - if tag_field != "DEPLOY_ACCOUNT" { + if tag_field != "DECLARE" { return Err(serde::de::Error::custom("invalid `type` value")); } } @@ -3310,12 +3643,13 @@ impl<'de> Deserialize<'de> for PendingDeployAccountTransactionReceipt { actual_fee: tagged.actual_fee, messages_sent: tagged.messages_sent, events: tagged.events, + execution_resources: tagged.execution_resources, execution_result: tagged.execution_result, }) } } -impl Serialize for PendingDeployTransactionReceipt { +impl Serialize for PendingDeployAccountTransactionReceipt { fn serialize(&self, serializer: S) -> Result { #[serde_as] #[derive(Serialize)] @@ -3324,28 +3658,30 @@ impl Serialize for PendingDeployTransactionReceipt { pub transaction_hash: &'a FieldElement, #[serde_as(as = "UfeHex")] pub actual_fee: &'a FieldElement, - pub r#type: &'a str, pub messages_sent: &'a [MsgToL1], pub events: &'a [Event], pub finality_status: &'a TransactionFinalityStatus, + pub execution_resources: &'a ExecutionResources, #[serde(flatten)] pub execution_result: &'a ExecutionResult, + pub r#type: &'a str, #[serde_as(as = "UfeHex")] pub contract_address: &'a FieldElement, } - let r#type = "DEPLOY"; - let finality_status = &TransactionFinalityStatus::AcceptedOnL2; + let r#type = "DEPLOY_ACCOUNT"; + let tagged = Tagged { transaction_hash: &self.transaction_hash, actual_fee: &self.actual_fee, - r#type, messages_sent: &self.messages_sent, events: &self.events, finality_status, + execution_resources: &self.execution_resources, execution_result: &self.execution_result, + r#type, contract_address: &self.contract_address, }; @@ -3353,7 +3689,7 @@ impl Serialize for PendingDeployTransactionReceipt { } } -impl<'de> Deserialize<'de> for PendingDeployTransactionReceipt { +impl<'de> Deserialize<'de> for PendingDeployAccountTransactionReceipt { fn deserialize>(deserializer: D) -> Result { #[serde_as] #[derive(Deserialize)] @@ -3363,33 +3699,35 @@ impl<'de> Deserialize<'de> for PendingDeployTransactionReceipt { pub transaction_hash: FieldElement, #[serde_as(as = "UfeHex")] pub actual_fee: FieldElement, - pub r#type: Option, pub messages_sent: Vec, pub events: Vec, pub finality_status: TransactionFinalityStatus, + pub execution_resources: ExecutionResources, #[serde(flatten)] pub execution_result: ExecutionResult, + pub r#type: Option, #[serde_as(as = "UfeHex")] pub contract_address: FieldElement, } let tagged = Tagged::deserialize(deserializer)?; + if tagged.finality_status != TransactionFinalityStatus::AcceptedOnL2 { + return Err(serde::de::Error::custom("invalid `finality_status` value")); + } + if let Some(tag_field) = &tagged.r#type { - if tag_field != "DEPLOY" { + if tag_field != "DEPLOY_ACCOUNT" { return Err(serde::de::Error::custom("invalid `type` value")); } } - if tagged.finality_status != TransactionFinalityStatus::AcceptedOnL2 { - return Err(serde::de::Error::custom("invalid `finality_status` value")); - } - Ok(Self { transaction_hash: tagged.transaction_hash, actual_fee: tagged.actual_fee, messages_sent: tagged.messages_sent, events: tagged.events, + execution_resources: tagged.execution_resources, execution_result: tagged.execution_result, contract_address: tagged.contract_address, }) @@ -3401,14 +3739,15 @@ impl Serialize for PendingInvokeTransactionReceipt { #[serde_as] #[derive(Serialize)] struct Tagged<'a> { + pub r#type: &'a str, #[serde_as(as = "UfeHex")] pub transaction_hash: &'a FieldElement, #[serde_as(as = "UfeHex")] pub actual_fee: &'a FieldElement, - pub r#type: &'a str, pub messages_sent: &'a [MsgToL1], pub events: &'a [Event], pub finality_status: &'a TransactionFinalityStatus, + pub execution_resources: &'a ExecutionResources, #[serde(flatten)] pub execution_result: &'a ExecutionResult, } @@ -3418,12 +3757,13 @@ impl Serialize for PendingInvokeTransactionReceipt { let finality_status = &TransactionFinalityStatus::AcceptedOnL2; let tagged = Tagged { + r#type, transaction_hash: &self.transaction_hash, actual_fee: &self.actual_fee, - r#type, messages_sent: &self.messages_sent, events: &self.events, finality_status, + execution_resources: &self.execution_resources, execution_result: &self.execution_result, }; @@ -3437,14 +3777,15 @@ impl<'de> Deserialize<'de> for PendingInvokeTransactionReceipt { #[derive(Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { + pub r#type: Option, #[serde_as(as = "UfeHex")] pub transaction_hash: FieldElement, #[serde_as(as = "UfeHex")] pub actual_fee: FieldElement, - pub r#type: Option, pub messages_sent: Vec, pub events: Vec, pub finality_status: TransactionFinalityStatus, + pub execution_resources: ExecutionResources, #[serde(flatten)] pub execution_result: ExecutionResult, } @@ -3466,6 +3807,7 @@ impl<'de> Deserialize<'de> for PendingInvokeTransactionReceipt { actual_fee: tagged.actual_fee, messages_sent: tagged.messages_sent, events: tagged.events, + execution_resources: tagged.execution_resources, execution_result: tagged.execution_result, }) } @@ -3476,14 +3818,16 @@ impl Serialize for PendingL1HandlerTransactionReceipt { #[serde_as] #[derive(Serialize)] struct Tagged<'a> { + pub r#type: &'a str, + pub message_hash: &'a Hash256, #[serde_as(as = "UfeHex")] pub transaction_hash: &'a FieldElement, #[serde_as(as = "UfeHex")] pub actual_fee: &'a FieldElement, - pub r#type: &'a str, pub messages_sent: &'a [MsgToL1], pub events: &'a [Event], pub finality_status: &'a TransactionFinalityStatus, + pub execution_resources: &'a ExecutionResources, #[serde(flatten)] pub execution_result: &'a ExecutionResult, } @@ -3493,12 +3837,14 @@ impl Serialize for PendingL1HandlerTransactionReceipt { let finality_status = &TransactionFinalityStatus::AcceptedOnL2; let tagged = Tagged { + r#type, + message_hash: &self.message_hash, transaction_hash: &self.transaction_hash, actual_fee: &self.actual_fee, - r#type, messages_sent: &self.messages_sent, events: &self.events, finality_status, + execution_resources: &self.execution_resources, execution_result: &self.execution_result, }; @@ -3512,14 +3858,16 @@ impl<'de> Deserialize<'de> for PendingL1HandlerTransactionReceipt { #[derive(Deserialize)] #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] struct Tagged { + pub r#type: Option, + pub message_hash: Hash256, #[serde_as(as = "UfeHex")] pub transaction_hash: FieldElement, #[serde_as(as = "UfeHex")] pub actual_fee: FieldElement, - pub r#type: Option, pub messages_sent: Vec, pub events: Vec, pub finality_status: TransactionFinalityStatus, + pub execution_resources: ExecutionResources, #[serde(flatten)] pub execution_result: ExecutionResult, } @@ -3537,10 +3885,12 @@ impl<'de> Deserialize<'de> for PendingL1HandlerTransactionReceipt { } Ok(Self { + message_hash: tagged.message_hash, transaction_hash: tagged.transaction_hash, actual_fee: tagged.actual_fee, messages_sent: tagged.messages_sent, events: tagged.events, + execution_resources: tagged.execution_resources, execution_result: tagged.execution_result, }) } @@ -5444,22 +5794,87 @@ impl<'de> Deserialize<'de> for GetTransactionReceiptRequest { } } -impl Serialize for PendingTransactionsRequest { +impl Serialize for GetTransactionStatusRequest { fn serialize(&self, serializer: S) -> Result { + #[serde_as] + #[derive(Serialize)] + #[serde(transparent)] + struct Field0<'a> { + #[serde_as(as = "UfeHex")] + pub transaction_hash: &'a FieldElement, + } + use serde::ser::SerializeSeq; - let seq = serializer.serialize_seq(Some(0))?; + let mut seq = serializer.serialize_seq(None)?; + + seq.serialize_element(&Field0 { + transaction_hash: &self.transaction_hash, + })?; + seq.end() } } -impl<'de> Deserialize<'de> for PendingTransactionsRequest { +impl<'a> Serialize for GetTransactionStatusRequestRef<'a> { + fn serialize(&self, serializer: S) -> Result { + #[serde_as] + #[derive(Serialize)] + #[serde(transparent)] + struct Field0<'a> { + #[serde_as(as = "UfeHex")] + pub transaction_hash: &'a FieldElement, + } + + use serde::ser::SerializeSeq; + + let mut seq = serializer.serialize_seq(None)?; + + seq.serialize_element(&Field0 { + transaction_hash: self.transaction_hash, + })?; + + seq.end() + } +} + +impl<'de> Deserialize<'de> for GetTransactionStatusRequest { fn deserialize>(deserializer: D) -> Result { - let elements = Vec::<()>::deserialize(deserializer)?; - if !elements.is_empty() { - return Err(serde::de::Error::custom("invalid sequence length")); + #[serde_as] + #[derive(Deserialize)] + struct AsObject { + #[serde_as(as = "UfeHex")] + pub transaction_hash: FieldElement, + } + + #[serde_as] + #[derive(Deserialize)] + #[serde(transparent)] + struct Field0 { + #[serde_as(as = "UfeHex")] + pub transaction_hash: FieldElement, + } + + let temp = serde_json::Value::deserialize(deserializer)?; + + if let Ok(mut elements) = Vec::::deserialize(&temp) { + let field0 = serde_json::from_value::( + elements + .pop() + .ok_or_else(|| serde::de::Error::custom("invalid sequence length"))?, + ) + .map_err(|err| serde::de::Error::custom(format!("failed to parse element: {}", err)))?; + + Ok(Self { + transaction_hash: field0.transaction_hash, + }) + } else if let Ok(object) = AsObject::deserialize(&temp) { + Ok(Self { + transaction_hash: object.transaction_hash, + }) + } else { + Err(serde::de::Error::custom("invalid sequence length")) } - Ok(Self) } } @@ -5606,6 +6021,25 @@ impl<'de> Deserialize<'de> for SimulateTransactionsRequest { } } +impl Serialize for SpecVersionRequest { + fn serialize(&self, serializer: S) -> Result { + use serde::ser::SerializeSeq; + + let seq = serializer.serialize_seq(Some(0))?; + seq.end() + } +} + +impl<'de> Deserialize<'de> for SpecVersionRequest { + fn deserialize>(deserializer: D) -> Result { + let elements = Vec::<()>::deserialize(deserializer)?; + if !elements.is_empty() { + return Err(serde::de::Error::custom("invalid sequence length")); + } + Ok(Self) + } +} + impl Serialize for SyncingRequest { fn serialize(&self, serializer: S) -> Result { use serde::ser::SerializeSeq; @@ -5627,12 +6061,10 @@ impl<'de> Deserialize<'de> for SyncingRequest { impl Serialize for TraceBlockTransactionsRequest { fn serialize(&self, serializer: S) -> Result { - #[serde_as] #[derive(Serialize)] #[serde(transparent)] struct Field0<'a> { - #[serde_as(as = "UfeHex")] - pub block_hash: &'a FieldElement, + pub block_id: &'a BlockId, } use serde::ser::SerializeSeq; @@ -5640,7 +6072,7 @@ impl Serialize for TraceBlockTransactionsRequest { let mut seq = serializer.serialize_seq(None)?; seq.serialize_element(&Field0 { - block_hash: &self.block_hash, + block_id: &self.block_id, })?; seq.end() @@ -5649,12 +6081,10 @@ impl Serialize for TraceBlockTransactionsRequest { impl<'a> Serialize for TraceBlockTransactionsRequestRef<'a> { fn serialize(&self, serializer: S) -> Result { - #[serde_as] #[derive(Serialize)] #[serde(transparent)] struct Field0<'a> { - #[serde_as(as = "UfeHex")] - pub block_hash: &'a FieldElement, + pub block_id: &'a BlockId, } use serde::ser::SerializeSeq; @@ -5662,7 +6092,7 @@ impl<'a> Serialize for TraceBlockTransactionsRequestRef<'a> { let mut seq = serializer.serialize_seq(None)?; seq.serialize_element(&Field0 { - block_hash: self.block_hash, + block_id: self.block_id, })?; seq.end() @@ -5674,16 +6104,13 @@ impl<'de> Deserialize<'de> for TraceBlockTransactionsRequest { #[serde_as] #[derive(Deserialize)] struct AsObject { - #[serde_as(as = "UfeHex")] - pub block_hash: FieldElement, + pub block_id: BlockId, } - #[serde_as] #[derive(Deserialize)] #[serde(transparent)] struct Field0 { - #[serde_as(as = "UfeHex")] - pub block_hash: FieldElement, + pub block_id: BlockId, } let temp = serde_json::Value::deserialize(deserializer)?; @@ -5697,11 +6124,11 @@ impl<'de> Deserialize<'de> for TraceBlockTransactionsRequest { .map_err(|err| serde::de::Error::custom(format!("failed to parse element: {}", err)))?; Ok(Self { - block_hash: field0.block_hash, + block_id: field0.block_id, }) } else if let Ok(object) = AsObject::deserialize(&temp) { Ok(Self { - block_hash: object.block_hash, + block_id: object.block_id, }) } else { Err(serde::de::Error::custom("invalid sequence length")) diff --git a/starknet-core/src/types/mod.rs b/starknet-core/src/types/mod.rs index 4b4e2a9a..d6c95d5d 100644 --- a/starknet-core/src/types/mod.rs +++ b/starknet-core/src/types/mod.rs @@ -17,23 +17,24 @@ pub use codegen::{ BlockStatus, BlockTag, BlockWithTxHashes, BlockWithTxs, BroadcastedDeclareTransactionV1, BroadcastedDeclareTransactionV2, BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, CallType, CompressedLegacyContractClass, ContractStorageDiffItem, - DeclareTransactionReceipt, DeclareTransactionTrace, DeclareTransactionV0, DeclareTransactionV1, - DeclareTransactionV2, DeclaredClassItem, DeployAccountTransaction, + DataAvailabilityMode, DeclareTransactionReceipt, DeclareTransactionTrace, DeclareTransactionV0, + DeclareTransactionV1, DeclareTransactionV2, DeclaredClassItem, DeployAccountTransaction, DeployAccountTransactionReceipt, DeployAccountTransactionTrace, DeployTransaction, DeployTransactionReceipt, DeployedContractItem, EmittedEvent, EntryPointType, - EntryPointsByType, Event, EventContent, EventFilter, EventFilterWithPage, EventsChunk, + EntryPointsByType, Event, EventFilter, EventFilterWithPage, EventsChunk, ExecutionResources, FeeEstimate, FlattenedSierraClass, FunctionCall, FunctionInvocation, FunctionStateMutability, InvokeTransactionReceipt, InvokeTransactionTrace, InvokeTransactionV0, InvokeTransactionV1, L1HandlerTransaction, L1HandlerTransactionReceipt, L1HandlerTransactionTrace, LegacyContractEntryPoint, LegacyEntryPointsByType, LegacyEventAbiEntry, LegacyEventAbiType, LegacyFunctionAbiEntry, LegacyFunctionAbiType, LegacyStructAbiEntry, LegacyStructAbiType, - LegacyStructMember, LegacyTypedParameter, MsgFromL1, MsgToL1, NonceUpdate, - PendingBlockWithTxHashes, PendingBlockWithTxs, PendingDeclareTransactionReceipt, - PendingDeployAccountTransactionReceipt, PendingDeployTransactionReceipt, + LegacyStructMember, LegacyTypedParameter, MsgFromL1, MsgToL1, NonceUpdate, OrderedEvent, + OrderedMessage, PendingBlockWithTxHashes, PendingBlockWithTxs, + PendingDeclareTransactionReceipt, PendingDeployAccountTransactionReceipt, PendingInvokeTransactionReceipt, PendingL1HandlerTransactionReceipt, PendingStateUpdate, - ReplacedClassItem, ResultPageRequest, RevertedInvocation, SierraEntryPoint, - SimulatedTransaction, SimulationFlag, StarknetError, StateDiff, StateUpdate, StorageEntry, - SyncStatus, TransactionExecutionStatus, TransactionFinalityStatus, TransactionTraceWithHash, + ReplacedClassItem, ResourceLimits, ResourcePrice, ResultPageRequest, RevertedInvocation, + SequencerTransactionStatus, SierraEntryPoint, SimulatedTransaction, SimulationFlag, + StarknetError, StateDiff, StateUpdate, StorageEntry, SyncStatus, TransactionExecutionStatus, + TransactionFinalityStatus, TransactionTraceWithHash, }; pub mod eth_address; @@ -161,6 +162,14 @@ pub enum ContractClass { Legacy(CompressedLegacyContractClass), } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum TransactionStatus { + Received, + Rejected, + AcceptedOnL2(TransactionExecutionStatus), + AcceptedOnL1(TransactionExecutionStatus), +} + #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] #[serde(tag = "type")] pub enum Transaction { @@ -238,8 +247,6 @@ pub enum PendingTransactionReceipt { L1Handler(PendingL1HandlerTransactionReceipt), #[serde(rename = "DECLARE")] Declare(PendingDeclareTransactionReceipt), - #[serde(rename = "DEPLOY")] - Deploy(PendingDeployTransactionReceipt), #[serde(rename = "DEPLOY_ACCOUNT")] DeployAccount(PendingDeployAccountTransactionReceipt), } @@ -253,11 +260,15 @@ pub enum LegacyContractAbiEntry { } #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] -#[serde(untagged)] +#[serde(tag = "type")] pub enum TransactionTrace { + #[serde(rename = "INVOKE")] Invoke(InvokeTransactionTrace), + #[serde(rename = "DEPLOY_ACCOUNT")] DeployAccount(DeployAccountTransactionTrace), + #[serde(rename = "L1_HANDLER")] L1Handler(L1HandlerTransactionTrace), + #[serde(rename = "DECLARE")] Declare(DeclareTransactionTrace), } @@ -316,6 +327,17 @@ impl MaybePendingBlockWithTxs { } } +impl TransactionStatus { + pub fn finality_status(&self) -> SequencerTransactionStatus { + match self { + TransactionStatus::Received => SequencerTransactionStatus::Received, + TransactionStatus::Rejected => SequencerTransactionStatus::Rejected, + TransactionStatus::AcceptedOnL2(_) => SequencerTransactionStatus::AcceptedOnL2, + TransactionStatus::AcceptedOnL1(_) => SequencerTransactionStatus::AcceptedOnL1, + } + } +} + impl Transaction { pub fn transaction_hash(&self) -> &FieldElement { match self { @@ -408,7 +430,6 @@ impl PendingTransactionReceipt { PendingTransactionReceipt::Invoke(receipt) => &receipt.transaction_hash, PendingTransactionReceipt::L1Handler(receipt) => &receipt.transaction_hash, PendingTransactionReceipt::Declare(receipt) => &receipt.transaction_hash, - PendingTransactionReceipt::Deploy(receipt) => &receipt.transaction_hash, PendingTransactionReceipt::DeployAccount(receipt) => &receipt.transaction_hash, } } @@ -422,7 +443,6 @@ impl PendingTransactionReceipt { PendingTransactionReceipt::Invoke(receipt) => &receipt.execution_result, PendingTransactionReceipt::L1Handler(receipt) => &receipt.execution_result, PendingTransactionReceipt::Declare(receipt) => &receipt.execution_result, - PendingTransactionReceipt::Deploy(receipt) => &receipt.execution_result, PendingTransactionReceipt::DeployAccount(receipt) => &receipt.execution_result, } } @@ -527,7 +547,6 @@ impl TryFrom for StarknetError { 63 => StarknetError::UnexpectedError, 10 => StarknetError::NoTraceAvailable, 25 => StarknetError::InvalidTransactionHash, - 26 => StarknetError::InvalidBlockHash, _ => return Err(()), }) } diff --git a/starknet-core/src/types/requests.rs b/starknet-core/src/types/requests.rs index caf7e071..324b9421 100644 --- a/starknet-core/src/types/requests.rs +++ b/starknet-core/src/types/requests.rs @@ -12,7 +12,8 @@ pub use super::codegen::{ GetStateUpdateRequestRef, GetStorageAtRequest, GetStorageAtRequestRef, GetTransactionByBlockIdAndIndexRequest, GetTransactionByBlockIdAndIndexRequestRef, GetTransactionByHashRequest, GetTransactionByHashRequestRef, GetTransactionReceiptRequest, - GetTransactionReceiptRequestRef, PendingTransactionsRequest, SimulateTransactionsRequest, - SimulateTransactionsRequestRef, SyncingRequest, TraceBlockTransactionsRequest, - TraceBlockTransactionsRequestRef, TraceTransactionRequest, TraceTransactionRequestRef, + GetTransactionReceiptRequestRef, GetTransactionStatusRequest, GetTransactionStatusRequestRef, + SimulateTransactionsRequest, SimulateTransactionsRequestRef, SpecVersionRequest, + SyncingRequest, TraceBlockTransactionsRequest, TraceBlockTransactionsRequestRef, + TraceTransactionRequest, TraceTransactionRequestRef, }; diff --git a/starknet-core/src/types/serde_impls.rs b/starknet-core/src/types/serde_impls.rs index 39ee3e49..76b5aac9 100644 --- a/starknet-core/src/types/serde_impls.rs +++ b/starknet-core/src/types/serde_impls.rs @@ -165,6 +165,71 @@ mod block_id { } } +mod transaction_status { + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + + use crate::types::{SequencerTransactionStatus, TransactionExecutionStatus, TransactionStatus}; + + #[derive(Serialize, Deserialize)] + #[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))] + struct Raw { + finality_status: SequencerTransactionStatus, + #[serde(skip_serializing_if = "Option::is_none")] + execution_status: Option, + } + + impl Serialize for TransactionStatus { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let raw = match self { + TransactionStatus::Received => Raw { + finality_status: SequencerTransactionStatus::Received, + execution_status: None, + }, + TransactionStatus::Rejected => Raw { + finality_status: SequencerTransactionStatus::Rejected, + execution_status: None, + }, + TransactionStatus::AcceptedOnL2(exe) => Raw { + finality_status: SequencerTransactionStatus::AcceptedOnL2, + execution_status: Some(*exe), + }, + TransactionStatus::AcceptedOnL1(exe) => Raw { + finality_status: SequencerTransactionStatus::AcceptedOnL1, + execution_status: Some(*exe), + }, + }; + + raw.serialize(serializer) + } + } + + impl<'de> Deserialize<'de> for TransactionStatus { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let raw = Raw::deserialize(deserializer)?; + + match (raw.finality_status, raw.execution_status) { + (SequencerTransactionStatus::Received, None) => Ok(Self::Received), + (SequencerTransactionStatus::Rejected, None) => Ok(Self::Rejected), + (SequencerTransactionStatus::AcceptedOnL2, Some(exe)) => { + Ok(Self::AcceptedOnL2(exe)) + } + (SequencerTransactionStatus::AcceptedOnL1, Some(exe)) => { + Ok(Self::AcceptedOnL1(exe)) + } + _ => Err(serde::de::Error::custom( + "invalid combination of finality_status and execution_status", + )), + } + } + } +} + // Deriving the Serialize trait directly results in duplicate fields since the variants also write // the tag fields when individually serialized. mod enum_ser_impls { @@ -238,7 +303,6 @@ mod enum_ser_impls { Self::Invoke(variant) => variant.serialize(serializer), Self::L1Handler(variant) => variant.serialize(serializer), Self::Declare(variant) => variant.serialize(serializer), - Self::Deploy(variant) => variant.serialize(serializer), Self::DeployAccount(variant) => variant.serialize(serializer), } } diff --git a/starknet-providers/src/any.rs b/starknet-providers/src/any.rs index a4dc95b8..f625ae3a 100644 --- a/starknet-providers/src/any.rs +++ b/starknet-providers/src/any.rs @@ -6,7 +6,7 @@ use starknet_core::types::{ EventsPage, FeeEstimate, FieldElement, FunctionCall, InvokeTransactionResult, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate, MaybePendingTransactionReceipt, MsgFromL1, SimulatedTransaction, SimulationFlag, - SyncStatusType, Transaction, TransactionTrace, TransactionTraceWithHash, + SyncStatusType, Transaction, TransactionStatus, TransactionTrace, TransactionTraceWithHash, }; use crate::{ @@ -32,6 +32,17 @@ pub enum AnyProvider { #[cfg_attr(not(target_arch = "wasm32"), async_trait)] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] impl Provider for AnyProvider { + async fn spec_version(&self) -> Result { + match self { + Self::JsonRpcHttp(inner) => { + as Provider>::spec_version(inner).await + } + Self::SequencerGateway(inner) => { + ::spec_version(inner).await + } + } + } + async fn get_block_with_tx_hashes( &self, block_id: B, @@ -121,6 +132,31 @@ impl Provider for AnyProvider { } } + async fn get_transaction_status( + &self, + transaction_hash: H, + ) -> Result + where + H: AsRef + Send + Sync, + { + match self { + Self::JsonRpcHttp(inner) => { + as Provider>::get_transaction_status( + inner, + transaction_hash, + ) + .await + } + Self::SequencerGateway(inner) => { + ::get_transaction_status( + inner, + transaction_hash, + ) + .await + } + } + } + async fn get_transaction_by_hash( &self, transaction_hash: H, @@ -384,17 +420,6 @@ impl Provider for AnyProvider { } } - async fn pending_transactions(&self) -> Result, ProviderError> { - match self { - Self::JsonRpcHttp(inner) => { - as Provider>::pending_transactions(inner).await - } - Self::SequencerGateway(inner) => { - ::pending_transactions(inner).await - } - } - } - async fn syncing(&self) -> Result { match self { Self::JsonRpcHttp(inner) => { @@ -589,22 +614,22 @@ impl Provider for AnyProvider { } } - async fn trace_block_transactions( + async fn trace_block_transactions( &self, - block_hash: H, + block_id: B, ) -> Result, ProviderError> where - H: AsRef + Send + Sync, + B: AsRef + Send + Sync, { match self { Self::JsonRpcHttp(inner) => { as Provider>::trace_block_transactions( - inner, block_hash, + inner, block_id, ) .await } Self::SequencerGateway(inner) => { - ::trace_block_transactions(inner, block_hash) + ::trace_block_transactions(inner, block_id) .await } } diff --git a/starknet-providers/src/jsonrpc/mod.rs b/starknet-providers/src/jsonrpc/mod.rs index 17b9d82b..d45a0f14 100644 --- a/starknet-providers/src/jsonrpc/mod.rs +++ b/starknet-providers/src/jsonrpc/mod.rs @@ -13,7 +13,7 @@ use starknet_core::{ InvokeTransactionResult, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate, MaybePendingTransactionReceipt, MsgFromL1, ResultPageRequest, SimulatedTransaction, SimulationFlag, StarknetError, SyncStatusType, Transaction, - TransactionTrace, TransactionTraceWithHash, + TransactionStatus, TransactionTrace, TransactionTraceWithHash, }, }; @@ -32,6 +32,8 @@ pub struct JsonRpcClient { #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub enum JsonRpcMethod { + #[serde(rename = "starknet_specVersion")] + SpecVersion, #[serde(rename = "starknet_getBlockWithTxHashes")] GetBlockWithTxHashes, #[serde(rename = "starknet_getBlockWithTxs")] @@ -40,6 +42,8 @@ pub enum JsonRpcMethod { GetStateUpdate, #[serde(rename = "starknet_getStorageAt")] GetStorageAt, + #[serde(rename = "starknet_getTransactionStatus")] + GetTransactionStatus, #[serde(rename = "starknet_getTransactionByHash")] GetTransactionByHash, #[serde(rename = "starknet_getTransactionByBlockIdAndIndex")] @@ -66,8 +70,6 @@ pub enum JsonRpcMethod { BlockHashAndNumber, #[serde(rename = "starknet_chainId")] ChainId, - #[serde(rename = "starknet_pendingTransactions")] - PendingTransactions, #[serde(rename = "starknet_syncing")] Syncing, #[serde(rename = "starknet_getEvents")] @@ -96,10 +98,12 @@ pub struct JsonRpcRequest { #[derive(Debug, Clone)] pub enum JsonRpcRequestData { + SpecVersion(SpecVersionRequest), GetBlockWithTxHashes(GetBlockWithTxHashesRequest), GetBlockWithTxs(GetBlockWithTxsRequest), GetStateUpdate(GetStateUpdateRequest), GetStorageAt(GetStorageAtRequest), + GetTransactionStatus(GetTransactionStatusRequest), GetTransactionByHash(GetTransactionByHashRequest), GetTransactionByBlockIdAndIndex(GetTransactionByBlockIdAndIndexRequest), GetTransactionReceipt(GetTransactionReceiptRequest), @@ -113,7 +117,6 @@ pub enum JsonRpcRequestData { BlockNumber(BlockNumberRequest), BlockHashAndNumber(BlockHashAndNumberRequest), ChainId(ChainIdRequest), - PendingTransactions(PendingTransactionsRequest), Syncing(SyncingRequest), GetEvents(GetEventsRequest), GetNonce(GetNonceRequest), @@ -206,6 +209,12 @@ impl Provider for JsonRpcClient where T: 'static + JsonRpcTransport + Sync + Send, { + /// Returns the version of the Starknet JSON-RPC specification being used + async fn spec_version(&self) -> Result { + self.send_request(JsonRpcMethod::SpecVersion, SpecVersionRequest) + .await + } + /// Get block information with transaction hashes given the block id async fn get_block_with_tx_hashes( &self, @@ -282,6 +291,24 @@ where .0) } + /// Gets the transaction status (possibly reflecting that the tx is still in + /// the mempool, or dropped from it) + async fn get_transaction_status( + &self, + transaction_hash: H, + ) -> Result + where + H: AsRef + Send + Sync, + { + self.send_request( + JsonRpcMethod::GetTransactionStatus, + GetTransactionStatusRequestRef { + transaction_hash: transaction_hash.as_ref(), + }, + ) + .await + } + /// Get the details and status of a submitted transaction async fn get_transaction_by_hash( &self, @@ -489,15 +516,6 @@ where .0) } - /// Returns the transactions in the transaction pool, recognized by this sequencer - async fn pending_transactions(&self) -> Result, ProviderError> { - self.send_request( - JsonRpcMethod::PendingTransactions, - PendingTransactionsRequest, - ) - .await - } - /// Returns an object about the sync status, or false if the node is not synching async fn syncing(&self) -> Result { self.send_request(JsonRpcMethod::Syncing, SyncingRequest) @@ -642,17 +660,17 @@ where } /// Retrieve traces for all transactions in the given block. - async fn trace_block_transactions( + async fn trace_block_transactions( &self, - block_hash: H, + block_id: B, ) -> Result, ProviderError> where - H: AsRef + Send + Sync, + B: AsRef + Send + Sync, { self.send_request( JsonRpcMethod::TraceBlockTransactions, TraceBlockTransactionsRequestRef { - block_hash: block_hash.as_ref(), + block_id: block_id.as_ref(), }, ) .await @@ -676,6 +694,10 @@ impl<'de> Deserialize<'de> for JsonRpcRequest { let raw_request = RawRequest::deserialize(deserializer)?; let request_data = match raw_request.method { + JsonRpcMethod::SpecVersion => JsonRpcRequestData::SpecVersion( + serde_json::from_value::(raw_request.params) + .map_err(error_mapper)?, + ), JsonRpcMethod::GetBlockWithTxHashes => JsonRpcRequestData::GetBlockWithTxHashes( serde_json::from_value::(raw_request.params) .map_err(error_mapper)?, @@ -692,6 +714,10 @@ impl<'de> Deserialize<'de> for JsonRpcRequest { serde_json::from_value::(raw_request.params) .map_err(error_mapper)?, ), + JsonRpcMethod::GetTransactionStatus => JsonRpcRequestData::GetTransactionStatus( + serde_json::from_value::(raw_request.params) + .map_err(error_mapper)?, + ), JsonRpcMethod::GetTransactionByHash => JsonRpcRequestData::GetTransactionByHash( serde_json::from_value::(raw_request.params) .map_err(error_mapper)?, @@ -749,10 +775,6 @@ impl<'de> Deserialize<'de> for JsonRpcRequest { serde_json::from_value::(raw_request.params) .map_err(error_mapper)?, ), - JsonRpcMethod::PendingTransactions => JsonRpcRequestData::PendingTransactions( - serde_json::from_value::(raw_request.params) - .map_err(error_mapper)?, - ), JsonRpcMethod::Syncing => JsonRpcRequestData::Syncing( serde_json::from_value::(raw_request.params) .map_err(error_mapper)?, diff --git a/starknet-providers/src/provider.rs b/starknet-providers/src/provider.rs index 4d08886f..86ad7ef7 100644 --- a/starknet-providers/src/provider.rs +++ b/starknet-providers/src/provider.rs @@ -7,7 +7,7 @@ use starknet_core::types::{ EventsPage, FeeEstimate, FieldElement, FunctionCall, InvokeTransactionResult, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate, MaybePendingTransactionReceipt, MsgFromL1, SimulatedTransaction, SimulationFlag, StarknetError, - SyncStatusType, Transaction, TransactionTrace, TransactionTraceWithHash, + SyncStatusType, Transaction, TransactionStatus, TransactionTrace, TransactionTraceWithHash, }; use std::{any::Any, error::Error, fmt::Debug}; @@ -15,6 +15,9 @@ use std::{any::Any, error::Error, fmt::Debug}; #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[auto_impl(&, Box, Arc)] pub trait Provider { + /// Returns the version of the Starknet JSON-RPC specification being used + async fn spec_version(&self) -> Result; + /// Get block information with transaction hashes given the block id async fn get_block_with_tx_hashes( &self, @@ -51,6 +54,15 @@ pub trait Provider { K: AsRef + Send + Sync, B: AsRef + Send + Sync; + /// Gets the transaction status (possibly reflecting that the tx is still in + /// the mempool, or dropped from it) + async fn get_transaction_status( + &self, + transaction_hash: H, + ) -> Result + where + H: AsRef + Send + Sync; + /// Get the details and status of a submitted transaction async fn get_transaction_by_hash( &self, @@ -145,9 +157,6 @@ pub trait Provider { /// Return the currently configured Starknet chain id async fn chain_id(&self) -> Result; - /// Returns the transactions in the transaction pool, recognized by this sequencer - async fn pending_transactions(&self) -> Result, ProviderError>; - /// Returns an object about the sync status, or false if the node is not synching async fn syncing(&self) -> Result; @@ -216,12 +225,12 @@ pub trait Provider { S: AsRef<[SimulationFlag]> + Send + Sync; /// Retrieve traces for all transactions in the given block. - async fn trace_block_transactions( + async fn trace_block_transactions( &self, - block_hash: H, + block_id: B, ) -> Result, ProviderError> where - H: AsRef + Send + Sync; + B: AsRef + Send + Sync; /// Same as [estimate_fee], but only with one estimate. async fn estimate_fee_single( diff --git a/starknet-providers/src/sequencer/models/conversions.rs b/starknet-providers/src/sequencer/models/conversions.rs index 5b0d22ed..b94a4be8 100644 --- a/starknet-providers/src/sequencer/models/conversions.rs +++ b/starknet-providers/src/sequencer/models/conversions.rs @@ -51,6 +51,11 @@ impl TryFrom for core::MaybePendingBlockWithTxHashes { new_root: state_root, timestamp: value.timestamp, sequencer_address: value.sequencer_address.unwrap_or_default(), + l1_gas_price: core::ResourcePrice { + price_in_strk: None, + price_in_wei: value.gas_price.try_into().map_err(|_| ConversionError)?, + }, + starknet_version: value.starknet_version.ok_or(ConversionError)?, transactions: value .transactions .iter() @@ -68,6 +73,11 @@ impl TryFrom for core::MaybePendingBlockWithTxHashes { timestamp: value.timestamp, sequencer_address: value.sequencer_address.unwrap_or_default(), parent_hash: value.parent_block_hash, + l1_gas_price: core::ResourcePrice { + price_in_strk: None, + price_in_wei: value.gas_price.try_into().map_err(|_| ConversionError)?, + }, + starknet_version: value.starknet_version.ok_or(ConversionError)?, })), // Unknown combination _ => Err(ConversionError), @@ -90,6 +100,11 @@ impl TryFrom for core::MaybePendingBlockWithTxs { new_root: state_root, timestamp: value.timestamp, sequencer_address: value.sequencer_address.unwrap_or_default(), + l1_gas_price: core::ResourcePrice { + price_in_strk: None, + price_in_wei: value.gas_price.try_into().map_err(|_| ConversionError)?, + }, + starknet_version: value.starknet_version.ok_or(ConversionError)?, transactions: value .transactions .into_iter() @@ -107,6 +122,11 @@ impl TryFrom for core::MaybePendingBlockWithTxs { timestamp: value.timestamp, sequencer_address: value.sequencer_address.unwrap_or_default(), parent_hash: value.parent_block_hash, + l1_gas_price: core::ResourcePrice { + price_in_strk: None, + price_in_wei: value.gas_price.try_into().map_err(|_| ConversionError)?, + }, + starknet_version: value.starknet_version.ok_or(ConversionError)?, })), // Unknown combination _ => Err(ConversionError), @@ -392,10 +412,11 @@ impl TryFrom for core::PendingTransactionReceipt { fn try_from(value: TransactionWithReceipt) -> Result { match value.transaction.r#type.as_ref().ok_or(ConversionError)? { TransactionType::Declare(_) => Ok(Self::Declare(value.receipt.try_into()?)), - TransactionType::Deploy(_) => Ok(Self::Deploy(value.try_into()?)), - TransactionType::DeployAccount(_) => Ok(Self::DeployAccount(value.receipt.try_into()?)), + TransactionType::DeployAccount(_) => Ok(Self::DeployAccount(value.try_into()?)), TransactionType::InvokeFunction(_) => Ok(Self::Invoke(value.receipt.try_into()?)), - TransactionType::L1Handler(_) => Ok(Self::L1Handler(value.receipt.try_into()?)), + TransactionType::L1Handler(_) => Ok(Self::L1Handler(value.try_into()?)), + // Impossible to have a pending DEPLOY receipt + TransactionType::Deploy(_) => Err(ConversionError), } } } @@ -409,7 +430,7 @@ impl TryFrom for core::TransactionReceipt { TransactionType::Deploy(_) => Ok(Self::Deploy(value.try_into()?)), TransactionType::DeployAccount(_) => Ok(Self::DeployAccount(value.try_into()?)), TransactionType::InvokeFunction(_) => Ok(Self::Invoke(value.receipt.try_into()?)), - TransactionType::L1Handler(_) => Ok(Self::L1Handler(value.receipt.try_into()?)), + TransactionType::L1Handler(_) => Ok(Self::L1Handler(value.try_into()?)), } } } @@ -427,6 +448,7 @@ impl TryFrom for core::PendingDeclareTransactionReceipt { .map(|item| item.into()) .collect(), events: value.events.into_iter().map(|item| item.into()).collect(), + execution_resources: value.execution_resources.ok_or(ConversionError)?.into(), execution_result: convert_execution_result( value.status, value.execution_status, @@ -436,7 +458,7 @@ impl TryFrom for core::PendingDeclareTransactionReceipt { } } -impl TryFrom for core::PendingDeployTransactionReceipt { +impl TryFrom for core::PendingDeployAccountTransactionReceipt { type Error = ConversionError; fn try_from(value: TransactionWithReceipt) -> Result { @@ -455,20 +477,25 @@ impl TryFrom for core::PendingDeployTransactionReceipt { .into_iter() .map(|item| item.into()) .collect(), - contract_address: match value.transaction.r#type { - Some(TransactionType::Deploy(inner)) => inner.contract_address, - _ => return Err(ConversionError), - }, + execution_resources: value + .receipt + .execution_resources + .ok_or(ConversionError)? + .into(), execution_result: convert_execution_result( value.receipt.status, value.receipt.execution_status, value.receipt.revert_error, )?, + contract_address: match value.transaction.r#type.ok_or(ConversionError)? { + TransactionType::DeployAccount(tx) => tx.contract_address, + _ => return Err(ConversionError), + }, }) } } -impl TryFrom for core::PendingDeployAccountTransactionReceipt { +impl TryFrom for core::PendingInvokeTransactionReceipt { type Error = ConversionError; fn try_from(value: TransactionReceipt) -> Result { @@ -481,6 +508,7 @@ impl TryFrom for core::PendingDeployAccountTransactionReceip .map(|item| item.into()) .collect(), events: value.events.into_iter().map(|item| item.into()).collect(), + execution_resources: value.execution_resources.ok_or(ConversionError)?.into(), execution_result: convert_execution_result( value.status, value.execution_status, @@ -490,46 +518,45 @@ impl TryFrom for core::PendingDeployAccountTransactionReceip } } -impl TryFrom for core::PendingInvokeTransactionReceipt { +impl TryFrom for core::PendingL1HandlerTransactionReceipt { type Error = ConversionError; - fn try_from(value: TransactionReceipt) -> Result { + fn try_from(value: TransactionWithReceipt) -> Result { + // The sequencer never serves the message hash, so we have to compute it ourselves. + let l1_handler_tx: core::L1HandlerTransaction = match value.transaction.r#type.unwrap() { + TransactionType::L1Handler(tx) => tx.try_into().map_err(|_| ConversionError)?, + _ => return Err(ConversionError), + }; + let msg_to_l2 = l1_handler_tx + .parse_msg_to_l2() + .map_err(|_| ConversionError)?; + Ok(Self { - transaction_hash: value.transaction_hash, - actual_fee: value.actual_fee.ok_or(ConversionError)?, + transaction_hash: value.receipt.transaction_hash, + actual_fee: value.receipt.actual_fee.ok_or(ConversionError)?, messages_sent: value + .receipt .l2_to_l1_messages .into_iter() .map(|item| item.into()) .collect(), - events: value.events.into_iter().map(|item| item.into()).collect(), - execution_result: convert_execution_result( - value.status, - value.execution_status, - value.revert_error, - )?, - }) - } -} - -impl TryFrom for core::PendingL1HandlerTransactionReceipt { - type Error = ConversionError; - - fn try_from(value: TransactionReceipt) -> Result { - Ok(Self { - transaction_hash: value.transaction_hash, - actual_fee: value.actual_fee.ok_or(ConversionError)?, - messages_sent: value - .l2_to_l1_messages + events: value + .receipt + .events .into_iter() .map(|item| item.into()) .collect(), - events: value.events.into_iter().map(|item| item.into()).collect(), + execution_resources: value + .receipt + .execution_resources + .ok_or(ConversionError)? + .into(), execution_result: convert_execution_result( - value.status, - value.execution_status, - value.revert_error, + value.receipt.status, + value.receipt.execution_status, + value.receipt.revert_error, )?, + message_hash: msg_to_l2.hash(), }) } } @@ -550,6 +577,7 @@ impl TryFrom for core::DeclareTransactionReceipt { .map(|item| item.into()) .collect(), events: value.events.into_iter().map(|item| item.into()).collect(), + execution_resources: value.execution_resources.ok_or(ConversionError)?.into(), execution_result: convert_execution_result( value.status, value.execution_status, @@ -589,6 +617,11 @@ impl TryFrom for core::DeployTransactionReceipt { Some(TransactionType::Deploy(inner)) => inner.contract_address, _ => return Err(ConversionError), }, + execution_resources: value + .receipt + .execution_resources + .ok_or(ConversionError)? + .into(), execution_result: convert_execution_result( value.receipt.status, value.receipt.execution_status, @@ -628,6 +661,11 @@ impl TryFrom for core::DeployAccountTransactionReceipt { Some(TransactionType::DeployAccount(inner)) => inner.contract_address, _ => return Err(ConversionError), }, + execution_resources: value + .receipt + .execution_resources + .ok_or(ConversionError)? + .into(), execution_result: convert_execution_result( value.receipt.status, value.receipt.execution_status, @@ -653,6 +691,7 @@ impl TryFrom for core::InvokeTransactionReceipt { .map(|item| item.into()) .collect(), events: value.events.into_iter().map(|item| item.into()).collect(), + execution_resources: value.execution_resources.ok_or(ConversionError)?.into(), execution_result: convert_execution_result( value.status, value.execution_status, @@ -662,27 +701,52 @@ impl TryFrom for core::InvokeTransactionReceipt { } } -impl TryFrom for core::L1HandlerTransactionReceipt { +impl TryFrom for core::L1HandlerTransactionReceipt { type Error = ConversionError; - fn try_from(value: TransactionReceipt) -> Result { + fn try_from(value: TransactionWithReceipt) -> Result { + // The sequencer never serves the message hash, so we have to compute it ourselves. + let l1_handler_tx: core::L1HandlerTransaction = match value.transaction.r#type.unwrap() { + TransactionType::L1Handler(tx) => tx.try_into().map_err(|_| ConversionError)?, + _ => return Err(ConversionError), + }; + let msg_to_l2 = l1_handler_tx + .parse_msg_to_l2() + .map_err(|_| ConversionError)?; + Ok(Self { - transaction_hash: value.transaction_hash, - actual_fee: value.actual_fee.ok_or(ConversionError)?, - finality_status: value.finality_status.ok_or(ConversionError)?.try_into()?, - block_hash: value.block_hash.ok_or(ConversionError)?, - block_number: value.block_number.ok_or(ConversionError)?, + transaction_hash: value.receipt.transaction_hash, + actual_fee: value.receipt.actual_fee.ok_or(ConversionError)?, + finality_status: value + .receipt + .finality_status + .ok_or(ConversionError)? + .try_into()?, + block_hash: value.receipt.block_hash.ok_or(ConversionError)?, + block_number: value.receipt.block_number.ok_or(ConversionError)?, messages_sent: value + .receipt .l2_to_l1_messages .into_iter() .map(|item| item.into()) .collect(), - events: value.events.into_iter().map(|item| item.into()).collect(), + events: value + .receipt + .events + .into_iter() + .map(|item| item.into()) + .collect(), + execution_resources: value + .receipt + .execution_resources + .ok_or(ConversionError)? + .into(), execution_result: convert_execution_result( - value.status, - value.execution_status, - value.revert_error, + value.receipt.status, + value.receipt.execution_status, + value.receipt.revert_error, )?, + message_hash: msg_to_l2.hash(), }) } } @@ -892,75 +956,6 @@ impl TryFrom for core::ContractClass { } } -impl TryFrom for core::TransactionTrace { - type Error = ConversionError; - - fn try_from(value: TransactionTrace) -> Result { - // Unlike JSON-RPC, which names fields from different variants differently, there's no way - // to distinguish between Invoke, DeployAccount, and L1Handler traces. (The only exception - // is when the Invoke execution reverts, which makes it definitely an Invoke variant.) - // - // For these variants, we simply always resolve to Invoke. This is suboptimal but still - // better than just failing the conversion. This is yet another reason to avoid using the - // sequencer gateway provider. - - let validate_invocation = match value.validate_invocation { - Some(invocation) => Some(invocation.try_into()?), - None => None, - }; - - let fee_transfer_invocation = match value.fee_transfer_invocation { - Some(invocation) => Some(invocation.try_into()?), - None => None, - }; - - match value.function_invocation { - Some(invocation) => Ok(Self::Invoke(core::InvokeTransactionTrace { - validate_invocation, - - execute_invocation: match value.revert_error { - Some(revert_error) => { - core::ExecuteInvocation::Reverted(core::RevertedInvocation { - revert_reason: revert_error, - }) - } - None => core::ExecuteInvocation::Success(invocation.try_into()?), - }, - fee_transfer_invocation, - })), - None => { - // Only DECLARE transactions do not have `function_invocation` - Ok(Self::Declare(core::DeclareTransactionTrace { - validate_invocation, - fee_transfer_invocation, - })) - } - } - } -} - -impl TryFrom for core::TransactionTraceWithHash { - type Error = ConversionError; - - fn try_from(value: TransactionTraceWithHash) -> Result { - Ok(Self { - transaction_hash: value.transaction_hash, - trace_root: value.trace.try_into()?, - }) - } -} - -impl TryFrom for core::SimulatedTransaction { - type Error = ConversionError; - - fn try_from(value: TransactionSimulationInfo) -> Result { - Ok(Self { - transaction_trace: value.trace.try_into()?, - fee_estimation: value.fee_estimation.into(), - }) - } -} - impl TryFrom for core::FunctionInvocation { type Error = ConversionError; @@ -1014,16 +1009,17 @@ impl From for core::CallType { } } -impl From for core::EventContent { +impl From for core::OrderedEvent { fn from(value: OrderedEventResponse) -> Self { Self { keys: value.keys, data: value.data, + order: value.order, } } } -impl From for core::MsgToL1 { +impl From for core::OrderedMessage { fn from(value: OrderedL2ToL1MessageResponseWithFromAddress) -> Self { Self { from_address: value.from, @@ -1033,6 +1029,76 @@ impl From for core::MsgToL1 { ) .unwrap(), payload: value.message.payload, + order: value.message.order, + } + } +} + +impl From for core::ExecutionResources { + fn from(value: ExecutionResources) -> Self { + Self { + steps: value.n_steps, + memory_holes: Some(value.n_memory_holes), + range_check_builtin_applications: value + .builtin_instance_counter + .range_check_builtin + .unwrap_or_default(), + pedersen_builtin_applications: value + .builtin_instance_counter + .pedersen_builtin + .unwrap_or_default(), + poseidon_builtin_applications: value + .builtin_instance_counter + .poseidon_builtin + .unwrap_or_default(), + ec_op_builtin_applications: value + .builtin_instance_counter + .ec_op_builtin + .unwrap_or_default(), + ecdsa_builtin_applications: value + .builtin_instance_counter + .ecdsa_builtin + .unwrap_or_default(), + bitwise_builtin_applications: value + .builtin_instance_counter + .bitwise_builtin + .unwrap_or_default(), + keccak_builtin_applications: value + .builtin_instance_counter + .keccak_builtin + .unwrap_or_default(), + } + } +} + +impl TryFrom for core::TransactionStatus { + type Error = ConversionError; + + fn try_from(value: TransactionStatusInfo) -> Result { + if let TransactionStatus::Rejected = value.status { + return Ok(Self::Rejected); + } + + let exec_status = match value.execution_status.ok_or(ConversionError)? { + TransactionExecutionStatus::Succeeded => { + Some(core::TransactionExecutionStatus::Succeeded) + } + TransactionExecutionStatus::Reverted => { + Some(core::TransactionExecutionStatus::Reverted) + } + TransactionExecutionStatus::Rejected => None, + }; + + match value.finality_status { + Some(TransactionFinalityStatus::Received) => Ok(Self::Received), + Some(TransactionFinalityStatus::AcceptedOnL2) => { + Ok(Self::AcceptedOnL2(exec_status.ok_or(ConversionError)?)) + } + Some(TransactionFinalityStatus::AcceptedOnL1) => { + Ok(Self::AcceptedOnL1(exec_status.ok_or(ConversionError)?)) + } + // `NotReceived` must be handled on the caller before converting + _ => Err(ConversionError), } } } diff --git a/starknet-providers/src/sequencer/models/transaction_receipt.rs b/starknet-providers/src/sequencer/models/transaction_receipt.rs index e315dd97..15069483 100644 --- a/starknet-providers/src/sequencer/models/transaction_receipt.rs +++ b/starknet-providers/src/sequencer/models/transaction_receipt.rs @@ -115,6 +115,8 @@ pub struct BuiltinInstanceCounter { pub output_builtin: Option, pub ecdsa_builtin: Option, pub ec_op_builtin: Option, + pub poseidon_builtin: Option, + pub keccak_builtin: Option, } #[serde_as] diff --git a/starknet-providers/src/sequencer/provider.rs b/starknet-providers/src/sequencer/provider.rs index 92478ca3..c6e58529 100644 --- a/starknet-providers/src/sequencer/provider.rs +++ b/starknet-providers/src/sequencer/provider.rs @@ -10,7 +10,7 @@ use starknet_core::types::{ EventsPage, FeeEstimate, FieldElement, FunctionCall, InvokeTransactionResult, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate, MaybePendingTransactionReceipt, MsgFromL1, SimulatedTransaction, SimulationFlag, StarknetError, - SyncStatusType, Transaction, TransactionTrace, TransactionTraceWithHash, + SyncStatusType, Transaction, TransactionStatus, TransactionTrace, TransactionTraceWithHash, }; use crate::{ @@ -22,10 +22,16 @@ use crate::{ Provider, ProviderError, SequencerGatewayProvider, }; +use super::models::TransactionFinalityStatus; + #[allow(unused)] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] impl Provider for SequencerGatewayProvider { + async fn spec_version(&self) -> Result { + Ok(String::from("0.6.0")) + } + async fn get_block_with_tx_hashes( &self, block_id: B, @@ -85,6 +91,30 @@ impl Provider for SequencerGatewayProvider { .await?) } + /// Gets the transaction status (possibly reflecting that the tx is still in + /// the mempool, or dropped from it) + async fn get_transaction_status( + &self, + transaction_hash: H, + ) -> Result + where + H: AsRef + Send + Sync, + { + let status = self + .get_transaction_status(*transaction_hash.as_ref()) + .await?; + + // `NotReceived` is not a valid status for JSON-RPC. It's an error. + if let Some(TransactionFinalityStatus::NotReceived) = &status.finality_status { + return Err(ProviderError::StarknetError(StarknetErrorWithMessage { + code: MaybeUnknownErrorCode::Known(StarknetError::TransactionHashNotFound), + message: "Transaction hash not found".into(), + })); + } + + Ok(status.try_into()?) + } + async fn get_transaction_by_hash( &self, transaction_hash: H, @@ -282,19 +312,6 @@ impl Provider for SequencerGatewayProvider { Ok(self.chain_id) } - async fn pending_transactions(&self) -> Result, ProviderError> { - let block = self.get_block(super::models::BlockId::Pending).await?; - if block.status == super::models::BlockStatus::Pending { - Ok(block - .transactions - .into_iter() - .map(|tx| tx.try_into()) - .collect::>()?) - } else { - Ok(vec![]) - } - } - async fn syncing(&self) -> Result { Ok(SyncStatusType::NotSyncing) } @@ -385,15 +402,17 @@ impl Provider for SequencerGatewayProvider { async fn trace_transaction( &self, - transaction_hash: H, + _transaction_hash: H, ) -> Result where H: AsRef + Send + Sync, { - Ok(self - .get_transaction_trace(*transaction_hash.as_ref()) - .await? - .try_into()?) + // With JSON-RPC v0.5.0 it's no longer possible to convert feeder traces to JSON-RPC traces. So we simply pretend that it's not supported here. + // + // This is fine as the feeder gateway is soon to be removed anyways. + Err(ProviderError::Other(Box::new( + GatewayClientError::MethodNotSupported, + ))) } async fn simulate_transactions( @@ -407,54 +426,27 @@ impl Provider for SequencerGatewayProvider { T: AsRef<[BroadcastedTransaction]> + Send + Sync, S: AsRef<[SimulationFlag]> + Send + Sync, { - let transactions = transactions.as_ref(); - if transactions.len() != 1 { - return Err(ProviderError::Other(Box::new( - GatewayClientError::BulkSimulationNotSupported, - ))); - } - - let transaction = transactions[0].to_owned(); - - let mut skip_validate = false; - for flag in simulation_flags.as_ref().iter() { - match flag { - SimulationFlag::SkipValidate => { - skip_validate = true; - } - SimulationFlag::SkipFeeCharge => { - return Err(ProviderError::Other(Box::new( - GatewayClientError::UnsupportedSimulationFlag, - ))); - } - } - } - - let simulation = self - .simulate_transaction( - transaction.try_into()?, - block_id.as_ref().to_owned().into(), - skip_validate, - ) - .await?; - - Ok(vec![simulation.try_into()?]) + // With JSON-RPC v0.5.0 it's no longer possible to convert feeder traces to JSON-RPC traces. So we simply pretend that it's not supported here. + // + // This is fine as the feeder gateway is soon to be removed anyways. + Err(ProviderError::Other(Box::new( + GatewayClientError::MethodNotSupported, + ))) } - async fn trace_block_transactions( + async fn trace_block_transactions( &self, - block_hash: H, + block_id: B, ) -> Result, ProviderError> where - H: AsRef + Send + Sync, + B: AsRef + Send + Sync, { - Ok(self - .get_block_traces(super::models::BlockId::Hash(*block_hash.as_ref())) - .await? - .traces - .into_iter() - .map(|est| est.try_into()) - .collect::, _>>()?) + // With JSON-RPC v0.5.0 it's no longer possible to convert feeder traces to JSON-RPC traces. So we simply pretend that it's not supported here. + // + // This is fine as the feeder gateway is soon to be removed anyways. + Err(ProviderError::Other(Box::new( + GatewayClientError::MethodNotSupported, + ))) } } diff --git a/starknet-providers/tests/jsonrpc.rs b/starknet-providers/tests/jsonrpc.rs index d2063187..41466fd5 100644 --- a/starknet-providers/tests/jsonrpc.rs +++ b/starknet-providers/tests/jsonrpc.rs @@ -4,8 +4,8 @@ use starknet_core::{ DeclareTransaction, EthAddress, EventFilter, ExecuteInvocation, ExecutionResult, FieldElement, FunctionCall, InvokeTransaction, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate, MaybePendingTransactionReceipt, - MsgFromL1, StarknetError, SyncStatusType, Transaction, TransactionReceipt, - TransactionTrace, + MsgFromL1, StarknetError, SyncStatusType, Transaction, TransactionExecutionStatus, + TransactionReceipt, TransactionStatus, TransactionTrace, }, utils::{get_selector_from_name, get_storage_var_address}, }; @@ -17,10 +17,19 @@ use url::Url; fn create_jsonrpc_client() -> JsonRpcClient { let rpc_url = - std::env::var("STARKNET_RPC").unwrap_or("https://rpc-goerli-1.starknet.rs/rpc/v0.4".into()); + std::env::var("STARKNET_RPC").unwrap_or("https://rpc-goerli-1.starknet.rs/rpc/v0.5".into()); JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())) } +#[tokio::test] +async fn jsonrpc_spec_version() { + let rpc_client = create_jsonrpc_client(); + + let version = rpc_client.spec_version().await.unwrap(); + + assert_eq!(version, "0.5.1"); +} + #[tokio::test] async fn jsonrpc_get_block_with_tx_hashes() { let rpc_client = create_jsonrpc_client(); @@ -99,6 +108,66 @@ async fn jsonrpc_get_storage_at() { assert!(eth_balance > FieldElement::ZERO); } +#[tokio::test] +async fn jsonrpc_get_transaction_status_rejected() { + let rpc_client = create_jsonrpc_client(); + + let status = rpc_client + .get_transaction_status( + FieldElement::from_hex_be( + "0x07362a9daa42d9e4be657ed5a50f7fc04ac2017714cddb6c88dc08f48a782632", + ) + .unwrap(), + ) + .await + .unwrap(); + + match status { + TransactionStatus::Rejected => {} + _ => panic!("unexpected transaction status"), + } +} + +#[tokio::test] +async fn jsonrpc_get_transaction_status_succeeded() { + let rpc_client = create_jsonrpc_client(); + + let status = rpc_client + .get_transaction_status( + FieldElement::from_hex_be( + "0x042fe661cf973a9e62dbf587cfb6d1808e377f394e4fea2c62a4fd02b5ba3473", + ) + .unwrap(), + ) + .await + .unwrap(); + + match status { + TransactionStatus::AcceptedOnL1(TransactionExecutionStatus::Succeeded) => {} + _ => panic!("unexpected transaction status"), + } +} + +#[tokio::test] +async fn jsonrpc_get_transaction_status_reverted() { + let rpc_client = create_jsonrpc_client(); + + let status = rpc_client + .get_transaction_status( + FieldElement::from_hex_be( + "0x03998d935e23ee0b4956c40e8a5f64f6767176e7e44981328295a2fc20e6892c", + ) + .unwrap(), + ) + .await + .unwrap(); + + match status { + TransactionStatus::AcceptedOnL1(TransactionExecutionStatus::Reverted) => {} + _ => panic!("unexpected transaction status"), + } +} + #[tokio::test] async fn jsonrpc_get_transaction_by_hash_invoke_v0() { let rpc_client = create_jsonrpc_client(); @@ -366,15 +435,18 @@ async fn jsonrpc_get_transaction_receipt_invoke_reverted() { async fn jsonrpc_get_transaction_receipt_l1_handler() { let rpc_client = create_jsonrpc_client(); - let receipt = rpc_client - .get_transaction_receipt( - FieldElement::from_hex_be( - "0374286ae28f201e61ffbc5b022cc9701208640b405ea34ea9799f97d5d2d23c", - ) - .unwrap(), - ) - .await - .unwrap(); + let tx_hash = FieldElement::from_hex_be( + "0374286ae28f201e61ffbc5b022cc9701208640b405ea34ea9799f97d5d2d23c", + ) + .unwrap(); + + let tx = rpc_client.get_transaction_by_hash(tx_hash).await.unwrap(); + let receipt = rpc_client.get_transaction_receipt(tx_hash).await.unwrap(); + + let tx = match tx { + Transaction::L1Handler(tx) => tx, + _ => panic!("unexpected tx type"), + }; let receipt = match receipt { MaybePendingTransactionReceipt::Receipt(TransactionReceipt::L1Handler(receipt)) => receipt, @@ -385,6 +457,8 @@ async fn jsonrpc_get_transaction_receipt_l1_handler() { ExecutionResult::Succeeded => {} _ => panic!("unexpected execution result"), } + + assert_eq!(tx.parse_msg_to_l2().unwrap().hash(), receipt.message_hash); } #[tokio::test] @@ -706,13 +780,6 @@ async fn jsonrpc_chain_id() { assert!(chain_id > FieldElement::ZERO); } -#[tokio::test] -async fn jsonrpc_pending_transactions() { - let rpc_client = create_jsonrpc_client(); - - rpc_client.pending_transactions().await.unwrap(); -} - #[tokio::test] async fn jsonrpc_syncing() { let rpc_client = create_jsonrpc_client();