From d226c414c7ec4329fc05320b40246a72263983a5 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Wed, 24 Sep 2025 11:39:06 +0200 Subject: [PATCH 01/10] feat: ink_revive crate --- Cargo.lock | 34 +++- Cargo.toml | 3 + crates/e2e/Cargo.toml | 3 +- crates/e2e/sandbox/Cargo.toml | 2 + crates/revive/Cargo.toml | 41 ++++ crates/revive/src/evm.rs | 87 +++++++++ crates/revive/src/hex_serde.rs | 85 +++++++++ crates/revive/src/lib.rs | 9 + crates/revive/src/primitives.rs | 176 ++++++++++++++++++ .../sol-cross-contract/Cargo.toml | 2 +- .../sol-cross-contract/e2e_tests.rs | 8 +- .../solidity-abi/sol-encoding/Cargo.toml | 2 +- .../solidity-abi/sol-encoding/e2e_tests.rs | 10 +- 13 files changed, 445 insertions(+), 17 deletions(-) create mode 100644 crates/revive/Cargo.toml create mode 100644 crates/revive/src/evm.rs create mode 100644 crates/revive/src/hex_serde.rs create mode 100644 crates/revive/src/lib.rs create mode 100644 crates/revive/src/primitives.rs diff --git a/Cargo.lock b/Cargo.lock index 60c18bf98bb..eb4bed07265 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1224,9 +1224,9 @@ dependencies = [ [[package]] name = "blst" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fd49896f12ac9b6dcd7a5998466b9b58263a695a3dd1ecc1aaca2e12a90b080" +checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45" dependencies = [ "cc", "glob", @@ -1336,9 +1336,9 @@ dependencies = [ [[package]] name = "c-kzg" -version = "2.1.1" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7318cfa722931cb5fe0838b98d3ce5621e75f6a6408abc21721d80de9223f2e4" +checksum = "137a2a2878ed823ef1bd73e5441e245602aae5360022113b8ad259ca4b5b8727" dependencies = [ "blst", "cc", @@ -1538,7 +1538,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -2346,7 +2346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.0", + "windows-sys 0.60.2", ] [[package]] @@ -3485,6 +3485,7 @@ dependencies = [ "ink_e2e_macro", "ink_env", "ink_primitives 6.0.0-alpha.4", + "ink_revive", "ink_sandbox", "itertools 0.14.0", "jsonrpsee", @@ -3713,6 +3714,20 @@ dependencies = [ "xxhash-rust", ] +[[package]] +name = "ink_revive" +version = "6.0.0-alpha.4" +dependencies = [ + "alloy-core", + "frame-support", + "ink_primitives 6.0.0-alpha.4", + "pallet-revive-uapi", + "parity-scale-codec", + "scale-info", + "serde", + "sp-runtime", +] + [[package]] name = "ink_sandbox" version = "6.0.0-alpha.4" @@ -3721,6 +3736,7 @@ dependencies = [ "frame-support", "frame-system", "ink_primitives 6.0.0-alpha.4", + "ink_revive", "pallet-balances", "pallet-revive", "pallet-timestamp", @@ -5836,7 +5852,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.0", + "windows-sys 0.60.2", ] [[package]] @@ -7847,7 +7863,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.61.0", + "windows-sys 0.60.2", ] [[package]] @@ -8747,7 +8763,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 95fac355d3a..3dff31d072c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "crates/ink/ir", "crates/ink/macro", "crates/metadata", + "crates/revive", "crates/prelude", "crates/primitives", "crates/storage", @@ -104,6 +105,7 @@ xcm = { package = "staging-xcm", git = "https://github.com/use-ink/polkadot-sdk. polkavm-derive = { version = "0.26.0", default-features = false } # Solidity dependencies +alloy-core = { version = "1.1.0", default-features = false } alloy-sol-types = { version = "1.3.0", default-features = false } const_format = { version = "0.2.34", features = ["fmt"] } keccak-const = "0.2.0" @@ -121,6 +123,7 @@ ink_macro = { version = "=6.0.0-alpha.4", path = "crates/ink/macro", default-fea ink_metadata = { version = "=6.0.0-alpha.4", path = "crates/metadata", default-features = false } ink_prelude = { version = "=6.0.0-alpha.4", path = "crates/prelude", default-features = false } ink_primitives = { version = "=6.0.0-alpha.4", path = "crates/primitives", default-features = false } +ink_revive = { version = "=6.0.0-alpha.4", path = "crates/revive", default-features = false } ink_storage = { version = "=6.0.0-alpha.4", path = "crates/storage", default-features = false } ink_storage_traits = { version = "=6.0.0-alpha.4", path = "crates/storage/traits", default-features = false } diff --git a/crates/e2e/Cargo.toml b/crates/e2e/Cargo.toml index e83b112dcf7..9cdb1a4425c 100644 --- a/crates/e2e/Cargo.toml +++ b/crates/e2e/Cargo.toml @@ -19,6 +19,7 @@ ink_e2e_macro = { workspace = true, default-features = true } ink = { workspace = true, default-features = true } ink_env = { workspace = true, default-features = true } ink_primitives = { workspace = true, default-features = true } +ink_revive = { workspace = true, default-features = true } ink_sandbox = { version = "=6.0.0-alpha.4", path = "./sandbox", optional = true } cargo_metadata = { workspace = true } @@ -61,7 +62,6 @@ default = [ "std" ] std = [ "impl-serde/std", "ink_e2e_macro/std", - "pallet-revive/std", "scale-info/std", "scale/std", "serde/std", @@ -72,6 +72,7 @@ std = [ "sp-runtime-interface/std", "sp-weights/std", "ink_e2e_macro/std", + "ink_revive/std", "ink_sandbox?/std", "frame-support/std", ] diff --git a/crates/e2e/sandbox/Cargo.toml b/crates/e2e/sandbox/Cargo.toml index 35ee1eee1e3..dacc4dcdb7d 100644 --- a/crates/e2e/sandbox/Cargo.toml +++ b/crates/e2e/sandbox/Cargo.toml @@ -23,6 +23,7 @@ sp-externalities = { workspace = true } sp-runtime = { workspace = true } sp-io = { workspace = true } ink_primitives = { workspace = true } +ink_revive = { workspace = true } paste = { workspace = true } scale-info = { workspace = true } @@ -37,6 +38,7 @@ std = [ "frame-system/std", "frame-metadata/std", "ink_primitives/std", + "ink_revive/std", "pallet-balances/std", "pallet-revive/std", "pallet-timestamp/std", diff --git a/crates/revive/Cargo.toml b/crates/revive/Cargo.toml new file mode 100644 index 00000000000..f6e726eade7 --- /dev/null +++ b/crates/revive/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "ink_revive" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +description = "ink! revive primitives (placeholder)" +repository.workspace = true +homepage.workspace = true +keywords.workspace = true +categories.workspace = true + +[lib] +path = "src/lib.rs" + +[dependencies] +scale = { workspace = true } +frame-support = { workspace = true } +scale-info = { workspace = true } +serde = { workspace = true, features = ["derive"] } +ink_primitives = { workspace = true } +# sp-weights = { workspace = true } +# sp-core = { workspace = true } +sp-runtime = { workspace = true } +pallet-revive-uapi = { workspace = true, features = ["scale"] } +alloy-core = { workspace = true, features = ["sol-types"] } + +[features] +default = ["std"] +std = [ + "alloy-core/std", + "scale/std", + "scale-info/std", + "frame-support/std", + "ink_primitives/std", + # "sp-weights/std", + # "sp-core/std", + "sp-runtime/std", + "serde/std", +] + diff --git a/crates/revive/src/evm.rs b/crates/revive/src/evm.rs new file mode 100644 index 00000000000..c849010327c --- /dev/null +++ b/crates/revive/src/evm.rs @@ -0,0 +1,87 @@ +use scale::{Decode, Encode}; +use serde::{ + Deserialize, + Serialize, +}; +use alloc::vec::Vec; +use scale_info::TypeInfo; +use ink_primitives::{ + H160, U256, H256 +}; + + +/// A smart contract execution call trace. +#[derive( + TypeInfo, Default, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq, +)] +#[serde(rename_all = "camelCase")] +pub struct CallTrace { + /// Address of the sender. + pub from: H160, + /// Amount of gas provided for the call. + pub gas: Gas, + /// Amount of gas used. + pub gas_used: Gas, + /// Address of the receiver. + pub to: H160, + /// Call input data. + pub input: Vec, + /// Return data. + #[serde(skip_serializing_if = "Vec::is_empty")] + pub output: Vec, + /// The error message if the call failed. + #[serde(skip_serializing_if = "Option::is_none")] + pub error: Option, + /// The revert reason, if the call reverted. + #[serde(skip_serializing_if = "Option::is_none")] + pub revert_reason: Option, + /// List of sub-calls. + #[serde(skip_serializing_if = "Vec::is_empty")] + pub calls: Vec>, + /// List of logs emitted during the call. + #[serde(skip_serializing_if = "Vec::is_empty")] + pub logs: Vec, + /// Amount of value transferred. + #[serde(skip_serializing_if = "Option::is_none")] + pub value: Option, + /// Type of call. + #[serde(rename = "type")] + pub call_type: CallType, +} + +/// A log emitted during a call. +#[derive( + Debug, Default, Clone, Encode, Decode, TypeInfo, Serialize, Deserialize, Eq, PartialEq, +)] +pub struct CallLog { + /// The address of the contract that emitted the log. + pub address: H160, + /// The topics used to index the log. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub topics: Vec, + /// The log's data. + pub data: Vec, + /// Position of the log relative to subcalls within the same trace + /// See for details + #[serde(with = "super::hex_serde")] + pub position: u32, +} + +/// The type of call that was executed. +#[derive( + Default, TypeInfo, Encode, Decode, Serialize, Deserialize, Eq, PartialEq, Clone, Debug, +)] +#[serde(rename_all = "UPPERCASE")] +pub enum CallType { + /// A regular call. + #[default] + Call, + /// A read-only call. + StaticCall, + /// A delegate call. + DelegateCall, + /// A create call. + Create, + /// A create2 call. + Create2, +} \ No newline at end of file diff --git a/crates/revive/src/hex_serde.rs b/crates/revive/src/hex_serde.rs new file mode 100644 index 00000000000..e57926a8fd2 --- /dev/null +++ b/crates/revive/src/hex_serde.rs @@ -0,0 +1,85 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use alloc::{format, string::String, vec::Vec}; +use alloy_core::hex; +use serde::{Deserialize, Deserializer, Serializer}; + +pub trait HexCodec: Sized { + type Error; + fn to_hex(&self) -> String; + fn from_hex(s: String) -> Result; +} + +macro_rules! impl_hex_codec { + ($($t:ty),*) => { + $( + impl HexCodec for $t { + type Error = core::num::ParseIntError; + fn to_hex(&self) -> String { + format!("0x{:x}", self) + } + fn from_hex(s: String) -> Result { + <$t>::from_str_radix(s.trim_start_matches("0x"), 16) + } + } + )* + }; +} + +impl_hex_codec!(u8, u32); + +impl HexCodec for [u8; T] { + type Error = hex::FromHexError; + fn to_hex(&self) -> String { + format!("0x{}", hex::encode(self)) + } + fn from_hex(s: String) -> Result { + let data = hex::decode(s.trim_start_matches("0x"))?; + data.try_into().map_err(|_| hex::FromHexError::InvalidStringLength) + } +} + +impl HexCodec for Vec { + type Error = hex::FromHexError; + fn to_hex(&self) -> String { + format!("0x{}", hex::encode(self)) + } + fn from_hex(s: String) -> Result { + hex::decode(s.trim_start_matches("0x")) + } +} + +pub fn serialize(value: &T, serializer: S) -> Result +where + S: Serializer, + T: HexCodec, +{ + let s = value.to_hex(); + serializer.serialize_str(&s) +} + +pub fn deserialize<'de, D, T>(deserializer: D) -> Result +where + D: Deserializer<'de>, + T: HexCodec, + ::Error: core::fmt::Debug, +{ + let s = String::deserialize(deserializer)?; + let value = T::from_hex(s).map_err(|e| serde::de::Error::custom(format!("{:?}", e)))?; + Ok(value) +} \ No newline at end of file diff --git a/crates/revive/src/lib.rs b/crates/revive/src/lib.rs new file mode 100644 index 00000000000..01f334ad2c5 --- /dev/null +++ b/crates/revive/src/lib.rs @@ -0,0 +1,9 @@ +#![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + +mod evm; +mod hex_serde; +mod primitives; + +pub use evm::CallTrace; +pub use primitives::{ContractResult, ExecReturnValue, InstantiateReturnValue, StorageDeposit}; diff --git a/crates/revive/src/primitives.rs b/crates/revive/src/primitives.rs new file mode 100644 index 00000000000..a0685b95efb --- /dev/null +++ b/crates/revive/src/primitives.rs @@ -0,0 +1,176 @@ +#![cfg_attr(not(feature = "std"), allow(unused_imports))] + +use pallet_revive_uapi::ReturnFlags; +use scale::{Decode, Encode, MaxEncodedLen}; +use alloc::vec::Vec; +use scale_info::TypeInfo; +use frame_support::weights::Weight; +use ink_primitives::{ + H160, +}; +use sp_runtime::{ + traits::{Saturating, Zero}, + DispatchError, RuntimeDebug, +}; + +/// The amount of balance that was either charged or refunded in order to pay for storage. +#[derive( + Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo, +)] +pub enum StorageDeposit { + /// The transaction reduced storage consumption. + /// + /// This means that the specified amount of balance was transferred from the involved + /// deposit accounts to the origin. + Refund(Balance), + /// The transaction increased storage consumption. + /// + /// This means that the specified amount of balance was transferred from the origin + /// to the involved deposit accounts. + Charge(Balance), +} + +impl Default for StorageDeposit { + fn default() -> Self { + Self::Charge(Zero::zero()) + } +} + +impl StorageDeposit { + /// Returns how much balance is charged or `0` in case of a refund. + pub fn charge_or_zero(&self) -> Balance { + match self { + Self::Charge(amount) => *amount, + Self::Refund(_) => Zero::zero(), + } + } + + pub fn is_zero(&self) -> bool { + match self { + Self::Charge(amount) => amount.is_zero(), + Self::Refund(amount) => amount.is_zero(), + } + } +} + +impl StorageDeposit +where + Balance: Saturating + Ord + Copy, +{ + /// This is essentially a saturating signed add. + pub fn saturating_add(&self, rhs: &Self) -> Self { + use StorageDeposit::*; + match (self, rhs) { + (Charge(lhs), Charge(rhs)) => Charge(lhs.saturating_add(*rhs)), + (Refund(lhs), Refund(rhs)) => Refund(lhs.saturating_add(*rhs)), + (Charge(lhs), Refund(rhs)) => + if lhs >= rhs { + Charge(lhs.saturating_sub(*rhs)) + } else { + Refund(rhs.saturating_sub(*lhs)) + }, + (Refund(lhs), Charge(rhs)) => + if lhs > rhs { + Refund(lhs.saturating_sub(*rhs)) + } else { + Charge(rhs.saturating_sub(*lhs)) + }, + } + } + + /// This is essentially a saturating signed sub. + pub fn saturating_sub(&self, rhs: &Self) -> Self { + use StorageDeposit::*; + match (self, rhs) { + (Charge(lhs), Refund(rhs)) => Charge(lhs.saturating_add(*rhs)), + (Refund(lhs), Charge(rhs)) => Refund(lhs.saturating_add(*rhs)), + (Charge(lhs), Charge(rhs)) => + if lhs >= rhs { + Charge(lhs.saturating_sub(*rhs)) + } else { + Refund(rhs.saturating_sub(*lhs)) + }, + (Refund(lhs), Refund(rhs)) => + if lhs > rhs { + Refund(lhs.saturating_sub(*rhs)) + } else { + Charge(rhs.saturating_sub(*lhs)) + }, + } + } + + /// If the amount of deposit (this type) is constrained by a `limit` this calculates how + /// much balance (if any) is still available from this limit. + /// + /// # Note + /// + /// In case of a refund the return value can be larger than `limit`. + pub fn available(&self, limit: &Balance) -> Balance { + use StorageDeposit::*; + match self { + Charge(amount) => limit.saturating_sub(*amount), + Refund(amount) => limit.saturating_add(*amount), + } + } +} + +/// Result type of a `bare_call` or `bare_instantiate` call as well as `ContractsApi::call` and +/// `ContractsApi::instantiate`. +/// +/// It contains the execution result together with some auxiliary information. +/// +/// #Note +/// +/// It has been extended to include `events` at the end of the struct while not bumping the +/// `ContractsApi` version. Therefore when SCALE decoding a `ContractResult` its trailing data +/// should be ignored to avoid any potential compatibility issues. +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct ContractResult { + /// How much weight was consumed during execution. + pub gas_consumed: Weight, + /// How much weight is required as gas limit in order to execute this call. + /// + /// This value should be used to determine the weight limit for on-chain execution. + /// + /// # Note + /// + /// This can only be different from [`Self::gas_consumed`] when weight pre charging + /// is used. Currently, only `seal_call_runtime` makes use of pre charging. + /// Additionally, any `seal_call` or `seal_instantiate` makes use of pre-charging + /// when a non-zero `gas_limit` argument is supplied. + pub gas_required: Weight, + /// How much balance was paid by the origin into the contract's deposit account in order to + /// pay for storage. + /// + /// The storage deposit is never actually charged from the origin in case of [`Self::result`] + /// is `Err`. This is because on error all storage changes are rolled back including the + /// payment of the deposit. + pub storage_deposit: StorageDeposit, + /// The execution result of the vm binary code. + pub result: Result, +} + +/// Output of a contract call or instantiation which ran to completion. +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Default)] +pub struct ExecReturnValue { + /// Flags passed along by `seal_return`. Empty when `seal_return` was never called. + pub flags: ReturnFlags, + /// Buffer passed along by `seal_return`. Empty when `seal_return` was never called. + pub data: Vec, +} + +impl ExecReturnValue { + /// The contract did revert all storage changes. + pub fn did_revert(&self) -> bool { + self.flags.contains(ReturnFlags::REVERT) + } +} + +/// The result of a successful contract instantiation. +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct InstantiateReturnValue { + /// The output of the called constructor. + pub result: ExecReturnValue, + /// The address of the new contract. + pub addr: H160, +} \ No newline at end of file diff --git a/integration-tests/solidity-abi/sol-cross-contract/Cargo.toml b/integration-tests/solidity-abi/sol-cross-contract/Cargo.toml index 2c71661acf4..40b5ce0e40a 100755 --- a/integration-tests/solidity-abi/sol-cross-contract/Cargo.toml +++ b/integration-tests/solidity-abi/sol-cross-contract/Cargo.toml @@ -12,7 +12,7 @@ sha3 = { version = "0.10", default-features = false } [dev-dependencies] ink_e2e = { path = "../../../crates/e2e", features = ["sandbox"] } ink_sandbox = { path = "../../../crates/e2e/sandbox" } -pallet-revive = { git = "https://github.com/use-ink/polkadot-sdk.git", rev = "a71ec19a94702ea71767ba5ac97603ea6c6305c1", default-features = false } +ink_revive = { path = "../../../crates/revive" } sha3 = { version = "0.10" } other-contract-sol = { path = "other-contract-sol" } diff --git a/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs b/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs index 741cbbe6b0a..7df0d806c0c 100644 --- a/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs +++ b/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs @@ -13,7 +13,7 @@ use ink::{ primitives::DepositLimit, }; use ink_sandbox::frame_system::pallet_prelude::OriginFor; -use pallet_revive::ExecReturnValue; +use ink_revive::ExecReturnValue; const STORAGE_DEPOSIT_LIMIT: DepositLimit = DepositLimit::UnsafeOnlyForDryRun; @@ -172,7 +172,11 @@ impl ContractSandbox { STORAGE_DEPOSIT_LIMIT, ); - result.result.expect("sandbox call contract failed") + let call_raw = result.result.expect("sandbox call contract failed"); + ExecReturnValue { + flags: call_raw.flags, + data: call_raw.data + } } } diff --git a/integration-tests/solidity-abi/sol-encoding/Cargo.toml b/integration-tests/solidity-abi/sol-encoding/Cargo.toml index e6e3223c68a..8d9b76e2e6d 100755 --- a/integration-tests/solidity-abi/sol-encoding/Cargo.toml +++ b/integration-tests/solidity-abi/sol-encoding/Cargo.toml @@ -11,7 +11,7 @@ ink = { path = "../../../crates/ink", default-features = false } [dev-dependencies] ink_e2e = { path = "../../../crates/e2e", features = ["sandbox"] } ink_sandbox = { path = "../../../crates/e2e/sandbox" } -pallet-revive = { git = "https://github.com/use-ink/polkadot-sdk.git", rev = "a71ec19a94702ea71767ba5ac97603ea6c6305c1", default-features = false } +ink_revive = { path = "../../../crates/revive" } sha3 = { version = "0.10" } [lib] diff --git a/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs b/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs index ba753d52518..a5a5285907a 100644 --- a/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs +++ b/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs @@ -12,7 +12,7 @@ use ink_sandbox::{ api::prelude::*, frame_system::pallet_prelude::OriginFor, }; -use pallet_revive::ExecReturnValue; +use ink_revive::ExecReturnValue; const STORAGE_DEPOSIT_LIMIT: DepositLimit = DepositLimit::UnsafeOnlyForDryRun; @@ -114,7 +114,7 @@ impl ContractSandbox { data: Vec, origin: OriginFor<::Runtime>, ) -> ExecReturnValue { - ::call_contract( + let call_raw = ::call_contract( &mut self.sandbox, self.contract_addr, 0, @@ -124,7 +124,11 @@ impl ContractSandbox { STORAGE_DEPOSIT_LIMIT, ) .result - .expect("sandbox call contract failed") + .expect("sandbox call contract failed"); + ExecReturnValue { + flags: call_raw.flags, + data: call_raw.data + } } } From b9eeff6ac34ee1602a154a52feb7b4a73dda177b Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Wed, 24 Sep 2025 16:40:12 +0200 Subject: [PATCH 02/10] refactor: remove revive references from e2e crate --- Cargo.lock | 3 +- crates/e2e/Cargo.toml | 1 - crates/e2e/src/backend.rs | 2 +- crates/e2e/src/contract_results.rs | 2 +- crates/e2e/src/error.rs | 2 +- crates/e2e/src/lib.rs | 2 +- crates/e2e/src/sandbox_client.rs | 85 +++++++++++++--- crates/e2e/src/subxt_client.rs | 2 +- crates/e2e/src/xts.rs | 2 +- crates/revive/Cargo.toml | 6 +- crates/revive/src/evm.rs | 157 ++++++++++++++++++++++++++++- crates/revive/src/lib.rs | 5 +- crates/revive/src/primitives.rs | 14 ++- 13 files changed, 252 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb4bed07265..7a1e0b42b7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3489,7 +3489,6 @@ dependencies = [ "ink_sandbox", "itertools 0.14.0", "jsonrpsee", - "pallet-revive", "parity-scale-codec", "regex", "scale-info", @@ -3719,12 +3718,14 @@ name = "ink_revive" version = "6.0.0-alpha.4" dependencies = [ "alloy-core", + "derive_more 2.0.1", "frame-support", "ink_primitives 6.0.0-alpha.4", "pallet-revive-uapi", "parity-scale-codec", "scale-info", "serde", + "sp-core", "sp-runtime", ] diff --git a/crates/e2e/Cargo.toml b/crates/e2e/Cargo.toml index 9cdb1a4425c..a4186782dec 100644 --- a/crates/e2e/Cargo.toml +++ b/crates/e2e/Cargo.toml @@ -24,7 +24,6 @@ ink_sandbox = { version = "=6.0.0-alpha.4", path = "./sandbox", optional = true cargo_metadata = { workspace = true } contract-build = { workspace = true } -pallet-revive = { workspace = true } funty = { workspace = true } impl-serde = { workspace = true } jsonrpsee = { workspace = true, features = ["ws-client"] } diff --git a/crates/e2e/src/backend.rs b/crates/e2e/src/backend.rs index 759059f2da8..1f0451e8619 100644 --- a/crates/e2e/src/backend.rs +++ b/crates/e2e/src/backend.rs @@ -22,7 +22,7 @@ use ink_primitives::{ abi::AbiEncodeWith, }; use jsonrpsee::core::async_trait; -use pallet_revive::evm::CallTrace; +use ink_revive::evm::CallTrace; use sp_weights::Weight; use subxt::dynamic::Value; diff --git a/crates/e2e/src/contract_results.rs b/crates/e2e/src/contract_results.rs index 99e844b258a..07de4163540 100644 --- a/crates/e2e/src/contract_results.rs +++ b/crates/e2e/src/contract_results.rs @@ -36,7 +36,7 @@ use ink_primitives::{ H256, MessageResult, }; -use pallet_revive::{ +use ink_revive::{ CodeUploadResult, ExecReturnValue, InstantiateReturnValue, diff --git a/crates/e2e/src/error.rs b/crates/e2e/src/error.rs index 71f4fcd7962..369d233d922 100644 --- a/crates/e2e/src/error.rs +++ b/crates/e2e/src/error.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use pallet_revive::evm::CallTrace; +use ink_revive::evm::CallTrace; use std::fmt; /// An error occurred while interacting with the E2E backend. diff --git a/crates/e2e/src/lib.rs b/crates/e2e/src/lib.rs index 4698998956f..1186171cdcd 100644 --- a/crates/e2e/src/lib.rs +++ b/crates/e2e/src/lib.rs @@ -57,7 +57,7 @@ pub use node_proc::{ TestNodeProcess, TestNodeProcessBuilder, }; -pub use pallet_revive::evm::CallTrace; +pub use ink_revive::evm::CallTrace; #[cfg(feature = "sandbox")] pub use sandbox_client::{ Client as SandboxClient, diff --git a/crates/e2e/src/sandbox_client.rs b/crates/e2e/src/sandbox_client.rs index 56714feab1e..fcbdc4ebf9f 100644 --- a/crates/e2e/src/sandbox_client.rs +++ b/crates/e2e/src/sandbox_client.rs @@ -60,6 +60,7 @@ use ink_primitives::{ DepositLimit, H160, abi::AbiEncodeWith, + U256 }; use ink_sandbox::{ AccountIdFor, @@ -73,19 +74,24 @@ use ink_sandbox::{ pallet_revive, }; use jsonrpsee::core::async_trait; -use pallet_revive::{ - AddressMapper, +use ink_revive::{ + ExecReturnValue, CodeUploadReturnValue, InstantiateReturnValue, - MomentOf, evm::{ CallTrace, - CallTracerConfig, - Trace, - TracerType, - U256, + CallLog }, }; +use pallet_revive::{ + AddressMapper, + MomentOf, + evm::{ + TracerType, + Trace, + CallTracerConfig, + } +}; use scale::Decode; use sp_core::{ Pair as _, @@ -360,7 +366,7 @@ where }; let trace = match tracer.collect_trace() { - Some(Trace::Call(call_trace)) => Some(call_trace), + Some(Trace::Call(call_trace)) => Some(to_revive_trace(call_trace)), _ => None, }; @@ -444,10 +450,13 @@ where let result = ContractResult:: { gas_consumed: dry_run_result.gas_consumed, gas_required: dry_run_result.gas_required, - storage_deposit: dry_run_result.storage_deposit, + storage_deposit: to_revive_storage_deposit(dry_run_result.storage_deposit), result: dry_run_result.result.map(|res| { InstantiateReturnValue { - result: res.result, + result: ExecReturnValue { + flags: res.result.flags, + data: res.result.data, + }, addr: res.addr, } }), @@ -556,7 +565,7 @@ where .map_err(|err| SandboxErr::new(format!("bare_call: {err:?}"))) })?; let trace = match tracer.collect_trace() { - Some(Trace::Call(call_trace)) => Some(call_trace), + Some(Trace::Call(call_trace)) => Some(to_revive_trace(call_trace)), _ => None, }; @@ -630,8 +639,13 @@ where exec_result: ContractExecResultFor:: { gas_consumed: result.gas_consumed, gas_required: result.gas_required, - storage_deposit: result.storage_deposit, - result: result.result, + storage_deposit: to_revive_storage_deposit(result.storage_deposit), + result: result.result.map(|res| { + ExecReturnValue { + flags: res.flags, + data: res.data, + } + }), }, trace: None, // todo _marker: Default::default(), @@ -829,3 +843,48 @@ where let origin = RawOrigin::Signed(caller); OriginFor::::from(origin) } + + +/// Convert a `pallet_revive::CallTrace` (sandbox) into an `ink_revive::CallTrace` (API). +fn to_revive_trace(t: pallet_revive::evm::CallTrace) -> CallTrace { + CallTrace { + from: t.from, + gas: t.gas, + gas_used: t.gas_used, + to: t.to, + input: t.input.0, + output: t.output.0, + error: t.error, + revert_reason: t.revert_reason, + calls: t.calls.into_iter().map(to_revive_trace).collect(), + logs: t.logs.into_iter().map(|log| CallLog { + address: log.address, + topics: log.topics, + data: log.data.0, + ..Default::default() + }).collect(), + value: t.value, + call_type: to_revive_call_type(t.call_type), + } +} + +/// Convert a `pallet_revive::CallType` into an `ink_revive::evm::CallType`. +fn to_revive_call_type(ct: pallet_revive::evm::CallType) -> ink_revive::evm::CallType { + match ct { + pallet_revive::evm::CallType::Call => ink_revive::evm::CallType::Call, + pallet_revive::evm::CallType::StaticCall => ink_revive::evm::CallType::StaticCall, + pallet_revive::evm::CallType::DelegateCall => ink_revive::evm::CallType::DelegateCall, + pallet_revive::evm::CallType::Create => ink_revive::evm::CallType::Create, + pallet_revive::evm::CallType::Create2 => ink_revive::evm::CallType::Create2, + } +} + +/// Convert a `ink_revive::StorageDeposit` into an `ink_revive::StorageDeposit`. +fn to_revive_storage_deposit( + sd: pallet_revive::StorageDeposit, +) -> ink_revive::StorageDeposit { + match sd { + pallet_revive::StorageDeposit::Charge(b) => ink_revive::StorageDeposit::Charge(b), + pallet_revive::StorageDeposit::Refund(b) => ink_revive::StorageDeposit::Refund(b), + } +} diff --git a/crates/e2e/src/subxt_client.rs b/crates/e2e/src/subxt_client.rs index 4fb2bf5a4f9..26ced5bca26 100644 --- a/crates/e2e/src/subxt_client.rs +++ b/crates/e2e/src/subxt_client.rs @@ -74,7 +74,7 @@ use ink_primitives::{ abi::AbiEncodeWith, }; use jsonrpsee::core::async_trait; -use pallet_revive::evm::CallTrace; +use ink_revive::evm::CallTrace; use scale::{ Decode, Encode, diff --git a/crates/e2e/src/xts.rs b/crates/e2e/src/xts.rs index 4874ba85b5e..025869c9ec8 100644 --- a/crates/e2e/src/xts.rs +++ b/crates/e2e/src/xts.rs @@ -29,7 +29,7 @@ use ink_primitives::{ Address, DepositLimit, }; -use pallet_revive::{ +use ink_revive::{ CodeUploadResult, evm::{ CallTrace, diff --git a/crates/revive/Cargo.toml b/crates/revive/Cargo.toml index f6e726eade7..1ea8d80561c 100644 --- a/crates/revive/Cargo.toml +++ b/crates/revive/Cargo.toml @@ -19,8 +19,8 @@ frame-support = { workspace = true } scale-info = { workspace = true } serde = { workspace = true, features = ["derive"] } ink_primitives = { workspace = true } -# sp-weights = { workspace = true } -# sp-core = { workspace = true } +derive_more = { workspace = true, features = ["from", "try_into"] } +sp-core = { workspace = true } sp-runtime = { workspace = true } pallet-revive-uapi = { workspace = true, features = ["scale"] } alloy-core = { workspace = true, features = ["sol-types"] } @@ -34,7 +34,7 @@ std = [ "frame-support/std", "ink_primitives/std", # "sp-weights/std", - # "sp-core/std", + "sp-core/std", "sp-runtime/std", "serde/std", ] diff --git a/crates/revive/src/evm.rs b/crates/revive/src/evm.rs index c849010327c..c317a5984b4 100644 --- a/crates/revive/src/evm.rs +++ b/crates/revive/src/evm.rs @@ -1,9 +1,10 @@ use scale::{Decode, Encode}; use serde::{ - Deserialize, - Serialize, + ser::{SerializeMap, Serializer}, + Deserialize, Serialize, }; -use alloc::vec::Vec; +use derive_more::From; +use alloc::{collections::BTreeMap, string::String, vec::Vec}; use scale_info::TypeInfo; use ink_primitives::{ H160, U256, H256 @@ -84,4 +85,154 @@ pub enum CallType { Create, /// A create2 call. Create2, +} + +/// The configuration for the call tracer. +#[derive(Clone, Debug, Decode, Serialize, Deserialize, Encode, PartialEq, TypeInfo)] +#[serde(default, rename_all = "camelCase")] +pub struct CallTracerConfig { + /// Whether to include logs in the trace. + pub with_logs: bool, + + /// Whether to only include the top-level calls in the trace. + pub only_top_call: bool, +} + +impl Default for CallTracerConfig { + fn default() -> Self { + Self { with_logs: true, only_top_call: false } + } +} + +/// A Trace +#[derive(TypeInfo, From, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq)] +#[serde(untagged)] +pub enum Trace { + /// A call trace. + Call(CallTrace), + /// A prestate trace. + Prestate(PrestateTrace), +} + +/// A prestate Trace +#[derive(TypeInfo, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq)] +#[serde(untagged)] +pub enum PrestateTrace { + /// The Prestate mode returns the accounts necessary to execute a given transaction + Prestate(BTreeMap), + + /// The diff mode returns the differences between the transaction's pre and post-state + /// The result only contains the accounts that were modified by the transaction + DiffMode { + /// The state before the call. + /// The accounts in the `pre` field will contain all of their basic fields, even if those + /// fields have not been modified. For `storage` however, only non-empty slots that have + /// been modified will be included + pre: BTreeMap, + /// The state after the call. + /// It only contains the specific fields that were actually modified during the transaction + post: BTreeMap, + }, +} + +impl PrestateTrace { + /// Returns the pre and post trace info. + pub fn state_mut( + &mut self, + ) -> (&mut BTreeMap, Option<&mut BTreeMap>) { + match self { + PrestateTrace::Prestate(pre) => (pre, None), + PrestateTrace::DiffMode { pre, post } => (pre, Some(post)), + } + } +} + +/// The info of a prestate trace. +#[derive( + TypeInfo, Default, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq, +)] +pub struct PrestateTraceInfo { + /// The balance of the account. + #[serde(skip_serializing_if = "Option::is_none")] + pub balance: Option, + /// The nonce of the account. + #[serde(skip_serializing_if = "Option::is_none")] + pub nonce: Option, + /// The code of the contract account. + #[serde(skip_serializing_if = "Option::is_none")] + pub code: Option>, + /// The storage of the contract account. + #[serde(skip_serializing_if = "is_empty", serialize_with = "serialize_map_skip_none")] + pub storage: BTreeMap, Option>>, +} + +/// Returns true if the map has no `Some` element +pub fn is_empty(map: &BTreeMap>) -> bool { + !map.values().any(|v| v.is_some()) +} + +/// Serializes a map, skipping `None` values. +pub fn serialize_map_skip_none( + map: &BTreeMap>, + serializer: S, +) -> Result +where + S: Serializer, + K: serde::Serialize, + V: serde::Serialize, +{ + let len = map.values().filter(|v| v.is_some()).count(); + let mut ser_map = serializer.serialize_map(Some(len))?; + + for (key, opt_val) in map { + if let Some(val) = opt_val { + ser_map.serialize_entry(key, val)?; + } + } + + ser_map.end() +} + +/// The type of tracer to use. +/// Only "callTracer" is supported for now. +#[derive(TypeInfo, Debug, Clone, Encode, Decode, Serialize, Deserialize, PartialEq)] +#[serde(tag = "tracer", content = "tracerConfig", rename_all = "camelCase")] +pub enum TracerType { + /// A tracer that traces calls. + CallTracer(Option), + + /// A tracer that traces the prestate. + PrestateTracer(Option), +} + +impl From for TracerType { + fn from(config: CallTracerConfig) -> Self { + TracerType::CallTracer(Some(config)) + } +} + +impl Default for TracerType { + fn default() -> Self { + TracerType::CallTracer(Some(CallTracerConfig::default())) + } +} + +/// The configuration for the prestate tracer. +#[derive(Clone, Debug, Decode, Serialize, Deserialize, Encode, PartialEq, TypeInfo)] +#[serde(default, rename_all = "camelCase")] +pub struct PrestateTracerConfig { + /// Whether to include the diff mode in the trace. + pub diff_mode: bool, + + /// Whether to include storage in the trace. + pub disable_storage: bool, + + /// Whether to include code in the trace. + pub disable_code: bool, +} + +impl Default for PrestateTracerConfig { + fn default() -> Self { + Self { diff_mode: false, disable_storage: false, disable_code: false } + } } \ No newline at end of file diff --git a/crates/revive/src/lib.rs b/crates/revive/src/lib.rs index 01f334ad2c5..a54bc14d273 100644 --- a/crates/revive/src/lib.rs +++ b/crates/revive/src/lib.rs @@ -1,9 +1,8 @@ #![cfg_attr(not(feature = "std"), no_std)] extern crate alloc; -mod evm; +pub mod evm; mod hex_serde; mod primitives; -pub use evm::CallTrace; -pub use primitives::{ContractResult, ExecReturnValue, InstantiateReturnValue, StorageDeposit}; +pub use primitives::{ContractResult, ExecReturnValue, InstantiateReturnValue, StorageDeposit, CodeUploadResult, CodeUploadReturnValue}; diff --git a/crates/revive/src/primitives.rs b/crates/revive/src/primitives.rs index a0685b95efb..275dbfcfc8c 100644 --- a/crates/revive/src/primitives.rs +++ b/crates/revive/src/primitives.rs @@ -173,4 +173,16 @@ pub struct InstantiateReturnValue { pub result: ExecReturnValue, /// The address of the new contract. pub addr: H160, -} \ No newline at end of file +} + +/// The result of successfully uploading a contract. +#[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo)] +pub struct CodeUploadReturnValue { + /// The key under which the new code is stored. + pub code_hash: sp_core::H256, + /// The deposit that was reserved at the caller. Is zero when the code already existed. + pub deposit: Balance, +} + +/// Result type of a `bare_code_upload` call. +pub type CodeUploadResult = Result, DispatchError>; From 361f991777b830df7fd8376c1217160f92d4c1af Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Wed, 24 Sep 2025 16:41:14 +0200 Subject: [PATCH 03/10] chore: format --- crates/e2e/src/backend.rs | 2 +- crates/e2e/src/lib.rs | 2 +- crates/e2e/src/sandbox_client.rs | 57 +++--- crates/e2e/src/subxt_client.rs | 2 +- crates/revive/src/evm.rs | 326 +++++++++++++++++-------------- crates/revive/src/hex_serde.rs | 72 ++++--- crates/revive/src/lib.rs | 9 +- crates/revive/src/primitives.rs | 285 ++++++++++++++------------- 8 files changed, 415 insertions(+), 340 deletions(-) diff --git a/crates/e2e/src/backend.rs b/crates/e2e/src/backend.rs index 1f0451e8619..74907d79dbb 100644 --- a/crates/e2e/src/backend.rs +++ b/crates/e2e/src/backend.rs @@ -21,8 +21,8 @@ use ink_primitives::{ H160, abi::AbiEncodeWith, }; -use jsonrpsee::core::async_trait; use ink_revive::evm::CallTrace; +use jsonrpsee::core::async_trait; use sp_weights::Weight; use subxt::dynamic::Value; diff --git a/crates/e2e/src/lib.rs b/crates/e2e/src/lib.rs index 1186171cdcd..34b414192ca 100644 --- a/crates/e2e/src/lib.rs +++ b/crates/e2e/src/lib.rs @@ -53,11 +53,11 @@ pub use contract_results::{ UploadResult, }; pub use ink_e2e_macro::test; +pub use ink_revive::evm::CallTrace; pub use node_proc::{ TestNodeProcess, TestNodeProcessBuilder, }; -pub use ink_revive::evm::CallTrace; #[cfg(feature = "sandbox")] pub use sandbox_client::{ Client as SandboxClient, diff --git a/crates/e2e/src/sandbox_client.rs b/crates/e2e/src/sandbox_client.rs index fcbdc4ebf9f..13487470402 100644 --- a/crates/e2e/src/sandbox_client.rs +++ b/crates/e2e/src/sandbox_client.rs @@ -59,8 +59,17 @@ use ink_env::{ use ink_primitives::{ DepositLimit, H160, + U256, abi::AbiEncodeWith, - U256 +}; +use ink_revive::{ + CodeUploadReturnValue, + ExecReturnValue, + InstantiateReturnValue, + evm::{ + CallLog, + CallTrace, + }, }; use ink_sandbox::{ AccountIdFor, @@ -74,23 +83,14 @@ use ink_sandbox::{ pallet_revive, }; use jsonrpsee::core::async_trait; -use ink_revive::{ - ExecReturnValue, - CodeUploadReturnValue, - InstantiateReturnValue, - evm::{ - CallTrace, - CallLog - }, -}; use pallet_revive::{ AddressMapper, - MomentOf, + MomentOf, evm::{ - TracerType, - Trace, CallTracerConfig, - } + Trace, + TracerType, + }, }; use scale::Decode; use sp_core::{ @@ -642,9 +642,9 @@ where storage_deposit: to_revive_storage_deposit(result.storage_deposit), result: result.result.map(|res| { ExecReturnValue { - flags: res.flags, - data: res.data, - } + flags: res.flags, + data: res.data, + } }), }, trace: None, // todo @@ -844,7 +844,6 @@ where OriginFor::::from(origin) } - /// Convert a `pallet_revive::CallTrace` (sandbox) into an `ink_revive::CallTrace` (API). fn to_revive_trace(t: pallet_revive::evm::CallTrace) -> CallTrace { CallTrace { @@ -857,12 +856,18 @@ fn to_revive_trace(t: pallet_revive::evm::CallTrace) -> CallTrace { error: t.error, revert_reason: t.revert_reason, calls: t.calls.into_iter().map(to_revive_trace).collect(), - logs: t.logs.into_iter().map(|log| CallLog { - address: log.address, - topics: log.topics, - data: log.data.0, - ..Default::default() - }).collect(), + logs: t + .logs + .into_iter() + .map(|log| { + CallLog { + address: log.address, + topics: log.topics, + data: log.data.0, + ..Default::default() + } + }) + .collect(), value: t.value, call_type: to_revive_call_type(t.call_type), } @@ -873,7 +878,9 @@ fn to_revive_call_type(ct: pallet_revive::evm::CallType) -> ink_revive::evm::Cal match ct { pallet_revive::evm::CallType::Call => ink_revive::evm::CallType::Call, pallet_revive::evm::CallType::StaticCall => ink_revive::evm::CallType::StaticCall, - pallet_revive::evm::CallType::DelegateCall => ink_revive::evm::CallType::DelegateCall, + pallet_revive::evm::CallType::DelegateCall => { + ink_revive::evm::CallType::DelegateCall + } pallet_revive::evm::CallType::Create => ink_revive::evm::CallType::Create, pallet_revive::evm::CallType::Create2 => ink_revive::evm::CallType::Create2, } diff --git a/crates/e2e/src/subxt_client.rs b/crates/e2e/src/subxt_client.rs index 26ced5bca26..110e4757785 100644 --- a/crates/e2e/src/subxt_client.rs +++ b/crates/e2e/src/subxt_client.rs @@ -73,8 +73,8 @@ use ink_primitives::{ DepositLimit, abi::AbiEncodeWith, }; -use jsonrpsee::core::async_trait; use ink_revive::evm::CallTrace; +use jsonrpsee::core::async_trait; use scale::{ Decode, Encode, diff --git a/crates/revive/src/evm.rs b/crates/revive/src/evm.rs index c317a5984b4..03611a9d4a2 100644 --- a/crates/revive/src/evm.rs +++ b/crates/revive/src/evm.rs @@ -1,196 +1,222 @@ -use scale::{Decode, Encode}; -use serde::{ - ser::{SerializeMap, Serializer}, - Deserialize, Serialize, +use alloc::{ + collections::BTreeMap, + string::String, + vec::Vec, }; use derive_more::From; -use alloc::{collections::BTreeMap, string::String, vec::Vec}; -use scale_info::TypeInfo; use ink_primitives::{ - H160, U256, H256 + H160, + H256, + U256, +}; +use scale::{ + Decode, + Encode, +}; +use scale_info::TypeInfo; +use serde::{ + Deserialize, + Serialize, + ser::{ + SerializeMap, + Serializer, + }, }; - /// A smart contract execution call trace. #[derive( - TypeInfo, Default, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq, + TypeInfo, Default, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq, )] #[serde(rename_all = "camelCase")] pub struct CallTrace { - /// Address of the sender. - pub from: H160, - /// Amount of gas provided for the call. - pub gas: Gas, - /// Amount of gas used. - pub gas_used: Gas, - /// Address of the receiver. - pub to: H160, - /// Call input data. - pub input: Vec, - /// Return data. - #[serde(skip_serializing_if = "Vec::is_empty")] - pub output: Vec, - /// The error message if the call failed. - #[serde(skip_serializing_if = "Option::is_none")] - pub error: Option, - /// The revert reason, if the call reverted. - #[serde(skip_serializing_if = "Option::is_none")] - pub revert_reason: Option, - /// List of sub-calls. - #[serde(skip_serializing_if = "Vec::is_empty")] - pub calls: Vec>, - /// List of logs emitted during the call. - #[serde(skip_serializing_if = "Vec::is_empty")] - pub logs: Vec, - /// Amount of value transferred. - #[serde(skip_serializing_if = "Option::is_none")] - pub value: Option, - /// Type of call. - #[serde(rename = "type")] - pub call_type: CallType, + /// Address of the sender. + pub from: H160, + /// Amount of gas provided for the call. + pub gas: Gas, + /// Amount of gas used. + pub gas_used: Gas, + /// Address of the receiver. + pub to: H160, + /// Call input data. + pub input: Vec, + /// Return data. + #[serde(skip_serializing_if = "Vec::is_empty")] + pub output: Vec, + /// The error message if the call failed. + #[serde(skip_serializing_if = "Option::is_none")] + pub error: Option, + /// The revert reason, if the call reverted. + #[serde(skip_serializing_if = "Option::is_none")] + pub revert_reason: Option, + /// List of sub-calls. + #[serde(skip_serializing_if = "Vec::is_empty")] + pub calls: Vec>, + /// List of logs emitted during the call. + #[serde(skip_serializing_if = "Vec::is_empty")] + pub logs: Vec, + /// Amount of value transferred. + #[serde(skip_serializing_if = "Option::is_none")] + pub value: Option, + /// Type of call. + #[serde(rename = "type")] + pub call_type: CallType, } /// A log emitted during a call. #[derive( - Debug, Default, Clone, Encode, Decode, TypeInfo, Serialize, Deserialize, Eq, PartialEq, + Debug, Default, Clone, Encode, Decode, TypeInfo, Serialize, Deserialize, Eq, PartialEq, )] pub struct CallLog { - /// The address of the contract that emitted the log. - pub address: H160, - /// The topics used to index the log. - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub topics: Vec, - /// The log's data. - pub data: Vec, - /// Position of the log relative to subcalls within the same trace - /// See for details - #[serde(with = "super::hex_serde")] - pub position: u32, + /// The address of the contract that emitted the log. + pub address: H160, + /// The topics used to index the log. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub topics: Vec, + /// The log's data. + pub data: Vec, + /// Position of the log relative to subcalls within the same trace + /// See for details + #[serde(with = "super::hex_serde")] + pub position: u32, } /// The type of call that was executed. #[derive( - Default, TypeInfo, Encode, Decode, Serialize, Deserialize, Eq, PartialEq, Clone, Debug, + Default, TypeInfo, Encode, Decode, Serialize, Deserialize, Eq, PartialEq, Clone, Debug, )] #[serde(rename_all = "UPPERCASE")] pub enum CallType { - /// A regular call. - #[default] - Call, - /// A read-only call. - StaticCall, - /// A delegate call. - DelegateCall, - /// A create call. - Create, - /// A create2 call. - Create2, + /// A regular call. + #[default] + Call, + /// A read-only call. + StaticCall, + /// A delegate call. + DelegateCall, + /// A create call. + Create, + /// A create2 call. + Create2, } /// The configuration for the call tracer. #[derive(Clone, Debug, Decode, Serialize, Deserialize, Encode, PartialEq, TypeInfo)] #[serde(default, rename_all = "camelCase")] pub struct CallTracerConfig { - /// Whether to include logs in the trace. - pub with_logs: bool, + /// Whether to include logs in the trace. + pub with_logs: bool, - /// Whether to only include the top-level calls in the trace. - pub only_top_call: bool, + /// Whether to only include the top-level calls in the trace. + pub only_top_call: bool, } impl Default for CallTracerConfig { - fn default() -> Self { - Self { with_logs: true, only_top_call: false } - } + fn default() -> Self { + Self { + with_logs: true, + only_top_call: false, + } + } } /// A Trace -#[derive(TypeInfo, From, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq)] +#[derive( + TypeInfo, From, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq, +)] #[serde(untagged)] pub enum Trace { - /// A call trace. - Call(CallTrace), - /// A prestate trace. - Prestate(PrestateTrace), + /// A call trace. + Call(CallTrace), + /// A prestate trace. + Prestate(PrestateTrace), } /// A prestate Trace -#[derive(TypeInfo, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq)] +#[derive( + TypeInfo, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq, +)] #[serde(untagged)] pub enum PrestateTrace { - /// The Prestate mode returns the accounts necessary to execute a given transaction - Prestate(BTreeMap), - - /// The diff mode returns the differences between the transaction's pre and post-state - /// The result only contains the accounts that were modified by the transaction - DiffMode { - /// The state before the call. - /// The accounts in the `pre` field will contain all of their basic fields, even if those - /// fields have not been modified. For `storage` however, only non-empty slots that have - /// been modified will be included - pre: BTreeMap, - /// The state after the call. - /// It only contains the specific fields that were actually modified during the transaction - post: BTreeMap, - }, + /// The Prestate mode returns the accounts necessary to execute a given transaction + Prestate(BTreeMap), + + /// The diff mode returns the differences between the transaction's pre and post-state + /// The result only contains the accounts that were modified by the transaction + DiffMode { + /// The state before the call. + /// The accounts in the `pre` field will contain all of their basic fields, even + /// if those fields have not been modified. For `storage` however, only + /// non-empty slots that have been modified will be included + pre: BTreeMap, + /// The state after the call. + /// It only contains the specific fields that were actually modified during the + /// transaction + post: BTreeMap, + }, } impl PrestateTrace { - /// Returns the pre and post trace info. - pub fn state_mut( - &mut self, - ) -> (&mut BTreeMap, Option<&mut BTreeMap>) { - match self { - PrestateTrace::Prestate(pre) => (pre, None), - PrestateTrace::DiffMode { pre, post } => (pre, Some(post)), - } - } + /// Returns the pre and post trace info. + pub fn state_mut( + &mut self, + ) -> ( + &mut BTreeMap, + Option<&mut BTreeMap>, + ) { + match self { + PrestateTrace::Prestate(pre) => (pre, None), + PrestateTrace::DiffMode { pre, post } => (pre, Some(post)), + } + } } /// The info of a prestate trace. #[derive( - TypeInfo, Default, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq, + TypeInfo, Default, Encode, Decode, Serialize, Deserialize, Clone, Debug, Eq, PartialEq, )] pub struct PrestateTraceInfo { - /// The balance of the account. - #[serde(skip_serializing_if = "Option::is_none")] - pub balance: Option, - /// The nonce of the account. - #[serde(skip_serializing_if = "Option::is_none")] - pub nonce: Option, - /// The code of the contract account. - #[serde(skip_serializing_if = "Option::is_none")] - pub code: Option>, - /// The storage of the contract account. - #[serde(skip_serializing_if = "is_empty", serialize_with = "serialize_map_skip_none")] - pub storage: BTreeMap, Option>>, + /// The balance of the account. + #[serde(skip_serializing_if = "Option::is_none")] + pub balance: Option, + /// The nonce of the account. + #[serde(skip_serializing_if = "Option::is_none")] + pub nonce: Option, + /// The code of the contract account. + #[serde(skip_serializing_if = "Option::is_none")] + pub code: Option>, + /// The storage of the contract account. + #[serde( + skip_serializing_if = "is_empty", + serialize_with = "serialize_map_skip_none" + )] + pub storage: BTreeMap, Option>>, } /// Returns true if the map has no `Some` element pub fn is_empty(map: &BTreeMap>) -> bool { - !map.values().any(|v| v.is_some()) + !map.values().any(|v| v.is_some()) } /// Serializes a map, skipping `None` values. pub fn serialize_map_skip_none( - map: &BTreeMap>, - serializer: S, + map: &BTreeMap>, + serializer: S, ) -> Result where - S: Serializer, - K: serde::Serialize, - V: serde::Serialize, + S: Serializer, + K: serde::Serialize, + V: serde::Serialize, { - let len = map.values().filter(|v| v.is_some()).count(); - let mut ser_map = serializer.serialize_map(Some(len))?; + let len = map.values().filter(|v| v.is_some()).count(); + let mut ser_map = serializer.serialize_map(Some(len))?; - for (key, opt_val) in map { - if let Some(val) = opt_val { - ser_map.serialize_entry(key, val)?; - } - } + for (key, opt_val) in map { + if let Some(val) = opt_val { + ser_map.serialize_entry(key, val)?; + } + } - ser_map.end() + ser_map.end() } /// The type of tracer to use. @@ -198,41 +224,45 @@ where #[derive(TypeInfo, Debug, Clone, Encode, Decode, Serialize, Deserialize, PartialEq)] #[serde(tag = "tracer", content = "tracerConfig", rename_all = "camelCase")] pub enum TracerType { - /// A tracer that traces calls. - CallTracer(Option), + /// A tracer that traces calls. + CallTracer(Option), - /// A tracer that traces the prestate. - PrestateTracer(Option), + /// A tracer that traces the prestate. + PrestateTracer(Option), } impl From for TracerType { - fn from(config: CallTracerConfig) -> Self { - TracerType::CallTracer(Some(config)) - } + fn from(config: CallTracerConfig) -> Self { + TracerType::CallTracer(Some(config)) + } } impl Default for TracerType { - fn default() -> Self { - TracerType::CallTracer(Some(CallTracerConfig::default())) - } + fn default() -> Self { + TracerType::CallTracer(Some(CallTracerConfig::default())) + } } /// The configuration for the prestate tracer. #[derive(Clone, Debug, Decode, Serialize, Deserialize, Encode, PartialEq, TypeInfo)] #[serde(default, rename_all = "camelCase")] pub struct PrestateTracerConfig { - /// Whether to include the diff mode in the trace. - pub diff_mode: bool, + /// Whether to include the diff mode in the trace. + pub diff_mode: bool, - /// Whether to include storage in the trace. - pub disable_storage: bool, + /// Whether to include storage in the trace. + pub disable_storage: bool, - /// Whether to include code in the trace. - pub disable_code: bool, + /// Whether to include code in the trace. + pub disable_code: bool, } impl Default for PrestateTracerConfig { - fn default() -> Self { - Self { diff_mode: false, disable_storage: false, disable_code: false } - } -} \ No newline at end of file + fn default() -> Self { + Self { + diff_mode: false, + disable_storage: false, + disable_code: false, + } + } +} diff --git a/crates/revive/src/hex_serde.rs b/crates/revive/src/hex_serde.rs index e57926a8fd2..15fcd849ded 100644 --- a/crates/revive/src/hex_serde.rs +++ b/crates/revive/src/hex_serde.rs @@ -15,14 +15,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -use alloc::{format, string::String, vec::Vec}; +use alloc::{ + format, + string::String, + vec::Vec, +}; use alloy_core::hex; -use serde::{Deserialize, Deserializer, Serializer}; +use serde::{ + Deserialize, + Deserializer, + Serializer, +}; pub trait HexCodec: Sized { - type Error; - fn to_hex(&self) -> String; - fn from_hex(s: String) -> Result; + type Error; + fn to_hex(&self) -> String; + fn from_hex(s: String) -> Result; } macro_rules! impl_hex_codec { @@ -44,42 +52,44 @@ macro_rules! impl_hex_codec { impl_hex_codec!(u8, u32); impl HexCodec for [u8; T] { - type Error = hex::FromHexError; - fn to_hex(&self) -> String { - format!("0x{}", hex::encode(self)) - } - fn from_hex(s: String) -> Result { - let data = hex::decode(s.trim_start_matches("0x"))?; - data.try_into().map_err(|_| hex::FromHexError::InvalidStringLength) - } + type Error = hex::FromHexError; + fn to_hex(&self) -> String { + format!("0x{}", hex::encode(self)) + } + fn from_hex(s: String) -> Result { + let data = hex::decode(s.trim_start_matches("0x"))?; + data.try_into() + .map_err(|_| hex::FromHexError::InvalidStringLength) + } } impl HexCodec for Vec { - type Error = hex::FromHexError; - fn to_hex(&self) -> String { - format!("0x{}", hex::encode(self)) - } - fn from_hex(s: String) -> Result { - hex::decode(s.trim_start_matches("0x")) - } + type Error = hex::FromHexError; + fn to_hex(&self) -> String { + format!("0x{}", hex::encode(self)) + } + fn from_hex(s: String) -> Result { + hex::decode(s.trim_start_matches("0x")) + } } pub fn serialize(value: &T, serializer: S) -> Result where - S: Serializer, - T: HexCodec, + S: Serializer, + T: HexCodec, { - let s = value.to_hex(); - serializer.serialize_str(&s) + let s = value.to_hex(); + serializer.serialize_str(&s) } pub fn deserialize<'de, D, T>(deserializer: D) -> Result where - D: Deserializer<'de>, - T: HexCodec, - ::Error: core::fmt::Debug, + D: Deserializer<'de>, + T: HexCodec, + ::Error: core::fmt::Debug, { - let s = String::deserialize(deserializer)?; - let value = T::from_hex(s).map_err(|e| serde::de::Error::custom(format!("{:?}", e)))?; - Ok(value) -} \ No newline at end of file + let s = String::deserialize(deserializer)?; + let value = + T::from_hex(s).map_err(|e| serde::de::Error::custom(format!("{:?}", e)))?; + Ok(value) +} diff --git a/crates/revive/src/lib.rs b/crates/revive/src/lib.rs index a54bc14d273..192de0ab247 100644 --- a/crates/revive/src/lib.rs +++ b/crates/revive/src/lib.rs @@ -5,4 +5,11 @@ pub mod evm; mod hex_serde; mod primitives; -pub use primitives::{ContractResult, ExecReturnValue, InstantiateReturnValue, StorageDeposit, CodeUploadResult, CodeUploadReturnValue}; +pub use primitives::{ + CodeUploadResult, + CodeUploadReturnValue, + ContractResult, + ExecReturnValue, + InstantiateReturnValue, + StorageDeposit, +}; diff --git a/crates/revive/src/primitives.rs b/crates/revive/src/primitives.rs index 275dbfcfc8c..71ae9df92aa 100644 --- a/crates/revive/src/primitives.rs +++ b/crates/revive/src/primitives.rs @@ -1,188 +1,209 @@ #![cfg_attr(not(feature = "std"), allow(unused_imports))] -use pallet_revive_uapi::ReturnFlags; -use scale::{Decode, Encode, MaxEncodedLen}; use alloc::vec::Vec; -use scale_info::TypeInfo; use frame_support::weights::Weight; -use ink_primitives::{ - H160, +use ink_primitives::H160; +use pallet_revive_uapi::ReturnFlags; +use scale::{ + Decode, + Encode, + MaxEncodedLen, }; +use scale_info::TypeInfo; use sp_runtime::{ - traits::{Saturating, Zero}, - DispatchError, RuntimeDebug, + DispatchError, + RuntimeDebug, + traits::{ + Saturating, + Zero, + }, }; /// The amount of balance that was either charged or refunded in order to pay for storage. #[derive( - Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + MaxEncodedLen, + RuntimeDebug, + TypeInfo, )] pub enum StorageDeposit { - /// The transaction reduced storage consumption. - /// - /// This means that the specified amount of balance was transferred from the involved - /// deposit accounts to the origin. - Refund(Balance), - /// The transaction increased storage consumption. - /// - /// This means that the specified amount of balance was transferred from the origin - /// to the involved deposit accounts. - Charge(Balance), + /// The transaction reduced storage consumption. + /// + /// This means that the specified amount of balance was transferred from the involved + /// deposit accounts to the origin. + Refund(Balance), + /// The transaction increased storage consumption. + /// + /// This means that the specified amount of balance was transferred from the origin + /// to the involved deposit accounts. + Charge(Balance), } impl Default for StorageDeposit { - fn default() -> Self { - Self::Charge(Zero::zero()) - } + fn default() -> Self { + Self::Charge(Zero::zero()) + } } impl StorageDeposit { - /// Returns how much balance is charged or `0` in case of a refund. - pub fn charge_or_zero(&self) -> Balance { - match self { - Self::Charge(amount) => *amount, - Self::Refund(_) => Zero::zero(), - } - } + /// Returns how much balance is charged or `0` in case of a refund. + pub fn charge_or_zero(&self) -> Balance { + match self { + Self::Charge(amount) => *amount, + Self::Refund(_) => Zero::zero(), + } + } - pub fn is_zero(&self) -> bool { - match self { - Self::Charge(amount) => amount.is_zero(), - Self::Refund(amount) => amount.is_zero(), - } - } + pub fn is_zero(&self) -> bool { + match self { + Self::Charge(amount) => amount.is_zero(), + Self::Refund(amount) => amount.is_zero(), + } + } } impl StorageDeposit where - Balance: Saturating + Ord + Copy, + Balance: Saturating + Ord + Copy, { - /// This is essentially a saturating signed add. - pub fn saturating_add(&self, rhs: &Self) -> Self { - use StorageDeposit::*; - match (self, rhs) { - (Charge(lhs), Charge(rhs)) => Charge(lhs.saturating_add(*rhs)), - (Refund(lhs), Refund(rhs)) => Refund(lhs.saturating_add(*rhs)), - (Charge(lhs), Refund(rhs)) => - if lhs >= rhs { - Charge(lhs.saturating_sub(*rhs)) - } else { - Refund(rhs.saturating_sub(*lhs)) - }, - (Refund(lhs), Charge(rhs)) => - if lhs > rhs { - Refund(lhs.saturating_sub(*rhs)) - } else { - Charge(rhs.saturating_sub(*lhs)) - }, - } - } + /// This is essentially a saturating signed add. + pub fn saturating_add(&self, rhs: &Self) -> Self { + use StorageDeposit::*; + match (self, rhs) { + (Charge(lhs), Charge(rhs)) => Charge(lhs.saturating_add(*rhs)), + (Refund(lhs), Refund(rhs)) => Refund(lhs.saturating_add(*rhs)), + (Charge(lhs), Refund(rhs)) => { + if lhs >= rhs { + Charge(lhs.saturating_sub(*rhs)) + } else { + Refund(rhs.saturating_sub(*lhs)) + } + } + (Refund(lhs), Charge(rhs)) => { + if lhs > rhs { + Refund(lhs.saturating_sub(*rhs)) + } else { + Charge(rhs.saturating_sub(*lhs)) + } + } + } + } - /// This is essentially a saturating signed sub. - pub fn saturating_sub(&self, rhs: &Self) -> Self { - use StorageDeposit::*; - match (self, rhs) { - (Charge(lhs), Refund(rhs)) => Charge(lhs.saturating_add(*rhs)), - (Refund(lhs), Charge(rhs)) => Refund(lhs.saturating_add(*rhs)), - (Charge(lhs), Charge(rhs)) => - if lhs >= rhs { - Charge(lhs.saturating_sub(*rhs)) - } else { - Refund(rhs.saturating_sub(*lhs)) - }, - (Refund(lhs), Refund(rhs)) => - if lhs > rhs { - Refund(lhs.saturating_sub(*rhs)) - } else { - Charge(rhs.saturating_sub(*lhs)) - }, - } - } + /// This is essentially a saturating signed sub. + pub fn saturating_sub(&self, rhs: &Self) -> Self { + use StorageDeposit::*; + match (self, rhs) { + (Charge(lhs), Refund(rhs)) => Charge(lhs.saturating_add(*rhs)), + (Refund(lhs), Charge(rhs)) => Refund(lhs.saturating_add(*rhs)), + (Charge(lhs), Charge(rhs)) => { + if lhs >= rhs { + Charge(lhs.saturating_sub(*rhs)) + } else { + Refund(rhs.saturating_sub(*lhs)) + } + } + (Refund(lhs), Refund(rhs)) => { + if lhs > rhs { + Refund(lhs.saturating_sub(*rhs)) + } else { + Charge(rhs.saturating_sub(*lhs)) + } + } + } + } - /// If the amount of deposit (this type) is constrained by a `limit` this calculates how - /// much balance (if any) is still available from this limit. - /// - /// # Note - /// - /// In case of a refund the return value can be larger than `limit`. - pub fn available(&self, limit: &Balance) -> Balance { - use StorageDeposit::*; - match self { - Charge(amount) => limit.saturating_sub(*amount), - Refund(amount) => limit.saturating_add(*amount), - } - } + /// If the amount of deposit (this type) is constrained by a `limit` this calculates + /// how much balance (if any) is still available from this limit. + /// + /// # Note + /// + /// In case of a refund the return value can be larger than `limit`. + pub fn available(&self, limit: &Balance) -> Balance { + use StorageDeposit::*; + match self { + Charge(amount) => limit.saturating_sub(*amount), + Refund(amount) => limit.saturating_add(*amount), + } + } } -/// Result type of a `bare_call` or `bare_instantiate` call as well as `ContractsApi::call` and -/// `ContractsApi::instantiate`. +/// Result type of a `bare_call` or `bare_instantiate` call as well as +/// `ContractsApi::call` and `ContractsApi::instantiate`. /// /// It contains the execution result together with some auxiliary information. /// /// #Note /// -/// It has been extended to include `events` at the end of the struct while not bumping the -/// `ContractsApi` version. Therefore when SCALE decoding a `ContractResult` its trailing data -/// should be ignored to avoid any potential compatibility issues. +/// It has been extended to include `events` at the end of the struct while not bumping +/// the `ContractsApi` version. Therefore when SCALE decoding a `ContractResult` its +/// trailing data should be ignored to avoid any potential compatibility issues. #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct ContractResult { - /// How much weight was consumed during execution. - pub gas_consumed: Weight, - /// How much weight is required as gas limit in order to execute this call. - /// - /// This value should be used to determine the weight limit for on-chain execution. - /// - /// # Note - /// - /// This can only be different from [`Self::gas_consumed`] when weight pre charging - /// is used. Currently, only `seal_call_runtime` makes use of pre charging. - /// Additionally, any `seal_call` or `seal_instantiate` makes use of pre-charging - /// when a non-zero `gas_limit` argument is supplied. - pub gas_required: Weight, - /// How much balance was paid by the origin into the contract's deposit account in order to - /// pay for storage. - /// - /// The storage deposit is never actually charged from the origin in case of [`Self::result`] - /// is `Err`. This is because on error all storage changes are rolled back including the - /// payment of the deposit. - pub storage_deposit: StorageDeposit, - /// The execution result of the vm binary code. - pub result: Result, + /// How much weight was consumed during execution. + pub gas_consumed: Weight, + /// How much weight is required as gas limit in order to execute this call. + /// + /// This value should be used to determine the weight limit for on-chain execution. + /// + /// # Note + /// + /// This can only be different from [`Self::gas_consumed`] when weight pre charging + /// is used. Currently, only `seal_call_runtime` makes use of pre charging. + /// Additionally, any `seal_call` or `seal_instantiate` makes use of pre-charging + /// when a non-zero `gas_limit` argument is supplied. + pub gas_required: Weight, + /// How much balance was paid by the origin into the contract's deposit account in + /// order to pay for storage. + /// + /// The storage deposit is never actually charged from the origin in case of + /// [`Self::result`] is `Err`. This is because on error all storage changes are + /// rolled back including the payment of the deposit. + pub storage_deposit: StorageDeposit, + /// The execution result of the vm binary code. + pub result: Result, } /// Output of a contract call or instantiation which ran to completion. #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Default)] pub struct ExecReturnValue { - /// Flags passed along by `seal_return`. Empty when `seal_return` was never called. - pub flags: ReturnFlags, - /// Buffer passed along by `seal_return`. Empty when `seal_return` was never called. - pub data: Vec, + /// Flags passed along by `seal_return`. Empty when `seal_return` was never called. + pub flags: ReturnFlags, + /// Buffer passed along by `seal_return`. Empty when `seal_return` was never called. + pub data: Vec, } impl ExecReturnValue { - /// The contract did revert all storage changes. - pub fn did_revert(&self) -> bool { - self.flags.contains(ReturnFlags::REVERT) - } + /// The contract did revert all storage changes. + pub fn did_revert(&self) -> bool { + self.flags.contains(ReturnFlags::REVERT) + } } /// The result of a successful contract instantiation. #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct InstantiateReturnValue { - /// The output of the called constructor. - pub result: ExecReturnValue, - /// The address of the new contract. - pub addr: H160, + /// The output of the called constructor. + pub result: ExecReturnValue, + /// The address of the new contract. + pub addr: H160, } /// The result of successfully uploading a contract. #[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo)] pub struct CodeUploadReturnValue { - /// The key under which the new code is stored. - pub code_hash: sp_core::H256, - /// The deposit that was reserved at the caller. Is zero when the code already existed. - pub deposit: Balance, + /// The key under which the new code is stored. + pub code_hash: sp_core::H256, + /// The deposit that was reserved at the caller. Is zero when the code already + /// existed. + pub deposit: Balance, } /// Result type of a `bare_code_upload` call. -pub type CodeUploadResult = Result, DispatchError>; +pub type CodeUploadResult = + Result, DispatchError>; From 4797cc4f848d67697910158339359ee25d866a54 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Wed, 24 Sep 2025 20:32:59 +0200 Subject: [PATCH 04/10] chore: format in tests --- crates/revive/Cargo.toml | 1 - .../solidity-abi/sol-cross-contract/e2e_tests.rs | 4 ++-- integration-tests/solidity-abi/sol-encoding/e2e_tests.rs | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/revive/Cargo.toml b/crates/revive/Cargo.toml index 1ea8d80561c..14419d8c037 100644 --- a/crates/revive/Cargo.toml +++ b/crates/revive/Cargo.toml @@ -33,7 +33,6 @@ std = [ "scale-info/std", "frame-support/std", "ink_primitives/std", - # "sp-weights/std", "sp-core/std", "sp-runtime/std", "serde/std", diff --git a/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs b/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs index 7df0d806c0c..0d6ecf6aeee 100644 --- a/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs +++ b/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs @@ -12,8 +12,8 @@ use ink::{ SolEncode, primitives::DepositLimit, }; -use ink_sandbox::frame_system::pallet_prelude::OriginFor; use ink_revive::ExecReturnValue; +use ink_sandbox::frame_system::pallet_prelude::OriginFor; const STORAGE_DEPOSIT_LIMIT: DepositLimit = DepositLimit::UnsafeOnlyForDryRun; @@ -175,7 +175,7 @@ impl ContractSandbox { let call_raw = result.result.expect("sandbox call contract failed"); ExecReturnValue { flags: call_raw.flags, - data: call_raw.data + data: call_raw.data, } } } diff --git a/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs b/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs index a5a5285907a..ca45c8a58c6 100644 --- a/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs +++ b/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs @@ -6,13 +6,13 @@ use ink::{ primitives::DepositLimit, }; use ink_e2e::ContractsRegistry; +use ink_revive::ExecReturnValue; use ink_sandbox::{ DefaultSandbox, Sandbox, api::prelude::*, frame_system::pallet_prelude::OriginFor, }; -use ink_revive::ExecReturnValue; const STORAGE_DEPOSIT_LIMIT: DepositLimit = DepositLimit::UnsafeOnlyForDryRun; @@ -127,7 +127,7 @@ impl ContractSandbox { .expect("sandbox call contract failed"); ExecReturnValue { flags: call_raw.flags, - data: call_raw.data + data: call_raw.data, } } } From daf7837b4f6ded224b8ceca877aab4fd36ec953a Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Thu, 25 Sep 2025 09:48:39 +0200 Subject: [PATCH 05/10] docs: licenses in ink_revive files --- crates/revive/src/evm.rs | 17 +++++++++++++++++ crates/revive/src/lib.rs | 14 ++++++++++++++ crates/revive/src/primitives.rs | 17 +++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/crates/revive/src/evm.rs b/crates/revive/src/evm.rs index 03611a9d4a2..77c78ac5bb3 100644 --- a/crates/revive/src/evm.rs +++ b/crates/revive/src/evm.rs @@ -1,3 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use alloc::{ collections::BTreeMap, string::String, diff --git a/crates/revive/src/lib.rs b/crates/revive/src/lib.rs index 192de0ab247..dde5d22af58 100644 --- a/crates/revive/src/lib.rs +++ b/crates/revive/src/lib.rs @@ -1,3 +1,17 @@ +// Copyright (C) Use Ink (UK) Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #![cfg_attr(not(feature = "std"), no_std)] extern crate alloc; diff --git a/crates/revive/src/primitives.rs b/crates/revive/src/primitives.rs index 71ae9df92aa..bb54c3fbaf9 100644 --- a/crates/revive/src/primitives.rs +++ b/crates/revive/src/primitives.rs @@ -1,3 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #![cfg_attr(not(feature = "std"), allow(unused_imports))] use alloc::vec::Vec; From 842163e805fb047f17369ec54da89ba683375da5 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Thu, 25 Sep 2025 14:44:55 +0200 Subject: [PATCH 06/10] refactor: move pallet_revive deps into ink_sandbox --- crates/e2e/sandbox/src/lib.rs | 56 +++++++++++++++++++++++ crates/e2e/src/sandbox_client.rs | 77 +++++--------------------------- 2 files changed, 68 insertions(+), 65 deletions(-) diff --git a/crates/e2e/sandbox/src/lib.rs b/crates/e2e/sandbox/src/lib.rs index 3cae6bb33d9..64d5605d7fc 100644 --- a/crates/e2e/sandbox/src/lib.rs +++ b/crates/e2e/sandbox/src/lib.rs @@ -17,6 +17,10 @@ use frame_system::{ }, }; use ink_primitives::U256; +use ink_revive::evm::{ + CallLog, + CallTrace, +}; pub use macros::{ BlockBuilder, DefaultSandbox, @@ -170,3 +174,55 @@ where let evm_value: U256 = value.into(); native_to_eth_ratio.saturating_mul(evm_value) } + +/// Convert a `pallet_revive::CallTrace` (sandbox) into an `ink_revive::CallTrace` (API). +pub fn to_revive_trace(t: pallet_revive::evm::CallTrace) -> CallTrace { + CallTrace { + from: t.from, + gas: t.gas, + gas_used: t.gas_used, + to: t.to, + input: t.input.0, + output: t.output.0, + error: t.error, + revert_reason: t.revert_reason, + calls: t.calls.into_iter().map(to_revive_trace).collect(), + logs: t + .logs + .into_iter() + .map(|log| { + CallLog { + address: log.address, + topics: log.topics, + data: log.data.0, + ..Default::default() + } + }) + .collect(), + value: t.value, + call_type: to_revive_call_type(t.call_type), + } +} + +/// Convert a `pallet_revive::CallType` into an `ink_revive::evm::CallType`. +fn to_revive_call_type(ct: pallet_revive::evm::CallType) -> ink_revive::evm::CallType { + match ct { + pallet_revive::evm::CallType::Call => ink_revive::evm::CallType::Call, + pallet_revive::evm::CallType::StaticCall => ink_revive::evm::CallType::StaticCall, + pallet_revive::evm::CallType::DelegateCall => { + ink_revive::evm::CallType::DelegateCall + } + pallet_revive::evm::CallType::Create => ink_revive::evm::CallType::Create, + pallet_revive::evm::CallType::Create2 => ink_revive::evm::CallType::Create2, + } +} + +/// Convert a `ink_revive::StorageDeposit` into an `ink_revive::StorageDeposit`. +pub fn to_revive_storage_deposit( + sd: pallet_revive::StorageDeposit, +) -> ink_revive::StorageDeposit { + match sd { + pallet_revive::StorageDeposit::Charge(b) => ink_revive::StorageDeposit::Charge(b), + pallet_revive::StorageDeposit::Refund(b) => ink_revive::StorageDeposit::Refund(b), + } +} diff --git a/crates/e2e/src/sandbox_client.rs b/crates/e2e/src/sandbox_client.rs index 13487470402..e670c211057 100644 --- a/crates/e2e/src/sandbox_client.rs +++ b/crates/e2e/src/sandbox_client.rs @@ -66,10 +66,7 @@ use ink_revive::{ CodeUploadReturnValue, ExecReturnValue, InstantiateReturnValue, - evm::{ - CallLog, - CallTrace, - }, + evm::CallTrace, }; use ink_sandbox::{ AccountIdFor, @@ -81,17 +78,19 @@ use ink_sandbox::{ frame_system::pallet_prelude::OriginFor, pallet_balances, pallet_revive, -}; -use jsonrpsee::core::async_trait; -use pallet_revive::{ - AddressMapper, - MomentOf, - evm::{ - CallTracerConfig, - Trace, - TracerType, + pallet_revive::{ + AddressMapper, + MomentOf, + evm::{ + CallTracerConfig, + Trace, + TracerType, + }, }, + to_revive_storage_deposit, + to_revive_trace, }; +use jsonrpsee::core::async_trait; use scale::Decode; use sp_core::{ Pair as _, @@ -843,55 +842,3 @@ where let origin = RawOrigin::Signed(caller); OriginFor::::from(origin) } - -/// Convert a `pallet_revive::CallTrace` (sandbox) into an `ink_revive::CallTrace` (API). -fn to_revive_trace(t: pallet_revive::evm::CallTrace) -> CallTrace { - CallTrace { - from: t.from, - gas: t.gas, - gas_used: t.gas_used, - to: t.to, - input: t.input.0, - output: t.output.0, - error: t.error, - revert_reason: t.revert_reason, - calls: t.calls.into_iter().map(to_revive_trace).collect(), - logs: t - .logs - .into_iter() - .map(|log| { - CallLog { - address: log.address, - topics: log.topics, - data: log.data.0, - ..Default::default() - } - }) - .collect(), - value: t.value, - call_type: to_revive_call_type(t.call_type), - } -} - -/// Convert a `pallet_revive::CallType` into an `ink_revive::evm::CallType`. -fn to_revive_call_type(ct: pallet_revive::evm::CallType) -> ink_revive::evm::CallType { - match ct { - pallet_revive::evm::CallType::Call => ink_revive::evm::CallType::Call, - pallet_revive::evm::CallType::StaticCall => ink_revive::evm::CallType::StaticCall, - pallet_revive::evm::CallType::DelegateCall => { - ink_revive::evm::CallType::DelegateCall - } - pallet_revive::evm::CallType::Create => ink_revive::evm::CallType::Create, - pallet_revive::evm::CallType::Create2 => ink_revive::evm::CallType::Create2, - } -} - -/// Convert a `ink_revive::StorageDeposit` into an `ink_revive::StorageDeposit`. -fn to_revive_storage_deposit( - sd: pallet_revive::StorageDeposit, -) -> ink_revive::StorageDeposit { - match sd { - pallet_revive::StorageDeposit::Charge(b) => ink_revive::StorageDeposit::Charge(b), - pallet_revive::StorageDeposit::Refund(b) => ink_revive::StorageDeposit::Refund(b), - } -} From bfbbdaa4e380071821eb85ce453239c9c5df486b Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Thu, 25 Sep 2025 14:50:43 +0200 Subject: [PATCH 07/10] refactor: rename ink_revive to ink_revive_types --- Cargo.lock | 6 ++-- Cargo.toml | 4 +-- crates/e2e/Cargo.toml | 4 +-- crates/e2e/sandbox/Cargo.toml | 4 +-- crates/e2e/sandbox/src/lib.rs | 35 ++++++++++++------- crates/e2e/src/backend.rs | 2 +- crates/e2e/src/contract_results.rs | 2 +- crates/e2e/src/error.rs | 2 +- crates/e2e/src/lib.rs | 2 +- crates/e2e/src/sandbox_client.rs | 2 +- crates/e2e/src/subxt_client.rs | 2 +- crates/e2e/src/xts.rs | 2 +- crates/{revive => revive-types}/Cargo.toml | 2 +- crates/{revive => revive-types}/src/evm.rs | 0 .../{revive => revive-types}/src/hex_serde.rs | 0 crates/{revive => revive-types}/src/lib.rs | 0 .../src/primitives.rs | 0 .../sol-cross-contract/Cargo.toml | 2 +- .../sol-cross-contract/e2e_tests.rs | 2 +- .../solidity-abi/sol-encoding/Cargo.toml | 2 +- .../solidity-abi/sol-encoding/e2e_tests.rs | 2 +- 21 files changed, 43 insertions(+), 34 deletions(-) rename crates/{revive => revive-types}/Cargo.toml (97%) rename crates/{revive => revive-types}/src/evm.rs (100%) rename crates/{revive => revive-types}/src/hex_serde.rs (100%) rename crates/{revive => revive-types}/src/lib.rs (100%) rename crates/{revive => revive-types}/src/primitives.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 7a1e0b42b7a..92d60251280 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3485,7 +3485,7 @@ dependencies = [ "ink_e2e_macro", "ink_env", "ink_primitives 6.0.0-alpha.4", - "ink_revive", + "ink_revive_types", "ink_sandbox", "itertools 0.14.0", "jsonrpsee", @@ -3714,7 +3714,7 @@ dependencies = [ ] [[package]] -name = "ink_revive" +name = "ink_revive_types" version = "6.0.0-alpha.4" dependencies = [ "alloy-core", @@ -3737,7 +3737,7 @@ dependencies = [ "frame-support", "frame-system", "ink_primitives 6.0.0-alpha.4", - "ink_revive", + "ink_revive_types", "pallet-balances", "pallet-revive", "pallet-timestamp", diff --git a/Cargo.toml b/Cargo.toml index 3dff31d072c..0cafe5d2405 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ members = [ "crates/ink/ir", "crates/ink/macro", "crates/metadata", - "crates/revive", + "crates/revive-types", "crates/prelude", "crates/primitives", "crates/storage", @@ -123,7 +123,7 @@ ink_macro = { version = "=6.0.0-alpha.4", path = "crates/ink/macro", default-fea ink_metadata = { version = "=6.0.0-alpha.4", path = "crates/metadata", default-features = false } ink_prelude = { version = "=6.0.0-alpha.4", path = "crates/prelude", default-features = false } ink_primitives = { version = "=6.0.0-alpha.4", path = "crates/primitives", default-features = false } -ink_revive = { version = "=6.0.0-alpha.4", path = "crates/revive", default-features = false } +ink_revive_types = { version = "=6.0.0-alpha.4", path = "crates/revive-types", default-features = false } ink_storage = { version = "=6.0.0-alpha.4", path = "crates/storage", default-features = false } ink_storage_traits = { version = "=6.0.0-alpha.4", path = "crates/storage/traits", default-features = false } diff --git a/crates/e2e/Cargo.toml b/crates/e2e/Cargo.toml index a4186782dec..c65f1cc9e0b 100644 --- a/crates/e2e/Cargo.toml +++ b/crates/e2e/Cargo.toml @@ -19,7 +19,7 @@ ink_e2e_macro = { workspace = true, default-features = true } ink = { workspace = true, default-features = true } ink_env = { workspace = true, default-features = true } ink_primitives = { workspace = true, default-features = true } -ink_revive = { workspace = true, default-features = true } +ink_revive_types = { workspace = true, default-features = true } ink_sandbox = { version = "=6.0.0-alpha.4", path = "./sandbox", optional = true } cargo_metadata = { workspace = true } @@ -71,7 +71,7 @@ std = [ "sp-runtime-interface/std", "sp-weights/std", "ink_e2e_macro/std", - "ink_revive/std", + "ink_revive_types/std", "ink_sandbox?/std", "frame-support/std", ] diff --git a/crates/e2e/sandbox/Cargo.toml b/crates/e2e/sandbox/Cargo.toml index dacc4dcdb7d..608d2f20382 100644 --- a/crates/e2e/sandbox/Cargo.toml +++ b/crates/e2e/sandbox/Cargo.toml @@ -23,7 +23,7 @@ sp-externalities = { workspace = true } sp-runtime = { workspace = true } sp-io = { workspace = true } ink_primitives = { workspace = true } -ink_revive = { workspace = true } +ink_revive_types = { workspace = true } paste = { workspace = true } scale-info = { workspace = true } @@ -38,7 +38,7 @@ std = [ "frame-system/std", "frame-metadata/std", "ink_primitives/std", - "ink_revive/std", + "ink_revive_types/std", "pallet-balances/std", "pallet-revive/std", "pallet-timestamp/std", diff --git a/crates/e2e/sandbox/src/lib.rs b/crates/e2e/sandbox/src/lib.rs index 64d5605d7fc..4f88bb95f34 100644 --- a/crates/e2e/sandbox/src/lib.rs +++ b/crates/e2e/sandbox/src/lib.rs @@ -17,7 +17,7 @@ use frame_system::{ }, }; use ink_primitives::U256; -use ink_revive::evm::{ +use ink_revive_types::evm::{ CallLog, CallTrace, }; @@ -175,7 +175,8 @@ where native_to_eth_ratio.saturating_mul(evm_value) } -/// Convert a `pallet_revive::CallTrace` (sandbox) into an `ink_revive::CallTrace` (API). +/// Convert a `pallet_revive::CallTrace` (sandbox) into an `ink_revive_types::CallTrace` +/// (API). pub fn to_revive_trace(t: pallet_revive::evm::CallTrace) -> CallTrace { CallTrace { from: t.from, @@ -204,25 +205,33 @@ pub fn to_revive_trace(t: pallet_revive::evm::CallTrace) -> CallTrace { } } -/// Convert a `pallet_revive::CallType` into an `ink_revive::evm::CallType`. -fn to_revive_call_type(ct: pallet_revive::evm::CallType) -> ink_revive::evm::CallType { +/// Convert a `pallet_revive::CallType` into an `ink_revive_types::evm::CallType`. +fn to_revive_call_type( + ct: pallet_revive::evm::CallType, +) -> ink_revive_types::evm::CallType { match ct { - pallet_revive::evm::CallType::Call => ink_revive::evm::CallType::Call, - pallet_revive::evm::CallType::StaticCall => ink_revive::evm::CallType::StaticCall, + pallet_revive::evm::CallType::Call => ink_revive_types::evm::CallType::Call, + pallet_revive::evm::CallType::StaticCall => { + ink_revive_types::evm::CallType::StaticCall + } pallet_revive::evm::CallType::DelegateCall => { - ink_revive::evm::CallType::DelegateCall + ink_revive_types::evm::CallType::DelegateCall } - pallet_revive::evm::CallType::Create => ink_revive::evm::CallType::Create, - pallet_revive::evm::CallType::Create2 => ink_revive::evm::CallType::Create2, + pallet_revive::evm::CallType::Create => ink_revive_types::evm::CallType::Create, + pallet_revive::evm::CallType::Create2 => ink_revive_types::evm::CallType::Create2, } } -/// Convert a `ink_revive::StorageDeposit` into an `ink_revive::StorageDeposit`. +/// Convert a `pallet_revive::StorageDeposit` into an `ink_revive_types::StorageDeposit`. pub fn to_revive_storage_deposit( sd: pallet_revive::StorageDeposit, -) -> ink_revive::StorageDeposit { +) -> ink_revive_types::StorageDeposit { match sd { - pallet_revive::StorageDeposit::Charge(b) => ink_revive::StorageDeposit::Charge(b), - pallet_revive::StorageDeposit::Refund(b) => ink_revive::StorageDeposit::Refund(b), + pallet_revive::StorageDeposit::Charge(b) => { + ink_revive_types::StorageDeposit::Charge(b) + } + pallet_revive::StorageDeposit::Refund(b) => { + ink_revive_types::StorageDeposit::Refund(b) + } } } diff --git a/crates/e2e/src/backend.rs b/crates/e2e/src/backend.rs index 74907d79dbb..958c7d8c304 100644 --- a/crates/e2e/src/backend.rs +++ b/crates/e2e/src/backend.rs @@ -21,7 +21,7 @@ use ink_primitives::{ H160, abi::AbiEncodeWith, }; -use ink_revive::evm::CallTrace; +use ink_revive_types::evm::CallTrace; use jsonrpsee::core::async_trait; use sp_weights::Weight; use subxt::dynamic::Value; diff --git a/crates/e2e/src/contract_results.rs b/crates/e2e/src/contract_results.rs index 07de4163540..5bb49c0fa27 100644 --- a/crates/e2e/src/contract_results.rs +++ b/crates/e2e/src/contract_results.rs @@ -36,7 +36,7 @@ use ink_primitives::{ H256, MessageResult, }; -use ink_revive::{ +use ink_revive_types::{ CodeUploadResult, ExecReturnValue, InstantiateReturnValue, diff --git a/crates/e2e/src/error.rs b/crates/e2e/src/error.rs index 369d233d922..8fb99044301 100644 --- a/crates/e2e/src/error.rs +++ b/crates/e2e/src/error.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use ink_revive::evm::CallTrace; +use ink_revive_types::evm::CallTrace; use std::fmt; /// An error occurred while interacting with the E2E backend. diff --git a/crates/e2e/src/lib.rs b/crates/e2e/src/lib.rs index 34b414192ca..096d9e96b5d 100644 --- a/crates/e2e/src/lib.rs +++ b/crates/e2e/src/lib.rs @@ -53,7 +53,7 @@ pub use contract_results::{ UploadResult, }; pub use ink_e2e_macro::test; -pub use ink_revive::evm::CallTrace; +pub use ink_revive_types::evm::CallTrace; pub use node_proc::{ TestNodeProcess, TestNodeProcessBuilder, diff --git a/crates/e2e/src/sandbox_client.rs b/crates/e2e/src/sandbox_client.rs index e670c211057..5139bc390d5 100644 --- a/crates/e2e/src/sandbox_client.rs +++ b/crates/e2e/src/sandbox_client.rs @@ -62,7 +62,7 @@ use ink_primitives::{ U256, abi::AbiEncodeWith, }; -use ink_revive::{ +use ink_revive_types::{ CodeUploadReturnValue, ExecReturnValue, InstantiateReturnValue, diff --git a/crates/e2e/src/subxt_client.rs b/crates/e2e/src/subxt_client.rs index 110e4757785..5bc722049d7 100644 --- a/crates/e2e/src/subxt_client.rs +++ b/crates/e2e/src/subxt_client.rs @@ -73,7 +73,7 @@ use ink_primitives::{ DepositLimit, abi::AbiEncodeWith, }; -use ink_revive::evm::CallTrace; +use ink_revive_types::evm::CallTrace; use jsonrpsee::core::async_trait; use scale::{ Decode, diff --git a/crates/e2e/src/xts.rs b/crates/e2e/src/xts.rs index 025869c9ec8..0e9e488e83b 100644 --- a/crates/e2e/src/xts.rs +++ b/crates/e2e/src/xts.rs @@ -29,7 +29,7 @@ use ink_primitives::{ Address, DepositLimit, }; -use ink_revive::{ +use ink_revive_types::{ CodeUploadResult, evm::{ CallTrace, diff --git a/crates/revive/Cargo.toml b/crates/revive-types/Cargo.toml similarity index 97% rename from crates/revive/Cargo.toml rename to crates/revive-types/Cargo.toml index 14419d8c037..5a4a427993f 100644 --- a/crates/revive/Cargo.toml +++ b/crates/revive-types/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ink_revive" +name = "ink_revive_types" version.workspace = true authors.workspace = true edition.workspace = true diff --git a/crates/revive/src/evm.rs b/crates/revive-types/src/evm.rs similarity index 100% rename from crates/revive/src/evm.rs rename to crates/revive-types/src/evm.rs diff --git a/crates/revive/src/hex_serde.rs b/crates/revive-types/src/hex_serde.rs similarity index 100% rename from crates/revive/src/hex_serde.rs rename to crates/revive-types/src/hex_serde.rs diff --git a/crates/revive/src/lib.rs b/crates/revive-types/src/lib.rs similarity index 100% rename from crates/revive/src/lib.rs rename to crates/revive-types/src/lib.rs diff --git a/crates/revive/src/primitives.rs b/crates/revive-types/src/primitives.rs similarity index 100% rename from crates/revive/src/primitives.rs rename to crates/revive-types/src/primitives.rs diff --git a/integration-tests/solidity-abi/sol-cross-contract/Cargo.toml b/integration-tests/solidity-abi/sol-cross-contract/Cargo.toml index 40b5ce0e40a..dfc7b82d33e 100755 --- a/integration-tests/solidity-abi/sol-cross-contract/Cargo.toml +++ b/integration-tests/solidity-abi/sol-cross-contract/Cargo.toml @@ -12,7 +12,7 @@ sha3 = { version = "0.10", default-features = false } [dev-dependencies] ink_e2e = { path = "../../../crates/e2e", features = ["sandbox"] } ink_sandbox = { path = "../../../crates/e2e/sandbox" } -ink_revive = { path = "../../../crates/revive" } +ink_revive_types = { path = "../../../crates/revive-types" } sha3 = { version = "0.10" } other-contract-sol = { path = "other-contract-sol" } diff --git a/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs b/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs index 0d6ecf6aeee..dc2a13959bb 100644 --- a/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs +++ b/integration-tests/solidity-abi/sol-cross-contract/e2e_tests.rs @@ -12,7 +12,7 @@ use ink::{ SolEncode, primitives::DepositLimit, }; -use ink_revive::ExecReturnValue; +use ink_revive_types::ExecReturnValue; use ink_sandbox::frame_system::pallet_prelude::OriginFor; const STORAGE_DEPOSIT_LIMIT: DepositLimit = DepositLimit::UnsafeOnlyForDryRun; diff --git a/integration-tests/solidity-abi/sol-encoding/Cargo.toml b/integration-tests/solidity-abi/sol-encoding/Cargo.toml index 8d9b76e2e6d..8ac0cfcac38 100755 --- a/integration-tests/solidity-abi/sol-encoding/Cargo.toml +++ b/integration-tests/solidity-abi/sol-encoding/Cargo.toml @@ -11,7 +11,7 @@ ink = { path = "../../../crates/ink", default-features = false } [dev-dependencies] ink_e2e = { path = "../../../crates/e2e", features = ["sandbox"] } ink_sandbox = { path = "../../../crates/e2e/sandbox" } -ink_revive = { path = "../../../crates/revive" } +ink_revive_types = { path = "../../../crates/revive-types" } sha3 = { version = "0.10" } [lib] diff --git a/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs b/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs index ca45c8a58c6..1e81ae71345 100644 --- a/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs +++ b/integration-tests/solidity-abi/sol-encoding/e2e_tests.rs @@ -6,7 +6,7 @@ use ink::{ primitives::DepositLimit, }; use ink_e2e::ContractsRegistry; -use ink_revive::ExecReturnValue; +use ink_revive_types::ExecReturnValue; use ink_sandbox::{ DefaultSandbox, Sandbox, From a0d173b93bc7ced6387ee79a636fe528fb01502f Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Fri, 26 Sep 2025 08:42:47 +0200 Subject: [PATCH 08/10] docs: description and version in ink_revive_types --- crates/revive-types/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/revive-types/Cargo.toml b/crates/revive-types/Cargo.toml index 5a4a427993f..f8fb5e5c98c 100644 --- a/crates/revive-types/Cargo.toml +++ b/crates/revive-types/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "ink_revive_types" version.workspace = true -authors.workspace = true +authors = ["Use Ink ", "Parity Technologies "] edition.workspace = true license.workspace = true -description = "ink! revive primitives (placeholder)" +description = "Primitives copied from Parity's Polkadot SDK module `pallet-revive`. Copied to reduce the build times of ink! contracts." repository.workspace = true homepage.workspace = true keywords.workspace = true From dec49d12f077af993ab04575af72320aa5b4eba5 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Fri, 26 Sep 2025 08:48:26 +0200 Subject: [PATCH 09/10] refactor: remove some unnecesary dependencies --- Cargo.lock | 2 -- crates/revive-types/Cargo.toml | 4 ---- crates/revive-types/src/primitives.rs | 9 ++++++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 92d60251280..21bc59fed67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3719,13 +3719,11 @@ version = "6.0.0-alpha.4" dependencies = [ "alloy-core", "derive_more 2.0.1", - "frame-support", "ink_primitives 6.0.0-alpha.4", "pallet-revive-uapi", "parity-scale-codec", "scale-info", "serde", - "sp-core", "sp-runtime", ] diff --git a/crates/revive-types/Cargo.toml b/crates/revive-types/Cargo.toml index f8fb5e5c98c..b4adf252d7b 100644 --- a/crates/revive-types/Cargo.toml +++ b/crates/revive-types/Cargo.toml @@ -15,12 +15,10 @@ path = "src/lib.rs" [dependencies] scale = { workspace = true } -frame-support = { workspace = true } scale-info = { workspace = true } serde = { workspace = true, features = ["derive"] } ink_primitives = { workspace = true } derive_more = { workspace = true, features = ["from", "try_into"] } -sp-core = { workspace = true } sp-runtime = { workspace = true } pallet-revive-uapi = { workspace = true, features = ["scale"] } alloy-core = { workspace = true, features = ["sol-types"] } @@ -31,9 +29,7 @@ std = [ "alloy-core/std", "scale/std", "scale-info/std", - "frame-support/std", "ink_primitives/std", - "sp-core/std", "sp-runtime/std", "serde/std", ] diff --git a/crates/revive-types/src/primitives.rs b/crates/revive-types/src/primitives.rs index bb54c3fbaf9..1b41461f70f 100644 --- a/crates/revive-types/src/primitives.rs +++ b/crates/revive-types/src/primitives.rs @@ -18,8 +18,11 @@ #![cfg_attr(not(feature = "std"), allow(unused_imports))] use alloc::vec::Vec; -use frame_support::weights::Weight; -use ink_primitives::H160; +use ink_primitives::{ + H160, + H256, + Weight, +}; use pallet_revive_uapi::ReturnFlags; use scale::{ Decode, @@ -215,7 +218,7 @@ pub struct InstantiateReturnValue { #[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo)] pub struct CodeUploadReturnValue { /// The key under which the new code is stored. - pub code_hash: sp_core::H256, + pub code_hash: H256, /// The deposit that was reserved at the caller. Is zero when the code already /// existed. pub deposit: Balance, From 2a9152ff50294dcd891cd6c723be3f24cb2c288d Mon Sep 17 00:00:00 2001 From: davidsemakula Date: Fri, 26 Sep 2025 13:06:55 +0300 Subject: [PATCH 10/10] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index abdba2861da..b24fb09107f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Implements the API for the `pallet-revive` host function `to_account_id` - [#2578](https://github.com/use-ink/ink/pull/2578) - Add `#[ink::contract_ref]` attribute - [#2648](https://github.com/use-ink/ink/pull/2648) +- Add `ink_revive_types` (and remove `pallet-revive` dependency from `ink_e2e`) - [#2657](https://github.com/use-ink/ink/pull/2657) ### Changed - Marks the `pallet-revive` host function `account_id` stable - [#2578](https://github.com/use-ink/ink/pull/2578)