From 5477cc6c39c47bcadcc716e074abd50a5cae1332 Mon Sep 17 00:00:00 2001 From: Nimrod Weiss Date: Mon, 19 Aug 2024 11:38:05 +0300 Subject: [PATCH] refactor(fee): tx_args holds valid resource bounds --- .../src/execution/syscalls/hint_processor.rs | 48 +++---- crates/blockifier/src/test_utils/declare.rs | 2 +- .../src/test_utils/deploy_account.rs | 2 +- crates/blockifier/src/test_utils/invoke.rs | 2 +- .../src/transaction/transactions.rs | 6 +- crates/gateway/src/gateway_test.rs | 4 +- crates/gateway/src/utils.rs | 7 +- crates/mempool/src/mempool.rs | 12 +- crates/mempool/src/mempool_test.rs | 4 +- crates/mempool/src/transaction_queue.rs | 23 ++-- .../src/starknet_api_test_utils.rs | 4 +- crates/native_blockifier/src/py_declare.rs | 3 +- .../src/py_deploy_account.rs | 3 +- .../src/py_invoke_function.rs | 3 +- .../native_blockifier/src/py_transaction.rs | 14 +- crates/papyrus_common/src/transaction_hash.rs | 15 +-- .../src/converters/transaction.rs | 123 +++++++++--------- .../src/converters/transaction_test.rs | 19 ++- .../src/proto/p2p/proto/transaction.proto | 1 + crates/papyrus_rpc/src/v0_6/api/mod.rs | 28 ++-- crates/papyrus_rpc/src/v0_6/transaction.rs | 27 ++++ crates/papyrus_rpc/src/v0_7/api/mod.rs | 28 ++-- crates/papyrus_rpc/src/v0_7/transaction.rs | 27 ++++ .../tests/gateway_integration_test.rs | 4 +- .../src/serialization/serializers.rs | 17 ++- crates/papyrus_test_utils/src/lib.rs | 18 ++- .../src/executable_transaction.rs | 10 +- crates/starknet_api/src/rpc_transaction.rs | 7 +- crates/starknet_api/src/transaction.rs | 64 ++++++++- crates/starknet_api/src/transaction_hash.rs | 15 +-- .../src/reader/objects/test_utils.rs | 8 +- .../src/reader/objects/transaction.rs | 8 +- 32 files changed, 348 insertions(+), 208 deletions(-) diff --git a/crates/blockifier/src/execution/syscalls/hint_processor.rs b/crates/blockifier/src/execution/syscalls/hint_processor.rs index 579f4d9b9e..a199efc122 100644 --- a/crates/blockifier/src/execution/syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/syscalls/hint_processor.rs @@ -468,35 +468,25 @@ impl<'a> SyscallHintProcessor<'a> { let l2_gas_as_felt = Felt::from_hex(L2_GAS).map_err(SyscallExecutionError::from)?; let l1_data_gas_as_felt = Felt::from_hex(L1_DATA).map_err(SyscallExecutionError::from)?; - let flat_resource_bounds = match tx_info.resource_bounds { - ValidResourceBounds::L1Gas(l1_bounds) => { - vec![ - l1_gas_as_felt, - Felt::from(l1_bounds.max_amount), - Felt::from(l1_bounds.max_price_per_unit), - l2_gas_as_felt, - Felt::ZERO, - Felt::ZERO, - ] - } - ValidResourceBounds::AllResources(AllResourceBounds { - l1_gas, - l2_gas, - l1_data_gas, - }) => { - vec![ - l1_gas_as_felt, - Felt::from(l1_gas.max_amount), - Felt::from(l1_gas.max_price_per_unit), - l2_gas_as_felt, - Felt::from(l2_gas.max_amount), - Felt::from(l2_gas.max_price_per_unit), - l1_data_gas_as_felt, - Felt::from(l1_data_gas.max_amount), - Felt::from(l1_data_gas.max_price_per_unit), - ] - } - }; + let l1_gas_bounds = tx_info.resource_bounds.get_l1_bounds(); + let l2_gas_bounds = tx_info.resource_bounds.get_l2_bounds(); + let mut flat_resource_bounds = vec![ + l1_gas_as_felt, + Felt::from(l1_gas_bounds.max_amount), + Felt::from(l1_gas_bounds.max_price_per_unit), + l2_gas_as_felt, + Felt::from(l2_gas_bounds.max_amount), + Felt::from(l2_gas_bounds.max_price_per_unit), + ]; + if let ValidResourceBounds::AllResources(AllResourceBounds { l1_data_gas, .. }) = + tx_info.resource_bounds + { + flat_resource_bounds.extend(vec![ + l1_data_gas_as_felt, + Felt::from(l1_data_gas.max_amount), + Felt::from(l1_data_gas.max_price_per_unit), + ]) + } self.allocate_data_segment(vm, &flat_resource_bounds) } diff --git a/crates/blockifier/src/test_utils/declare.rs b/crates/blockifier/src/test_utils/declare.rs index ab5470c130..eb794a97f6 100644 --- a/crates/blockifier/src/test_utils/declare.rs +++ b/crates/blockifier/src/test_utils/declare.rs @@ -108,7 +108,7 @@ pub fn declare_tx(declare_tx_args: DeclareTxArgs, class_info: ClassInfo) -> Acco starknet_api::transaction::DeclareTransaction::V3(DeclareTransactionV3 { signature: declare_tx_args.signature, sender_address: declare_tx_args.sender_address, - resource_bounds: declare_tx_args.resource_bounds, + resource_bounds: declare_tx_args.resource_bounds.try_into().expect("todo"), tip: declare_tx_args.tip, nonce_data_availability_mode: declare_tx_args.nonce_data_availability_mode, fee_data_availability_mode: declare_tx_args.fee_data_availability_mode, diff --git a/crates/blockifier/src/test_utils/deploy_account.rs b/crates/blockifier/src/test_utils/deploy_account.rs index 1ae7a58340..128a430945 100644 --- a/crates/blockifier/src/test_utils/deploy_account.rs +++ b/crates/blockifier/src/test_utils/deploy_account.rs @@ -96,7 +96,7 @@ pub fn deploy_account_tx( } else if deploy_tx_args.version == TransactionVersion::THREE { starknet_api::transaction::DeployAccountTransaction::V3(DeployAccountTransactionV3 { signature: deploy_tx_args.signature, - resource_bounds: deploy_tx_args.resource_bounds, + resource_bounds: deploy_tx_args.resource_bounds.try_into().expect("todo"), tip: deploy_tx_args.tip, nonce_data_availability_mode: deploy_tx_args.nonce_data_availability_mode, fee_data_availability_mode: deploy_tx_args.fee_data_availability_mode, diff --git a/crates/blockifier/src/test_utils/invoke.rs b/crates/blockifier/src/test_utils/invoke.rs index b1e025bc0e..64b6847960 100644 --- a/crates/blockifier/src/test_utils/invoke.rs +++ b/crates/blockifier/src/test_utils/invoke.rs @@ -96,7 +96,7 @@ pub fn invoke_tx(invoke_args: InvokeTxArgs) -> InvokeTransaction { }) } else if invoke_args.version == TransactionVersion::THREE { starknet_api::transaction::InvokeTransaction::V3(InvokeTransactionV3 { - resource_bounds: invoke_args.resource_bounds, + resource_bounds: invoke_args.resource_bounds.try_into().expect("todo"), calldata: invoke_args.calldata, sender_address: invoke_args.sender_address, nonce: invoke_args.nonce, diff --git a/crates/blockifier/src/transaction/transactions.rs b/crates/blockifier/src/transaction/transactions.rs index b75965e8e7..098112ecdb 100644 --- a/crates/blockifier/src/transaction/transactions.rs +++ b/crates/blockifier/src/transaction/transactions.rs @@ -296,7 +296,7 @@ impl TransactionInfoCreator for DeclareTransaction { starknet_api::transaction::DeclareTransaction::V3(tx) => { Ok(TransactionInfo::Current(CurrentTransactionInfo { common_fields, - resource_bounds: tx.resource_bounds.clone().try_into()?, + resource_bounds: tx.resource_bounds.clone(), tip: tx.tip, nonce_data_availability_mode: tx.nonce_data_availability_mode, fee_data_availability_mode: tx.fee_data_availability_mode, @@ -411,7 +411,7 @@ impl TransactionInfoCreator for DeployAccountTransaction { starknet_api::transaction::DeployAccountTransaction::V3(tx) => { Ok(TransactionInfo::Current(CurrentTransactionInfo { common_fields, - resource_bounds: tx.resource_bounds.clone().try_into()?, + resource_bounds: tx.resource_bounds.clone(), tip: tx.tip, nonce_data_availability_mode: tx.nonce_data_availability_mode, fee_data_availability_mode: tx.fee_data_availability_mode, @@ -535,7 +535,7 @@ impl TransactionInfoCreator for InvokeTransaction { starknet_api::transaction::InvokeTransaction::V3(tx) => { Ok(TransactionInfo::Current(CurrentTransactionInfo { common_fields, - resource_bounds: tx.resource_bounds.clone().try_into()?, + resource_bounds: tx.resource_bounds.clone(), tip: tx.tip, nonce_data_availability_mode: tx.nonce_data_availability_mode, fee_data_availability_mode: tx.fee_data_availability_mode, diff --git a/crates/gateway/src/gateway_test.rs b/crates/gateway/src/gateway_test.rs index 46e0967417..72e09c6e12 100644 --- a/crates/gateway/src/gateway_test.rs +++ b/crates/gateway/src/gateway_test.rs @@ -10,7 +10,7 @@ use mempool_test_utils::starknet_api_test_utils::{create_executable_tx, invoke_t use mockall::predicate::eq; use starknet_api::core::ContractAddress; use starknet_api::rpc_transaction::RpcTransaction; -use starknet_api::transaction::TransactionHash; +use starknet_api::transaction::{TransactionHash, ValidResourceBounds}; use starknet_mempool_types::communication::MockMempoolClient; use starknet_mempool_types::mempool_types::{Account, AccountState, MempoolInput}; use starknet_sierra_compile::config::SierraToCasmCompilationConfig; @@ -72,7 +72,7 @@ async fn test_add_tx() { tx_hash, *tx.tip(), *tx.nonce(), - tx.resource_bounds().clone().into(), + ValidResourceBounds::AllResources(tx.resource_bounds().clone()), ), account: Account { sender_address, state: AccountState { nonce: *tx.nonce() } }, })) diff --git a/crates/gateway/src/utils.rs b/crates/gateway/src/utils.rs index 1b8af37bb6..f1ebf4dd76 100644 --- a/crates/gateway/src/utils.rs +++ b/crates/gateway/src/utils.rs @@ -19,6 +19,7 @@ use starknet_api::transaction::{ DeployAccountTransactionV3, InvokeTransactionV3, TransactionHasher, + ValidResourceBounds, }; use tracing::error; @@ -35,7 +36,7 @@ pub fn rpc_tx_to_account_tx( let declare_tx = DeclareTransaction::V3(DeclareTransactionV3 { class_hash: ClassHash::default(), /* FIXME(yael 15/4/24): call the starknet-api * function once ready */ - resource_bounds: tx.resource_bounds.clone().into(), + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds.clone()), tip: tx.tip, signature: tx.signature.clone(), nonce: tx.nonce, @@ -63,7 +64,7 @@ pub fn rpc_tx_to_account_tx( } RpcTransaction::DeployAccount(RpcDeployAccountTransaction::V3(tx)) => { let deploy_account_tx = DeployAccountTransaction::V3(DeployAccountTransactionV3 { - resource_bounds: tx.resource_bounds.clone().into(), + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds.clone()), tip: tx.tip, signature: tx.signature.clone(), nonce: tx.nonce, @@ -99,7 +100,7 @@ pub fn rpc_tx_to_account_tx( } RpcTransaction::Invoke(RpcInvokeTransaction::V3(tx)) => { let invoke_tx = starknet_api::transaction::InvokeTransaction::V3(InvokeTransactionV3 { - resource_bounds: tx.resource_bounds.clone().into(), + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds.clone()), tip: tx.tip, signature: tx.signature.clone(), nonce: tx.nonce, diff --git a/crates/mempool/src/mempool.rs b/crates/mempool/src/mempool.rs index d79250e98f..cd9f63d82e 100644 --- a/crates/mempool/src/mempool.rs +++ b/crates/mempool/src/mempool.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use starknet_api::core::{ContractAddress, Nonce}; use starknet_api::executable_transaction::Transaction; -use starknet_api::transaction::{DeprecatedResourceBoundsMapping, Resource, Tip, TransactionHash}; +use starknet_api::transaction::{Tip, TransactionHash, ValidResourceBounds}; use starknet_mempool_types::errors::MempoolError; use starknet_mempool_types::mempool_types::{Account, AccountState, MempoolInput, MempoolResult}; @@ -200,13 +200,13 @@ impl Mempool { /// TODO(Mohammad): rename this struct to `ThinTransaction` once that name /// becomes available, to better reflect its purpose and usage. /// TODO(Mohammad): restore the Copy once ResourceBoundsMapping implements it. -#[derive(Clone, Debug, Default, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct TransactionReference { pub sender_address: ContractAddress, pub nonce: Nonce, pub tx_hash: TransactionHash, pub tip: Tip, - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, } impl TransactionReference { @@ -224,10 +224,6 @@ impl TransactionReference { } pub fn get_l2_gas_price(&self) -> u128 { - self.resource_bounds - .0 - .get(&Resource::L2Gas) - .map(|bounds| bounds.max_price_per_unit) - .expect("Expected a valid L2 gas resource bounds.") + self.resource_bounds.get_l2_bounds().max_price_per_unit } } diff --git a/crates/mempool/src/mempool_test.rs b/crates/mempool/src/mempool_test.rs index 5e3ac66369..3734f71df7 100644 --- a/crates/mempool/src/mempool_test.rs +++ b/crates/mempool/src/mempool_test.rs @@ -11,7 +11,7 @@ use rstest::{fixture, rstest}; use starknet_api::core::{ContractAddress, Nonce, PatriciaKey}; use starknet_api::executable_transaction::Transaction; use starknet_api::hash::StarkHash; -use starknet_api::transaction::{Tip, TransactionHash}; +use starknet_api::transaction::{Tip, TransactionHash, ValidResourceBounds}; use starknet_api::{contract_address, felt, patricia_key}; use starknet_mempool_types::errors::MempoolError; use starknet_mempool_types::mempool_types::{Account, AccountState}; @@ -167,7 +167,7 @@ macro_rules! add_tx_input { }}; (tip: $tip:expr, tx_hash: $tx_hash:expr, sender_address: $sender_address:expr, tx_nonce: $tx_nonce:expr, account_nonce: $account_nonce:expr) => {{ - add_tx_input!(tip: $tip, tx_hash: $tx_hash, sender_address: $sender_address, tx_nonce: $tx_nonce, account_nonce: $account_nonce, resource_bounds: test_resource_bounds_mapping().into()) + add_tx_input!(tip: $tip, tx_hash: $tx_hash, sender_address: $sender_address, tx_nonce: $tx_nonce, account_nonce: $account_nonce, resource_bounds: ValidResourceBounds::AllResources(test_resource_bounds_mapping())) }}; (tx_hash: $tx_hash:expr, sender_address: $sender_address:expr, tx_nonce: $tx_nonce:expr, account_nonce: $account_nonce:expr) => { add_tx_input!(tip: 0, tx_hash: $tx_hash, sender_address: $sender_address, tx_nonce: $tx_nonce, account_nonce: $account_nonce) diff --git a/crates/mempool/src/transaction_queue.rs b/crates/mempool/src/transaction_queue.rs index 5413fa698a..a550a83208 100644 --- a/crates/mempool/src/transaction_queue.rs +++ b/crates/mempool/src/transaction_queue.rs @@ -2,7 +2,13 @@ use std::cmp::Ordering; use std::collections::{BTreeSet, HashMap}; use starknet_api::core::{ContractAddress, Nonce}; -use starknet_api::transaction::{Resource, ResourceBounds}; +use starknet_api::transaction::{ + AllResourceBounds, + ResourceBounds, + Tip, + TransactionHash, + ValidResourceBounds, +}; use crate::mempool::TransactionReference; @@ -91,13 +97,14 @@ impl TransactionQueue { fn _promote_txs_to_priority(&mut self, threshold: u128) { let tmp_split_tx = PendingTransaction(TransactionReference { - resource_bounds: vec![ - (Resource::L1Gas, ResourceBounds::default()), - (Resource::L2Gas, ResourceBounds { max_amount: 0, max_price_per_unit: threshold }), - ] - .try_into() - .unwrap(), - ..Default::default() + resource_bounds: ValidResourceBounds::AllResources(AllResourceBounds { + l2_gas: ResourceBounds { max_amount: 0, max_price_per_unit: threshold }, + ..Default::default() + }), + sender_address: ContractAddress::default(), + nonce: Nonce::default(), + tx_hash: TransactionHash::default(), + tip: Tip::default(), }); // Split off the pending queue at the given transaction higher than the threshold. diff --git a/crates/mempool_test_utils/src/starknet_api_test_utils.rs b/crates/mempool_test_utils/src/starknet_api_test_utils.rs index bc57399051..32880351d7 100644 --- a/crates/mempool_test_utils/src/starknet_api_test_utils.rs +++ b/crates/mempool_test_utils/src/starknet_api_test_utils.rs @@ -24,13 +24,13 @@ use starknet_api::transaction::{ AllResourceBounds, Calldata, ContractAddressSalt, - DeprecatedResourceBoundsMapping as ExecutableResourceBoundsMapping, PaymasterData, ResourceBounds, Tip, TransactionHash, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_api::{calldata, felt}; use starknet_types_core::felt::Felt; @@ -567,7 +567,7 @@ pub fn create_executable_tx( tx_hash: TransactionHash, tip: Tip, nonce: Nonce, - resource_bounds: ExecutableResourceBoundsMapping, + resource_bounds: ValidResourceBounds, ) -> Transaction { Transaction::Invoke(InvokeTransaction { tx: starknet_api::transaction::InvokeTransaction::V3( diff --git a/crates/native_blockifier/src/py_declare.rs b/crates/native_blockifier/src/py_declare.rs index 9e01caaaaf..b8d74535f0 100644 --- a/crates/native_blockifier/src/py_declare.rs +++ b/crates/native_blockifier/src/py_declare.rs @@ -10,7 +10,6 @@ use starknet_api::transaction::{ DeclareTransactionV0V1, DeclareTransactionV2, DeclareTransactionV3, - DeprecatedResourceBoundsMapping, Fee, PaymasterData, Tip, @@ -88,7 +87,7 @@ impl TryFrom for DeclareTransactionV3 { type Error = NativeBlockifierInputError; fn try_from(tx: PyDeclareTransactionV3) -> Result { Ok(Self { - resource_bounds: DeprecatedResourceBoundsMapping::try_from(tx.resource_bounds)?, + resource_bounds: tx.resource_bounds.try_into()?, tip: Tip(tx.tip), signature: TransactionSignature(from_py_felts(tx.signature)), nonce: Nonce(tx.nonce.0), diff --git a/crates/native_blockifier/src/py_deploy_account.rs b/crates/native_blockifier/src/py_deploy_account.rs index a5671842a0..b25b464103 100644 --- a/crates/native_blockifier/src/py_deploy_account.rs +++ b/crates/native_blockifier/src/py_deploy_account.rs @@ -10,7 +10,6 @@ use starknet_api::transaction::{ ContractAddressSalt, DeployAccountTransactionV1, DeployAccountTransactionV3, - DeprecatedResourceBoundsMapping, Fee, PaymasterData, Tip, @@ -64,7 +63,7 @@ impl TryFrom for DeployAccountTransactionV3 { type Error = NativeBlockifierInputError; fn try_from(tx: PyDeployAccountTransactionV3) -> Result { Ok(Self { - resource_bounds: DeprecatedResourceBoundsMapping::try_from(tx.resource_bounds)?, + resource_bounds: tx.resource_bounds.try_into()?, tip: Tip(tx.tip), signature: TransactionSignature(from_py_felts(tx.signature)), nonce: Nonce(tx.nonce.0), diff --git a/crates/native_blockifier/src/py_invoke_function.rs b/crates/native_blockifier/src/py_invoke_function.rs index 64f7559917..974d0b9b1d 100644 --- a/crates/native_blockifier/src/py_invoke_function.rs +++ b/crates/native_blockifier/src/py_invoke_function.rs @@ -9,7 +9,6 @@ use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::transaction::{ AccountDeploymentData, Calldata, - DeprecatedResourceBoundsMapping, Fee, InvokeTransactionV0, InvokeTransactionV1, @@ -87,7 +86,7 @@ impl TryFrom for InvokeTransactionV3 { type Error = NativeBlockifierInputError; fn try_from(tx: PyInvokeTransactionV3) -> Result { Ok(Self { - resource_bounds: DeprecatedResourceBoundsMapping::try_from(tx.resource_bounds)?, + resource_bounds: tx.resource_bounds.try_into()?, tip: Tip(tx.tip), signature: TransactionSignature(from_py_felts(tx.signature)), nonce: Nonce(tx.nonce.0), diff --git a/crates/native_blockifier/src/py_transaction.rs b/crates/native_blockifier/src/py_transaction.rs index 443ed57c90..aaa6e071e9 100644 --- a/crates/native_blockifier/src/py_transaction.rs +++ b/crates/native_blockifier/src/py_transaction.rs @@ -11,7 +11,12 @@ use blockifier::transaction::transaction_execution::Transaction; use blockifier::transaction::transaction_types::TransactionType; use pyo3::exceptions::PyValueError; use pyo3::prelude::*; -use starknet_api::transaction::{Resource, ResourceBounds}; +use starknet_api::transaction::{ + DeprecatedResourceBoundsMapping, + Resource, + ResourceBounds, + ValidResourceBounds, +}; use starknet_api::StarknetApiError; use crate::errors::{NativeBlockifierInputError, NativeBlockifierResult}; @@ -84,6 +89,13 @@ impl TryFrom } } +impl TryFrom for ValidResourceBounds { + type Error = StarknetApiError; + fn try_from(py_resource_bounds_mapping: PyResourceBoundsMapping) -> Result { + DeprecatedResourceBoundsMapping::try_from(py_resource_bounds_mapping)?.try_into() + } +} + #[derive(Clone)] pub enum PyDataAvailabilityMode { L1 = 0, diff --git a/crates/papyrus_common/src/transaction_hash.rs b/crates/papyrus_common/src/transaction_hash.rs index 6b4da55441..23ef713879 100644 --- a/crates/papyrus_common/src/transaction_hash.rs +++ b/crates/papyrus_common/src/transaction_hash.rs @@ -16,18 +16,17 @@ use starknet_api::transaction::{ DeployAccountTransactionV1, DeployAccountTransactionV3, DeployTransaction, - DeprecatedResourceBoundsMapping, InvokeTransaction, InvokeTransactionV0, InvokeTransactionV1, InvokeTransactionV3, L1HandlerTransaction, - Resource, ResourceBounds, Tip, Transaction, TransactionHash, TransactionVersion, + ValidResourceBounds, }; use starknet_api::StarknetApiError; use starknet_types_core::felt::Felt; @@ -220,16 +219,14 @@ pub(crate) fn ascii_as_felt(ascii_str: &str) -> Result { // An implementation of the SNIP: https://github.com/EvyatarO/SNIPs/blob/snip-8/SNIPS/snip-8.md fn get_tip_resource_bounds_hash( - resource_bounds_mapping: &DeprecatedResourceBoundsMapping, + resource_bounds: &ValidResourceBounds, tip: &Tip, ) -> Result { - let l1_resource_bounds = - resource_bounds_mapping.0.get(&Resource::L1Gas).expect("Missing l1 resource"); - let l1_resource = get_concat_resource(l1_resource_bounds, L1_GAS)?; + let l1_resource_bounds = resource_bounds.get_l1_bounds(); + let l2_resource_bounds = resource_bounds.get_l2_bounds(); - let l2_resource_bounds = - resource_bounds_mapping.0.get(&Resource::L2Gas).expect("Missing l2 resource"); - let l2_resource = get_concat_resource(l2_resource_bounds, L2_GAS)?; + let l1_resource = get_concat_resource(&l1_resource_bounds, L1_GAS)?; + let l2_resource = get_concat_resource(&l2_resource_bounds, L2_GAS)?; Ok(HashChain::new() .chain(&tip.0.into()) diff --git a/crates/papyrus_protobuf/src/converters/transaction.rs b/crates/papyrus_protobuf/src/converters/transaction.rs index a929942c1a..3179088ce6 100644 --- a/crates/papyrus_protobuf/src/converters/transaction.rs +++ b/crates/papyrus_protobuf/src/converters/transaction.rs @@ -7,6 +7,7 @@ use prost::Message; use starknet_api::core::{ClassHash, CompiledClassHash, EntryPointSelector, Nonce}; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, DeclareTransaction, @@ -17,7 +18,6 @@ use starknet_api::transaction::{ DeployAccountTransactionV1, DeployAccountTransactionV3, DeployTransaction, - DeprecatedResourceBoundsMapping, Fee, FullTransaction, InvokeTransaction, @@ -26,7 +26,6 @@ use starknet_api::transaction::{ InvokeTransactionV3, L1HandlerTransaction, PaymasterData, - Resource, ResourceBounds, Tip, Transaction, @@ -34,6 +33,7 @@ use starknet_api::transaction::{ TransactionOutput, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; @@ -440,11 +440,11 @@ impl From for protobuf::transaction::DeployAccountV1 impl TryFrom for DeployAccountTransactionV3 { type Error = ProtobufConversionError; fn try_from(value: protobuf::transaction::DeployAccountV3) -> Result { - let resource_bounds = DeprecatedResourceBoundsMapping::try_from( - value.resource_bounds.ok_or(ProtobufConversionError::MissingField { + let resource_bounds = ValidResourceBounds::try_from(value.resource_bounds.ok_or( + ProtobufConversionError::MissingField { field_description: "DeployAccountV3::resource_bounds", - })?, - )?; + }, + )?)?; let tip = Tip(value.tip); @@ -550,41 +550,39 @@ impl From for protobuf::transaction::DeployAccountV3 } } -impl TryFrom for DeprecatedResourceBoundsMapping { +impl TryFrom for ValidResourceBounds { type Error = ProtobufConversionError; fn try_from(value: protobuf::ResourceBounds) -> Result { - let mut resource_bounds = DeprecatedResourceBoundsMapping::default(); let Some(l1_gas) = value.l1_gas else { return Err(ProtobufConversionError::MissingField { field_description: "ResourceBounds::l1_gas", }); }; - let max_amount = l1_gas.max_amount; - let max_price_per_unit_felt = Felt::try_from(l1_gas.max_price_per_unit.ok_or( - ProtobufConversionError::MissingField { - field_description: "ResourceBounds::l1_gas::max_price_per_unit", - }, - )?)?; - let max_price_per_unit = - try_from_starkfelt_to_u128(max_price_per_unit_felt).map_err(|_| { - ProtobufConversionError::OutOfRangeValue { - type_description: "u128", - value_as_str: format!("{max_price_per_unit_felt:?}"), - } - })?; - - resource_bounds - .0 - .insert(Resource::L1Gas, ResourceBounds { max_amount, max_price_per_unit }); let Some(l2_gas) = value.l2_gas else { return Err(ProtobufConversionError::MissingField { field_description: "ResourceBounds::l2_gas", }); }; - let max_amount = l2_gas.max_amount; - let max_price_per_unit_felt = Felt::try_from(l2_gas.max_price_per_unit.ok_or( + // TODO(Shahak): Assert data gas is not none once we remove support for 0.13.2. + let l1_data_gas = value.l1_data_gas.unwrap_or_default(); + let l1_gas: ResourceBounds = l1_gas.try_into()?; + let l2_gas: ResourceBounds = l2_gas.try_into()?; + let l1_data_gas: ResourceBounds = l1_data_gas.try_into()?; + Ok(if l1_data_gas.is_zero() && l2_gas.is_zero() { + ValidResourceBounds::L1Gas(l1_gas) + } else { + ValidResourceBounds::AllResources(AllResourceBounds { l1_gas, l2_gas, l1_data_gas }) + }) + } +} + +impl TryFrom for ResourceBounds { + type Error = ProtobufConversionError; + fn try_from(value: protobuf::ResourceLimits) -> Result { + let max_amount = value.max_amount; + let max_price_per_unit_felt = Felt::try_from(value.max_price_per_unit.ok_or( ProtobufConversionError::MissingField { - field_description: "ResourceBounds::l2_gas::max_price_per_unit", + field_description: "ResourceBounds::ResourceLimits::max_price_per_unit", }, )?)?; let max_price_per_unit = @@ -594,36 +592,37 @@ impl TryFrom for DeprecatedResourceBoundsMapping { value_as_str: format!("{max_price_per_unit_felt:?}"), } })?; - resource_bounds - .0 - .insert(Resource::L2Gas, ResourceBounds { max_amount, max_price_per_unit }); - Ok(resource_bounds) + Ok(ResourceBounds { max_amount, max_price_per_unit }) } } -impl From for protobuf::ResourceBounds { - fn from(value: DeprecatedResourceBoundsMapping) -> Self { - let mut res = protobuf::ResourceBounds::default(); - - let resource_bounds_default = ResourceBounds::default(); - let resource_bounds_l1 = value.0.get(&Resource::L1Gas).unwrap_or(&resource_bounds_default); - - let resource_limits_l1 = protobuf::ResourceLimits { - max_amount: resource_bounds_l1.max_amount, - max_price_per_unit: Some(Felt::from(resource_bounds_l1.max_price_per_unit).into()), - }; - res.l1_gas = Some(resource_limits_l1); - - let resource_bounds_default = ResourceBounds::default(); - let resource_bounds_l2 = value.0.get(&Resource::L2Gas).unwrap_or(&resource_bounds_default); - - let resource_limits_l2 = protobuf::ResourceLimits { - max_amount: resource_bounds_l2.max_amount, - max_price_per_unit: Some(Felt::from(resource_bounds_l2.max_price_per_unit).into()), - }; - res.l2_gas = Some(resource_limits_l2); +impl From for protobuf::ResourceLimits { + fn from(value: ResourceBounds) -> Self { + protobuf::ResourceLimits { + max_amount: value.max_amount, + max_price_per_unit: Some(Felt::from(value.max_price_per_unit).into()), + } + } +} - res +impl From for protobuf::ResourceBounds { + fn from(value: ValidResourceBounds) -> Self { + match value { + ValidResourceBounds::L1Gas(l1_gas) => protobuf::ResourceBounds { + l1_gas: Some(l1_gas.into()), + l2_gas: Some(value.get_l2_bounds().into()), + l1_data_gas: Some(ResourceBounds::default().into()), + }, + ValidResourceBounds::AllResources(AllResourceBounds { + l1_gas, + l2_gas, + l1_data_gas, + }) => protobuf::ResourceBounds { + l1_gas: Some(l1_gas.into()), + l2_gas: Some(l2_gas.into()), + l1_data_gas: Some(l1_data_gas.into()), + }, + } } } @@ -756,11 +755,11 @@ impl From for protobuf::transaction::InvokeV1 { impl TryFrom for InvokeTransactionV3 { type Error = ProtobufConversionError; fn try_from(value: protobuf::transaction::InvokeV3) -> Result { - let resource_bounds = DeprecatedResourceBoundsMapping::try_from( - value.resource_bounds.ok_or(ProtobufConversionError::MissingField { + let resource_bounds = ValidResourceBounds::try_from(value.resource_bounds.ok_or( + ProtobufConversionError::MissingField { field_description: "InvokeV3::resource_bounds", - })?, - )?; + }, + )?)?; let tip = Tip(value.tip); @@ -1074,11 +1073,11 @@ impl From for protobuf::transaction::DeclareV2 { impl TryFrom for DeclareTransactionV3 { type Error = ProtobufConversionError; fn try_from(value: protobuf::transaction::DeclareV3) -> Result { - let resource_bounds = DeprecatedResourceBoundsMapping::try_from( - value.resource_bounds.ok_or(ProtobufConversionError::MissingField { + let resource_bounds = ValidResourceBounds::try_from(value.resource_bounds.ok_or( + ProtobufConversionError::MissingField { field_description: "DeclareV3::resource_bounds", - })?, - )?; + }, + )?)?; let tip = Tip(value.tip); diff --git a/crates/papyrus_protobuf/src/converters/transaction_test.rs b/crates/papyrus_protobuf/src/converters/transaction_test.rs index 82387f1539..1da42eb53d 100644 --- a/crates/papyrus_protobuf/src/converters/transaction_test.rs +++ b/crates/papyrus_protobuf/src/converters/transaction_test.rs @@ -3,21 +3,21 @@ use papyrus_test_utils::{get_rng, GetTestInstance}; use rand::random; use starknet_api::execution_resources::{Builtin, ExecutionResources, GasVector}; use starknet_api::transaction::{ + AllResourceBounds, DeclareTransaction, DeclareTransactionOutput, DeployAccountTransaction, DeployAccountTransactionOutput, DeployTransactionOutput, - DeprecatedResourceBoundsMapping, FullTransaction, InvokeTransaction, InvokeTransactionOutput, L1HandlerTransactionOutput, - Resource, ResourceBounds, Transaction as StarknetApiTransaction, TransactionHash, TransactionOutput, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; @@ -196,13 +196,10 @@ lazy_static! { da_gas_consumed: GasVector::default(), gas_consumed: GasVector::default(), }; - static ref RESOURCE_BOUNDS_MAPPING: DeprecatedResourceBoundsMapping = - DeprecatedResourceBoundsMapping( - [ - (Resource::L1Gas, ResourceBounds { max_amount: 0x5, max_price_per_unit: 0x6 }), - (Resource::L2Gas, ResourceBounds { max_amount: 0x5, max_price_per_unit: 0x6 }), - ] - .into_iter() - .collect(), - ); + static ref RESOURCE_BOUNDS_MAPPING: ValidResourceBounds = + ValidResourceBounds::AllResources(AllResourceBounds { + l1_gas: ResourceBounds { max_amount: 0x5, max_price_per_unit: 0x6 }, + l2_gas: ResourceBounds { max_amount: 0x500, max_price_per_unit: 0x600 }, + l1_data_gas: ResourceBounds { max_amount: 0x30, max_price_per_unit: 0x30 } + }); } diff --git a/crates/papyrus_protobuf/src/proto/p2p/proto/transaction.proto b/crates/papyrus_protobuf/src/proto/p2p/proto/transaction.proto index 9ab1244cf5..33065edd51 100644 --- a/crates/papyrus_protobuf/src/proto/p2p/proto/transaction.proto +++ b/crates/papyrus_protobuf/src/proto/p2p/proto/transaction.proto @@ -10,6 +10,7 @@ message ResourceLimits { message ResourceBounds { ResourceLimits l1_gas = 1; ResourceLimits l2_gas = 2; + ResourceLimits l1_data_gas = 3; } message AccountSignature { diff --git a/crates/papyrus_rpc/src/v0_6/api/mod.rs b/crates/papyrus_rpc/src/v0_6/api/mod.rs index 6c20c3db50..eb44f5eb63 100644 --- a/crates/papyrus_rpc/src/v0_6/api/mod.rs +++ b/crates/papyrus_rpc/src/v0_6/api/mod.rs @@ -334,8 +334,10 @@ impl TryFrom for ExecutableTransactionInput { // TODO(yair): pass the right value for only_query field. match value { BroadcastedTransaction::Declare(tx) => Ok(tx.try_into()?), - BroadcastedTransaction::DeployAccount(tx) => Ok(Self::DeployAccount(tx.into(), false)), - BroadcastedTransaction::Invoke(tx) => Ok(Self::Invoke(tx.into(), false)), + BroadcastedTransaction::DeployAccount(tx) => { + Ok(Self::DeployAccount(tx.try_into()?, false)) + } + BroadcastedTransaction::Invoke(tx) => Ok(Self::Invoke(tx.try_into()?, false)), } } } @@ -522,9 +524,10 @@ fn user_deprecated_contract_class_to_sn_api( }) } -impl From for starknet_api::transaction::DeployAccountTransaction { - fn from(tx: DeployAccountTransaction) -> Self { - match tx { +impl TryFrom for starknet_api::transaction::DeployAccountTransaction { + type Error = ErrorObjectOwned; + fn try_from(tx: DeployAccountTransaction) -> Result { + Ok(match tx { DeployAccountTransaction::Version1(DeployAccountTransactionV1 { max_fee, signature, @@ -554,7 +557,7 @@ impl From for starknet_api::transaction::DeployAccount nonce_data_availability_mode, fee_data_availability_mode, }) => Self::V3(starknet_api::transaction::DeployAccountTransactionV3 { - resource_bounds: resource_bounds.into(), + resource_bounds: resource_bounds.try_into()?, tip, signature, nonce, @@ -565,13 +568,14 @@ impl From for starknet_api::transaction::DeployAccount fee_data_availability_mode, paymaster_data, }), - } + }) } } -impl From for starknet_api::transaction::InvokeTransaction { - fn from(value: InvokeTransaction) -> Self { - match value { +impl TryFrom for starknet_api::transaction::InvokeTransaction { + type Error = ErrorObjectOwned; + fn try_from(value: InvokeTransaction) -> Result { + Ok(match value { InvokeTransaction::Version0(InvokeTransactionV0 { max_fee, version: _, @@ -613,7 +617,7 @@ impl From for starknet_api::transaction::InvokeTransaction { nonce_data_availability_mode, fee_data_availability_mode, }) => Self::V3(starknet_api::transaction::InvokeTransactionV3 { - resource_bounds: resource_bounds.into(), + resource_bounds: resource_bounds.try_into()?, tip, signature, nonce, @@ -624,7 +628,7 @@ impl From for starknet_api::transaction::InvokeTransaction { paymaster_data, account_deployment_data, }), - } + }) } } diff --git a/crates/papyrus_rpc/src/v0_6/transaction.rs b/crates/papyrus_rpc/src/v0_6/transaction.rs index 9bed607338..d2c4133220 100644 --- a/crates/papyrus_rpc/src/v0_6/transaction.rs +++ b/crates/papyrus_rpc/src/v0_6/transaction.rs @@ -27,6 +27,7 @@ use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::serde_utils::bytes_from_hex_str; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, DeployTransaction, @@ -157,6 +158,32 @@ impl From for starknet_api::transaction::DeprecatedResour } } +impl TryFrom for starknet_api::transaction::ValidResourceBounds { + type Error = ErrorObjectOwned; + fn try_from(value: ResourceBoundsMapping) -> Result { + if !value.l2_gas.is_zero() { + Err(internal_server_error("Got a transaction with non zero l2 gas.")) + } else { + Ok(Self::L1Gas(value.l1_gas)) + } + } +} + +impl From for ResourceBoundsMapping { + fn from(value: starknet_api::transaction::ValidResourceBounds) -> Self { + match value { + starknet_api::transaction::ValidResourceBounds::L1Gas(l1_gas) => { + Self { l1_gas, l2_gas: ResourceBounds::default() } + } + starknet_api::transaction::ValidResourceBounds::AllResources(AllResourceBounds { + l1_gas, + l2_gas, + .. + }) => Self { l1_gas, l2_gas }, + } + } +} + impl From for ResourceBoundsMapping { fn from(value: starknet_api::transaction::DeprecatedResourceBoundsMapping) -> Self { Self { diff --git a/crates/papyrus_rpc/src/v0_7/api/mod.rs b/crates/papyrus_rpc/src/v0_7/api/mod.rs index a19000eaf0..0c1492bc42 100644 --- a/crates/papyrus_rpc/src/v0_7/api/mod.rs +++ b/crates/papyrus_rpc/src/v0_7/api/mod.rs @@ -331,8 +331,10 @@ impl TryFrom for ExecutableTransactionInput { // TODO(yair): pass the right value for only_query field. match value { BroadcastedTransaction::Declare(tx) => Ok(tx.try_into()?), - BroadcastedTransaction::DeployAccount(tx) => Ok(Self::DeployAccount(tx.into(), false)), - BroadcastedTransaction::Invoke(tx) => Ok(Self::Invoke(tx.into(), false)), + BroadcastedTransaction::DeployAccount(tx) => { + Ok(Self::DeployAccount(tx.try_into()?, false)) + } + BroadcastedTransaction::Invoke(tx) => Ok(Self::Invoke(tx.try_into()?, false)), } } } @@ -519,9 +521,10 @@ fn user_deprecated_contract_class_to_sn_api( }) } -impl From for starknet_api::transaction::DeployAccountTransaction { - fn from(tx: DeployAccountTransaction) -> Self { - match tx { +impl TryFrom for starknet_api::transaction::DeployAccountTransaction { + type Error = ErrorObjectOwned; + fn try_from(tx: DeployAccountTransaction) -> Result { + Ok(match tx { DeployAccountTransaction::Version1(DeployAccountTransactionV1 { max_fee, signature, @@ -551,7 +554,7 @@ impl From for starknet_api::transaction::DeployAccount nonce_data_availability_mode, fee_data_availability_mode, }) => Self::V3(starknet_api::transaction::DeployAccountTransactionV3 { - resource_bounds: resource_bounds.into(), + resource_bounds: resource_bounds.try_into()?, tip, signature, nonce, @@ -562,13 +565,14 @@ impl From for starknet_api::transaction::DeployAccount fee_data_availability_mode, paymaster_data, }), - } + }) } } -impl From for starknet_api::transaction::InvokeTransaction { - fn from(value: InvokeTransaction) -> Self { - match value { +impl TryFrom for starknet_api::transaction::InvokeTransaction { + type Error = ErrorObjectOwned; + fn try_from(value: InvokeTransaction) -> Result { + Ok(match value { InvokeTransaction::Version0(InvokeTransactionV0 { max_fee, version: _, @@ -610,7 +614,7 @@ impl From for starknet_api::transaction::InvokeTransaction { nonce_data_availability_mode, fee_data_availability_mode, }) => Self::V3(starknet_api::transaction::InvokeTransactionV3 { - resource_bounds: resource_bounds.into(), + resource_bounds: resource_bounds.try_into()?, tip, signature, nonce, @@ -621,7 +625,7 @@ impl From for starknet_api::transaction::InvokeTransaction { paymaster_data, account_deployment_data, }), - } + }) } } diff --git a/crates/papyrus_rpc/src/v0_7/transaction.rs b/crates/papyrus_rpc/src/v0_7/transaction.rs index 8f4596b664..c246ad5bb7 100644 --- a/crates/papyrus_rpc/src/v0_7/transaction.rs +++ b/crates/papyrus_rpc/src/v0_7/transaction.rs @@ -29,6 +29,7 @@ use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::serde_utils::bytes_from_hex_str; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, DeployTransaction, @@ -169,6 +170,32 @@ impl From for Resour } } +impl TryFrom for starknet_api::transaction::ValidResourceBounds { + type Error = ErrorObjectOwned; + fn try_from(value: ResourceBoundsMapping) -> Result { + if !value.l2_gas.is_zero() { + Err(internal_server_error("Got a transaction with non zero l2 gas.")) + } else { + Ok(Self::L1Gas(value.l1_gas)) + } + } +} + +impl From for ResourceBoundsMapping { + fn from(value: starknet_api::transaction::ValidResourceBounds) -> Self { + match value { + starknet_api::transaction::ValidResourceBounds::L1Gas(l1_gas) => { + Self { l1_gas, l2_gas: ResourceBounds::default() } + } + starknet_api::transaction::ValidResourceBounds::AllResources(AllResourceBounds { + l1_gas, + l2_gas, + .. + }) => Self { l1_gas, l2_gas }, + } + } +} + #[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] pub struct DeclareTransactionV3 { pub resource_bounds: ResourceBoundsMapping, diff --git a/crates/papyrus_rpc/tests/gateway_integration_test.rs b/crates/papyrus_rpc/tests/gateway_integration_test.rs index 2b8e238cc0..3d01d547a4 100644 --- a/crates/papyrus_rpc/tests/gateway_integration_test.rs +++ b/crates/papyrus_rpc/tests/gateway_integration_test.rs @@ -102,7 +102,9 @@ async fn test_gw_integration_testnet() { // Update the signature. let hash = get_transaction_hash( - &Transaction::Invoke(InvokeTransactionRPC0_6::Version1(invoke_tx.clone()).into()), + &Transaction::Invoke( + InvokeTransactionRPC0_6::Version1(invoke_tx.clone()).try_into().unwrap(), + ), &ChainId::Sepolia, &TransactionOptions::default(), ) diff --git a/crates/papyrus_storage/src/serialization/serializers.rs b/crates/papyrus_storage/src/serialization/serializers.rs index 2b19e9b01b..e58e5366be 100644 --- a/crates/papyrus_storage/src/serialization/serializers.rs +++ b/crates/papyrus_storage/src/serialization/serializers.rs @@ -76,6 +76,7 @@ use starknet_api::state::{ }; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, DeclareTransaction, @@ -119,6 +120,7 @@ use starknet_api::transaction::{ TransactionOutput, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; use tracing::warn; @@ -147,6 +149,11 @@ const COMPRESSION_THRESHOLD_BYTES: usize = 384; auto_storage_serde! { pub struct AccountDeploymentData(pub Vec); + pub struct AllResourceBounds { + pub l1_gas: ResourceBounds, + pub l2_gas: ResourceBounds, + pub l1_data_gas: ResourceBounds, + } pub struct BlockHash(pub StarkHash); pub struct StorageBlockHeader { pub block_hash: BlockHash, @@ -211,7 +218,7 @@ auto_storage_serde! { pub sender_address: ContractAddress, } pub struct DeclareTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -419,6 +426,10 @@ auto_storage_serde! { } pub struct TransactionSignature(pub Vec); pub struct TransactionVersion(pub Felt); + pub enum ValidResourceBounds { + L1Gas(ResourceBounds) = 0, + AllResources(AllResourceBounds) = 1, + } pub struct Version{ pub major: u32, pub minor: u32, @@ -1162,7 +1173,7 @@ auto_storage_serde_conditionally_compressed! { } pub struct DeployAccountTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -1198,7 +1209,7 @@ auto_storage_serde_conditionally_compressed! { } pub struct InvokeTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, diff --git a/crates/papyrus_test_utils/src/lib.rs b/crates/papyrus_test_utils/src/lib.rs index 20c39d27ee..d62893e045 100644 --- a/crates/papyrus_test_utils/src/lib.rs +++ b/crates/papyrus_test_utils/src/lib.rs @@ -99,6 +99,7 @@ use starknet_api::state::{ }; use starknet_api::transaction::{ AccountDeploymentData, + AllResourceBounds, Calldata, ContractAddressSalt, DeclareTransaction, @@ -142,6 +143,7 @@ use starknet_api::transaction::{ TransactionOutput, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; @@ -420,6 +422,11 @@ pub trait GetTestInstance: Sized { auto_impl_get_test_instance! { pub struct AccountDeploymentData(pub Vec); + pub struct AllResourceBounds { + pub l1_gas: ResourceBounds, + pub l2_gas: ResourceBounds, + pub l1_data_gas: ResourceBounds, + } pub struct BlockHash(pub StarkHash); pub struct BlockHeader { pub block_hash: BlockHash, @@ -517,7 +524,7 @@ auto_impl_get_test_instance! { pub sender_address: ContractAddress, } pub struct DeclareTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -550,7 +557,7 @@ auto_impl_get_test_instance! { pub constructor_calldata: Calldata, } pub struct DeployAccountTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -657,7 +664,7 @@ auto_impl_get_test_instance! { pub calldata: Calldata, } pub struct InvokeTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -784,6 +791,11 @@ auto_impl_get_test_instance! { pub r#type: String, } + pub enum ValidResourceBounds { + L1Gas(ResourceBounds) = 0, + AllResources(AllResourceBounds) = 1, + } + pub struct CasmContractClass { pub prime: BigUint, pub compiler_version: String, diff --git a/crates/starknet_api/src/executable_transaction.rs b/crates/starknet_api/src/executable_transaction.rs index 6a2246f7d8..c53f91591b 100644 --- a/crates/starknet_api/src/executable_transaction.rs +++ b/crates/starknet_api/src/executable_transaction.rs @@ -8,12 +8,12 @@ use crate::transaction::{ AccountDeploymentData, Calldata, ContractAddressSalt, - DeprecatedResourceBoundsMapping, PaymasterData, Tip, TransactionHash, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; macro_rules! implement_inner_tx_getter_calls { @@ -29,7 +29,7 @@ macro_rules! implement_getter_calls { $(pub fn $field(&self) -> $field_type { self.$field })* - }; +}; } /// Represents a paid Starknet transaction. @@ -83,7 +83,7 @@ impl Transaction { } } - pub fn resource_bounds(&self) -> Option<&DeprecatedResourceBoundsMapping> { + pub fn resource_bounds(&self) -> Option<&ValidResourceBounds> { match self { Transaction::Declare(declare_tx) => match &declare_tx.tx { crate::transaction::DeclareTransaction::V3(tx_v3) => Some(&tx_v3.resource_bounds), @@ -114,7 +114,9 @@ impl Transaction { sender_address, tip: *rpc_tx.tip(), nonce: *rpc_tx.nonce(), - resource_bounds: rpc_tx.resource_bounds().clone().into(), + resource_bounds: ValidResourceBounds::AllResources( + rpc_tx.resource_bounds().clone(), + ), signature: TransactionSignature::default(), calldata: Calldata::default(), nonce_data_availability_mode: DataAvailabilityMode::L1, diff --git a/crates/starknet_api/src/rpc_transaction.rs b/crates/starknet_api/src/rpc_transaction.rs index 5dce9b4009..f6e8ceef43 100644 --- a/crates/starknet_api/src/rpc_transaction.rs +++ b/crates/starknet_api/src/rpc_transaction.rs @@ -32,6 +32,7 @@ use crate::transaction::{ Tip, Transaction, TransactionSignature, + ValidResourceBounds, }; use crate::StarknetApiError; @@ -189,7 +190,7 @@ impl From for DeclareTransactionV3 { Self { class_hash: ClassHash::default(), /* FIXME(yael 15/4/24): call the starknet-api * function once ready */ - resource_bounds: tx.resource_bounds.into(), + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds), tip: tx.tip, signature: tx.signature, nonce: tx.nonce, @@ -221,7 +222,7 @@ pub struct RpcDeployAccountTransactionV3 { impl From for DeployAccountTransactionV3 { fn from(tx: RpcDeployAccountTransactionV3) -> Self { Self { - resource_bounds: tx.resource_bounds.into(), + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds), tip: tx.tip, signature: tx.signature, nonce: tx.nonce, @@ -253,7 +254,7 @@ pub struct RpcInvokeTransactionV3 { impl From for InvokeTransactionV3 { fn from(tx: RpcInvokeTransactionV3) -> Self { Self { - resource_bounds: tx.resource_bounds.into(), + resource_bounds: ValidResourceBounds::AllResources(tx.resource_bounds), tip: tx.tip, signature: tx.signature, nonce: tx.nonce, diff --git a/crates/starknet_api/src/transaction.rs b/crates/starknet_api/src/transaction.rs index dd7cd746d8..39bd199d46 100644 --- a/crates/starknet_api/src/transaction.rs +++ b/crates/starknet_api/src/transaction.rs @@ -216,7 +216,7 @@ impl TransactionHasher for DeclareTransactionV2 { /// A declare V3 transaction. #[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] pub struct DeclareTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -325,7 +325,7 @@ impl TransactionHasher for DeployAccountTransactionV1 { /// A deploy account V3 transaction. #[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] pub struct DeployAccountTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -462,7 +462,7 @@ impl TransactionHasher for InvokeTransactionV1 { /// An invoke V3 transaction. #[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] pub struct InvokeTransactionV3 { - pub resource_bounds: DeprecatedResourceBoundsMapping, + pub resource_bounds: ValidResourceBounds, pub tip: Tip, pub signature: TransactionSignature, pub nonce: Nonce, @@ -883,6 +883,7 @@ pub enum Resource { #[derive( Clone, Copy, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, )] +// TODO(Nimrod): Consider renaming this struct. pub struct ResourceBounds { // Specifies the maximum amount of each resource allowed for usage during the execution. #[serde(serialize_with = "u64_to_hex", deserialize_with = "hex_to_u64")] @@ -958,12 +959,28 @@ impl TryFrom> for DeprecatedResourceBoundsMappin } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub enum ValidResourceBounds { L1Gas(ResourceBounds), // Pre 0.13.3. Only L1 gas. L2 bounds are signed but never used. AllResources(AllResourceBounds), } +impl ValidResourceBounds { + pub fn get_l1_bounds(&self) -> ResourceBounds { + match self { + Self::L1Gas(l1_bounds) => *l1_bounds, + Self::AllResources(AllResourceBounds { l1_gas, .. }) => *l1_gas, + } + } + + pub fn get_l2_bounds(&self) -> ResourceBounds { + match self { + Self::L1Gas(_) => ResourceBounds::default(), + Self::AllResources(AllResourceBounds { l2_gas, .. }) => *l2_gas, + } + } +} + #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize)] pub struct AllResourceBounds { pub l1_gas: ResourceBounds, @@ -981,6 +998,45 @@ impl AllResourceBounds { } } +/// Deserializes raw resource bounds, given as map, into valid resource bounds. +// TODO(Nimrod): Figure out how to get same result with adding #[derive(Deserialize)]. +impl<'de> Deserialize<'de> for ValidResourceBounds { + fn deserialize(de: D) -> Result + where + D: Deserializer<'de>, + { + let raw_resource_bounds: BTreeMap = Deserialize::deserialize(de)?; + ValidResourceBounds::try_from(DeprecatedResourceBoundsMapping(raw_resource_bounds)) + .map_err(serde::de::Error::custom) + } +} + +/// Serializes ValidResourceBounds as map for Backwards compatibility. +// TODO(Nimrod): Figure out how to get same result with adding #[derive(Serialize)]. +impl Serialize for ValidResourceBounds { + fn serialize(&self, s: S) -> Result + where + S: Serializer, + { + let map = match self { + ValidResourceBounds::L1Gas(l1_gas) => BTreeMap::from([ + (Resource::L1Gas, *l1_gas), + (Resource::L2Gas, ResourceBounds::default()), + ]), + ValidResourceBounds::AllResources(AllResourceBounds { + l1_gas, + l2_gas, + l1_data_gas, + }) => BTreeMap::from([ + (Resource::L1Gas, *l1_gas), + (Resource::L2Gas, *l2_gas), + (Resource::L1DataGas, *l1_data_gas), + ]), + }; + DeprecatedResourceBoundsMapping(map).serialize(s) + } +} + impl TryFrom for ValidResourceBounds { type Error = StarknetApiError; fn try_from( diff --git a/crates/starknet_api/src/transaction_hash.rs b/crates/starknet_api/src/transaction_hash.rs index cb01a4c451..347b5736dd 100644 --- a/crates/starknet_api/src/transaction_hash.rs +++ b/crates/starknet_api/src/transaction_hash.rs @@ -15,18 +15,17 @@ use crate::transaction::{ DeployAccountTransactionV1, DeployAccountTransactionV3, DeployTransaction, - DeprecatedResourceBoundsMapping, InvokeTransaction, InvokeTransactionV0, InvokeTransactionV1, InvokeTransactionV3, L1HandlerTransaction, - Resource, ResourceBounds, Tip, Transaction, TransactionHash, TransactionVersion, + ValidResourceBounds, }; use crate::StarknetApiError; @@ -176,16 +175,14 @@ pub(crate) fn ascii_as_felt(ascii_str: &str) -> Result { // An implementation of the SNIP: https://github.com/EvyatarO/SNIPs/blob/snip-8/SNIPS/snip-8.md fn get_tip_resource_bounds_hash( - resource_bounds_mapping: &DeprecatedResourceBoundsMapping, + resource_bounds: &ValidResourceBounds, tip: &Tip, ) -> Result { - let l1_resource_bounds = - resource_bounds_mapping.0.get(&Resource::L1Gas).expect("Missing l1 resource"); - let l1_resource = get_concat_resource(l1_resource_bounds, L1_GAS)?; + let l1_resource_bounds = resource_bounds.get_l1_bounds(); + let l2_resource_bounds = resource_bounds.get_l2_bounds(); - let l2_resource_bounds = - resource_bounds_mapping.0.get(&Resource::L2Gas).expect("Missing l2 resource"); - let l2_resource = get_concat_resource(l2_resource_bounds, L2_GAS)?; + let l1_resource = get_concat_resource(&l1_resource_bounds, L1_GAS)?; + let l2_resource = get_concat_resource(&l2_resource_bounds, L2_GAS)?; Ok(HashChain::new() .chain(&tip.0.into()) diff --git a/crates/starknet_client/src/reader/objects/test_utils.rs b/crates/starknet_client/src/reader/objects/test_utils.rs index 3876eeb723..f4d0f8491e 100644 --- a/crates/starknet_client/src/reader/objects/test_utils.rs +++ b/crates/starknet_client/src/reader/objects/test_utils.rs @@ -16,7 +16,6 @@ use starknet_api::transaction::{ AccountDeploymentData, Calldata, ContractAddressSalt, - DeprecatedResourceBoundsMapping, Event, Fee, L1ToL2Payload, @@ -27,6 +26,7 @@ use starknet_api::transaction::{ TransactionOffsetInBlock, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use starknet_types_core::felt::Felt; @@ -60,7 +60,7 @@ auto_impl_get_test_instance! { Reserved = 0, } pub struct IntermediateDeclareTransaction { - pub resource_bounds: Option, + pub resource_bounds: Option, pub tip: Option, pub signature: TransactionSignature, pub nonce: Nonce, @@ -76,7 +76,7 @@ auto_impl_get_test_instance! { pub transaction_hash: TransactionHash, } pub struct IntermediateDeployAccountTransaction { - pub resource_bounds: Option, + pub resource_bounds: Option, pub tip: Option, pub signature: TransactionSignature, pub nonce: Nonce, @@ -100,7 +100,7 @@ auto_impl_get_test_instance! { pub version: TransactionVersion, } pub struct IntermediateInvokeTransaction { - pub resource_bounds: Option, + pub resource_bounds: Option, pub tip: Option, pub calldata: Calldata, pub sender_address: ContractAddress, diff --git a/crates/starknet_client/src/reader/objects/transaction.rs b/crates/starknet_client/src/reader/objects/transaction.rs index 839ce41a74..4121cb26d8 100644 --- a/crates/starknet_client/src/reader/objects/transaction.rs +++ b/crates/starknet_client/src/reader/objects/transaction.rs @@ -23,7 +23,6 @@ use starknet_api::transaction::{ DeclareTransactionOutput, DeployAccountTransactionOutput, DeployTransactionOutput, - DeprecatedResourceBoundsMapping, Event, Fee, InvokeTransactionOutput, @@ -40,6 +39,7 @@ use starknet_api::transaction::{ TransactionOutput, TransactionSignature, TransactionVersion, + ValidResourceBounds, }; use strum_macros::EnumIter; use tracing::error; @@ -178,7 +178,7 @@ impl From for starknet_api::data_availability::Dat #[serde(deny_unknown_fields)] pub struct IntermediateDeclareTransaction { #[serde(skip_serializing_if = "Option::is_none")] - pub resource_bounds: Option, + pub resource_bounds: Option, #[serde(skip_serializing_if = "Option::is_none")] pub tip: Option, pub signature: TransactionSignature, @@ -347,7 +347,7 @@ impl From for starknet_api::transaction::DeployTransaction { #[serde(deny_unknown_fields)] pub struct IntermediateDeployAccountTransaction { #[serde(skip_serializing_if = "Option::is_none")] - pub resource_bounds: Option, + pub resource_bounds: Option, #[serde(skip_serializing_if = "Option::is_none")] pub tip: Option, pub signature: TransactionSignature, @@ -470,7 +470,7 @@ impl TryFrom #[serde(deny_unknown_fields)] pub struct IntermediateInvokeTransaction { #[serde(skip_serializing_if = "Option::is_none")] - pub resource_bounds: Option, + pub resource_bounds: Option, #[serde(skip_serializing_if = "Option::is_none")] pub tip: Option, pub calldata: Calldata,