From dc070343b031d57388eeb0124f930930fff9fd8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Thu, 10 Aug 2023 23:37:03 +0200 Subject: [PATCH 1/3] Expose environment types for offchain tooling --- bin/node/runtime/src/lib.rs | 1 + frame/contracts/src/lib.rs | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 0462a7afde0bd..d2043cde7f3ff 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1265,6 +1265,7 @@ impl pallet_contracts::Config for Runtime { type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; #[cfg(feature = "unsafe-debug")] type Debug = (); + type Environment = (); } impl pallet_sudo::Config for Runtime { diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 0186e190fb785..ac1ebb863dcd8 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -103,7 +103,7 @@ pub mod weights; #[cfg(test)] mod tests; use crate::{ - exec::{AccountIdOf, ErrorOrigin, ExecError, Executable, Key, Stack as ExecStack}, + exec::{AccountIdOf, ErrorOrigin, ExecError, Executable, Key, Stack as ExecStack, MomentOf}, gas::GasMeter, storage::{meter::Meter as StorageMeter, ContractInfo, DeletionQueueManager}, wasm::{CodeInfo, WasmBlob}, @@ -124,7 +124,7 @@ use frame_support::{ weights::Weight, BoundedVec, RuntimeDebugNoBound, }; -use frame_system::{ensure_signed, pallet_prelude::OriginFor, EventRecord, Pallet as System}; +use frame_system::{ensure_signed, pallet_prelude::{OriginFor, BlockNumberFor}, EventRecord, Pallet as System}; use pallet_contracts_primitives::{ Code, CodeUploadResult, CodeUploadReturnValue, ContractAccessError, ContractExecResult, ContractInstantiateResult, ContractResult, ExecReturnValue, GetStorageResult, @@ -179,6 +179,19 @@ const SENTINEL: u32 = u32::MAX; /// Example: `RUST_LOG=runtime::contracts=debug my_code --dev` const LOG_TARGET: &str = "runtime::contracts"; + +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[derive(Encode, Decode, Default, TypeInfo)] +#[scale_info(skip_type_params(T))] +pub struct Environment { + account_id: PhantomData>, + balance: PhantomData>, + hash: PhantomData<::Hash>, + hasher: PhantomData<::Hashing>, + timestamp: PhantomData>, + block_number: PhantomData>, +} + #[frame_support::pallet] pub mod pallet { use super::*; @@ -360,6 +373,9 @@ pub mod pallet { /// Do **not** use it in a production environment or for benchmarking purposes. #[cfg(feature = "unsafe-debug")] type Debug: unsafe_debug::UnsafeDebug; + + #[pallet::constant] + type Environment: Get>; } #[pallet::hooks] From 6fdf41d4dbe00fa905249ab5e8798f1126a2d8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 15 Aug 2023 17:44:35 +0200 Subject: [PATCH 2/3] Use EnvironmentType wrapper --- frame/contracts/src/lib.rs | 45 +++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 6870b00509771..b675ec762ecda 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -103,7 +103,7 @@ pub mod weights; #[cfg(test)] mod tests; use crate::{ - exec::{AccountIdOf, ErrorOrigin, ExecError, Executable, Key, Stack as ExecStack, MomentOf}, + exec::{AccountIdOf, ErrorOrigin, ExecError, Executable, Key, MomentOf, Stack as ExecStack}, gas::GasMeter, storage::{meter::Meter as StorageMeter, ContractInfo, DeletionQueueManager}, wasm::{CodeInfo, WasmBlob}, @@ -122,9 +122,13 @@ use frame_support::{ ConstU32, Contains, Get, Randomness, Time, }, weights::Weight, - BoundedVec, RuntimeDebug, RuntimeDebugNoBound, + BoundedVec, DefaultNoBound, RuntimeDebug, RuntimeDebugNoBound, +}; +use frame_system::{ + ensure_signed, + pallet_prelude::{BlockNumberFor, OriginFor}, + EventRecord, Pallet as System, }; -use frame_system::{ensure_signed, pallet_prelude::{OriginFor, BlockNumberFor}, EventRecord, Pallet as System}; use pallet_contracts_primitives::{ Code, CodeUploadResult, CodeUploadReturnValue, ContractAccessError, ContractExecResult, ContractInstantiateResult, ContractResult, ExecReturnValue, GetStorageResult, @@ -179,17 +183,34 @@ const SENTINEL: u32 = u32::MAX; /// Example: `RUST_LOG=runtime::contracts=debug my_code --dev` const LOG_TARGET: &str = "runtime::contracts"; +/// Wrapper around `PhantomData` to prevent it being filtered by `scale-info`. +/// +/// `scale-info` filters out `PhantomData` fields because usually we are only interested +/// in sized types. However, when trying to communicate **types** as opposed to **values** +/// we want to have those zero sized types be included. +#[derive(Encode, Decode, DefaultNoBound, TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct EnvironmentType(PhantomData); +/// List of all runtime configurable types that are used in the communication between +/// `pallet-contracts` and any given contract. +/// +/// Since those types are configurable they can vary between +/// chains all using `pallet-contracts`. Hence we need a mechanism to communicate those types +/// in a way that can be consumed by offchain tooling. +/// +/// This type only exists in order to appear in the metadata where it can be read by +/// offchain tooling. +#[derive(Encode, Decode, DefaultNoBound, TypeInfo)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] -#[derive(Encode, Decode, Default, TypeInfo)] #[scale_info(skip_type_params(T))] pub struct Environment { - account_id: PhantomData>, - balance: PhantomData>, - hash: PhantomData<::Hash>, - hasher: PhantomData<::Hashing>, - timestamp: PhantomData>, - block_number: PhantomData>, + account_id: EnvironmentType>, + balance: EnvironmentType>, + hash: EnvironmentType<::Hash>, + hasher: EnvironmentType<::Hashing>, + timestamp: EnvironmentType>, + block_number: EnvironmentType>, } #[frame_support::pallet] @@ -374,6 +395,10 @@ pub mod pallet { #[cfg(feature = "unsafe-debug")] type Debug: unsafe_debug::UnsafeDebug; + /// Type that bundles together all the runtime configurable interface types. + /// + /// This is not a real config. We just mention the type here as constant so that + /// its type appears in the metadata. Only valid value is `()`. #[pallet::constant] type Environment: Get>; } From 9592ce664fce3353ada7c81e1ed92deca182526c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 15 Aug 2023 17:57:18 +0200 Subject: [PATCH 3/3] Add type impl to test config --- frame/contracts/src/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 3132b8e39f7da..894cc53542a9b 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -467,6 +467,7 @@ impl Config for Test { type MaxDelegateDependencies = MaxDelegateDependencies; #[cfg(feature = "unsafe-debug")] type Debug = unsafe_debug::TestDebugger; + type Environment = (); } pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]);