diff --git a/Cargo.lock b/Cargo.lock index e912e2f..4c4dde2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1295,20 +1295,13 @@ dependencies = [ "contract-metadata", "contract-transcode", "drink-test-macro", - "frame-metadata", "frame-support", "frame-system", - "pallet-balances", - "pallet-contracts", - "pallet-contracts-uapi-next", - "pallet-timestamp", + "ink_sandbox", "parity-scale-codec", "parity-scale-codec-derive", - "paste", "scale-info", "serde_json", - "sp-externalities", - "sp-io", "sp-runtime-interface", "thiserror", "wat", @@ -1324,9 +1317,8 @@ dependencies = [ "contract-transcode", "crossterm 0.26.1", "drink", - "pallet-contracts", + "ink_sandbox", "ratatui", - "sp-core", "thiserror", ] @@ -2302,6 +2294,25 @@ dependencies = [ "xxhash-rust", ] +[[package]] +name = "ink_sandbox" +version = "5.0.0" +dependencies = [ + "frame-metadata", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-contracts", + "pallet-timestamp", + "parity-scale-codec", + "paste", + "scale-info", + "sp-core", + "sp-externalities", + "sp-io", + "wat", +] + [[package]] name = "ink_storage_traits" version = "5.0.0" diff --git a/Cargo.toml b/Cargo.toml index ef5fc84..0de3de3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,19 +41,12 @@ serde_json = { version = "1.0" } syn = { version = "2" } thiserror = { version = "1.0.40" } wat = { version = "1.0.71" } +ink_sandbox = { path = "/Users/pg/github/ink/crates/e2e/sandbox" } # Substrate dependencies -frame-metadata = { version = "16.0.0" } frame-support = { version = "30.0.0"} frame-system = { version = "30.0.0" } -pallet-balances = { version = "30.0.0" } -pallet-contracts = { version = "29.0.0" } -pallet-contracts-uapi = { package = "pallet-contracts-uapi-next", version = "=6.0.3", default-features = false } -pallet-timestamp = { version = "29.0.0"} -sp-core = { version = "30.0.0" } -sp-externalities = { version = "0.27.0" } -sp-io = { version = "32.0.0" } sp-runtime-interface = { version = "26.0.0" } # Local dependencies diff --git a/drink-cli/Cargo.toml b/drink-cli/Cargo.toml index 8286ae8..fe43655 100644 --- a/drink-cli/Cargo.toml +++ b/drink-cli/Cargo.toml @@ -18,7 +18,5 @@ contract-transcode = { workspace = true } ratatui = { workspace = true, features = ["all-widgets"] } thiserror = { workspace = true } -pallet-contracts = { workspace = true } -sp-core = { workspace = true, features = ["serde"] } - +ink_sandbox = { workspace = true } drink = { workspace = true, features = ["session"] } diff --git a/drink-cli/src/app_state/contracts.rs b/drink-cli/src/app_state/contracts.rs index a2dc0b2..0272d94 100644 --- a/drink-cli/src/app_state/contracts.rs +++ b/drink-cli/src/app_state/contracts.rs @@ -1,7 +1,7 @@ use std::{path::PathBuf, rc::Rc}; use contract_transcode::ContractMessageTranscoder; -use sp_core::crypto::AccountId32; +use drink::AccountId32; use ContractIndex::NoContracts; use crate::app_state::ContractIndex::CurrentContract; diff --git a/drink-cli/src/app_state/mod.rs b/drink-cli/src/app_state/mod.rs index 8028308..f35aed7 100644 --- a/drink-cli/src/app_state/mod.rs +++ b/drink-cli/src/app_state/mod.rs @@ -1,8 +1,7 @@ use std::{env, path::PathBuf}; pub use contracts::{Contract, ContractIndex, ContractRegistry}; -use drink::{runtime::MinimalSandbox, session::Session, Sandbox, Weight, DEFAULT_GAS_LIMIT}; -use sp_core::crypto::AccountId32; +use drink::{minimal::MinimalSandbox, session::Session, AccountId32, Sandbox, Weight}; pub use user_input::UserInput; use crate::app_state::output::Output; @@ -24,7 +23,7 @@ impl Default for ChainInfo { Self { block_height: 0, actor: MinimalSandbox::default_actor(), - gas_limit: DEFAULT_GAS_LIMIT, + gas_limit: MinimalSandbox::default_gas_limit(), } } } diff --git a/drink-cli/src/app_state/print.rs b/drink-cli/src/app_state/print.rs index a1b26e5..d9880a2 100644 --- a/drink-cli/src/app_state/print.rs +++ b/drink-cli/src/app_state/print.rs @@ -1,5 +1,4 @@ -use drink::contracts_api::decode_debug_buffer; -use pallet_contracts::ContractResult; +use drink::{pallet_contracts::ContractResult, sandbox_api::contracts_api::decode_debug_buffer}; use ratatui::{ style::{Color, Modifier, Style}, text::Span, diff --git a/drink-cli/src/cli.rs b/drink-cli/src/cli.rs index af70c2b..29c473f 100644 --- a/drink-cli/src/cli.rs +++ b/drink-cli/src/cli.rs @@ -1,5 +1,5 @@ use clap::Parser; -use sp_core::crypto::{AccountId32, Ss58Codec}; +use drink::{AccountId32, Ss58Codec}; #[derive(Parser)] pub enum CliCommand { diff --git a/drink-cli/src/executor/mod.rs b/drink-cli/src/executor/mod.rs index d9924e7..b7c09ce 100644 --- a/drink-cli/src/executor/mod.rs +++ b/drink-cli/src/executor/mod.rs @@ -5,8 +5,7 @@ use std::env; use anyhow::Result; use clap::Parser; -use drink::{sandbox::prelude::*, Weight}; -use sp_core::crypto::AccountId32; +use drink::{sandbox_api::prelude::*, AccountId32, Weight}; use crate::{app_state::AppState, cli::CliCommand}; diff --git a/drink/Cargo.toml b/drink/Cargo.toml index 1a03946..737637d 100644 --- a/drink/Cargo.toml +++ b/drink/Cargo.toml @@ -12,20 +12,13 @@ description = "Minimal sufficient architecture that allows for a fully functiona [dependencies] contract-metadata = { workspace = true, optional = true} contract-transcode = { workspace = true, optional = true } -frame-metadata = { workspace = true } frame-support = { workspace = true } frame-system = { workspace = true } -pallet-balances = { workspace = true } -pallet-contracts = { workspace = true } -pallet-contracts-uapi = { workspace = true } -pallet-timestamp = { workspace = true } parity-scale-codec = { workspace = true } parity-scale-codec-derive = { workspace = true } -sp-externalities = { workspace = true } -sp-io = { workspace = true } sp-runtime-interface = { workspace = true } +ink_sandbox = { workspace = true } -paste = { workspace = true } scale-info = { workspace = true } serde_json = { workspace = true, optional = true } thiserror = { workspace = true } diff --git a/drink/src/lib.rs b/drink/src/lib.rs index 683f9bb..c6b638e 100644 --- a/drink/src/lib.rs +++ b/drink/src/lib.rs @@ -4,54 +4,33 @@ #![warn(missing_docs)] pub mod errors; -pub mod runtime; -pub mod sandbox; -pub use sandbox::*; +pub mod pallet_contracts_debugging; #[cfg(feature = "session")] pub mod session; #[cfg(feature = "macros")] pub use drink_test_macro::{contract_bundle_provider, test}; pub use errors::Error; -use frame_support::traits::fungible::Inspect; -pub use frame_support::{ - sp_runtime::{AccountId32, DispatchError}, - weights::Weight, +pub use frame_support; +pub use ink_sandbox::{ + api as sandbox_api, create_sandbox, pallet_balances, pallet_contracts, pallet_timestamp, + sp_externalities, AccountId32, DispatchError, Sandbox, Ss58Codec, Weight, }; -use frame_system::EventRecord; -use pallet_contracts::{ContractExecResult, ContractInstantiateResult}; #[cfg(feature = "session")] pub use session::mock::{mock_message, ContractMock, MessageMock, MockedCallResult, Selector}; -/// Export pallets that are used in the minimal runtime. -pub use { - frame_support, frame_system, pallet_balances, pallet_contracts, pallet_timestamp, paste, - sp_externalities::Extension, sp_io::TestExternalities, -}; - -pub use crate::runtime::minimal::{self, MinimalSandbox}; - -/// Alias for `frame-system`'s `RuntimeCall` type. -pub type RuntimeCall = ::RuntimeCall; /// Main result type for the drink crate. pub type DrinkResult = std::result::Result; -/// Copied from pallet-contracts. -pub type EventRecordOf = EventRecord< - ::RuntimeEvent, - ::Hash, ->; - -type BalanceOf = - <::Currency as Inspect>>::Balance; - -/// Copied from pallet-contracts. -pub type ContractInstantiateResultFor = - ContractInstantiateResult, BalanceOf, EventRecordOf>; - -/// Copied from pallet-contracts. -pub type ContractExecResultFor = - ContractExecResult, EventRecordOf>; - -/// Default gas limit. -pub const DEFAULT_GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); +/// Minimal Sandbox runtime used for testing contracts with drink!. +#[allow(missing_docs)] +pub mod minimal { + use ink_sandbox::create_sandbox; + + // create_sandbox!(MinimalSandbox); + create_sandbox!( + MinimalSandbox, + (), + crate::pallet_contracts_debugging::DrinkDebug + ); +} diff --git a/drink/src/runtime/pallet_contracts_debugging.rs b/drink/src/pallet_contracts_debugging.rs similarity index 100% rename from drink/src/runtime/pallet_contracts_debugging.rs rename to drink/src/pallet_contracts_debugging.rs diff --git a/drink/src/runtime/pallet_contracts_debugging/intercepting.rs b/drink/src/pallet_contracts_debugging/intercepting.rs similarity index 78% rename from drink/src/runtime/pallet_contracts_debugging/intercepting.rs rename to drink/src/pallet_contracts_debugging/intercepting.rs index 413f1e3..7ae00a4 100644 --- a/drink/src/runtime/pallet_contracts_debugging/intercepting.rs +++ b/drink/src/pallet_contracts_debugging/intercepting.rs @@ -1,12 +1,15 @@ -use pallet_contracts::debug::{CallInterceptor, ExecResult, ExportedFunction}; +use ink_sandbox::AccountIdFor; use parity_scale_codec::{Decode, Encode}; -use crate::runtime::{ +use crate::{ + pallet_contracts::{ + debug::{CallInterceptor, ExecResult, ExportedFunction}, + Config, + }, pallet_contracts_debugging::{runtime::contract_call_debugger, DrinkDebug}, - AccountIdFor, }; -impl CallInterceptor for DrinkDebug { +impl CallInterceptor for DrinkDebug { fn intercept_call( contract_address: &AccountIdFor, entry_point: &ExportedFunction, diff --git a/drink/src/runtime/pallet_contracts_debugging/runtime.rs b/drink/src/pallet_contracts_debugging/runtime.rs similarity index 97% rename from drink/src/runtime/pallet_contracts_debugging/runtime.rs rename to drink/src/pallet_contracts_debugging/runtime.rs index ec1bcee..627cefb 100644 --- a/drink/src/runtime/pallet_contracts_debugging/runtime.rs +++ b/drink/src/pallet_contracts_debugging/runtime.rs @@ -1,7 +1,8 @@ use parity_scale_codec::Encode; -use sp_externalities::{decl_extension, ExternalitiesExt}; use sp_runtime_interface::runtime_interface; +use crate::sp_externalities::{decl_extension, ExternalitiesExt}; + /// Contracts pallet outsources debug callbacks through this runtime interface. /// /// Essentially, in our case, it just exposes extensions to the runtime. diff --git a/drink/src/runtime/pallet_contracts_debugging/tracing.rs b/drink/src/pallet_contracts_debugging/tracing.rs similarity index 77% rename from drink/src/runtime/pallet_contracts_debugging/tracing.rs rename to drink/src/pallet_contracts_debugging/tracing.rs index 5ebe20e..80c2ff2 100644 --- a/drink/src/runtime/pallet_contracts_debugging/tracing.rs +++ b/drink/src/pallet_contracts_debugging/tracing.rs @@ -1,11 +1,14 @@ -use pallet_contracts::{ - debug::{CallSpan, ExportedFunction}, - ExecReturnValue, Tracing, -}; +use ink_sandbox::AccountIdFor; -use crate::runtime::{pallet_contracts_debugging::DrinkDebug, AccountIdFor}; +use crate::{ + pallet_contracts::{ + debug::{CallSpan, ExportedFunction}, + Config, ExecReturnValue, Tracing, + }, + pallet_contracts_debugging::DrinkDebug, +}; -impl Tracing for DrinkDebug { +impl Tracing for DrinkDebug { type CallSpan = DrinkCallSpan>; fn new_call_span( @@ -36,7 +39,7 @@ pub struct DrinkCallSpan { impl CallSpan for DrinkCallSpan { fn after_call(self, output: &ExecReturnValue) { - crate::runtime::pallet_contracts_debugging::runtime::contract_call_debugger::after_call( + crate::pallet_contracts_debugging::runtime::contract_call_debugger::after_call( self.contract_address.encode(), matches!(self.entry_point, ExportedFunction::Call), self.input_data.to_vec(), diff --git a/drink/src/runtime.rs b/drink/src/runtime.rs deleted file mode 100644 index 4c603d9..0000000 --- a/drink/src/runtime.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Module containing a [`MinimalSandbox`] that implements the [`crate::Sandbox`] trait. -//! Also contains debugging utilities for the contracts pallet. - -pub mod minimal; -pub mod pallet_contracts_debugging; -pub use frame_metadata::RuntimeMetadataPrefixed; -pub use minimal::MinimalSandbox; - -/// The type of an account identifier. -pub type AccountIdFor = ::AccountId; - -/// The type of a hash. -pub type HashFor = ::Hash; diff --git a/drink/src/runtime/minimal.rs b/drink/src/runtime/minimal.rs deleted file mode 100644 index e6e0584..0000000 --- a/drink/src/runtime/minimal.rs +++ /dev/null @@ -1,285 +0,0 @@ -#![allow(missing_docs)] // `construct_macro` doesn't allow doc comments for the runtime type. - -use std::time::SystemTime; - -use frame_support::{ - sp_runtime::{ - traits::{Header, One}, - BuildStorage, - }, - traits::Hooks, -}; -use frame_system::pallet_prelude::BlockNumberFor; -use sp_io::TestExternalities; - -/// A helper struct for initializing and finalizing blocks. -pub struct BlockBuilder(std::marker::PhantomData); - -impl< - T: pallet_balances::Config + pallet_timestamp::Config + pallet_contracts::Config, - > BlockBuilder -{ - /// Create a new externalities with the given balances. - pub fn new_ext(balances: Vec<(T::AccountId, T::Balance)>) -> TestExternalities { - let mut storage = frame_system::GenesisConfig::::default() - .build_storage() - .unwrap(); - - pallet_balances::GenesisConfig:: { balances } - .assimilate_storage(&mut storage) - .unwrap(); - - let mut ext = TestExternalities::new(storage); - - ext.execute_with(|| Self::initialize_block(BlockNumberFor::::one(), Default::default())); - ext - } - - /// Initialize a new block at particular height. - pub fn initialize_block( - height: frame_system::pallet_prelude::BlockNumberFor, - parent_hash: ::Hash, - ) { - frame_system::Pallet::::reset_events(); - frame_system::Pallet::::initialize(&height, &parent_hash, &Default::default()); - pallet_balances::Pallet::::on_initialize(height); - pallet_timestamp::Pallet::::set_timestamp( - SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .expect("Time went backwards") - .as_secs(), - ); - pallet_timestamp::Pallet::::on_initialize(height); - pallet_contracts::Pallet::::on_initialize(height); - frame_system::Pallet::::note_finished_initialize(); - } - - /// Finalize a block at particular height. - pub fn finalize_block( - height: frame_system::pallet_prelude::BlockNumberFor, - ) -> ::Hash { - pallet_contracts::Pallet::::on_finalize(height); - pallet_timestamp::Pallet::::on_finalize(height); - pallet_balances::Pallet::::on_finalize(height); - frame_system::Pallet::::finalize().hash() - } -} - -/// Macro creating a minimal runtime with the given name. Optionally can take a chain extension -/// type as a second argument. -/// -/// The new macro will automatically implement `drink::Sandbox`. -#[macro_export] -macro_rules! create_minimal_sandbox { - ($name:ident) => { - $crate::paste::paste! { - $crate::create_minimal_sandbox!($name, [<$name Runtime>], ()); - } - }; - ($name:ident, $chain_extension: ty) => { - $crate::paste::paste! { - $crate::create_minimal_sandbox!($name, [<$name Runtime>], $chain_extension); - } - }; - ($sandbox:ident, $runtime:ident, $chain_extension: ty) => { - - -// ------------ Put all the boilerplate into an auxiliary module ----------------------------------- -mod construct_runtime { - - // ------------ Bring some common types into the scope ----------------------------------------- - use $crate::frame_support::{ - construct_runtime, - derive_impl, - parameter_types, - sp_runtime::{ - testing::H256, - traits::Convert, - AccountId32, Perbill, - }, - traits::{ConstBool, ConstU128, ConstU32, ConstU64, Currency, Randomness}, - weights::Weight, - }; - use $crate::runtime::pallet_contracts_debugging::DrinkDebug; - - // ------------ Define the runtime type as a collection of pallets ----------------------------- - construct_runtime!( - pub enum $runtime { - System: $crate::frame_system, - Balances: $crate::pallet_balances, - Timestamp: $crate::pallet_timestamp, - Contracts: $crate::pallet_contracts, - } - ); - - // ------------ Configure pallet system -------------------------------------------------------- - #[derive_impl($crate::frame_system::config_preludes::SolochainDefaultConfig as $crate::frame_system::DefaultConfig)] - impl $crate::frame_system::Config for $runtime { - type Block = $crate::frame_system::mocking::MockBlockU32<$runtime>; - type Version = (); - type BlockHashCount = ConstU32<250>; - type AccountData = $crate::pallet_balances::AccountData<<$runtime as $crate::pallet_balances::Config>::Balance>; - } - - // ------------ Configure pallet balances ------------------------------------------------------ - impl $crate::pallet_balances::Config for $runtime { - type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); - type Balance = u128; - type DustRemoval = (); - type ExistentialDeposit = ConstU128<1>; - type AccountStore = System; - type ReserveIdentifier = [u8; 8]; - type FreezeIdentifier = (); - type MaxLocks = (); - type MaxReserves = (); - type MaxFreezes = (); - type RuntimeHoldReason = RuntimeHoldReason; - type RuntimeFreezeReason = RuntimeFreezeReason; - } - - // ------------ Configure pallet timestamp ----------------------------------------------------- - impl $crate::pallet_timestamp::Config for $runtime { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = ConstU64<1>; - type WeightInfo = (); - } - - // ------------ Configure pallet contracts ----------------------------------------------------- - pub enum SandboxRandomness {} - impl Randomness for SandboxRandomness { - fn random(_subject: &[u8]) -> (H256, u32) { - unreachable!("No randomness") - } - } - - type BalanceOf = >::Balance; - impl Convert for $runtime { - fn convert(w: Weight) -> BalanceOf { - w.ref_time().into() - } - } - - parameter_types! { - pub SandboxSchedule: $crate::pallet_contracts::Schedule<$runtime> = { - <$crate::pallet_contracts::Schedule<$runtime>>::default() - }; - pub DeletionWeightLimit: Weight = Weight::zero(); - pub DefaultDepositLimit: BalanceOf = 10_000_000; - pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0); - pub MaxDelegateDependencies: u32 = 32; - } - - impl $crate::pallet_contracts::Config for $runtime { - type Time = Timestamp; - type Randomness = SandboxRandomness; - type Currency = Balances; - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; - type CallFilter = (); - type WeightPrice = Self; - type WeightInfo = (); - type ChainExtension = $chain_extension; - type Schedule = SandboxSchedule; - type CallStack = [$crate::pallet_contracts::Frame; 5]; - type DepositPerByte = ConstU128<1>; - type DepositPerItem = ConstU128<1>; - type AddressGenerator = $crate::pallet_contracts::DefaultAddressGenerator; - type MaxCodeLen = ConstU32<{ 123 * 1024 }>; - type MaxStorageKeyLen = ConstU32<128>; - type UnsafeUnstableInterface = ConstBool; - type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; - type Migrations = (); - type DefaultDepositLimit = DefaultDepositLimit; - type Debug = DrinkDebug; - type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; - type MaxDelegateDependencies = MaxDelegateDependencies; - type RuntimeHoldReason = RuntimeHoldReason; - type Environment = (); - type Xcm = (); - type ApiVersion = (); - } - - // ------------ Implement `drink::Runtime` trait --------------------------------------------------- - - /// Default initial balance for the default account. - pub const INITIAL_BALANCE: u128 = 1_000_000_000_000_000; - pub const DEFAULT_ACCOUNT: AccountId32 = AccountId32::new([1u8; 32]); - - pub struct $sandbox { - ext: $crate::TestExternalities, - } - - impl ::std::default::Default for $sandbox { - fn default() -> Self { - let ext = $crate::minimal::BlockBuilder::<$runtime>::new_ext(vec![( - DEFAULT_ACCOUNT, - INITIAL_BALANCE, - )]); - Self { ext } - } - } - - impl $crate::Sandbox for $sandbox { - type Runtime = $runtime; - - fn execute_with(&mut self, execute: impl FnOnce() -> T) -> T { - self.ext.execute_with(execute) - } - - fn dry_run(&mut self, action: impl FnOnce(&mut Self) -> T) -> T { - // Make a backup of the backend. - let backend_backup = self.ext.as_backend(); - // Run the action, potentially modifying storage. Ensure, that there are no pending changes - // that would affect the reverted backend. - let result = action(self); - self.ext.commit_all().expect("Failed to commit changes"); - - // Restore the backend. - self.ext.backend = backend_backup; - result - } - - fn register_extension(&mut self, ext: E) { - self.ext.register_extension(ext); - } - - fn initialize_block( - height: $crate::frame_system::pallet_prelude::BlockNumberFor, - parent_hash: ::Hash, - ) { - $crate::minimal::BlockBuilder::::initialize_block(height, parent_hash) - } - - fn finalize_block( - height: $crate::frame_system::pallet_prelude::BlockNumberFor, - ) -> ::Hash { - $crate::minimal::BlockBuilder::::finalize_block(height) - } - - fn default_actor() -> $crate::runtime::AccountIdFor { - DEFAULT_ACCOUNT - } - - fn get_metadata() -> $crate::runtime::RuntimeMetadataPrefixed { - Self::Runtime::metadata() - } - - fn convert_account_to_origin( - account: $crate::runtime::AccountIdFor, - ) -> <::RuntimeCall as $crate::frame_support::sp_runtime::traits::Dispatchable>::RuntimeOrigin { - Some(account).into() - } - } -} - -// ------------ Export runtime type itself, pallets and useful types from the auxiliary module ----- -pub use construct_runtime::{ - $sandbox, $runtime, Balances, Contracts, PalletInfo, RuntimeCall, RuntimeEvent, RuntimeHoldReason, - RuntimeOrigin, System, Timestamp, -}; - }; -} - -create_minimal_sandbox!(MinimalSandbox); diff --git a/drink/src/sandbox.rs b/drink/src/sandbox.rs deleted file mode 100644 index 9ee863c..0000000 --- a/drink/src/sandbox.rs +++ /dev/null @@ -1,64 +0,0 @@ -//! Module containing the sandbox trait and its prelude. - -use core::any::Any; - -pub mod balance_api; -pub mod contracts_api; -pub mod system_api; -pub mod timestamp_api; - -/// The prelude of the sandbox module. -pub mod prelude { - pub use super::{ - balance_api::BalanceAPI, contracts_api::ContractAPI, system_api::SystemAPI, - timestamp_api::TimestampAPI, Sandbox, - }; -} - -use frame_metadata::RuntimeMetadataPrefixed; -use frame_support::sp_runtime::traits::Dispatchable; -use frame_system::pallet_prelude::BlockNumberFor; -use sp_externalities::Extension; - -/// The type of an account identifier. -pub type AccountIdFor = ::AccountId; - -/// Sandbox defines the API of a sandboxed runtime. -pub trait Sandbox { - /// The runtime associated with the sandbox. - type Runtime: frame_system::Config; - - /// Execute the given externalities. - fn execute_with(&mut self, execute: impl FnOnce() -> T) -> T; - - /// Dry run an action without modifying the storage. - fn dry_run(&mut self, action: impl FnOnce(&mut Self) -> T) -> T; - - /// Register an extension. - fn register_extension(&mut self, ext: E); - - /// Initialize a new block at particular height. - fn initialize_block( - _height: BlockNumberFor, - _parent_hash: ::Hash, - ) { - } - - /// Finalize a block at particular height. - fn finalize_block( - _height: BlockNumberFor, - ) -> ::Hash { - Default::default() - } - - /// Default actor for the sandbox. - fn default_actor() -> AccountIdFor; - - /// Metadata of the runtime. - fn get_metadata() -> RuntimeMetadataPrefixed; - - /// Convert an account to an call origin. - fn convert_account_to_origin( - account: AccountIdFor, - ) -> <::RuntimeCall as Dispatchable>::RuntimeOrigin; -} diff --git a/drink/src/sandbox/balance_api.rs b/drink/src/sandbox/balance_api.rs deleted file mode 100644 index 8f68e55..0000000 --- a/drink/src/sandbox/balance_api.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Balance API for the sandbox. -use frame_support::{sp_runtime::DispatchError, traits::fungible::Mutate}; - -use super::Sandbox; -use crate::runtime::AccountIdFor; - -type BalanceOf = ::Balance; - -/// Balance API for the sandbox. -pub trait BalanceAPI -where - T: Sandbox, - T::Runtime: pallet_balances::Config, -{ - /// Mint tokens to an account. - /// - /// # Arguments - /// - /// * `address` - The address of the account to add tokens to. - /// * `amount` - The number of tokens to add. - fn mint_into( - &mut self, - address: &AccountIdFor, - amount: BalanceOf, - ) -> Result, DispatchError>; - - /// Return the free balance of an account. - /// - /// # Arguments - /// - /// * `address` - The address of the account to query. - fn free_balance(&mut self, address: &AccountIdFor) -> BalanceOf; -} - -impl BalanceAPI for T -where - T: Sandbox, - T::Runtime: pallet_balances::Config, -{ - fn mint_into( - &mut self, - address: &AccountIdFor, - amount: BalanceOf, - ) -> Result, DispatchError> { - self.execute_with(|| pallet_balances::Pallet::::mint_into(address, amount)) - } - - fn free_balance(&mut self, address: &AccountIdFor) -> BalanceOf { - self.execute_with(|| pallet_balances::Pallet::::free_balance(address)) - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::MinimalSandbox; - #[test] - fn mint_works() { - let mut sandbox = MinimalSandbox::default(); - let balance = sandbox.free_balance(&MinimalSandbox::default_actor()); - - sandbox - .mint_into(&MinimalSandbox::default_actor(), 100) - .unwrap(); - - assert_eq!( - sandbox.free_balance(&MinimalSandbox::default_actor()), - balance + 100 - ); - } -} diff --git a/drink/src/sandbox/contracts_api.rs b/drink/src/sandbox/contracts_api.rs deleted file mode 100644 index 8746a4c..0000000 --- a/drink/src/sandbox/contracts_api.rs +++ /dev/null @@ -1,359 +0,0 @@ -//! Contracts API for the sandbox. -use std::ops::Not; - -use frame_support::{traits::fungible::Inspect, weights::Weight}; -use frame_system::Config as SysConfig; -use pallet_contracts::{ - Code, CodeUploadResult, CollectEvents, ContractInstantiateResult, DebugInfo, Determinism, -}; -use parity_scale_codec::Decode as _; - -use crate::{ - runtime::AccountIdFor, ContractExecResultFor, ContractInstantiateResultFor, EventRecordOf, - Sandbox, -}; - -type BalanceOf = - <::Currency as Inspect>>::Balance; - -/// Contract API used to interact with the contracts pallet. -pub trait ContractAPI { - /// The runtime contract config. - type T: pallet_contracts::Config; - - /// Interface for `bare_instantiate` contract call with a simultaneous upload. - /// - /// # Arguments - /// - /// * `contract_bytes` - The contract code. - /// * `value` - The number of tokens to be transferred to the contract. - /// * `data` - The input data to be passed to the contract (including constructor name). - /// * `salt` - The salt to be used for contract address derivation. - /// * `origin` - The sender of the contract call. - /// * `gas_limit` - The gas limit for the contract call. - /// * `storage_deposit_limit` - The storage deposit limit for the contract call. - #[allow(clippy::type_complexity, clippy::too_many_arguments)] - fn deploy_contract( - &mut self, - contract_bytes: Vec, - value: BalanceOf, - data: Vec, - salt: Vec, - origin: AccountIdFor, - gas_limit: Weight, - storage_deposit_limit: Option>, - ) -> ContractInstantiateResult, BalanceOf, EventRecordOf>; - - /// Interface for `bare_instantiate` contract call for a previously uploaded contract. - /// - /// # Arguments - /// - /// * `code_hash` - The code hash of the contract to instantiate. - /// * `value` - The number of tokens to be transferred to the contract. - /// * `data` - The input data to be passed to the contract (including constructor name). - /// * `salt` - The salt to be used for contract address derivation. - /// * `origin` - The sender of the contract call. - /// * `gas_limit` - The gas limit for the contract call. - /// * `storage_deposit_limit` - The storage deposit limit for the contract call. - #[allow(clippy::type_complexity, clippy::too_many_arguments)] - fn instantiate_contract( - &mut self, - code_hash: Vec, - value: BalanceOf, - data: Vec, - salt: Vec, - origin: AccountIdFor, - gas_limit: Weight, - storage_deposit_limit: Option>, - ) -> ContractInstantiateResult, BalanceOf, EventRecordOf>; - - /// Interface for `bare_upload_code` contract call. - /// - /// # Arguments - /// - /// * `contract_bytes` - The contract code. - /// * `origin` - The sender of the contract call. - /// * `storage_deposit_limit` - The storage deposit limit for the contract call. - fn upload_contract( - &mut self, - contract_bytes: Vec, - origin: AccountIdFor, - storage_deposit_limit: Option>, - determinism: Determinism, - ) -> CodeUploadResult<::Hash, BalanceOf>; - - /// Interface for `bare_call` contract call. - /// - /// # Arguments - /// - /// * `address` - The address of the contract to be called. - /// * `value` - The number of tokens to be transferred to the contract. - /// * `data` - The input data to be passed to the contract (including message name). - /// * `origin` - The sender of the contract call. - /// * `gas_limit` - The gas limit for the contract call. - /// * `storage_deposit_limit` - The storage deposit limit for the contract call. - #[allow(clippy::type_complexity, clippy::too_many_arguments)] - fn call_contract( - &mut self, - address: AccountIdFor, - value: BalanceOf, - data: Vec, - origin: AccountIdFor, - gas_limit: Weight, - storage_deposit_limit: Option>, - determinism: Determinism, - ) -> ContractExecResultFor; -} - -impl ContractAPI for T -where - T: Sandbox, - T::Runtime: pallet_contracts::Config, -{ - type T = T::Runtime; - - fn deploy_contract( - &mut self, - contract_bytes: Vec, - value: BalanceOf, - data: Vec, - salt: Vec, - origin: AccountIdFor, - gas_limit: Weight, - storage_deposit_limit: Option>, - ) -> ContractInstantiateResultFor { - self.execute_with(|| { - pallet_contracts::Pallet::::bare_instantiate( - origin, - value, - gas_limit, - storage_deposit_limit, - Code::Upload(contract_bytes), - data, - salt, - DebugInfo::UnsafeDebug, - CollectEvents::UnsafeCollect, - ) - }) - } - - fn instantiate_contract( - &mut self, - code_hash: Vec, - value: BalanceOf, - data: Vec, - salt: Vec, - origin: AccountIdFor, - gas_limit: Weight, - storage_deposit_limit: Option>, - ) -> ContractInstantiateResult, BalanceOf, EventRecordOf> - { - let mut code_hash = &code_hash[..]; - self.execute_with(|| { - pallet_contracts::Pallet::::bare_instantiate( - origin, - value, - gas_limit, - storage_deposit_limit, - Code::Existing( - ::Hash::decode(&mut code_hash) - .expect("Invalid code hash"), - ), - data, - salt, - DebugInfo::UnsafeDebug, - CollectEvents::UnsafeCollect, - ) - }) - } - - fn upload_contract( - &mut self, - contract_bytes: Vec, - origin: AccountIdFor, - storage_deposit_limit: Option>, - determinism: Determinism, - ) -> CodeUploadResult<::Hash, BalanceOf> { - self.execute_with(|| { - pallet_contracts::Pallet::::bare_upload_code( - origin, - contract_bytes, - storage_deposit_limit, - determinism, - ) - }) - } - - fn call_contract( - &mut self, - address: AccountIdFor, - value: BalanceOf, - data: Vec, - origin: AccountIdFor, - gas_limit: Weight, - storage_deposit_limit: Option>, - determinism: Determinism, - ) -> ContractExecResultFor { - self.execute_with(|| { - pallet_contracts::Pallet::::bare_call( - origin, - address, - value, - gas_limit, - storage_deposit_limit, - data, - DebugInfo::UnsafeDebug, - CollectEvents::UnsafeCollect, - determinism, - ) - }) - } -} - -/// Converts bytes to a '\n'-split string, ignoring empty lines. -pub fn decode_debug_buffer(buffer: &[u8]) -> Vec { - let decoded = buffer.iter().map(|b| *b as char).collect::(); - decoded - .split('\n') - .filter_map(|s| s.is_empty().not().then_some(s.to_string())) - .collect() -} - -#[cfg(test)] -mod tests { - use frame_support::sp_runtime::traits::Hash; - use pallet_contracts::Origin; - - use super::*; - use crate::{ - minimal::{MinimalSandbox, MinimalSandboxRuntime, RuntimeEvent}, - sandbox::prelude::*, - session::NO_SALT, - DEFAULT_GAS_LIMIT, - }; - - fn compile_module(contract_name: &str) -> Vec { - let path = [ - std::env::var("CARGO_MANIFEST_DIR") - .as_deref() - .unwrap_or("drink"), - "/test-resources/", - contract_name, - ".wat", - ] - .concat(); - wat::parse_file(path).expect("Failed to parse wat file") - } - - #[test] - fn can_upload_code() { - let mut sandbox = MinimalSandbox::default(); - let wasm_binary = compile_module("dummy"); - let hash = <::Hashing>::hash(&wasm_binary); - - let result = sandbox.upload_contract( - wasm_binary, - MinimalSandbox::default_actor(), - None, - Determinism::Enforced, - ); - - assert!(result.is_ok()); - assert_eq!(hash, result.unwrap().code_hash); - } - - #[test] - fn can_deploy_contract() { - let mut sandbox = MinimalSandbox::default(); - let wasm_binary = compile_module("dummy"); - - let events_before = sandbox.events(); - assert!(events_before.is_empty()); - - let result = sandbox.deploy_contract( - wasm_binary, - 0, - vec![], - NO_SALT, - MinimalSandbox::default_actor(), - DEFAULT_GAS_LIMIT, - None, - ); - assert!(result.result.is_ok()); - assert!(!result.result.unwrap().result.did_revert()); - - let events = result.events.expect("Drink should collect events"); - let event_count = events.len(); - let instantiation_event = events[event_count - 2].clone(); - assert!(matches!( - instantiation_event.event, - RuntimeEvent::Contracts( - pallet_contracts::Event::::Instantiated { .. } - ) - )); - let deposit_event = events[event_count - 1].clone(); - assert!(matches!( - deposit_event.event, - RuntimeEvent::Contracts( - pallet_contracts::Event::::StorageDepositTransferredAndHeld { .. } - ) - )); - } - - #[test] - fn can_call_contract() { - let mut sandbox = MinimalSandbox::default(); - let actor = MinimalSandbox::default_actor(); - let wasm_binary = compile_module("dummy"); - - let result = sandbox.deploy_contract( - wasm_binary, - 0, - vec![], - NO_SALT, - actor.clone(), - DEFAULT_GAS_LIMIT, - None, - ); - - let contract_address = result - .result - .expect("Contract should be deployed") - .account_id; - - sandbox.reset_events(); - - let result = sandbox.call_contract( - contract_address.clone(), - 0, - vec![], - actor.clone(), - DEFAULT_GAS_LIMIT, - None, - Determinism::Enforced, - ); - assert!(result.result.is_ok()); - assert!(!result.result.unwrap().did_revert()); - - let events = result.events.expect("Drink should collect events"); - assert_eq!(events.len(), 2); - - assert_eq!( - events[0].event, - RuntimeEvent::Contracts( - pallet_contracts::Event::::ContractEmitted { - contract: contract_address.clone(), - data: vec![0, 0, 0, 0], - } - ) - ); - - assert_eq!( - events[1].event, - RuntimeEvent::Contracts(pallet_contracts::Event::::Called { - contract: contract_address, - caller: Origin::Signed(actor), - }), - ); - } -} diff --git a/drink/src/sandbox/system_api.rs b/drink/src/sandbox/system_api.rs deleted file mode 100644 index e43df60..0000000 --- a/drink/src/sandbox/system_api.rs +++ /dev/null @@ -1,188 +0,0 @@ -//! System API for the sandbox. - -use frame_support::sp_runtime::{ - traits::{Dispatchable, Saturating}, - DispatchResultWithInfo, -}; -use frame_system::pallet_prelude::BlockNumberFor; - -use super::Sandbox; -use crate::{EventRecordOf, RuntimeCall}; - -/// System API for the sandbox. -pub trait SystemAPI { - /// The runtime system config. - type T: frame_system::Config; - - /// Build a new empty block and return the new height. - fn build_block(&mut self) -> BlockNumberFor; - - /// Build `n` empty blocks and return the new height. - /// - /// # Arguments - /// - /// * `n` - The number of blocks to build. - fn build_blocks(&mut self, n: u32) -> BlockNumberFor; - - /// Return the current height of the chain. - fn block_number(&mut self) -> BlockNumberFor; - - /// Return the events of the current block so far. - fn events(&mut self) -> Vec>; - - /// Reset the events of the current block. - fn reset_events(&mut self); - - /// Execute a runtime call (dispatchable). - /// - /// # Arguments - /// - /// * `call` - The runtime call to execute. - /// * `origin` - The origin of the call. - fn runtime_call as Dispatchable>::RuntimeOrigin>>( - &mut self, - call: RuntimeCall, - origin: Origin, - ) -> DispatchResultWithInfo< as Dispatchable>::PostInfo>; -} - -impl SystemAPI for T -where - T: Sandbox, - T::Runtime: frame_system::Config, -{ - type T = T::Runtime; - - fn build_block(&mut self) -> BlockNumberFor { - self.execute_with(|| { - let mut current_block = frame_system::Pallet::::block_number(); - let block_hash = T::finalize_block(current_block); - current_block.saturating_inc(); - T::initialize_block(current_block, block_hash); - current_block - }) - } - - fn build_blocks(&mut self, n: u32) -> BlockNumberFor { - let mut last_block = None; - for _ in 0..n { - last_block = Some(self.build_block()); - } - last_block.unwrap_or_else(|| self.block_number()) - } - - fn block_number(&mut self) -> BlockNumberFor { - self.execute_with(frame_system::Pallet::::block_number) - } - - fn events(&mut self) -> Vec> { - self.execute_with(frame_system::Pallet::::events) - } - - fn reset_events(&mut self) { - self.execute_with(frame_system::Pallet::::reset_events) - } - - fn runtime_call as Dispatchable>::RuntimeOrigin>>( - &mut self, - call: RuntimeCall, - origin: Origin, - ) -> DispatchResultWithInfo< as Dispatchable>::PostInfo> { - self.execute_with(|| call.dispatch(origin.into())) - } -} - -#[cfg(test)] -mod tests { - use frame_support::sp_runtime::{traits::Dispatchable, DispatchResultWithInfo}; - - use crate::{ - minimal::{MinimalSandbox, MinimalSandboxRuntime}, - runtime::minimal::RuntimeEvent, - sandbox::prelude::*, - AccountId32, RuntimeCall, Sandbox, - }; - - fn make_transfer( - sandbox: &mut MinimalSandbox, - dest: AccountId32, - value: u128, - ) -> DispatchResultWithInfo< as Dispatchable>::PostInfo> - { - assert_ne!( - MinimalSandbox::default_actor(), - dest, - "make_transfer should send to account different than default_actor" - ); - sandbox.runtime_call( - RuntimeCall::::Balances(pallet_balances::Call::< - MinimalSandboxRuntime, - >::transfer_allow_death { - dest: dest.into(), - value, - }), - Some(MinimalSandbox::default_actor()), - ) - } - - #[test] - fn dry_run_works() { - let mut sandbox = MinimalSandbox::default(); - let actor = MinimalSandbox::default_actor(); - let initial_balance = sandbox.free_balance(&actor); - - sandbox.dry_run(|sandbox| { - sandbox.mint_into(&actor, 100).unwrap(); - assert_eq!(sandbox.free_balance(&actor), initial_balance + 100); - }); - - assert_eq!(sandbox.free_balance(&actor), initial_balance); - } - - #[test] - fn runtime_call_works() { - let mut sandbox = MinimalSandbox::default(); - - const RECIPIENT: AccountId32 = AccountId32::new([2u8; 32]); - let initial_balance = sandbox.free_balance(&RECIPIENT); - - let result = make_transfer(&mut sandbox, RECIPIENT, 100); - assert!(result.is_ok()); - - let expected_balance = initial_balance + 100; - assert_eq!(sandbox.free_balance(&RECIPIENT), expected_balance); - } - - #[test] - fn current_events() { - let mut sandbox = MinimalSandbox::default(); - const RECIPIENT: AccountId32 = AccountId32::new([2u8; 32]); - - let events_before = sandbox.events(); - assert!(events_before.is_empty()); - - make_transfer(&mut sandbox, RECIPIENT, 1).expect("Failed to make transfer"); - - let events_after = sandbox.events(); - assert!(!events_after.is_empty()); - assert!(matches!( - events_after.last().unwrap().event, - RuntimeEvent::Balances(_) - )); - } - - #[test] - fn resetting_events() { - let mut sandbox = MinimalSandbox::default(); - const RECIPIENT: AccountId32 = AccountId32::new([3u8; 32]); - - make_transfer(&mut sandbox, RECIPIENT.clone(), 1).expect("Failed to make transfer"); - - assert!(!sandbox.events().is_empty()); - sandbox.reset_events(); - assert!(sandbox.events().is_empty()); - - make_transfer(&mut sandbox, RECIPIENT, 1).expect("Failed to make transfer"); - assert!(!sandbox.events().is_empty()); - } -} diff --git a/drink/src/sandbox/timestamp_api.rs b/drink/src/sandbox/timestamp_api.rs deleted file mode 100644 index c3347cd..0000000 --- a/drink/src/sandbox/timestamp_api.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! timestamp API for the sandbox. - -use crate::Sandbox; - -/// Generic Time type. -type MomentOf = ::Moment; - -/// Timestamp API used to interact with the timestamp pallet. -pub trait TimestampAPI { - /// The runtime timestamp config. - type T: pallet_timestamp::Config; - - /// Return the timestamp of the current block. - fn get_timestamp(&mut self) -> MomentOf; - - /// Set the timestamp of the current block. - /// - /// # Arguments - /// - /// * `timestamp` - The new timestamp to be set. - fn set_timestamp(&mut self, timestamp: MomentOf); -} - -impl TimestampAPI for T -where - T: Sandbox, - T::Runtime: pallet_timestamp::Config, -{ - type T = T::Runtime; - - fn get_timestamp(&mut self) -> MomentOf { - self.execute_with(pallet_timestamp::Pallet::::get) - } - - fn set_timestamp(&mut self, timestamp: MomentOf) { - self.execute_with(|| pallet_timestamp::Pallet::::set_timestamp(timestamp)) - } -} - -#[cfg(test)] -mod tests { - use crate::{runtime::MinimalSandbox, sandbox::prelude::*}; - - #[test] - fn getting_and_setting_timestamp_works() { - let mut sandbox = MinimalSandbox::default(); - for timestamp in 0..10 { - assert_ne!(sandbox.get_timestamp(), timestamp); - sandbox.set_timestamp(timestamp); - assert_eq!(sandbox.get_timestamp(), timestamp); - - sandbox.build_block(); - } - } -} diff --git a/drink/src/session.rs b/drink/src/session.rs index 7b9e740..880ba2a 100644 --- a/drink/src/session.rs +++ b/drink/src/session.rs @@ -11,18 +11,17 @@ pub use contract_transcode; use contract_transcode::ContractMessageTranscoder; use error::SessionError; use frame_support::{traits::fungible::Inspect, weights::Weight}; -use pallet_contracts::Determinism; +use ink_sandbox::{ + api::prelude::*, AccountIdFor, ContractExecResultFor, ContractInstantiateResultFor, Sandbox, +}; use parity_scale_codec::Decode; pub use record::{EventBatch, Record}; use crate::{ - runtime::{ - pallet_contracts_debugging::{InterceptingExt, TracingExt}, - AccountIdFor, HashFor, - }, - sandbox::prelude::*, + minimal::MinimalSandboxRuntime, + pallet_contracts::{Config, Determinism}, + pallet_contracts_debugging::{InterceptingExt, TracingExt}, session::mock::MockRegistry, - ContractExecResultFor, ContractInstantiateResultFor, Sandbox, DEFAULT_GAS_LIMIT, }; pub mod mock; @@ -37,11 +36,13 @@ pub use bundle::ContractBundle; use self::mocking_api::MockingApi; use crate::{ - errors::MessageResult, minimal::MinimalSandboxRuntime, session::transcoding::TranscoderRegistry, + errors::MessageResult, + // minimal::MinimalSandboxRuntime, + session::transcoding::TranscoderRegistry, }; -type BalanceOf = - <::Currency as Inspect>>::Balance; +type BalanceOf = <::Currency as Inspect>>::Balance; +type HashFor = ::Hash; /// Convenient value for an empty sequence of call/instantiation arguments. /// @@ -64,11 +65,11 @@ pub const NO_ENDOWMENT: Option> = None; /// ```rust, no_run /// # use std::rc::Rc; /// # use contract_transcode::ContractMessageTranscoder; +/// # use ink_sandbox::AccountId32; /// # use drink::{ /// # session::Session, -/// # AccountId32, /// # session::{NO_ARGS, NO_SALT, NO_ENDOWMENT}, -/// # runtime::MinimalSandbox +/// # minimal::MinimalSandbox /// # }; /// # /// # fn get_transcoder() -> Rc { @@ -91,10 +92,10 @@ pub const NO_ENDOWMENT: Option> = None; /// ```rust, no_run /// # use std::rc::Rc; /// # use contract_transcode::ContractMessageTranscoder; +/// # use ink_sandbox::AccountId32; /// # use drink::{ /// # session::Session, -/// # AccountId32, -/// # runtime::MinimalSandbox, +/// # minimal::MinimalSandbox, /// # session::{NO_ARGS, NO_ENDOWMENT, NO_SALT} /// # }; /// # fn get_transcoder() -> Rc { @@ -119,7 +120,7 @@ pub const NO_ENDOWMENT: Option> = None; /// # local_contract_file, /// # session::Session, /// # session::{ContractBundle, NO_ARGS, NO_SALT, NO_ENDOWMENT}, -/// # runtime::MinimalSandbox, +/// # minimal::MinimalSandbox /// # }; /// /// # fn main() -> Result<(), drink::session::error::SessionError> { @@ -135,7 +136,7 @@ pub const NO_ENDOWMENT: Option> = None; /// ``` pub struct Session where - T::Runtime: pallet_contracts::Config, + T::Runtime: Config, { sandbox: T, @@ -150,7 +151,7 @@ where impl Default for Session where - T::Runtime: pallet_contracts::Config, + T::Runtime: Config, T: Default, { fn default() -> Self { @@ -164,7 +165,7 @@ where sandbox, mocks, actor: T::default_actor(), - gas_limit: DEFAULT_GAS_LIMIT, + gas_limit: T::default_gas_limit(), determinism: Determinism::Enforced, transcoders: TranscoderRegistry::new(), record: Default::default(), @@ -174,7 +175,7 @@ where impl Session where - T::Runtime: pallet_contracts::Config, + T::Runtime: Config, { /// Sets a new actor and returns updated `self`. pub fn with_actor(self, actor: AccountIdFor) -> Self { diff --git a/drink/src/session/mock/extension.rs b/drink/src/session/mock/extension.rs index dbd583b..fa8f3c3 100644 --- a/drink/src/session/mock/extension.rs +++ b/drink/src/session/mock/extension.rs @@ -1,11 +1,11 @@ use std::sync::{Arc, Mutex}; -use pallet_contracts::{chain_extension::ReturnFlags, debug::ExecResult, ExecReturnValue}; use parity_scale_codec::{Decode, Encode}; use crate::{ errors::MessageResult, - runtime::pallet_contracts_debugging::InterceptingExtT, + pallet_contracts::{chain_extension::ReturnFlags, debug::ExecResult, ExecReturnValue}, + pallet_contracts_debugging::InterceptingExtT, session::mock::{MockRegistry, Selector}, }; diff --git a/drink/src/session/mocking_api.rs b/drink/src/session/mocking_api.rs index 538141a..41d4529 100644 --- a/drink/src/session/mocking_api.rs +++ b/drink/src/session/mocking_api.rs @@ -1,11 +1,15 @@ //! Mocking API for the sandbox. +use ink_sandbox::{api::prelude::*, AccountIdFor, Sandbox}; + use super::Session; use crate::{ - runtime::AccountIdFor, sandbox::prelude::*, session::mock::ContractMock, DEFAULT_GAS_LIMIT, + pallet_contracts::Config, + session::mock::ContractMock, + // DEFAULT_GAS_LIMIT, }; /// Interface for basic mocking operations. -pub trait MockingApi { +pub trait MockingApi { /// Deploy `mock` as a standard contract. Returns the address of the deployed contract. fn deploy(&mut self, mock: ContractMock) -> AccountIdFor; @@ -16,7 +20,7 @@ pub trait MockingApi { impl MockingApi for Session where - T::Runtime: pallet_contracts::Config, + T::Runtime: Config, { fn deploy(&mut self, mock: ContractMock) -> AccountIdFor { // We have to deploy some contract. We use a dummy contract for that. Thanks to that, we @@ -37,7 +41,7 @@ where vec![], salt, T::default_actor(), - DEFAULT_GAS_LIMIT, + T::default_gas_limit(), None, ) .result diff --git a/drink/src/session/record.rs b/drink/src/session/record.rs index 12af7a4..661dbe1 100644 --- a/drink/src/session/record.rs +++ b/drink/src/session/record.rs @@ -1,14 +1,14 @@ use std::rc::Rc; use contract_transcode::{ContractMessageTranscoder, Value}; +use frame_system::Config as SysConfig; +use ink_sandbox::{pallet_contracts, AccountIdFor, EventRecordOf}; use parity_scale_codec::{Decode, Encode}; use crate::{ errors::MessageResult, - minimal::MinimalSandboxRuntime, - runtime::{minimal::RuntimeEvent, AccountIdFor}, + minimal::{MinimalSandboxRuntime, RuntimeEvent}, session::{error::SessionError, BalanceOf}, - EventRecordOf, }; type ContractInstantiateResult = @@ -133,11 +133,11 @@ impl Record { } /// A batch of runtime events that were emitted during a single contract interaction. -pub struct EventBatch { +pub struct EventBatch { events: Vec>, } -impl EventBatch { +impl EventBatch { /// Returns all the events that were emitted during the contract interaction. pub fn all_events(&self) -> &[EventRecordOf] { &self.events diff --git a/drink/test-macro/src/lib.rs b/drink/test-macro/src/lib.rs index 20704c3..cade70e 100644 --- a/drink/test-macro/src/lib.rs +++ b/drink/test-macro/src/lib.rs @@ -45,10 +45,10 @@ type SynResult = Result; /// /// The macro will also create a new mutable session object and pass it to the decorated function by value. You can /// configure which sandbox should be used (by specifying a path to a type implementing -/// `drink::runtime::Sandbox` trait. Thus, your testcase function should accept a single argument: +/// `ink_sandbox::Sandbox` trait. Thus, your testcase function should accept a single argument: /// `mut session: Session<_>`. /// -/// By default, the macro will use `drink::runtime::MinimalSandbox`. +/// By default, the macro will use `drink::minimal::MinimalSandbox`. /// /// # Example /// @@ -92,7 +92,7 @@ fn test_internal(attr: TokenStream2, item: TokenStream2) -> SynResult