From 8c65570bd8309e3f21f05c74f2f5fb3543755718 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Sun, 2 Jun 2024 17:29:23 +0530 Subject: [PATCH 1/2] feat: L1 gas price/fix (#1625) Co-authored-by: Arun Jangra Co-authored-by: apoorvsadana <95699312+apoorvsadana@users.noreply.github.com> --- CHANGELOG.md | 2 + crates/client/l1-gas-price/src/types.rs | 2 +- crates/client/l1-gas-price/src/worker.rs | 12 ++-- crates/node/src/service.rs | 32 +++++---- .../articles/cn/madara-beast-article.md | 71 ++++++++++--------- docs/contributor-starter-pack.md | 53 +++++++------- examples/messaging/eth-config.json | 2 +- 7 files changed, 100 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 968c80d9d4..d789a4d79b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +- feat: L1 gas price/fix + ## v0.8.0 - feat: add `TransactionFilter` to pallet-starknet `Config` diff --git a/crates/client/l1-gas-price/src/types.rs b/crates/client/l1-gas-price/src/types.rs index d867acb28d..7257f6bf8a 100644 --- a/crates/client/l1-gas-price/src/types.rs +++ b/crates/client/l1-gas-price/src/types.rs @@ -29,7 +29,7 @@ pub struct FeeHistory { /// of the returned range, because this value can be derived from the newest block. Zeroes /// are returned for pre-EIP-4844 blocks. #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub base_fee_per_blob_gas: Vec, + pub base_fee_per_blob_gas: Vec, /// An array of block blob gas used ratios. These are calculated as the ratio of gasUsed and /// gasLimit. #[serde(default, skip_serializing_if = "Vec::is_empty")] diff --git a/crates/client/l1-gas-price/src/worker.rs b/crates/client/l1-gas-price/src/worker.rs index 2198c7d639..c90a91f71e 100644 --- a/crates/client/l1-gas-price/src/worker.rs +++ b/crates/client/l1-gas-price/src/worker.rs @@ -69,10 +69,14 @@ async fn update_gas_price( // The RPC responds with 301 elements for some reason. It's also just safer to manually // take the last 300. We choose 300 to get average gas caprice for last one hour (300 * 12 sec block // time). - let (_, blob_fee_history_one_hour) = - fee_history.result.base_fee_per_blob_gas.split_at(fee_history.result.base_fee_per_blob_gas.len() - 300); - - let avg_blob_base_fee = blob_fee_history_one_hour.iter().sum::() / blob_fee_history_one_hour.len() as u128; + let (_, blob_fee_history_one_hour) = fee_history + .result + .base_fee_per_blob_gas + .split_at(fee_history.result.base_fee_per_blob_gas.len().max(300) - 300); + + let avg_blob_base_fee = + blob_fee_history_one_hour.iter().map(|hex_str| u128::from_str_radix(&hex_str[2..], 16).unwrap()).sum::() + / blob_fee_history_one_hour.len() as u128; let eth_gas_price = u128::from_str_radix( fee_history diff --git a/crates/node/src/service.rs b/crates/node/src/service.rs index 08a016cce0..f3b8b11241 100644 --- a/crates/node/src/service.rs +++ b/crates/node/src/service.rs @@ -20,6 +20,7 @@ use mp_starknet_inherent::{ InherentDataProvider as StarknetInherentDataProvider, InherentError as StarknetInherentError, L1GasPrices, StarknetInherentData, DEFAULT_SEQUENCER_ADDRESS, SEQ_ADDR_STORAGE_KEY, }; +use pallet_starknet_runtime_api::StarknetRuntimeApi; use prometheus_endpoint::Registry; use sc_basic_authorship::ProposerFactory; use sc_client_api::{Backend, BlockBackend, BlockchainEvents, HeaderBackend}; @@ -33,7 +34,7 @@ use sc_telemetry::{Telemetry, TelemetryWorker}; use sc_transaction_pool::FullPool; use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_api::offchain::OffchainStorage; -use sp_api::ConstructRuntimeApi; +use sp_api::{ConstructRuntimeApi, ProvideRuntimeApi}; use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; use sp_offchain::STORAGE_PREFIX; @@ -346,18 +347,25 @@ pub fn new_full( ), ); - // Ensuring we've fetched the latest price before we start the node - futures::executor::block_on(mc_l1_gas_price::worker::run_worker( - ethereum_conf.clone(), - l1_gas_price.clone(), - false, - )); + let fees_disabled = client + .runtime_api() + .is_transaction_fee_disabled(client.chain_info().best_hash) + .expect("Failed to get fee status"); - task_manager.spawn_handle().spawn( - "l1-gas-prices-worker", - Some(MADARA_TASK_GROUP), - mc_l1_gas_price::worker::run_worker(ethereum_conf.clone(), l1_gas_price.clone(), true), - ); + if !fees_disabled { + // Ensuring we've fetched the latest price before we start the node + futures::executor::block_on(mc_l1_gas_price::worker::run_worker( + ethereum_conf.clone(), + l1_gas_price.clone(), + false, + )); + + task_manager.spawn_handle().spawn( + "l1-gas-prices-worker", + Some(MADARA_TASK_GROUP), + mc_l1_gas_price::worker::run_worker(ethereum_conf.clone(), l1_gas_price.clone(), true), + ); + } } } diff --git a/docs/content/articles/cn/madara-beast-article.md b/docs/content/articles/cn/madara-beast-article.md index 83ce33eca6..8586137585 100644 --- a/docs/content/articles/cn/madara-beast-article.md +++ b/docs/content/articles/cn/madara-beast-article.md @@ -30,30 +30,32 @@ 试想一下,为你的应用程序的特殊需求来量身定制一条区块链——这正是应用链可以提供的 功能。应用链是面向特定应用程序的区块链,开发人员可以灵活调整链的各个方面,从而满 -足能。应用链是面向特定应用程序的区块链,开发人员可以灵活调整链的各个方面,从而 +满足其应用的需求,例如选择不同的哈希函数或自定义共识算法。最棒的是,由于应用链建 立在L1 或 L2 区块链之上,可以继承其强大的安全性,为开发人员提供了两全其美的解决方案。 +-->L1 或 L2 区块链之上,可以继承其强大的安全性,为开发人员提供了两全其美的解决方 +案。 介绍下 Madara,这是一个将灵活性和极速性能相结合的划时代的排序器。排序器这一组件 负责执行交易并将它们分组到批次中。作为通往属于你的 Starknet 应用链的入口,Madara -为在责执行交易并将它们分组到批次中。作为通往属于你的 Starknet 应用链的入 +口,Madara 为在Starknet 生态系统中进行前所未有的实验开辟了广阔的可能性。 在我们深入探讨 Madara 如何为 Starknet 应用链带来强大的能力前,有必要解决一个问 题:为什么开发人员会选择在 Starknet 上构建应用链,而不是直接使用[Starknet 有效性 Rollups](https://starkware.co/resource/scaling-ethereum-navigating-the-blockchain-trilemma/#:~:text=top%20of%20them.-,Validity%20Rollups,-Validity%20rollups%2C%20also)。 -有人可能会想,Starknet 是否已经足以应对大多数情况。 +-->用[Starknet 有效性 Rollups](https://starkware.co/resource/scaling-ethereum-navigating-the-blockchain-trilemma/#:~:text=top%20of%20them.-,Validity%20Rollups,-Validity%20rollups%2C%20also)。有 +人可能会想,Starknet 是否已经足以应对大多数情况。 首先让我们了解下为什么应用链是 Starknet 生态系统中引人注目的扩展方式。 ## 为什么选择应用链 Madara 是由 StarkWare 探索团队,也称为[Keep Starknet Strange](https://github.com/keep-starknet-strange)开发的,专门为[Keep Starknet Strange](https://github.com/keep-starknet-strange)开发的,专 +门设计用于实现 StarkWare的[分形缩放](https://medium.com/starkware/fractal-scaling-from-l2-to-l3-7fe238ecfb4f)愿景。有许多令人信服的原因让开发人员选择创建一个 Starknet 应用链或 L3,而不是直 @@ -68,22 +70,23 @@ Madara 是由 StarkWare 探索团队,也称的整体成本,最高可达一百万倍。由于应用程序建立在其专用区块链上,从而无需与其 他应用竞争链上资源,吞吐量不受第三方应用活动的影响,这确保了持续平稳的流畅体验。 +-->应用竞争链上资源,吞吐量不受第三方应用活动的影响,这确保了持续平稳的流畅体 +验。 ### 定制化 像 Starknet 和 Ethereum 等通用链采取了多项措施来确保网络对所有人可用,但这导致了 一种受限的环境。通过应用链,开发人员可以微调其应用和基础设施的各个方面,创建量身定 -制受限的环境。通过应用链,开发人员可以微调其应用和基础设施的各个方面,创建量身 +定制的解决方案。不喜欢 Cairo VM 的某个特性?可以在你的应用链中将其排除掉。 ### 创新 应用链的可定制性还允许开发人员可以使用目前在 Starknet 中不可用或存在风险的功能。 应用链赋予每个团队自主权,允许他们编写和授权任何所需的代码 hints。这使得应用链能 -够用链赋予每个团队自主权,允许他们编写和授权任何所需的代码 hints。这使得应用链 +能够解锁许多用例,譬如可以在不泄露个人隐私的情况下执行链上 KYC。 ## Madara 对应用链堆栈的影响 @@ -92,31 +95,33 @@ Madara 是由 StarkWare 探索团队,也称包(StarkWare 的 [blockifier](https://github.com/starkware-libs/blockifier)包(StarkWare 的 + [blockifier](https://github.com/starkware-libs/blockifier)和 LambdaClass 的[starknet_in_rust](https://github.com/lambdaclass/starknet_in_rust))之间切 - 换的灵活性。无论选择了哪个执行工具包,底层框架都使用 Cairo VM。Cairo 语言有助于 - 创建可证明的程序,这样就能证明计算被正确执行。 + -->[starknet_in_rust](https://github.com/lambdaclass/starknet_in_rust))之间 + 切换的灵活性。无论选择了哪个执行工具包,底层框架都使用 Cairo VM。Cairo 语言有 + 助于创建可证明的程序,这样就能证明计算被正确执行。 2. **结算:** 作为有效性 Rollup,Madara 应用链的状态可以仅通过检查其结算层来重 建。通过在 Starknet L2 上更频繁的结算,L3 应用链可以实现更快的硬最终性,而去 中心化的排序层实现更强大的软最终性,因此,在这两方面(硬和软终结性),结算都得到了增排序层实现更强大的软最终性,因此,在这两方面(硬和软终结性),结算都得到了 + 增强。 3. **排序:** Madara 负责排序过程,可以根据应用的需求进行调整,无论是简单的 FCFS 或PGA,还是像 Narwhall 和 Bullshark 这类更复杂的方案。一些应用链可以选择部署加 - 密内PGA,还是像 Narwhall 和 Bullshark 这类更复杂的方案。一些应用链可以选择部署 + 加密内存池,以确保公平排序并减轻 MEV 的影响。 4. **数据可用性:** 数据可用性保证始终可访问完整的状态树,借此向用户提供信心, 即使 Madara 发生故障的情况下,他们也能证明自己拥有资产的所有权。Madara 将为开 - 发者使 Madara 发生故障的情况下,他们也能证明自己拥有资产的所有权。Madara 将为 + 开发者提供多种可供选择的数据可用性方案。 5. **治理:** 每个 Madara 应用链可以选择其治理模 型。[Snapshot X](https://twitter.com/SnapshotLabs)提供了一个依赖于存储证明 并完全基于链上的治理系统。其他治理机制也在探索中,譬如原生的 Substrate 治理面 - 板。链上治理是 Madara 的核心价值所在。 + -->完全基于链上的治理系统。其他治理机制也在探索中,譬如原生的 Substrate 治理 + 面板。链上治理是 Madara 的核心价值所在。 ![come come](https://lh4.googleusercontent.com/i7bXi2IPV-LTLzEgueA2SPHGULUFDj1OX4IznOQr5BeZe0hcey-VXA5TOV6q9XaVqBGAcYiie7u7uxw7q1ByZxjkPQKHERqKJTxhdDdTSgBQy8smyNO3jEHiNJv7Eqh8BMxjj4fFlQAW6gm-hQMzyIU) @@ -124,25 +129,27 @@ Madara 是由 StarkWare 探索团队,也称约,从而增强了 Cairo VM。Substrate 是一个开源 Rust 框架,以其灵活性而闻名,并用 -于构约,从而增强了 Cairo VM。Substrate 是一个开源 Rust 框架,以其灵活性而闻名,并 +用于构建可定制的区块链。与此同时,Cairo VM 专门设计用于高效生成程序执行的有效性证 明。通过在 L2 上使用状态跟踪和智能合约来验证这些证明,应用链确保集成了 Starknet 的安 -全性。这样,Madara 利用 Cairo 的强大功能实现了程序执行的可证明性。 +-->过在 L2 上使用状态跟踪和智能合约来验证这些证明,应用链确保集成了 Starknet 的 +安全性。这样,Madara 利用 Cairo 的强大功能实现了程序执行的可证明性。 Substrate 框架固有的模块化特性使开发者可以轻松地定制应用链。没有任何强加的假设, 允许你自行整合共识协议、哈希函数、签名方案、存储布局 - 无论你的应用需要什么, 都可以利用 Cairo 来生成证明。无论是 Starknet 还是 Ethereum 上,开发者都可以在继承 -底层链可以利用 Cairo 来生成证明。无论是 Starknet 还是 Ethereum 上,开发者都可以在继 +承底层链安全性的同时,不受限制的操作,并可被证明。 起初,Madara 将与 Starknet 非常相似,使智能合约可以在 Starknet 生态系统内进行组 合。未来将有更宏伟的计划,因为 Starknet 将与[Herodotus](https://www.herodotus.dev/)集来将有更宏伟的计划,因为 Starknet 将 +与[Herodotus](https://www.herodotus.dev/)集成,利用 [存储证明](https://book.starknet.io/chapter_8/storage_proofs.html)实 现互操作性。存储证明的整合还将使 Madara 应用链能够考虑来自其他链的状态和流动性。 +-->互操作性。存储证明的整合还将使 Madara 应用链能够考虑来自其他链的状态和流动 +性。 准备好见证由 Madara 开启的 Starknet 新纪元吧。 diff --git a/docs/contributor-starter-pack.md b/docs/contributor-starter-pack.md index 83f54eb29c..ff233d3d3a 100644 --- a/docs/contributor-starter-pack.md +++ b/docs/contributor-starter-pack.md @@ -41,25 +41,26 @@ are some key aspects of the mindset that can help you navigate your contribution journey: - _Openness to Learning_\ - Embrace a mindset of continuous learning and be open to acquiring new knowledge - and skills. Starknet is a recent ecosystem and does have its own unique concepts - and principles. Stay curious, ask questions (there are no dumb questions), and - be willing to explore and understand new concepts. + Embrace a mindset of continuous learning and be open to acquiring new + knowledge and skills. Starknet is a recent ecosystem and does have its own + unique concepts and principles. Stay curious, ask questions (there are no dumb + questions), and be willing to explore and understand new concepts. - _Patience and Perseverance_\ - Contributing to a complex or quickly evolving project takes time and effort. Be - patient with yourself and the learning process. Expect challenges along the way, - but persevere through them. Building expertise and making meaningful contributions - often requires persistence and determination. + Contributing to a complex or quickly evolving project takes time and effort. + Be patient with yourself and the learning process. Expect challenges along the + way, but persevere through them. Building expertise and making meaningful + contributions often requires persistence and determination. - _Collaboration and Communication_\ - Engage with the community, ask for guidance when needed, and seek feedback on your - contributions. Actively participate in GitHub discussions, issues or chat channels. - Be respectful and constructive with other builders. + Engage with the community, ask for guidance when needed, and seek feedback on + your contributions. Actively participate in GitHub discussions, issues or chat + channels. Be respectful and constructive with other builders. - _Respect for Existing Contributors_\ - Recognize and respect the work of existing contributors and maintainers. Appreciate - the efforts of others and collaborate with them in a respectful and inclusive manner. + Recognize and respect the work of existing contributors and maintainers. + Appreciate the efforts of others and collaborate with them in a respectful and + inclusive manner. With this mindset, you'll participate to Madara and Starknet projects in a collaborative and productive atmosphere. It's not everything about code but also @@ -82,7 +83,8 @@ some valuable and helpful resources. [The Rust Programming Language Book](https://doc.rust-lang.org/book/): read this first\ -[Rust by Example](https://doc.rust-lang.org/rust-by-example/): practical approach\ +[Rust by Example](https://doc.rust-lang.org/rust-by-example/): practical +approach\ [Rustlings](https://github.com/rust-lang/rustlings): Educative and interactive learning @@ -146,17 +148,19 @@ build. Some key features of Substrate are: - _Modular Framework_\ - Substrate provides a modular framework that allows developers to easily customize - and configure various components of a blockchain network. + Substrate provides a modular framework that allows developers to easily + customize and configure various components of a blockchain network. - _Efficiency and Scalability_\ - Substrate leverages advanced techniques such as in its transaction queue management - to ensure high performance and the ability to handle a large number of transactions. + Substrate leverages advanced techniques such as in its transaction queue + management to ensure high performance and the ability to handle a large number + of transactions. - _Runtime Upgradability_\ - Substrate allows for seamless runtime upgrades, enabling the introduction of new - features or bug fixes in a live blockchain network without requiring a hard fork. - This feature enhances the upgradability and maintainability of the blockchain system. + Substrate allows for seamless runtime upgrades, enabling the introduction of + new features or bug fixes in a live blockchain network without requiring a + hard fork. This feature enhances the upgradability and maintainability of the + blockchain system. Substrate achieves its modularity through three key components: the **client**, the **runtime**, and the **primitives**. Those are key concepts of Substrate @@ -283,7 +287,8 @@ organized and executed in a secure and deterministic manner. You can find Madara documentation (work in progress) [here](https://docs.madara.wtf/).\ -You can contribute to this documentation [here](https://github.com/keep-starknet-strange/madara-docs). +You can contribute to this documentation +[here](https://github.com/keep-starknet-strange/madara-docs). How to contribute? @@ -310,8 +315,8 @@ future of Ethereum scaling! guide](https://docs.github.com/en/get-started/quickstart/hello-world)\ [Madara GitHub repository](https://github.com/keep-starknet-strange/madara)\ [Madara Telegram](https://t.me/MadaraStarknet)\ -[Starknet Discord](https://discord.gg/qypnmzkhbc) (Or search for Starknet in discord's -servers browser) +[Starknet Discord](https://discord.gg/qypnmzkhbc) (Or search for Starknet in +discord's servers browser) ## Contribution rewards on OnlyDust diff --git a/examples/messaging/eth-config.json b/examples/messaging/eth-config.json index 5657dfa26a..b1b997e40f 100644 --- a/examples/messaging/eth-config.json +++ b/examples/messaging/eth-config.json @@ -1,6 +1,6 @@ { "provider": { - "rpc_endpoint": "https://eth.merkle.io", + "rpc_endpoint": "http://127.0.0.1:8545", "gas_price_poll_ms": 10000 }, "contracts": { From 280615b224554401811ea2f24cd48275c7a03572 Mon Sep 17 00:00:00 2001 From: Gerson <71728860+Gerson2102@users.noreply.github.com> Date: Tue, 4 Jun 2024 13:55:59 -0600 Subject: [PATCH 2/2] test: adding tests for all transactions v3 (#1607) --- CHANGELOG.md | 1 + .../pallets/starknet/src/tests/declare_tx.rs | 70 +++++++++++++++++- .../starknet/src/tests/deploy_account_tx.rs | 72 +++++++++++++++++- .../pallets/starknet/src/tests/invoke_tx.rs | 74 ++++++++++++++++++- crates/pallets/starknet/src/tests/utils.rs | 2 +- package-lock.json | 19 +++-- package.json | 4 +- 7 files changed, 224 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d789a4d79b..194890f5d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Next release +- test: Adding txv3 tests - feat: L1 gas price/fix ## v0.8.0 diff --git a/crates/pallets/starknet/src/tests/declare_tx.rs b/crates/pallets/starknet/src/tests/declare_tx.rs index 1103be3a77..538868b00b 100644 --- a/crates/pallets/starknet/src/tests/declare_tx.rs +++ b/crates/pallets/starknet/src/tests/declare_tx.rs @@ -9,19 +9,60 @@ use sp_runtime::transaction_validity::{ InvalidTransaction, TransactionSource, TransactionValidityError, ValidTransaction, }; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce, PatriciaKey}; +use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::hash::StarkFelt; use starknet_api::transaction::{ - DeclareTransaction as StarknetApiDeclareTransaction, DeclareTransactionV0V1, DeclareTransactionV2, Fee, - TransactionSignature, + DeclareTransaction as StarknetApiDeclareTransaction, DeclareTransactionV0V1, DeclareTransactionV2, + DeclareTransactionV3, Fee, TransactionSignature, }; use starknet_crypto::FieldElement; use super::mock::default_mock::*; use super::mock::*; -use super::utils::{get_contract_class, sign_message_hash}; +use super::utils::{create_resource_bounds, get_contract_class, sign_message_hash}; use crate::tests::{set_infinite_tokens, set_nonce}; use crate::Error; +fn create_declare_erc20_v3_transaction( + chain_id: Felt252Wrapper, + account_type: AccountType, + sender_address: Option, + signature: Option, + nonce: Option, +) -> BlockifierDeclareTransaction { + let sender_address = sender_address.unwrap_or_else(|| get_account_address(None, account_type)); + let erc20_class = get_contract_class("erc20.casm.json", 1); + let erc20_class_hash = + ClassHash(StarkFelt::try_from("0x057eca87f4b19852cfd4551cf4706ababc6251a8781733a0a11cf8e94211da95").unwrap()); + + let compiled_erc20_class_hash = CompiledClassHash( + StarkFelt::try_from("0x00df4d3042eec107abe704619f13d92bbe01a58029311b7a1886b23dcbb4ea87").unwrap(), + ); + + let mut tx = StarknetApiDeclareTransaction::V3(DeclareTransactionV3 { + resource_bounds: create_resource_bounds(), + tip: starknet_api::transaction::Tip::default(), + signature: TransactionSignature::default(), + nonce: nonce.unwrap_or_default(), + class_hash: erc20_class_hash, + compiled_class_hash: compiled_erc20_class_hash, + sender_address, + nonce_data_availability_mode: DataAvailabilityMode::L1, + fee_data_availability_mode: DataAvailabilityMode::L1, + paymaster_data: starknet_api::transaction::PaymasterData(vec![]), + account_deployment_data: starknet_api::transaction::AccountDeploymentData(vec![]), + }); + + let tx_hash = tx.compute_hash(chain_id, false); + // Force to do that because ComputeTransactionHash cannot be implemented on DeclareTransactionV0V1 + // directly... + if let StarknetApiDeclareTransaction::V3(tx) = &mut tx { + tx.signature = signature.unwrap_or_else(|| sign_message_hash(tx_hash)); + } + + BlockifierDeclareTransaction::new(tx, tx_hash, ClassInfo::new(&erc20_class, 1, 1).unwrap()).unwrap() +} + fn create_declare_erc20_v1_transaction( chain_id: Felt252Wrapper, account_type: AccountType, @@ -395,3 +436,26 @@ fn test_declare_using_transaction_v0() { assert!(Starknet::validate_unsigned(TransactionSource::InBlock, &crate::Call::declare { transaction }).is_ok()); }); } + +#[test] +fn given_contract_declare_tx3_than_works() { + new_test_ext::().execute_with(|| { + basic_test_setup(2); + + let none_origin = RuntimeOrigin::none(); + let chain_id = Starknet::chain_id(); + + let transaction = create_declare_erc20_v3_transaction( + chain_id, + AccountType::V1(AccountTypeV1Inner::NoValidate), + None, + None, + None, + ); + let class_hash = transaction.class_hash(); + let contract_class = transaction.contract_class(); + + assert_ok!(Starknet::declare(none_origin.clone(), transaction.clone())); + assert_eq!(Starknet::contract_class_by_class_hash(class_hash.0).unwrap(), contract_class); + }); +} diff --git a/crates/pallets/starknet/src/tests/deploy_account_tx.rs b/crates/pallets/starknet/src/tests/deploy_account_tx.rs index 149d89f881..3d00ef498a 100644 --- a/crates/pallets/starknet/src/tests/deploy_account_tx.rs +++ b/crates/pallets/starknet/src/tests/deploy_account_tx.rs @@ -7,17 +7,18 @@ use mp_transactions::compute_hash::ComputeTransactionHash; use sp_runtime::traits::ValidateUnsigned; use sp_runtime::transaction_validity::{InvalidTransaction, TransactionSource, TransactionValidityError}; use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress, Nonce}; +use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::hash::StarkFelt; use starknet_api::transaction::{ - Calldata, ContractAddressSalt, DeployAccountTransactionV1, Event as StarknetEvent, EventContent, EventData, - EventKey, Fee, TransactionSignature, + Calldata, ContractAddressSalt, DeployAccountTransactionV1, DeployAccountTransactionV3, Event as StarknetEvent, + EventContent, EventData, EventKey, Fee, TransactionSignature, }; use starknet_core::utils::get_selector_from_name; use starknet_crypto::FieldElement; use super::mock::default_mock::*; use super::mock::*; -use super::utils::{sign_message_hash, sign_message_hash_braavos}; +use super::utils::{create_resource_bounds, sign_message_hash, sign_message_hash_braavos}; use crate::tests::constants::{ACCOUNT_PUBLIC_KEY, SALT, TRANSFER_SELECTOR_NAME}; use crate::tests::{get_deploy_account_dummy, set_infinite_tokens, set_nonce}; use crate::{Error, StorageView}; @@ -42,6 +43,26 @@ fn deploy_v1_to_blockifier_deploy( ) } +fn deploy_v3_to_blockifier_deploy( + tx: DeployAccountTransactionV3, + chain_id: Felt252Wrapper, +) -> DeployAccountTransaction { + let tx_hash = tx.compute_hash(chain_id, false); + let contract_address = calculate_contract_address( + tx.contract_address_salt, + tx.class_hash, + &tx.constructor_calldata, + Default::default(), + ) + .unwrap(); + + DeployAccountTransaction::new( + starknet_api::transaction::DeployAccountTransaction::V3(tx), + tx_hash, + contract_address, + ) +} + fn helper_create_deploy_account_tx( chain_id: Felt252Wrapper, salt: ContractAddressSalt, @@ -60,6 +81,28 @@ fn helper_create_deploy_account_tx( deploy_v1_to_blockifier_deploy(tx, chain_id) } +fn helper_create_deploy_account_tx3( + chain_id: Felt252Wrapper, + salt: ContractAddressSalt, + calldata: Calldata, + account_class_hash: ClassHash, +) -> DeployAccountTransaction { + let tx = DeployAccountTransactionV3 { + resource_bounds: create_resource_bounds(), + tip: starknet_api::transaction::Tip::default(), + signature: TransactionSignature::default(), + nonce: Nonce(StarkFelt::ZERO), + class_hash: account_class_hash, + contract_address_salt: salt, + constructor_calldata: calldata, + nonce_data_availability_mode: DataAvailabilityMode::L1, + fee_data_availability_mode: DataAvailabilityMode::L1, + paymaster_data: starknet_api::transaction::PaymasterData(vec![]), + }; + + deploy_v3_to_blockifier_deploy(tx, chain_id) +} + #[test] fn given_contract_run_deploy_account_tx_works() { new_test_ext::().execute_with(|| { @@ -509,3 +552,26 @@ fn test_verify_nonce_in_unsigned_tx() { ); }); } + +#[test] +fn given_contract_run_deploy_account_tx3_works() { + new_test_ext::().execute_with(|| { + basic_test_setup(2); + let none_origin = RuntimeOrigin::none(); + let chain_id = Starknet::chain_id(); + // TEST ACCOUNT CONTRACT + // - ref testnet tx(0x0751b4b5b95652ad71b1721845882c3852af17e2ed0c8d93554b5b292abb9810) + let salt = ContractAddressSalt( + StarkFelt::try_from("0x03b37cbe4e9eac89d54c5f7cc6329a63a63e8c8db2bf936f981041e086752463").unwrap(), + ); + let (account_class_hash, calldata) = account_helper(AccountType::V0(AccountTypeV0Inner::NoValidate)); + + let deploy_tx = helper_create_deploy_account_tx3(chain_id, salt, calldata, account_class_hash); + let contract_address = deploy_tx.contract_address; + + set_infinite_tokens::(&contract_address); + + assert_ok!(Starknet::deploy_account(none_origin, deploy_tx)); + assert_eq!(Starknet::contract_class_hash_by_address(contract_address), account_class_hash.0); + }); +} diff --git a/crates/pallets/starknet/src/tests/invoke_tx.rs b/crates/pallets/starknet/src/tests/invoke_tx.rs index 22c99e3a02..0e0a370e1e 100644 --- a/crates/pallets/starknet/src/tests/invoke_tx.rs +++ b/crates/pallets/starknet/src/tests/invoke_tx.rs @@ -12,6 +12,7 @@ use sp_runtime::transaction_validity::{ InvalidTransaction, TransactionSource, TransactionValidityError, ValidTransaction, }; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce, PatriciaKey}; +use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::hash::StarkFelt; use starknet_api::state::StorageKey; use starknet_api::transaction::{ @@ -28,7 +29,8 @@ use super::constants::{ use super::mock::default_mock::*; use super::mock::*; use super::utils::{ - get_balance_contract_call, get_contract_class, set_account_erc20_balance_to_zero, sign_message_hash, + create_resource_bounds, get_balance_contract_call, get_contract_class, set_account_erc20_balance_to_zero, + sign_message_hash, }; use crate::tests::constants::{UDC_ADDRESS, UDC_SELECTOR}; use crate::tests::{ @@ -903,3 +905,73 @@ fn given_hardcoded_contract_set_erc20_balance_to_zero() { ); }); } + +#[test] +fn given_hardcoded_contract_run_invoke_tx_v3_with_inner_call_in_validate_then_it_fails() { + new_test_ext::().execute_with(|| { + basic_test_setup(2); + let none_origin = RuntimeOrigin::none(); + + let sender_address = get_account_address(None, AccountType::V0(AccountTypeV0Inner::InnerCall)); + let mut transaction = get_invoke_v3_dummy(Starknet::chain_id(), NONCE_ZERO); + if let starknet_api::transaction::InvokeTransaction::V3(tx) = &mut transaction.tx { + tx.signature = TransactionSignature(vec![StarkFelt::ONE, StarkFelt::ONE]); + tx.sender_address = sender_address; + }; + + let storage_key = get_storage_var_address("destination", &[]); + let destination = StarkFelt::try_from(TEST_CONTRACT_ADDRESS).unwrap(); + StorageView::::insert((sender_address, storage_key), destination); + + let storage_key = get_storage_var_address("function_selector", &[]); + let selector = get_selector_from_name("without_arg").unwrap(); + StorageView::::insert( + (sender_address, storage_key), + StarkFelt::from(Felt252Wrapper::from(selector)), + ); + + assert_err!(Starknet::invoke(none_origin, transaction), Error::::TransactionExecutionFailed); + }); +} + +#[test] +fn given_account_not_deployed_invoke_tx_v3_fails_for_nonce_not_one() { + new_test_ext::().execute_with(|| { + basic_test_setup(2); + + // Wrong address (not deployed) + let contract_address = ContractAddress(PatriciaKey(StarkFelt::try_from("0x13123131").unwrap())); + + let transaction = starknet_api::transaction::InvokeTransactionV3 { + resource_bounds: create_resource_bounds(), + tip: starknet_api::transaction::Tip::default(), + calldata: Calldata::default(), + sender_address: contract_address, + nonce: Nonce(StarkFelt::ZERO), + signature: TransactionSignature::default(), + nonce_data_availability_mode: DataAvailabilityMode::L1, + fee_data_availability_mode: DataAvailabilityMode::L1, + paymaster_data: starknet_api::transaction::PaymasterData(vec![]), + account_deployment_data: starknet_api::transaction::AccountDeploymentData(vec![StarkFelt::ZERO]), + }; + + assert_eq!( + Starknet::validate_unsigned( + TransactionSource::InBlock, + &crate::Call::invoke { transaction: transaction.into() } + ), + Err(TransactionValidityError::Invalid(InvalidTransaction::BadProof)) + ); + }) +} + +#[test] +fn given_hardcoded_contract_run_invoke_tx3_then_it_works() { + new_test_ext::().execute_with(|| { + basic_test_setup(2); + + let transaction = get_invoke_v3_dummy(Starknet::chain_id(), NONCE_ZERO); + + assert_ok!(Starknet::invoke(RuntimeOrigin::none(), transaction)); + }); +} diff --git a/crates/pallets/starknet/src/tests/utils.rs b/crates/pallets/starknet/src/tests/utils.rs index e2c83b1f63..82f82bd747 100644 --- a/crates/pallets/starknet/src/tests/utils.rs +++ b/crates/pallets/starknet/src/tests/utils.rs @@ -121,7 +121,7 @@ pub fn create_resource_bounds() -> starknet_api::transaction::ResourceBoundsMapp let mut map = BTreeMap::new(); map.insert( starknet_api::transaction::Resource::L1Gas, - starknet_api::transaction::ResourceBounds { max_amount: 10000, max_price_per_unit: 12000 }, + starknet_api::transaction::ResourceBounds { max_amount: 150000, max_price_per_unit: 12000 }, ); map.insert( starknet_api::transaction::Resource::L2Gas, diff --git a/package-lock.json b/package-lock.json index cccf518445..a75dfcab63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,14 +4,16 @@ "requires": true, "packages": { "": { - "dependencies": { - "prettier": "^3.2.5" + "devDependencies": { + "prettier": "3.3.0" } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", + "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", + "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -25,9 +27,10 @@ }, "dependencies": { "prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", + "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", + "dev": true } } } diff --git a/package.json b/package.json index edf7bed5f0..d85dc9d614 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "dependencies": { - "prettier": "^3.2.5" + "devDependencies": { + "prettier": "3.3.0" } }