diff --git a/Cargo.lock b/Cargo.lock index 336df617b7..d85544f40c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -483,15 +483,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "411aff151f2a73124ee473708e82ed51b2535f68928b6a1caa8bc1246ae6f7cd" dependencies = [ "alloy-rlp", + "arbitrary", "bytes", "cfg-if", "const-hex", + "derive_arbitrary", "derive_more 1.0.0", "hex-literal", "itoa", "k256", "keccak-asm", "proptest", + "proptest-derive", "rand 0.8.5", "ruint", "serde", @@ -960,6 +963,15 @@ version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "arc-swap" version = "1.7.1" @@ -3104,6 +3116,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58363ad8065ed891e3b14a8191b707677c7c7cb5b9d10030822506786d8d8108" dependencies = [ "anyhow", + "arbitrary", "bincode 2.0.0-rc.3", "bitvec", "generic-array", @@ -4321,6 +4334,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "derive_builder" version = "0.20.1" @@ -8067,6 +8091,7 @@ name = "katana-db" version = "1.0.0-alpha.17" dependencies = [ "anyhow", + "arbitrary", "criterion", "dojo-metrics", "katana-primitives", @@ -8190,6 +8215,7 @@ version = "1.0.0-alpha.17" dependencies = [ "alloy-primitives", "anyhow", + "arbitrary", "assert_matches", "base64 0.21.7", "derive_more 0.99.18", @@ -8207,6 +8233,7 @@ dependencies = [ "similar-asserts", "starknet 0.12.0", "starknet-crypto 0.7.2", + "starknet-types-core", "thiserror", ] @@ -10841,6 +10868,17 @@ dependencies = [ "unarray", ] +[[package]] +name = "proptest-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff7ff745a347b87471d859a377a9a404361e7efc2a971d73424a6d183c0fc77" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "prost" version = "0.12.6" @@ -11797,6 +11835,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" dependencies = [ "alloy-rlp", + "arbitrary", "ark-ff 0.3.0", "ark-ff 0.4.2", "bytes", @@ -13872,6 +13911,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b889ee5734db8b3c8a6551135c16764bf4ce1ab4955fffbb2ac5b6706542b64" dependencies = [ + "arbitrary", "lambdaworks-crypto", "lambdaworks-math", "lazy_static", diff --git a/Cargo.toml b/Cargo.toml index 0849bce8ea..ff158a0b33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,6 +118,7 @@ sozo-signers = { path = "crates/sozo/signers" } sozo-walnut = { path = "crates/sozo/walnut" } anyhow = "1.0.89" +arbitrary = { version = "1.3.2", features = [ "derive" ] } assert_fs = "1.1" assert_matches = "1.5.0" async-trait = "0.1.82" @@ -244,4 +245,4 @@ alloy-transport = { version = "0.3", default-features = false } starknet = "0.12.0" starknet-crypto = "0.7.1" -starknet-types-core = "0.1.6" +starknet-types-core = { version = "0.1.6", features = [ "arbitrary" ] } diff --git a/crates/katana/cairo/Cargo.toml b/crates/katana/cairo/Cargo.toml index 22672107a6..dd0776c248 100644 --- a/crates/katana/cairo/Cargo.toml +++ b/crates/katana/cairo/Cargo.toml @@ -19,3 +19,8 @@ cairo-lang-starknet-classes = "2.7.0" cairo-lang-utils = "2.7.0" cairo-vm = "1.0.1" starknet_api = { git = "https://github.com/dojoengine/sequencer", tag = "v0.8.0-rc3.2" } + +[features] +# Some types that we used from cairo-vm implements the `Arbitrary` trait, +# only under the `test_utils` feature. So we expose through this feature. +cairo-vm-test-utils = [ "cairo-vm/test_utils" ] diff --git a/crates/katana/core/src/backend/storage.rs b/crates/katana/core/src/backend/storage.rs index 50cc84e0e3..88ffd2a293 100644 --- a/crates/katana/core/src/backend/storage.rs +++ b/crates/katana/core/src/backend/storage.rs @@ -6,6 +6,7 @@ use katana_primitives::block::{ BlockHashOrNumber, BlockIdOrTag, FinalityStatus, SealedBlockWithStatus, }; use katana_primitives::chain_spec::ChainSpec; +use katana_primitives::da::L1DataAvailabilityMode; use katana_primitives::state::StateUpdatesWithDeclaredClasses; use katana_primitives::version::ProtocolVersion; use katana_provider::providers::db::DbProvider; @@ -182,7 +183,12 @@ impl Blockchain { forked_block.l1_data_gas_price.price_in_wei.to_u128().expect("should fit in u128"); block.header.l1_data_gas_prices.strk = forked_block.l1_data_gas_price.price_in_fri.to_u128().expect("should fit in u128"); - block.header.l1_da_mode = forked_block.l1_da_mode; + block.header.l1_da_mode = match forked_block.l1_da_mode { + starknet::core::types::L1DataAvailabilityMode::Blob => L1DataAvailabilityMode::Blob, + starknet::core::types::L1DataAvailabilityMode::Calldata => { + L1DataAvailabilityMode::Calldata + } + }; let block = block.seal_with_hash_and_status(forked_block.block_hash, status); let state_updates = chain.state_updates(); @@ -216,7 +222,7 @@ mod tests { Block, FinalityStatus, GasPrices, Header, SealedBlockWithStatus, }; use katana_primitives::da::L1DataAvailabilityMode; - use katana_primitives::fee::TxFeeInfo; + use katana_primitives::fee::{PriceUnit, TxFeeInfo}; use katana_primitives::genesis::constant::{ DEFAULT_ETH_FEE_TOKEN_ADDRESS, DEFAULT_LEGACY_ERC20_CASM, DEFAULT_LEGACY_ERC20_CLASS_HASH, DEFAULT_LEGACY_UDC_CASM, DEFAULT_LEGACY_UDC_CLASS_HASH, DEFAULT_UDC_ADDRESS, @@ -232,7 +238,6 @@ mod tests { }; use katana_provider::traits::state::StateFactoryProvider; use katana_provider::traits::transaction::{TransactionProvider, TransactionTraceProvider}; - use starknet::core::types::PriceUnit; use starknet::macros::felt; use super::Blockchain; diff --git a/crates/katana/executor/src/implementation/blockifier/utils.rs b/crates/katana/executor/src/implementation/blockifier/utils.rs index 544b14c0f8..7d7044d41a 100644 --- a/crates/katana/executor/src/implementation/blockifier/utils.rs +++ b/crates/katana/executor/src/implementation/blockifier/utils.rs @@ -45,7 +45,7 @@ use katana_cairo::starknet_api::transaction::{ }; use katana_primitives::chain::NamedChainId; use katana_primitives::env::{BlockEnv, CfgEnv}; -use katana_primitives::fee::TxFeeInfo; +use katana_primitives::fee::{PriceUnit, TxFeeInfo}; use katana_primitives::state::{StateUpdates, StateUpdatesWithDeclaredClasses}; use katana_primitives::trace::{L1Gas, TxExecInfo, TxResources}; use katana_primitives::transaction::{ @@ -53,7 +53,6 @@ use katana_primitives::transaction::{ }; use katana_primitives::{class, event, message, trace, Felt}; use katana_provider::traits::contract::ContractClassProvider; -use starknet::core::types::PriceUnit; use starknet::core::utils::parse_cairo_short_string; use super::state::{CachedState, StateDb}; @@ -480,15 +479,15 @@ pub(super) fn state_update_from_cached_state( } } -fn to_api_da_mode(mode: starknet::core::types::DataAvailabilityMode) -> DataAvailabilityMode { +fn to_api_da_mode(mode: katana_primitives::da::DataAvailabilityMode) -> DataAvailabilityMode { match mode { - starknet::core::types::DataAvailabilityMode::L1 => DataAvailabilityMode::L1, - starknet::core::types::DataAvailabilityMode::L2 => DataAvailabilityMode::L2, + katana_primitives::da::DataAvailabilityMode::L1 => DataAvailabilityMode::L1, + katana_primitives::da::DataAvailabilityMode::L2 => DataAvailabilityMode::L2, } } fn to_api_resource_bounds( - resource_bounds: starknet::core::types::ResourceBoundsMapping, + resource_bounds: katana_primitives::fee::ResourceBoundsMapping, ) -> ResourceBoundsMapping { let l1_gas = ResourceBounds { max_amount: resource_bounds.l1_gas.max_amount, @@ -572,7 +571,9 @@ pub fn to_exec_info(exec_info: TransactionExecutionInfo, r#type: TxType) -> TxEx actual_fee: exec_info.transaction_receipt.fee.0, revert_error: exec_info.revert_error.clone(), actual_resources: TxResources { - vm_resources: exec_info.transaction_receipt.resources.vm_resources, + vm_resources: to_execution_resources( + exec_info.transaction_receipt.resources.vm_resources, + ), n_reverted_steps: exec_info.transaction_receipt.resources.n_reverted_steps, data_availability: L1Gas { l1_gas: exec_info.transaction_receipt.da_gas.l1_data_gas, @@ -626,7 +627,7 @@ fn to_call_info(call: CallInfo) -> trace::CallInfo { entry_point_type, calldata, retdata, - execution_resources: call.resources, + execution_resources: to_execution_resources(call.resources), events, l2_to_l1_messages: l1_msg, storage_read_values, @@ -655,6 +656,16 @@ fn to_l2_l1_messages( message::OrderedL2ToL1Message { order, from_address, to_address, payload } } +fn to_execution_resources( + resources: ExecutionResources, +) -> katana_primitives::trace::ExecutionResources { + katana_primitives::trace::ExecutionResources { + n_steps: resources.n_steps, + n_memory_holes: resources.n_memory_holes, + builtin_instance_counter: resources.builtin_instance_counter, + } +} + #[cfg(test)] mod tests { diff --git a/crates/katana/executor/tests/simulate.rs b/crates/katana/executor/tests/simulate.rs index c474a2c744..a7b165e54c 100644 --- a/crates/katana/executor/tests/simulate.rs +++ b/crates/katana/executor/tests/simulate.rs @@ -5,10 +5,10 @@ use fixtures::{executor_factory, state_provider}; use katana_executor::{ExecutionOutput, ExecutorFactory, SimulationFlag}; use katana_primitives::block::GasPrices; use katana_primitives::env::BlockEnv; +use katana_primitives::fee::PriceUnit; use katana_primitives::transaction::ExecutableTxWithHash; use katana_provider::traits::state::StateProvider; use rstest_reuse::{self, *}; -use starknet::core::types::PriceUnit; use starknet::macros::felt; #[rstest::fixture] diff --git a/crates/katana/primitives/Cargo.toml b/crates/katana/primitives/Cargo.toml index 4f6de47088..0c692e4d9b 100644 --- a/crates/katana/primitives/Cargo.toml +++ b/crates/katana/primitives/Cargo.toml @@ -7,7 +7,10 @@ version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +katana-cairo.workspace = true + anyhow.workspace = true +arbitrary = { workspace = true, optional = true } base64.workspace = true derive_more.workspace = true lazy_static.workspace = true @@ -18,11 +21,11 @@ serde_json.workspace = true serde_with.workspace = true starknet.workspace = true starknet-crypto.workspace = true +starknet-types-core.workspace = true thiserror.workspace = true -alloy-primitives.workspace = true +alloy-primitives = { workspace = true, features = [ "arbitrary" ] } flate2 = { workspace = true, optional = true } -katana-cairo.workspace = true num-bigint = "0.4.6" [dev-dependencies] @@ -34,6 +37,12 @@ similar-asserts.workspace = true [features] default = [ "serde" ] +arbitrary = [ + "alloy-primitives/arbitrary", + "dep:arbitrary", + # See the comment in katana-cairo/Cargo.toml for why this is needed. + "katana-cairo/cairo-vm-test-utils", +] controller = [ ] rpc = [ "dep:flate2" ] serde = [ "alloy-primitives/serde" ] diff --git a/crates/katana/primitives/src/block.rs b/crates/katana/primitives/src/block.rs index 8e8a6492d7..2462efd739 100644 --- a/crates/katana/primitives/src/block.rs +++ b/crates/katana/primitives/src/block.rs @@ -32,6 +32,7 @@ pub type BlockHash = Felt; /// Finality status of a canonical block. #[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FinalityStatus { AcceptedOnL2, @@ -55,6 +56,7 @@ pub struct PartialHeader { // TODO: change names to wei and fri /// The L1 gas prices. #[derive(Debug, Default, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "UPPERCASE"))] pub struct GasPrices { @@ -73,6 +75,7 @@ impl GasPrices { /// Represents a block header. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Header { pub parent_hash: BlockHash, diff --git a/crates/katana/primitives/src/chain.rs b/crates/katana/primitives/src/chain.rs index a1f8408d8e..4190440f4d 100644 --- a/crates/katana/primitives/src/chain.rs +++ b/crates/katana/primitives/src/chain.rs @@ -5,6 +5,7 @@ use crate::{Felt, FromStrError}; /// Known chain ids that has been assigned a name. #[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum NamedChainId { Mainnet, @@ -72,6 +73,7 @@ impl TryFrom for NamedChainId { /// Represents a chain id. #[derive(Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum ChainId { /// A chain id with a known chain name. diff --git a/crates/katana/primitives/src/chain_spec.rs b/crates/katana/primitives/src/chain_spec.rs index c574600bd5..fe140ed932 100644 --- a/crates/katana/primitives/src/chain_spec.rs +++ b/crates/katana/primitives/src/chain_spec.rs @@ -2,7 +2,6 @@ use std::collections::BTreeMap; use alloy_primitives::U256; use lazy_static::lazy_static; -use starknet::core::types::L1DataAvailabilityMode; use starknet::core::utils::cairo_short_string_to_felt; use starknet_crypto::Felt; @@ -10,6 +9,7 @@ use crate::block::{Block, Header}; use crate::chain::ChainId; use crate::class::ClassHash; use crate::contract::ContractAddress; +use crate::da::L1DataAvailabilityMode; use crate::genesis::allocation::{DevAllocationsGenerator, GenesisAllocation}; use crate::genesis::constant::{ get_fee_token_balance_base_storage_address, DEFAULT_ACCOUNT_CLASS_PUBKEY_STORAGE_SLOT, @@ -225,12 +225,12 @@ mod tests { use std::str::FromStr; use alloy_primitives::U256; - use starknet::core::types::L1DataAvailabilityMode; use starknet::macros::felt; use super::*; use crate::address; use crate::block::{Block, GasPrices, Header}; + use crate::da::L1DataAvailabilityMode; use crate::genesis::allocation::{GenesisAccount, GenesisAccountAlloc, GenesisContractAlloc}; #[cfg(feature = "slot")] use crate::genesis::constant::{ diff --git a/crates/katana/primitives/src/contract.rs b/crates/katana/primitives/src/contract.rs index 08f2831da9..4d355287f3 100644 --- a/crates/katana/primitives/src/contract.rs +++ b/crates/katana/primitives/src/contract.rs @@ -16,6 +16,7 @@ pub type Nonce = Felt; /// Represents a contract address. #[derive(Default, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Debug)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ContractAddress(pub Felt); @@ -72,6 +73,7 @@ macro_rules! address { /// Represents a generic contract instance information. #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct GenericContractInfo { /// The nonce of the contract. diff --git a/crates/katana/primitives/src/da/mod.rs b/crates/katana/primitives/src/da/mod.rs index a2fa9776f4..02da463781 100644 --- a/crates/katana/primitives/src/da/mod.rs +++ b/crates/katana/primitives/src/da/mod.rs @@ -4,4 +4,23 @@ pub mod encoding; pub mod math; pub mod serde; -pub use ::starknet::core::types::L1DataAvailabilityMode; +/// L1 da mode. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] +#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))] +pub enum L1DataAvailabilityMode { + #[serde(rename = "BLOB")] + Blob, + #[serde(rename = "CALLDATA")] + Calldata, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] +#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))] +pub enum DataAvailabilityMode { + #[serde(rename = "L1")] + L1, + #[serde(rename = "L2")] + L2, +} diff --git a/crates/katana/primitives/src/event.rs b/crates/katana/primitives/src/event.rs index 56224d9a1c..fa65129a9f 100644 --- a/crates/katana/primitives/src/event.rs +++ b/crates/katana/primitives/src/event.rs @@ -4,6 +4,7 @@ use std::num::ParseIntError; use crate::Felt; #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct OrderedEvent { pub order: u64, diff --git a/crates/katana/primitives/src/fee.rs b/crates/katana/primitives/src/fee.rs index caa2577818..b55a07d3f3 100644 --- a/crates/katana/primitives/src/fee.rs +++ b/crates/katana/primitives/src/fee.rs @@ -1,7 +1,34 @@ -use starknet::core::types::PriceUnit; +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ResourceBounds { + /// The max amount of the resource that can be used in the tx + pub max_amount: u64, + /// The max price per unit of this resource for this tx + pub max_price_per_unit: u128, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ResourceBoundsMapping { + pub l1_gas: ResourceBounds, + pub l2_gas: ResourceBounds, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum PriceUnit { + #[serde(rename = "WEI")] + Wei, + #[serde(rename = "FRI")] + Fri, +} /// Information regarding the fee and gas usages of a transaction. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TxFeeInfo { /// The total amount of L1 gas consumed by the transaction. diff --git a/crates/katana/primitives/src/lib.rs b/crates/katana/primitives/src/lib.rs index 704de8c85a..be6b106c39 100644 --- a/crates/katana/primitives/src/lib.rs +++ b/crates/katana/primitives/src/lib.rs @@ -22,5 +22,5 @@ pub mod state; pub mod utils; pub use contract::ContractAddress; -pub use starknet::core::types::{Felt, FromStrError}; pub use starknet::macros::felt; +pub use starknet_types_core::felt::{Felt, FromStrError}; diff --git a/crates/katana/primitives/src/message.rs b/crates/katana/primitives/src/message.rs index 20b66fab6d..eb3942458a 100644 --- a/crates/katana/primitives/src/message.rs +++ b/crates/katana/primitives/src/message.rs @@ -2,6 +2,7 @@ use crate::contract::ContractAddress; use crate::Felt; #[derive(Debug, Clone, PartialEq, Eq, Default)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct OrderedL2ToL1Message { pub order: u64, diff --git a/crates/katana/primitives/src/receipt.rs b/crates/katana/primitives/src/receipt.rs index 76f5268350..a3d23025fc 100644 --- a/crates/katana/primitives/src/receipt.rs +++ b/crates/katana/primitives/src/receipt.rs @@ -6,6 +6,7 @@ use crate::trace::TxResources; use crate::Felt; #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Event { /// The contract address that emitted the event. @@ -18,6 +19,7 @@ pub struct Event { /// Represents a message sent to L1. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct MessageToL1 { /// The L2 contract address that sent the message. @@ -30,6 +32,7 @@ pub struct MessageToL1 { /// Receipt for a `Invoke` transaction. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct InvokeTxReceipt { /// Information about the transaction fee. @@ -46,6 +49,7 @@ pub struct InvokeTxReceipt { /// Receipt for a `Declare` transaction. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DeclareTxReceipt { /// Information about the transaction fee. @@ -62,6 +66,7 @@ pub struct DeclareTxReceipt { /// Receipt for a `L1Handler` transaction. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct L1HandlerTxReceipt { /// Information about the transaction fee. @@ -80,6 +85,7 @@ pub struct L1HandlerTxReceipt { /// Receipt for a `DeployAccount` transaction. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DeployAccountTxReceipt { /// Information about the transaction fee. @@ -98,6 +104,7 @@ pub struct DeployAccountTxReceipt { /// The receipt of a transaction containing the outputs of its execution. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum Receipt { Invoke(InvokeTxReceipt), diff --git a/crates/katana/primitives/src/trace.rs b/crates/katana/primitives/src/trace.rs index 8a69871ed3..e89d989c26 100644 --- a/crates/katana/primitives/src/trace.rs +++ b/crates/katana/primitives/src/trace.rs @@ -1,7 +1,6 @@ use std::collections::{HashMap, HashSet}; use katana_cairo::cairo_vm::types::builtin_name::BuiltinName; -use katana_cairo::cairo_vm::vm; use crate::class::ClassHash; use crate::contract::ContractAddress; @@ -10,9 +9,17 @@ use crate::message::OrderedL2ToL1Message; use crate::transaction::TxType; use crate::Felt; -pub type ExecutionResources = vm::runners::cairo_runner::ExecutionResources; +#[derive(Clone, Debug, Default, Eq, PartialEq)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ExecutionResources { + pub n_steps: usize, + pub n_memory_holes: usize, + pub builtin_instance_counter: HashMap, +} #[derive(Debug, Clone, PartialEq, Eq, Default)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TxExecInfo { /// Transaction validation call info; [None] for `L1Handler`. @@ -33,6 +40,7 @@ pub struct TxExecInfo { } #[derive(Debug, Clone, PartialEq, Eq, Default)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TxResources { pub n_reverted_steps: usize, @@ -42,6 +50,7 @@ pub struct TxResources { } #[derive(Debug, Clone, PartialEq, Eq, Default)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct L1Gas { pub l1_gas: u128, @@ -50,6 +59,7 @@ pub struct L1Gas { /// The call type. #[derive(Debug, Clone, PartialEq, Eq, Default)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum CallType { #[default] @@ -60,6 +70,7 @@ pub enum CallType { } #[derive(Debug, Clone, PartialEq, Eq, Default)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum EntryPointType { #[default] @@ -69,6 +80,7 @@ pub enum EntryPointType { } #[derive(Debug, Clone, PartialEq, Eq, Default)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CallInfo { /// The contract address which the call is initiated from. @@ -114,6 +126,7 @@ pub struct CallInfo { #[derive(Clone, Debug, Default, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[serde(transparent)] pub struct BuiltinCounters(HashMap); impl BuiltinCounters { diff --git a/crates/katana/primitives/src/transaction.rs b/crates/katana/primitives/src/transaction.rs index 54f039c05b..6bcd78e831 100644 --- a/crates/katana/primitives/src/transaction.rs +++ b/crates/katana/primitives/src/transaction.rs @@ -1,10 +1,11 @@ use alloy_primitives::B256; use derive_more::{AsRef, Deref, From}; -use starknet::core::types::{DataAvailabilityMode, ResourceBoundsMapping}; use crate::chain::ChainId; use crate::class::{ClassHash, CompiledClass, CompiledClassHash, FlattenedSierraClass}; use crate::contract::{ContractAddress, Nonce}; +use crate::da::DataAvailabilityMode; +use crate::fee::ResourceBoundsMapping; use crate::utils::transaction::{ compute_declare_v1_tx_hash, compute_declare_v2_tx_hash, compute_declare_v3_tx_hash, compute_deploy_account_v1_tx_hash, compute_deploy_account_v3_tx_hash, @@ -21,6 +22,7 @@ pub type TxNumber = u64; /// /// [Starknet API]: https://github.com/starkware-libs/starknet-specs/blob/b5c43955b1868b8e19af6d1736178e02ec84e678/api/starknet_api_openrpc.json #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum TxType { /// Invokes a function of a contract. @@ -41,6 +43,7 @@ pub enum TxType { } #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum Tx { Invoke(InvokeTx), @@ -152,6 +155,7 @@ impl DeclareTxWithClass { } #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum InvokeTx { V1(InvokeTxV1), @@ -159,6 +163,7 @@ pub enum InvokeTx { } #[derive(Debug, Clone, Default, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct InvokeTxV1 { /// The chain id of the chain on which the transaction is initiated. @@ -179,6 +184,7 @@ pub struct InvokeTxV1 { } #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct InvokeTxV3 { /// The chain id of the chain on which the transaction is initiated. @@ -218,7 +224,7 @@ impl InvokeTx { pub fn calculate_hash(&self, is_query: bool) -> TxHash { match self { InvokeTx::V1(tx) => compute_invoke_v1_tx_hash( - tx.sender_address.into(), + Felt::from(tx.sender_address), &tx.calldata, tx.max_fee, tx.chain_id.into(), @@ -227,7 +233,7 @@ impl InvokeTx { ), InvokeTx::V3(tx) => utils::transaction::compute_invoke_v3_tx_hash( - tx.sender_address.into(), + Felt::from(tx.sender_address), &tx.calldata, tx.tip, &tx.resource_bounds.l1_gas, @@ -245,6 +251,7 @@ impl InvokeTx { } #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum DeclareTx { V1(DeclareTxV1), @@ -264,6 +271,7 @@ impl DeclareTx { /// Represents a declare transaction type. #[derive(Debug, Clone, Default, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DeclareTxV1 { /// The chain id of the chain on which the transaction is initiated. @@ -285,6 +293,7 @@ pub struct DeclareTxV1 { /// Represents a declare transaction type. #[derive(Debug, Default, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DeclareTxV2 { /// The chain id of the chain on which the transaction is initiated. @@ -308,6 +317,7 @@ pub struct DeclareTxV2 { /// Represents a declare transaction type. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DeclareTxV3 { /// The chain id of the chain on which the transaction is initiated. @@ -344,7 +354,7 @@ impl DeclareTx { pub fn calculate_hash(&self, is_query: bool) -> TxHash { match self { DeclareTx::V1(tx) => compute_declare_v1_tx_hash( - tx.sender_address.into(), + Felt::from(tx.sender_address), tx.class_hash, tx.max_fee, tx.chain_id.into(), @@ -353,7 +363,7 @@ impl DeclareTx { ), DeclareTx::V2(tx) => compute_declare_v2_tx_hash( - tx.sender_address.into(), + Felt::from(tx.sender_address), tx.class_hash, tx.max_fee, tx.chain_id.into(), @@ -363,7 +373,7 @@ impl DeclareTx { ), DeclareTx::V3(tx) => compute_declare_v3_tx_hash( - tx.sender_address.into(), + Felt::from(tx.sender_address), tx.class_hash, tx.compiled_class_hash, tx.tip, @@ -383,6 +393,7 @@ impl DeclareTx { /// The transaction type for L1 handler invocation. #[derive(Debug, Clone, Default, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct L1HandlerTx { /// The L1 to L2 message nonce. @@ -408,7 +419,7 @@ impl L1HandlerTx { pub fn calculate_hash(&self) -> TxHash { compute_l1_handler_tx_hash( self.version, - self.contract_address.into(), + Felt::from(self.contract_address), self.entry_point_selector, &self.calldata, self.chain_id.into(), @@ -418,6 +429,7 @@ impl L1HandlerTx { } #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum DeployAccountTx { V1(DeployAccountTxV1), @@ -434,6 +446,7 @@ impl DeployAccountTx { } #[derive(Debug, Clone, Default, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DeployAccountTxV1 { /// The chain id of the chain on which the transaction is initiated. @@ -458,6 +471,7 @@ pub struct DeployAccountTxV1 { } #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DeployAccountTxV3 { /// The chain id of the chain on which the transaction is initiated. @@ -494,7 +508,7 @@ impl DeployAccountTx { pub fn calculate_hash(&self, is_query: bool) -> TxHash { match self { DeployAccountTx::V1(tx) => compute_deploy_account_v1_tx_hash( - tx.contract_address.into(), + Felt::from(tx.contract_address), &tx.constructor_calldata, tx.class_hash, tx.contract_address_salt, @@ -505,7 +519,7 @@ impl DeployAccountTx { ), DeployAccountTx::V3(tx) => compute_deploy_account_v3_tx_hash( - tx.contract_address.into(), + Felt::from(tx.contract_address), &tx.constructor_calldata, tx.class_hash, tx.contract_address_salt, diff --git a/crates/katana/primitives/src/utils/transaction.rs b/crates/katana/primitives/src/utils/transaction.rs index 933ffe5539..9c94d1054a 100644 --- a/crates/katana/primitives/src/utils/transaction.rs +++ b/crates/katana/primitives/src/utils/transaction.rs @@ -1,8 +1,10 @@ use alloy_primitives::B256; use starknet::core::crypto::compute_hash_on_elements; -use starknet::core::types::{DataAvailabilityMode, EthAddress, MsgToL1, MsgToL2, ResourceBounds}; +use starknet::core::types::{EthAddress, MsgToL1, MsgToL2}; use starknet_crypto::poseidon_hash_many; +use crate::da::DataAvailabilityMode; +use crate::fee::ResourceBounds; use crate::Felt; /// 2^ 128 diff --git a/crates/katana/primitives/src/version.rs b/crates/katana/primitives/src/version.rs index bd063b1c88..fda4fee664 100644 --- a/crates/katana/primitives/src/version.rs +++ b/crates/katana/primitives/src/version.rs @@ -4,6 +4,7 @@ pub const CURRENT_STARKNET_VERSION: ProtocolVersion = ProtocolVersion::new([0, 1 // TODO: figure out the exact format of the version string. /// Starknet protocol version. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] pub struct ProtocolVersion { /// Each segments represents a part of the version number. segments: [u8; 4], diff --git a/crates/katana/rpc/rpc-types/src/block.rs b/crates/katana/rpc/rpc-types/src/block.rs index 7636d542ff..b8cb53fafd 100644 --- a/crates/katana/rpc/rpc-types/src/block.rs +++ b/crates/katana/rpc/rpc-types/src/block.rs @@ -46,8 +46,12 @@ impl BlockWithTxs { FinalityStatus::AcceptedOnL1 => BlockStatus::AcceptedOnL1, FinalityStatus::AcceptedOnL2 => BlockStatus::AcceptedOnL2, }, - - l1_da_mode: block.header.l1_da_mode, + l1_da_mode: match block.header.l1_da_mode { + katana_primitives::da::L1DataAvailabilityMode::Blob => L1DataAvailabilityMode::Blob, + katana_primitives::da::L1DataAvailabilityMode::Calldata => { + L1DataAvailabilityMode::Calldata + } + }, l1_data_gas_price, }) } @@ -125,8 +129,12 @@ impl BlockWithTxHashes { FinalityStatus::AcceptedOnL1 => BlockStatus::AcceptedOnL1, FinalityStatus::AcceptedOnL2 => BlockStatus::AcceptedOnL2, }, - - l1_da_mode: block.header.l1_da_mode, + l1_da_mode: match block.header.l1_da_mode { + katana_primitives::da::L1DataAvailabilityMode::Blob => L1DataAvailabilityMode::Blob, + katana_primitives::da::L1DataAvailabilityMode::Calldata => { + L1DataAvailabilityMode::Calldata + } + }, l1_data_gas_price, }) } @@ -155,7 +163,12 @@ impl PendingBlockWithTxHashes { parent_hash: header.parent_hash, starknet_version: header.protocol_version.to_string(), sequencer_address: header.sequencer_address.into(), - l1_da_mode: header.l1_da_mode, + l1_da_mode: match header.l1_da_mode { + katana_primitives::da::L1DataAvailabilityMode::Blob => L1DataAvailabilityMode::Blob, + katana_primitives::da::L1DataAvailabilityMode::Calldata => { + L1DataAvailabilityMode::Calldata + } + }, l1_data_gas_price, }) } @@ -266,7 +279,12 @@ impl PendingBlockWithReceipts { timestamp: header.timestamp, sequencer_address: header.sequencer_address.into(), parent_hash: header.parent_hash, - l1_da_mode: header.l1_da_mode, + l1_da_mode: match header.l1_da_mode { + katana_primitives::da::L1DataAvailabilityMode::Blob => L1DataAvailabilityMode::Blob, + katana_primitives::da::L1DataAvailabilityMode::Calldata => { + L1DataAvailabilityMode::Calldata + } + }, l1_data_gas_price, starknet_version: header.protocol_version.to_string(), }) diff --git a/crates/katana/rpc/rpc-types/src/receipt.rs b/crates/katana/rpc/rpc-types/src/receipt.rs index fa1487927e..17dfe5df53 100644 --- a/crates/katana/rpc/rpc-types/src/receipt.rs +++ b/crates/katana/rpc/rpc-types/src/receipt.rs @@ -1,6 +1,6 @@ use katana_cairo::cairo_vm::types::builtin_name::BuiltinName; use katana_primitives::block::FinalityStatus; -use katana_primitives::fee::TxFeeInfo; +use katana_primitives::fee::{PriceUnit, TxFeeInfo}; use katana_primitives::receipt::{MessageToL1, Receipt}; use katana_primitives::transaction::TxHash; use serde::{Deserialize, Serialize}; @@ -209,5 +209,10 @@ impl From for ExecutionResources { } fn to_rpc_fee(fee: TxFeeInfo) -> FeePayment { - FeePayment { amount: fee.overall_fee.into(), unit: fee.unit } + let unit = match fee.unit { + PriceUnit::Wei => starknet::core::types::PriceUnit::Wei, + PriceUnit::Fri => starknet::core::types::PriceUnit::Fri, + }; + + FeePayment { amount: fee.overall_fee.into(), unit } } diff --git a/crates/katana/rpc/rpc-types/src/transaction.rs b/crates/katana/rpc/rpc-types/src/transaction.rs index 231ce2d771..4c466846fd 100644 --- a/crates/katana/rpc/rpc-types/src/transaction.rs +++ b/crates/katana/rpc/rpc-types/src/transaction.rs @@ -9,6 +9,8 @@ use katana_primitives::conversion::rpc::{ compiled_class_hash_from_flattened_sierra_class, flattened_sierra_to_compiled_class, legacy_rpc_to_compiled_class, }; +use katana_primitives::da::DataAvailabilityMode; +use katana_primitives::fee::{ResourceBounds, ResourceBoundsMapping}; use katana_primitives::transaction::{ DeclareTx, DeclareTxV1, DeclareTxV2, DeclareTxV3, DeclareTxWithClass, DeployAccountTx, DeployAccountTxV1, DeployAccountTxV3, InvokeTx, InvokeTxV1, InvokeTxV3, TxHash, TxWithHash, @@ -57,10 +59,10 @@ impl BroadcastedInvokeTx { signature: tx.signature, sender_address: tx.sender_address.into(), account_deployment_data: tx.account_deployment_data, - fee_data_availability_mode: tx.fee_data_availability_mode, - nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: from_rpc_da_mode(tx.fee_data_availability_mode), + nonce_data_availability_mode: from_rpc_da_mode(tx.nonce_data_availability_mode), paymaster_data: tx.paymaster_data, - resource_bounds: tx.resource_bounds, + resource_bounds: from_rpc_resource_bounds(tx.resource_bounds), tip: tx.tip, }), } @@ -151,9 +153,11 @@ impl BroadcastedDeclareTx { tip: tx.tip, paymaster_data: tx.paymaster_data, account_deployment_data: tx.account_deployment_data, - resource_bounds: tx.resource_bounds, - fee_data_availability_mode: tx.fee_data_availability_mode, - nonce_data_availability_mode: tx.nonce_data_availability_mode, + resource_bounds: from_rpc_resource_bounds(tx.resource_bounds), + fee_data_availability_mode: from_rpc_da_mode(tx.fee_data_availability_mode), + nonce_data_availability_mode: from_rpc_da_mode( + tx.nonce_data_availability_mode, + ), }), }) } @@ -219,10 +223,10 @@ impl BroadcastedDeployAccountTx { contract_address: contract_address.into(), constructor_calldata: tx.constructor_calldata, contract_address_salt: tx.contract_address_salt, - fee_data_availability_mode: tx.fee_data_availability_mode, - nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: from_rpc_da_mode(tx.fee_data_availability_mode), + nonce_data_availability_mode: from_rpc_da_mode(tx.nonce_data_availability_mode), paymaster_data: tx.paymaster_data, - resource_bounds: tx.resource_bounds, + resource_bounds: from_rpc_resource_bounds(tx.resource_bounds), tip: tx.tip, }) } @@ -283,10 +287,14 @@ impl From for Tx { signature: tx.signature, sender_address: tx.sender_address.into(), account_deployment_data: tx.account_deployment_data, - fee_data_availability_mode: tx.fee_data_availability_mode, - nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: to_rpc_da_mode( + tx.fee_data_availability_mode, + ), + nonce_data_availability_mode: to_rpc_da_mode( + tx.nonce_data_availability_mode, + ), paymaster_data: tx.paymaster_data, - resource_bounds: tx.resource_bounds, + resource_bounds: to_rpc_resource_bounds(tx.resource_bounds), tip: tx.tip, }, ), @@ -326,10 +334,12 @@ impl From for Tx { sender_address: tx.sender_address.into(), compiled_class_hash: tx.compiled_class_hash, account_deployment_data: tx.account_deployment_data, - fee_data_availability_mode: tx.fee_data_availability_mode, - nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: to_rpc_da_mode(tx.fee_data_availability_mode), + nonce_data_availability_mode: to_rpc_da_mode( + tx.nonce_data_availability_mode, + ), paymaster_data: tx.paymaster_data, - resource_bounds: tx.resource_bounds, + resource_bounds: to_rpc_resource_bounds(tx.resource_bounds), tip: tx.tip, }, ), @@ -368,10 +378,14 @@ impl From for Tx { class_hash: tx.class_hash, constructor_calldata: tx.constructor_calldata, contract_address_salt: tx.contract_address_salt, - fee_data_availability_mode: tx.fee_data_availability_mode, - nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: to_rpc_da_mode( + tx.fee_data_availability_mode, + ), + nonce_data_availability_mode: to_rpc_da_mode( + tx.nonce_data_availability_mode, + ), paymaster_data: tx.paymaster_data, - resource_bounds: tx.resource_bounds, + resource_bounds: to_rpc_resource_bounds(tx.resource_bounds), tip: tx.tip, }, ), @@ -441,10 +455,10 @@ impl From for InvokeTx { chain_id: ChainId::default(), sender_address: tx.sender_address.into(), account_deployment_data: tx.account_deployment_data, - fee_data_availability_mode: tx.fee_data_availability_mode, - nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: from_rpc_da_mode(tx.fee_data_availability_mode), + nonce_data_availability_mode: from_rpc_da_mode(tx.nonce_data_availability_mode), paymaster_data: tx.paymaster_data, - resource_bounds: tx.resource_bounds, + resource_bounds: from_rpc_resource_bounds(tx.resource_bounds), tip: tx.tip, }), } @@ -490,10 +504,10 @@ impl From for DeployAccountTx { contract_address: contract_address.into(), constructor_calldata: tx.constructor_calldata, contract_address_salt: tx.contract_address_salt, - fee_data_availability_mode: tx.fee_data_availability_mode, - nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: from_rpc_da_mode(tx.fee_data_availability_mode), + nonce_data_availability_mode: from_rpc_da_mode(tx.nonce_data_availability_mode), paymaster_data: tx.paymaster_data, - resource_bounds: tx.resource_bounds, + resource_bounds: from_rpc_resource_bounds(tx.resource_bounds), tip: tx.tip, }) } @@ -519,3 +533,52 @@ pub struct TransactionsPage { pub transactions: Vec<(TxWithHash, TxReceiptWithBlockInfo)>, pub cursor: TransactionsPageCursor, } + +// TODO: find a solution to avoid doing this conversion, this is not pretty at all. the reason why +// we had to do this in the first place is because of the orphan rule. i think eventually we should +// not rely on `starknet-rs` rpc types anymore and should instead define the types ourselves to have +// more flexibility. + +fn from_rpc_da_mode(mode: starknet::core::types::DataAvailabilityMode) -> DataAvailabilityMode { + match mode { + starknet::core::types::DataAvailabilityMode::L1 => DataAvailabilityMode::L1, + starknet::core::types::DataAvailabilityMode::L2 => DataAvailabilityMode::L2, + } +} + +fn to_rpc_da_mode(mode: DataAvailabilityMode) -> starknet::core::types::DataAvailabilityMode { + match mode { + DataAvailabilityMode::L1 => starknet::core::types::DataAvailabilityMode::L1, + DataAvailabilityMode::L2 => starknet::core::types::DataAvailabilityMode::L2, + } +} + +fn from_rpc_resource_bounds( + rpc_bounds: starknet::core::types::ResourceBoundsMapping, +) -> ResourceBoundsMapping { + ResourceBoundsMapping { + l1_gas: ResourceBounds { + max_amount: rpc_bounds.l1_gas.max_amount, + max_price_per_unit: rpc_bounds.l1_gas.max_price_per_unit, + }, + l2_gas: ResourceBounds { + max_amount: rpc_bounds.l2_gas.max_amount, + max_price_per_unit: rpc_bounds.l2_gas.max_price_per_unit, + }, + } +} + +fn to_rpc_resource_bounds( + bounds: ResourceBoundsMapping, +) -> starknet::core::types::ResourceBoundsMapping { + starknet::core::types::ResourceBoundsMapping { + l1_gas: starknet::core::types::ResourceBounds { + max_amount: bounds.l1_gas.max_amount, + max_price_per_unit: bounds.l1_gas.max_price_per_unit, + }, + l2_gas: starknet::core::types::ResourceBounds { + max_amount: bounds.l2_gas.max_amount, + max_price_per_unit: bounds.l2_gas.max_price_per_unit, + }, + } +} diff --git a/crates/katana/rpc/rpc/src/starknet/mod.rs b/crates/katana/rpc/rpc/src/starknet/mod.rs index 6f5b39063b..7f7250c023 100644 --- a/crates/katana/rpc/rpc/src/starknet/mod.rs +++ b/crates/katana/rpc/rpc/src/starknet/mod.rs @@ -32,7 +32,7 @@ use katana_rpc_types::error::starknet::StarknetApiError; use katana_rpc_types::FeeEstimate; use katana_tasks::{BlockingTaskPool, TokioTaskSpawner}; use starknet::core::types::{ - ContractClass, EventsPage, TransactionExecutionStatus, TransactionStatus, + ContractClass, EventsPage, PriceUnit, TransactionExecutionStatus, TransactionStatus, }; use crate::utils; @@ -111,9 +111,12 @@ impl StarknetApi { gas_price: fee.gas_price.into(), gas_consumed: fee.gas_consumed.into(), overall_fee: fee.overall_fee.into(), - unit: fee.unit, data_gas_price: Default::default(), data_gas_consumed: Default::default(), + unit: match fee.unit { + katana_primitives::fee::PriceUnit::Wei => PriceUnit::Wei, + katana_primitives::fee::PriceUnit::Fri => PriceUnit::Fri, + }, }), Err(err) => { diff --git a/crates/katana/rpc/rpc/src/starknet/trace.rs b/crates/katana/rpc/rpc/src/starknet/trace.rs index edfa21c95a..8002c206cf 100644 --- a/crates/katana/rpc/rpc/src/starknet/trace.rs +++ b/crates/katana/rpc/rpc/src/starknet/trace.rs @@ -14,8 +14,8 @@ use katana_rpc_types::{FeeEstimate, SimulationFlag}; use starknet::core::types::{ BlockTag, ComputationResources, DataAvailabilityResources, DataResources, DeclareTransactionTrace, DeployAccountTransactionTrace, ExecuteInvocation, ExecutionResources, - InvokeTransactionTrace, L1HandlerTransactionTrace, RevertedInvocation, SimulatedTransaction, - TransactionTrace, TransactionTraceWithHash, + InvokeTransactionTrace, L1HandlerTransactionTrace, PriceUnit, RevertedInvocation, + SimulatedTransaction, TransactionTrace, TransactionTraceWithHash, }; use super::StarknetApi; @@ -294,7 +294,10 @@ fn to_rpc_resources(resources: katana_primitives::trace::ExecutionResources) -> fn to_rpc_fee_estimate(fee: TxFeeInfo) -> FeeEstimate { FeeEstimate { - unit: fee.unit, + unit: match fee.unit { + katana_primitives::fee::PriceUnit::Wei => PriceUnit::Wei, + katana_primitives::fee::PriceUnit::Fri => PriceUnit::Fri, + }, gas_price: fee.gas_price.into(), overall_fee: fee.overall_fee.into(), gas_consumed: fee.gas_consumed.into(), diff --git a/crates/katana/storage/db/Cargo.toml b/crates/katana/storage/db/Cargo.toml index fc67cdfb6e..36b86bd266 100644 --- a/crates/katana/storage/db/Cargo.toml +++ b/crates/katana/storage/db/Cargo.toml @@ -7,7 +7,7 @@ version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -katana-primitives = { workspace = true } +katana-primitives = { workspace = true, features = [ "arbitrary" ] } anyhow.workspace = true dojo-metrics.workspace = true @@ -30,7 +30,7 @@ package = "reth-libmdbx" rev = "b34b0d3" [dev-dependencies] -# cairo-lang-starknet.workspace = true +arbitrary.workspace = true criterion.workspace = true starknet.workspace = true diff --git a/crates/katana/storage/db/src/models/block.rs b/crates/katana/storage/db/src/models/block.rs index 7734b7f517..c57f38d46f 100644 --- a/crates/katana/storage/db/src/models/block.rs +++ b/crates/katana/storage/db/src/models/block.rs @@ -4,6 +4,7 @@ use katana_primitives::transaction::TxNumber; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)] +#[cfg_attr(test, derive(::arbitrary::Arbitrary))] pub struct StoredBlockBodyIndices { /// The offset in database of the first transaction in the block. /// diff --git a/crates/katana/storage/db/src/models/contract.rs b/crates/katana/storage/db/src/models/contract.rs index 241e29dd59..18e170afe6 100644 --- a/crates/katana/storage/db/src/models/contract.rs +++ b/crates/katana/storage/db/src/models/contract.rs @@ -12,6 +12,7 @@ pub struct ContractInfoChangeList { } #[derive(Debug, Default, PartialEq, Eq)] +#[cfg_attr(test, derive(::arbitrary::Arbitrary))] pub struct ContractClassChange { pub contract_address: ContractAddress, /// The updated class hash of `contract_address`. @@ -38,6 +39,7 @@ impl Decompress for ContractClassChange { } #[derive(Debug, Default, PartialEq, Eq)] +#[cfg_attr(test, derive(::arbitrary::Arbitrary))] pub struct ContractNonceChange { pub contract_address: ContractAddress, /// The updated nonce value of `contract_address`. diff --git a/crates/katana/storage/db/src/models/storage.rs b/crates/katana/storage/db/src/models/storage.rs index b6264a481f..033316d83a 100644 --- a/crates/katana/storage/db/src/models/storage.rs +++ b/crates/katana/storage/db/src/models/storage.rs @@ -7,6 +7,7 @@ use crate::error::CodecError; /// /// `key` is the subkey for the dupsort table. #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] +#[cfg_attr(test, derive(::arbitrary::Arbitrary))] pub struct StorageEntry { /// The storage key. pub key: StorageKey, @@ -34,6 +35,7 @@ impl Decompress for StorageEntry { } #[derive(Debug, Clone, Default, PartialEq, Eq)] +#[cfg_attr(test, derive(::arbitrary::Arbitrary))] pub struct ContractStorageKey { pub contract_address: ContractAddress, pub key: StorageKey, @@ -59,6 +61,7 @@ impl Decode for ContractStorageKey { } #[derive(Debug, Clone, Default, PartialEq, Eq)] +#[cfg_attr(test, derive(::arbitrary::Arbitrary))] pub struct ContractStorageEntry { pub key: ContractStorageKey, pub value: StorageValue, diff --git a/crates/katana/storage/db/src/tables.rs b/crates/katana/storage/db/src/tables.rs index a3dd5f0800..ccb02bd147 100644 --- a/crates/katana/storage/db/src/tables.rs +++ b/crates/katana/storage/db/src/tables.rs @@ -288,11 +288,10 @@ mod tests { use katana_primitives::block::{BlockHash, BlockNumber, FinalityStatus, Header}; use katana_primitives::class::{ClassHash, CompiledClass, CompiledClassHash}; use katana_primitives::contract::{ContractAddress, GenericContractInfo}; - use katana_primitives::fee::TxFeeInfo; + use katana_primitives::fee::{PriceUnit, TxFeeInfo}; use katana_primitives::receipt::{InvokeTxReceipt, Receipt}; use katana_primitives::trace::TxExecInfo; use katana_primitives::transaction::{InvokeTx, Tx, TxHash, TxNumber}; - use starknet::core::types::PriceUnit; use starknet::macros::felt; use crate::codecs::{Compress, Decode, Decompress, Encode}; diff --git a/crates/katana/storage/provider/src/providers/db/mod.rs b/crates/katana/storage/provider/src/providers/db/mod.rs index 20d38c5e69..92f6ea1a0f 100644 --- a/crates/katana/storage/provider/src/providers/db/mod.rs +++ b/crates/katana/storage/provider/src/providers/db/mod.rs @@ -783,12 +783,11 @@ mod tests { Block, BlockHashOrNumber, FinalityStatus, Header, SealedBlockWithStatus, }; use katana_primitives::contract::ContractAddress; - use katana_primitives::fee::TxFeeInfo; + use katana_primitives::fee::{PriceUnit, TxFeeInfo}; use katana_primitives::receipt::{InvokeTxReceipt, Receipt}; use katana_primitives::state::{StateUpdates, StateUpdatesWithDeclaredClasses}; use katana_primitives::trace::TxExecInfo; use katana_primitives::transaction::{InvokeTx, Tx, TxHash, TxWithHash}; - use starknet::core::types::PriceUnit; use starknet::macros::felt; use super::DbProvider; diff --git a/crates/katana/storage/provider/tests/utils.rs b/crates/katana/storage/provider/tests/utils.rs index 8b552a107a..c3aafbfdf1 100644 --- a/crates/katana/storage/provider/tests/utils.rs +++ b/crates/katana/storage/provider/tests/utils.rs @@ -1,10 +1,9 @@ use katana_primitives::block::{Block, BlockHash, FinalityStatus, Header, SealedBlockWithStatus}; -use katana_primitives::fee::TxFeeInfo; +use katana_primitives::fee::{PriceUnit, TxFeeInfo}; use katana_primitives::receipt::{InvokeTxReceipt, Receipt}; use katana_primitives::trace::TxExecInfo; use katana_primitives::transaction::{InvokeTx, Tx, TxHash, TxWithHash}; use katana_primitives::Felt; -use starknet::core::types::PriceUnit; pub fn generate_dummy_txs_and_receipts( count: usize, diff --git a/crates/saya/provider/src/rpc/mod.rs b/crates/saya/provider/src/rpc/mod.rs index 606efaa683..53342ed35a 100644 --- a/crates/saya/provider/src/rpc/mod.rs +++ b/crates/saya/provider/src/rpc/mod.rs @@ -8,6 +8,7 @@ use jsonrpsee::http_client::HttpClientBuilder; use katana_primitives::block::{BlockIdOrTag, BlockNumber, GasPrices, Header, SealedBlock}; use katana_primitives::chain::ChainId; use katana_primitives::conversion::rpc as rpc_converter; +use katana_primitives::da::L1DataAvailabilityMode; use katana_primitives::state::StateUpdatesWithDeclaredClasses; use katana_primitives::transaction::TxWithHash; use katana_primitives::version::ProtocolVersion; @@ -104,7 +105,14 @@ impl Provider for JsonRpcProvider { block.l1_data_gas_price.price_in_wei.to_u128().unwrap(), block.l1_data_gas_price.price_in_fri.to_u128().unwrap(), ), - l1_da_mode: block.l1_da_mode, + l1_da_mode: match block.l1_da_mode { + starknet::core::types::L1DataAvailabilityMode::Blob => { + L1DataAvailabilityMode::Blob + } + starknet::core::types::L1DataAvailabilityMode::Calldata => { + L1DataAvailabilityMode::Calldata + } + }, timestamp: block.timestamp, state_root: block.new_root, sequencer_address: block.sequencer_address.into(), diff --git a/crates/saya/provider/src/rpc/transaction.rs b/crates/saya/provider/src/rpc/transaction.rs index 4632975ed8..2550040adc 100644 --- a/crates/saya/provider/src/rpc/transaction.rs +++ b/crates/saya/provider/src/rpc/transaction.rs @@ -1,5 +1,7 @@ //! Transactions related conversions. use katana_primitives::chain::ChainId; +use katana_primitives::da::DataAvailabilityMode; +use katana_primitives::fee::{ResourceBounds, ResourceBoundsMapping}; use katana_primitives::transaction::{ DeclareTx, DeclareTxV1, DeclareTxV2, DeclareTxV3, DeployAccountTx, DeployAccountTxV1, DeployAccountTxV3, InvokeTx, InvokeTxV1, InvokeTxV3, L1HandlerTx, Tx, TxWithHash, @@ -45,12 +47,12 @@ pub fn tx_from_rpc(tx_rpc: &Transaction, chain_id: ChainId) -> ProviderResult ProviderResult ProviderResult ProviderResult DataAvailabilityMode { + match mode { + starknet::core::types::DataAvailabilityMode::L1 => DataAvailabilityMode::L1, + starknet::core::types::DataAvailabilityMode::L2 => DataAvailabilityMode::L2, + } +} + +fn from_rpc_resource_bounds( + rpc_bounds: starknet::core::types::ResourceBoundsMapping, +) -> ResourceBoundsMapping { + ResourceBoundsMapping { + l1_gas: ResourceBounds { + max_amount: rpc_bounds.l1_gas.max_amount, + max_price_per_unit: rpc_bounds.l1_gas.max_price_per_unit, + }, + l2_gas: ResourceBounds { + max_amount: rpc_bounds.l2_gas.max_amount, + max_price_per_unit: rpc_bounds.l2_gas.max_price_per_unit, + }, + } +} diff --git a/spawn-and-move-db.tar.gz b/spawn-and-move-db.tar.gz index 8a26c58a2a..8fc827921b 100644 Binary files a/spawn-and-move-db.tar.gz and b/spawn-and-move-db.tar.gz differ diff --git a/types-test-db.tar.gz b/types-test-db.tar.gz index db63053e92..f1894f1b36 100644 Binary files a/types-test-db.tar.gz and b/types-test-db.tar.gz differ