diff --git a/Cargo.lock b/Cargo.lock index a1adf25..8963da0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -938,7 +938,7 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "drink" -version = "0.1.3" +version = "0.1.4" dependencies = [ "contract-transcode", "frame-support", @@ -948,6 +948,7 @@ dependencies = [ "pallet-contracts-primitives", "pallet-timestamp", "parity-scale-codec", + "parity-scale-codec-derive", "scale-info", "sp-externalities", "sp-runtime-interface", @@ -957,7 +958,7 @@ dependencies = [ [[package]] name = "drink-cli" -version = "0.1.3" +version = "0.1.4" dependencies = [ "anyhow", "clap", @@ -2447,9 +2448,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.4" +version = "3.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" +checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" dependencies = [ "arrayvec 0.7.3", "bitvec", @@ -2462,9 +2463,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.4" +version = "3.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" +checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -2619,9 +2620,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -3083,18 +3084,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 89a8b56..a078c5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ homepage = "https://github.com/Cardinal-Cryptography/drink" license = "Apache-2.0" readme = "README.md" repository = "https://github.com/Cardinal-Cryptography/drink" -version = "0.1.3" +version = "0.1.4" [workspace.dependencies] anyhow = { version = "1.0.71" } @@ -27,7 +27,8 @@ clap = { version = "4.3.4" } contract-build = { version = "3.0.1" } contract-transcode = { version = "3.0.1" } crossterm = { version = "0.26.0" } -parity-scale-codec = { version = "3.6.0" } +parity-scale-codec = { version = "=3.6.5" } +parity-scale-codec-derive = { version = "=3.6.5" } ratatui = { version = "0.21.0" } scale-info = { version = "2.5.0" } thiserror = { version = "1.0.40" } @@ -47,4 +48,4 @@ sp-runtime-interface = { version = "18.0.0" } # Local dependencies -drink = { version = "0.1.3", path = "drink" } +drink = { version = "0.1.4", path = "drink" } diff --git a/drink-cli/src/app_state/mod.rs b/drink-cli/src/app_state/mod.rs index b62b864..8f2f2f0 100644 --- a/drink-cli/src/app_state/mod.rs +++ b/drink-cli/src/app_state/mod.rs @@ -1,7 +1,11 @@ use std::{env, path::PathBuf}; pub use contracts::{Contract, ContractIndex, ContractRegistry}; -use drink::{runtime::MinimalRuntime, session::Session, Weight, DEFAULT_ACTOR, DEFAULT_GAS_LIMIT}; +use drink::{ + runtime::{MinimalRuntime, Runtime}, + session::Session, + Weight, DEFAULT_GAS_LIMIT, +}; use sp_core::crypto::AccountId32; pub use user_input::UserInput; @@ -14,7 +18,7 @@ mod user_input; #[derive(Clone, Eq, PartialEq, Debug)] pub struct ChainInfo { - pub block_height: u64, + pub block_height: u32, pub actor: AccountId32, pub gas_limit: Weight, } @@ -23,7 +27,7 @@ impl Default for ChainInfo { fn default() -> Self { Self { block_height: 0, - actor: DEFAULT_ACTOR, + actor: MinimalRuntime::default_actor(), gas_limit: DEFAULT_GAS_LIMIT, } } @@ -38,7 +42,7 @@ pub enum Mode { #[derive(Clone, Eq, PartialEq, Debug)] pub struct UiState { - pub pwd: PathBuf, + pub cwd: PathBuf, pub mode: Mode, pub user_input: UserInput, @@ -48,12 +52,12 @@ pub struct UiState { } impl UiState { - pub fn new(pwd_override: Option) -> Self { - let pwd = pwd_override.unwrap_or_else( - || env::current_dir().expect("Failed to get current directory")); + pub fn new(cwd_override: Option) -> Self { + let cwd = cwd_override + .unwrap_or_else(|| env::current_dir().expect("Failed to get current directory")); UiState { - pwd, + cwd, mode: Default::default(), user_input: Default::default(), output: Default::default(), @@ -76,11 +80,11 @@ pub struct AppState { } impl AppState { - pub fn new(pwd_override: Option) -> Self { + pub fn new(cwd_override: Option) -> Self { AppState { session: Session::new(None).expect("Failed to create drinking session"), chain_info: Default::default(), - ui_state: UiState::new(pwd_override), + ui_state: UiState::new(cwd_override), contracts: Default::default(), } } diff --git a/drink-cli/src/cli.rs b/drink-cli/src/cli.rs index 9aa420b..af70c2b 100644 --- a/drink-cli/src/cli.rs +++ b/drink-cli/src/cli.rs @@ -13,7 +13,7 @@ pub enum CliCommand { #[clap(alias = "nb")] NextBlock { #[clap(default_value = "1")] - count: u64, + count: u32, }, AddTokens { #[clap(value_parser = AccountId32::from_ss58check)] diff --git a/drink-cli/src/executor/contract.rs b/drink-cli/src/executor/contract.rs index b9086bf..627fc95 100644 --- a/drink-cli/src/executor/contract.rs +++ b/drink-cli/src/executor/contract.rs @@ -13,7 +13,7 @@ use crate::{ }; fn build_result(app_state: &mut AppState) -> Result { - let path_to_cargo_toml = app_state.ui_state.pwd.join(Path::new("Cargo.toml")); + let path_to_cargo_toml = app_state.ui_state.cwd.join(Path::new("Cargo.toml")); let manifest_path = ManifestPath::new(path_to_cargo_toml.clone()).map_err(|err| { BuildError::InvalidManifest { manifest_path: path_to_cargo_toml, @@ -48,7 +48,7 @@ pub fn build(app_state: &mut AppState) { pub fn deploy(app_state: &mut AppState, constructor: String, args: Vec, salt: Vec) { // Get raw contract bytes - let Some((contract_name, contract_file)) = find_wasm_blob(&app_state.ui_state.pwd) else { + let Some((contract_name, contract_file)) = find_wasm_blob(&app_state.ui_state.cwd) else { app_state.print_error("Failed to find contract file"); return; }; @@ -64,7 +64,7 @@ pub fn deploy(app_state: &mut AppState, constructor: String, args: Vec, // Read contract metadata and prepare transcoder let metadata_path = app_state .ui_state - .pwd + .cwd .join(format!("target/ink/{contract_name}.json")); let Ok(transcoder) = ContractMessageTranscoder::load(metadata_path) else { @@ -82,7 +82,7 @@ pub fn deploy(app_state: &mut AppState, constructor: String, args: Vec, app_state.contracts.add(Contract { name: contract_name, address, - base_path: app_state.ui_state.pwd.clone(), + base_path: app_state.ui_state.cwd.clone(), transcoder, }); app_state.print("Contract deployed successfully"); @@ -119,8 +119,8 @@ pub fn call(app_state: &mut AppState, message: String, args: Vec) { } } -fn find_wasm_blob(pwd: &Path) -> Option<(String, PathBuf)> { - let Ok(entries) = fs::read_dir(pwd.join("target/ink")) else { +fn find_wasm_blob(cwd: &Path) -> Option<(String, PathBuf)> { + let Ok(entries) = fs::read_dir(cwd.join("target/ink")) else { return None; }; let Some(file) = entries diff --git a/drink-cli/src/executor/error.rs b/drink-cli/src/executor/error.rs index 515f55a..f56b532 100644 --- a/drink-cli/src/executor/error.rs +++ b/drink-cli/src/executor/error.rs @@ -1,10 +1,12 @@ use thiserror::Error; - #[derive(Error, Debug)] pub(crate) enum BuildError { #[error("Invalid manifest path {manifest_path}: {err}")] - InvalidManifest { manifest_path: std::path::PathBuf, err: anyhow::Error }, + InvalidManifest { + manifest_path: std::path::PathBuf, + err: anyhow::Error, + }, #[error("Contract build failed: {err}")] BuildFailed { err: anyhow::Error }, #[error("Wasm code artifact not generated")] diff --git a/drink-cli/src/executor/mod.rs b/drink-cli/src/executor/mod.rs index ad79a6f..90dc9c4 100644 --- a/drink-cli/src/executor/mod.rs +++ b/drink-cli/src/executor/mod.rs @@ -29,10 +29,10 @@ pub fn execute(app_state: &mut AppState) -> Result<()> { match cli_command { CliCommand::Clear => app_state.ui_state.output.clear(), CliCommand::ChangeDir { path } => { - let target_dir = app_state.ui_state.pwd.join(path); + let target_dir = app_state.ui_state.cwd.join(path); match env::set_current_dir(target_dir) { Ok(_) => { - app_state.ui_state.pwd = + app_state.ui_state.cwd = env::current_dir().expect("Failed to get current directory"); app_state.print("Directory changed"); } @@ -66,7 +66,7 @@ pub fn execute(app_state: &mut AppState) -> Result<()> { Ok(()) } -fn build_blocks(app_state: &mut AppState, count: u64) { +fn build_blocks(app_state: &mut AppState, count: u32) { app_state.chain_info.block_height = app_state .session .chain_api() diff --git a/drink-cli/src/main.rs b/drink-cli/src/main.rs index c2f3109..e3c4d96 100644 --- a/drink-cli/src/main.rs +++ b/drink-cli/src/main.rs @@ -1,6 +1,7 @@ +use std::path::PathBuf; + use anyhow::Result; use clap::Parser; -use std::path::PathBuf; use crate::ui::run_ui; @@ -13,7 +14,7 @@ mod ui; #[command(author, version, about, long_about = None)] struct Args { /// Starts the CLI in the provided directory - #[arg(short, long, value_name = "DIRECTORY", )] + #[arg(short, long, value_name = "DIRECTORY")] path: Option, } diff --git a/drink-cli/src/ui/current_env.rs b/drink-cli/src/ui/current_env.rs index e7de94b..1891510 100644 --- a/drink-cli/src/ui/current_env.rs +++ b/drink-cli/src/ui/current_env.rs @@ -17,7 +17,7 @@ Block height: {} Deployed contracts: {} Current actor: {} Current contract: {{ {} }}"#, - app_state.ui_state.pwd.to_str().unwrap(), + app_state.ui_state.cwd.to_str().unwrap(), app_state.chain_info.block_height, app_state.contracts.count(), app_state.chain_info.actor, diff --git a/drink-cli/src/ui/mod.rs b/drink-cli/src/ui/mod.rs index 93988bd..3748722 100644 --- a/drink-cli/src/ui/mod.rs +++ b/drink-cli/src/ui/mod.rs @@ -6,8 +6,7 @@ mod layout; mod output; mod user_input; -use std::{io, io::Stdout}; -use std::path::PathBuf; +use std::{io, io::Stdout, path::PathBuf}; use anyhow::{anyhow, Result}; use crossterm::{ @@ -29,9 +28,9 @@ use crate::{ type Terminal = ratatui::Terminal>; -pub fn run_ui(pwd: Option) -> Result<()> { +pub fn run_ui(cwd: Option) -> Result<()> { let mut terminal = setup_dedicated_terminal()?; - let app_result = run_ui_app(&mut terminal, pwd); + let app_result = run_ui_app(&mut terminal, cwd); restore_original_terminal(terminal)?; app_result } @@ -54,8 +53,8 @@ fn restore_original_terminal(mut terminal: Terminal) -> Result<()> { terminal.show_cursor().map_err(|e| anyhow!(e)) } -fn run_ui_app(terminal: &mut Terminal, pwd_override: Option) -> Result<()> { - let mut app_state = AppState::new(pwd_override); +fn run_ui_app(terminal: &mut Terminal, cwd_override: Option) -> Result<()> { + let mut app_state = AppState::new(cwd_override); loop { terminal.draw(|f| layout(f, &mut app_state))?; diff --git a/drink/Cargo.toml b/drink/Cargo.toml index 830cb43..f3042c3 100644 --- a/drink/Cargo.toml +++ b/drink/Cargo.toml @@ -18,6 +18,7 @@ pallet-contracts = { workspace = true } pallet-contracts-primitives = { workspace = true } pallet-timestamp = { workspace = true } parity-scale-codec = { workspace = true } +parity-scale-codec-derive = { workspace = true } sp-externalities = { workspace = true } sp-runtime-interface = { workspace = true } diff --git a/drink/src/chain_api.rs b/drink/src/chain_api.rs index 9d52cf2..2be3b5d 100644 --- a/drink/src/chain_api.rs +++ b/drink/src/chain_api.rs @@ -2,11 +2,12 @@ use frame_support::{ dispatch::Dispatchable, - sp_runtime::{AccountId32, DispatchResultWithInfo}, + sp_runtime::{DispatchResultWithInfo, Saturating}, traits::tokens::currency::Currency, }; +use frame_system::pallet_prelude::BlockNumberFor; -use crate::{DrinkResult, Error, EventRecordOf, Runtime, Sandbox}; +use crate::{runtime::AccountIdFor, DrinkResult, Error, EventRecordOf, Runtime, Sandbox}; /// The runtime call type for a particular runtime. pub type RuntimeCall = ::RuntimeCall; @@ -14,17 +15,17 @@ pub type RuntimeCall = ::RuntimeCall; /// Interface for basic chain operations. pub trait ChainApi { /// Return the current height of the chain. - fn current_height(&mut self) -> u64; + fn current_height(&mut self) -> BlockNumberFor; /// Build a new empty block and return the new height. - fn build_block(&mut self) -> DrinkResult; + fn build_block(&mut self) -> DrinkResult>; /// Build `n` empty blocks and return the new height. /// /// # Arguments /// /// * `n` - The number of blocks to build. - fn build_blocks(&mut self, n: u64) -> DrinkResult { + fn build_blocks(&mut self, n: u32) -> DrinkResult> { let mut last_block = None; for _ in 0..n { last_block = Some(self.build_block()?); @@ -38,14 +39,14 @@ pub trait ChainApi { /// /// * `address` - The address of the account to add tokens to. /// * `amount` - The number of tokens to add. - fn add_tokens(&mut self, address: AccountId32, amount: u128); + fn add_tokens(&mut self, address: AccountIdFor, amount: u128); /// Return the balance of an account. /// /// # Arguments /// /// * `address` - The address of the account to query. - fn balance(&mut self, address: &AccountId32) -> u128; + fn balance(&mut self, address: &AccountIdFor) -> u128; /// Run an action without modifying the storage. /// @@ -74,27 +75,28 @@ pub trait ChainApi { } impl ChainApi for Sandbox { - fn current_height(&mut self) -> u64 { + fn current_height(&mut self) -> BlockNumberFor { self.externalities .execute_with(|| frame_system::Pallet::::block_number()) } - fn build_block(&mut self) -> DrinkResult { - let current_block = self.current_height(); + fn build_block(&mut self) -> DrinkResult> { + let mut current_block = self.current_height(); self.externalities.execute_with(|| { let block_hash = R::finalize_block(current_block).map_err(Error::BlockFinalize)?; - R::initialize_block(current_block + 1, block_hash).map_err(Error::BlockInitialize)?; - Ok(current_block + 1) + current_block.saturating_inc(); + R::initialize_block(current_block, block_hash).map_err(Error::BlockInitialize)?; + Ok(current_block) }) } - fn add_tokens(&mut self, address: AccountId32, amount: u128) { + fn add_tokens(&mut self, address: AccountIdFor, amount: u128) { self.externalities.execute_with(|| { let _ = pallet_balances::Pallet::::deposit_creating(&address, amount); }); } - fn balance(&mut self, address: &AccountId32) -> u128 { + fn balance(&mut self, address: &AccountIdFor) -> u128 { self.externalities .execute_with(|| pallet_balances::Pallet::::free_balance(address)) } @@ -141,8 +143,8 @@ mod tests { use crate::{ chain_api::{ChainApi, DispatchResultWithInfo, RuntimeCall}, - runtime::{minimal::RuntimeEvent, MinimalRuntime}, - AccountId32, Sandbox, DEFAULT_ACTOR, + runtime::{minimal::RuntimeEvent, MinimalRuntime, Runtime}, + AccountId32, Sandbox, }; fn make_transfer( @@ -153,20 +155,21 @@ mod tests { let call = RuntimeCall::::Balances( pallet_balances::Call::::transfer { dest, value }, ); - sandbox.runtime_call(call, Some(DEFAULT_ACTOR).into()) + sandbox.runtime_call(call, Some(MinimalRuntime::default_actor()).into()) } #[test] fn dry_run_works() { let mut sandbox = Sandbox::::new().expect("Failed to create sandbox"); - let initial_balance = sandbox.balance(&DEFAULT_ACTOR); + let actor = MinimalRuntime::default_actor(); + let initial_balance = sandbox.balance(&actor); sandbox.dry_run(|runtime| { - runtime.add_tokens(DEFAULT_ACTOR, 100); - assert_eq!(runtime.balance(&DEFAULT_ACTOR), initial_balance + 100); + runtime.add_tokens(actor.clone(), 100); + assert_eq!(runtime.balance(&actor), initial_balance + 100); }); - assert_eq!(sandbox.balance(&DEFAULT_ACTOR), initial_balance); + assert_eq!(sandbox.balance(&actor), initial_balance); } #[test] @@ -174,7 +177,7 @@ mod tests { let mut sandbox = Sandbox::::new().expect("Failed to create sandbox"); const RECIPIENT: AccountId32 = AccountId32::new([2u8; 32]); - assert_ne!(DEFAULT_ACTOR, RECIPIENT); + assert_ne!(MinimalRuntime::default_actor(), RECIPIENT); let initial_balance = sandbox.balance(&RECIPIENT); let result = make_transfer(&mut sandbox, RECIPIENT, 100); @@ -191,7 +194,8 @@ mod tests { let events_before = sandbox.get_current_block_events(); assert!(events_before.is_empty()); - make_transfer(&mut sandbox, DEFAULT_ACTOR, 1).expect("Failed to make transfer"); + make_transfer(&mut sandbox, MinimalRuntime::default_actor(), 1) + .expect("Failed to make transfer"); let events_after = sandbox.get_current_block_events(); assert_eq!(events_after.len(), 1); @@ -201,14 +205,15 @@ mod tests { #[test] fn resetting_events() { let mut sandbox = Sandbox::::new().expect("Failed to create sandbox"); + let actor = MinimalRuntime::default_actor(); - make_transfer(&mut sandbox, DEFAULT_ACTOR, 1).expect("Failed to make transfer"); + make_transfer(&mut sandbox, actor.clone(), 1).expect("Failed to make transfer"); assert!(!sandbox.get_current_block_events().is_empty()); sandbox.reset_current_block_events(); assert!(sandbox.get_current_block_events().is_empty()); - make_transfer(&mut sandbox, DEFAULT_ACTOR, 1).expect("Failed to make transfer"); + make_transfer(&mut sandbox, actor, 1).expect("Failed to make transfer"); assert!(!sandbox.get_current_block_events().is_empty()); } } diff --git a/drink/src/contract_api.rs b/drink/src/contract_api.rs index b0c5235..7104654 100644 --- a/drink/src/contract_api.rs +++ b/drink/src/contract_api.rs @@ -1,12 +1,15 @@ //! Contracts API. -use frame_support::{sp_runtime::AccountId32, weights::Weight}; +use frame_support::weights::Weight; use pallet_contracts::{CollectEvents, DebugInfo, Determinism}; use pallet_contracts_primitives::{ Code, CodeUploadResult, ContractExecResult, ContractInstantiateResult, }; -use crate::{runtime::Runtime, EventRecordOf, Sandbox}; +use crate::{ + runtime::{AccountIdFor, Runtime}, + EventRecordOf, Sandbox, +}; /// Interface for contract-related operations. pub trait ContractApi { @@ -28,10 +31,10 @@ pub trait ContractApi { value: u128, data: Vec, salt: Vec, - origin: AccountId32, + origin: AccountIdFor, gas_limit: Weight, storage_deposit_limit: Option, - ) -> ContractInstantiateResult>; + ) -> ContractInstantiateResult, u128, EventRecordOf>; /// Interface for `bare_upload_code` contract call. /// @@ -43,7 +46,7 @@ pub trait ContractApi { fn upload_contract( &mut self, contract_bytes: Vec, - origin: AccountId32, + origin: AccountIdFor, storage_deposit_limit: Option, ) -> CodeUploadResult<::Hash, u128>; @@ -59,10 +62,10 @@ pub trait ContractApi { /// * `storage_deposit_limit` - The storage deposit limit for the contract call. fn call_contract( &mut self, - address: AccountId32, + address: AccountIdFor, value: u128, data: Vec, - origin: AccountId32, + origin: AccountIdFor, gas_limit: Weight, storage_deposit_limit: Option, ) -> ContractExecResult>; @@ -75,10 +78,10 @@ impl ContractApi for Sandbox { value: u128, data: Vec, salt: Vec, - origin: AccountId32, + origin: AccountIdFor, gas_limit: Weight, storage_deposit_limit: Option, - ) -> ContractInstantiateResult> { + ) -> ContractInstantiateResult, u128, EventRecordOf> { self.externalities.execute_with(|| { pallet_contracts::Pallet::::bare_instantiate( origin, @@ -97,7 +100,7 @@ impl ContractApi for Sandbox { fn upload_contract( &mut self, contract_bytes: Vec, - origin: AccountId32, + origin: AccountIdFor, storage_deposit_limit: Option, ) -> CodeUploadResult<::Hash, u128> { self.externalities.execute_with(|| { @@ -112,10 +115,10 @@ impl ContractApi for Sandbox { fn call_contract( &mut self, - address: AccountId32, + address: AccountIdFor, value: u128, data: Vec, - origin: AccountId32, + origin: AccountIdFor, gas_limit: Weight, storage_deposit_limit: Option, ) -> ContractExecResult> { @@ -147,10 +150,7 @@ mod tests { use pallet_contracts::Origin; use super::*; - use crate::{ - chain_api::ChainApi, minimal::RuntimeEvent, MinimalRuntime, DEFAULT_ACTOR, - DEFAULT_GAS_LIMIT, - }; + use crate::{chain_api::ChainApi, minimal::RuntimeEvent, MinimalRuntime, DEFAULT_GAS_LIMIT}; fn compile_module(contract_name: &str) -> Vec { let path = [ @@ -171,7 +171,7 @@ mod tests { let wasm_binary = compile_module("dummy"); let hash = <::Hashing>::hash(&wasm_binary); - let result = sandbox.upload_contract(wasm_binary, DEFAULT_ACTOR, None); + let result = sandbox.upload_contract(wasm_binary, MinimalRuntime::default_actor(), None); assert!(result.is_ok()); assert_eq!(hash, result.unwrap().code_hash); @@ -190,7 +190,7 @@ mod tests { 0, vec![], vec![], - DEFAULT_ACTOR, + MinimalRuntime::default_actor(), DEFAULT_GAS_LIMIT, None, ); @@ -208,6 +208,7 @@ mod tests { #[test] fn can_call_contract() { let mut sandbox = Sandbox::::new().unwrap(); + let actor = MinimalRuntime::default_actor(); let wasm_binary = compile_module("dummy"); let result = sandbox.deploy_contract( @@ -215,7 +216,7 @@ mod tests { 0, vec![], vec![], - DEFAULT_ACTOR, + actor.clone(), DEFAULT_GAS_LIMIT, None, ); @@ -231,7 +232,7 @@ mod tests { contract_address.clone(), 0, vec![], - DEFAULT_ACTOR, + actor.clone(), DEFAULT_GAS_LIMIT, None, ); @@ -253,7 +254,7 @@ mod tests { events[1].event, RuntimeEvent::Contracts(pallet_contracts::Event::::Called { contract: contract_address, - caller: Origin::Signed(DEFAULT_ACTOR), + caller: Origin::Signed(actor), }), ); } diff --git a/drink/src/lib.rs b/drink/src/lib.rs index e7bc280..74df6c4 100644 --- a/drink/src/lib.rs +++ b/drink/src/lib.rs @@ -12,13 +12,17 @@ pub mod session; use std::marker::PhantomData; pub use error::Error; -use frame_support::{sp_io::TestExternalities, sp_runtime::BuildStorage}; +use frame_support::{ + sp_io::TestExternalities, + sp_runtime::{traits::One, BuildStorage}, +}; pub use frame_support::{sp_runtime::AccountId32, weights::Weight}; -use frame_system::{EventRecord, GenesisConfig}; +use frame_system::{pallet_prelude::BlockNumberFor, EventRecord, GenesisConfig}; -use crate::pallet_contracts_debugging::DebugExt; -use crate::runtime::pallet_contracts_debugging::NoopDebugExt; -use crate::runtime::*; +use crate::{ + pallet_contracts_debugging::DebugExt, + runtime::{pallet_contracts_debugging::NoopDebugExt, *}, +}; /// Main result type for the drink crate. pub type DrinkResult = std::result::Result; @@ -33,8 +37,6 @@ pub struct Sandbox { _phantom: PhantomData, } -/// Default extrinsic origin. -pub const DEFAULT_ACTOR: AccountId32 = AccountId32::new([1u8; 32]); /// Default gas limit. pub const DEFAULT_GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); @@ -43,7 +45,7 @@ impl Sandbox { /// /// Returns an error if the storage could not be initialized. /// - /// The storage is initialized with a genesis block with a single account `DEFAULT_ACTOR` with + /// The storage is initialized with a genesis block with a single account `R::default_actor()` with /// `INITIAL_BALANCE`. pub fn new() -> DrinkResult { let mut storage = GenesisConfig::::default() @@ -61,7 +63,7 @@ impl Sandbox { .externalities // We start the chain from the 1st block, so that events are collected (they are not // recorded for the genesis block...). - .execute_with(|| R::initialize_block(1, Default::default())) + .execute_with(|| R::initialize_block(BlockNumberFor::::one(), Default::default())) .map_err(Error::BlockInitialize)?; // We register a noop debug extension by default. diff --git a/drink/src/runtime/minimal.rs b/drink/src/runtime/minimal.rs index 2b69ebb..f8863b6 100644 --- a/drink/src/runtime/minimal.rs +++ b/drink/src/runtime/minimal.rs @@ -14,14 +14,18 @@ use frame_support::{ }; // Re-export all pallets. pub use frame_system; +use frame_system::pallet_prelude::BlockNumberFor; pub use pallet_balances; pub use pallet_contracts; use pallet_contracts::{DefaultAddressGenerator, Frame, Schedule}; pub use pallet_timestamp; -use crate::{runtime::pallet_contracts_debugging::DrinkDebug, Runtime, DEFAULT_ACTOR}; +use crate::{ + runtime::{pallet_contracts_debugging::DrinkDebug, AccountIdFor}, + Runtime, +}; -type Block = frame_system::mocking::MockBlock; +type Block = frame_system::mocking::MockBlockU32; frame_support::construct_runtime!( pub enum MinimalRuntime { @@ -45,7 +49,7 @@ impl frame_system::Config for MinimalRuntime { type AccountId = AccountId32; type Lookup = IdentityLookup; type RuntimeEvent = RuntimeEvent; - type BlockHashCount = ConstU64<250>; + type BlockHashCount = ConstU32<250>; type DbWeight = (); type Version = (); type PalletInfo = PalletInfo; @@ -82,8 +86,8 @@ impl pallet_timestamp::Config for MinimalRuntime { } pub enum SandboxRandomness {} -impl Randomness for SandboxRandomness { - fn random(_subject: &[u8]) -> (H256, u64) { +impl Randomness for SandboxRandomness { + fn random(_subject: &[u8]) -> (H256, u32) { todo!("No randomness") } } @@ -133,12 +137,12 @@ pub const INITIAL_BALANCE: u128 = 1_000_000_000_000_000; impl Runtime for MinimalRuntime { fn initialize_storage(storage: &mut Storage) -> Result<(), String> { pallet_balances::GenesisConfig:: { - balances: vec![(DEFAULT_ACTOR, INITIAL_BALANCE)], + balances: vec![(Self::default_actor(), INITIAL_BALANCE)], } .assimilate_storage(storage) } - fn initialize_block(height: u64, parent_hash: H256) -> Result<(), String> { + fn initialize_block(height: BlockNumberFor, parent_hash: H256) -> Result<(), String> { System::reset_events(); System::initialize(&height, &parent_hash, &Default::default()); @@ -157,11 +161,15 @@ impl Runtime for MinimalRuntime { Ok(()) } - fn finalize_block(height: u64) -> Result { + fn finalize_block(height: BlockNumberFor) -> Result { Contracts::on_finalize(height); Timestamp::on_finalize(height); Balances::on_finalize(height); Ok(System::finalize().hash()) } + + fn default_actor() -> AccountIdFor { + AccountId32::new([1u8; 32]) + } } diff --git a/drink/src/runtime/mod.rs b/drink/src/runtime/mod.rs index cf4f54c..c862c16 100644 --- a/drink/src/runtime/mod.rs +++ b/drink/src/runtime/mod.rs @@ -4,17 +4,19 @@ pub mod minimal; pub mod pallet_contracts_debugging; -use frame_support::sp_runtime::{AccountId32, Storage}; +use frame_support::sp_runtime::Storage; +use frame_system::pallet_prelude::BlockNumberFor; pub use minimal::MinimalRuntime; +/// The type of an account identifier. +pub type AccountIdFor = ::AccountId; + /// A runtime to use. /// /// Must contain at least system, balances and contracts pallets. pub trait Runtime: - frame_system::Config< - AccountId = AccountId32, - Block = frame_system::mocking::MockBlock, - > + pallet_balances::Config + frame_system::Config + + pallet_balances::Config + pallet_contracts::Config> { /// Initialize the storage at the genesis block. @@ -24,14 +26,19 @@ pub trait Runtime: /// Initialize a new block at particular height. fn initialize_block( - _height: u64, + _height: BlockNumberFor, _parent_hash: ::Hash, ) -> Result<(), String> { Ok(()) } /// Finalize a block at particular height. - fn finalize_block(_height: u64) -> Result<::Hash, String> { + fn finalize_block( + _height: BlockNumberFor, + ) -> Result<::Hash, String> { Ok(Default::default()) } + + /// Default actor for the runtime. + fn default_actor() -> AccountIdFor; } diff --git a/drink/src/runtime/pallet_contracts_debugging.rs b/drink/src/runtime/pallet_contracts_debugging.rs index f2ca81d..47504a3 100644 --- a/drink/src/runtime/pallet_contracts_debugging.rs +++ b/drink/src/runtime/pallet_contracts_debugging.rs @@ -26,9 +26,7 @@ use pallet_contracts_primitives::ExecReturnValue; use sp_externalities::{decl_extension, ExternalitiesExt}; use sp_runtime_interface::runtime_interface; -use crate::runtime::Runtime; - -type AccountIdOf = ::AccountId; +use crate::runtime::{AccountIdFor, Runtime}; /// The trait that allows injecting custom logic to handle contract debugging directly in the /// contracts pallet. @@ -73,10 +71,10 @@ trait ContractCallDebugger { pub enum DrinkDebug {} impl Tracing for DrinkDebug { - type CallSpan = DrinkCallSpan>; + type CallSpan = DrinkCallSpan>; fn new_call_span( - contract_address: &AccountIdOf, + contract_address: &AccountIdFor, entry_point: ExportedFunction, input_data: &[u8], ) -> Self::CallSpan { @@ -101,11 +99,10 @@ pub struct DrinkCallSpan { pub input_data: Vec, } -impl> CallSpan for DrinkCallSpan { +impl CallSpan for DrinkCallSpan { fn after_call(self, output: &ExecReturnValue) { - let raw_contract_address: &[u8] = self.contract_address.as_ref(); contract_call_debugger::after_call( - raw_contract_address.to_vec(), + self.contract_address.encode(), matches!(self.entry_point, ExportedFunction::Call), self.input_data.to_vec(), output.data.clone(), diff --git a/drink/src/session.rs b/drink/src/session.rs index 2f636d8..8d3fbba 100644 --- a/drink/src/session.rs +++ b/drink/src/session.rs @@ -9,8 +9,11 @@ use pallet_contracts_primitives::{ContractExecResult, ContractInstantiateResult} use thiserror::Error; use crate::{ - chain_api::ChainApi, contract_api::ContractApi, pallet_contracts_debugging::DebugExt, - runtime::Runtime, AccountId32, EventRecordOf, Sandbox, DEFAULT_ACTOR, DEFAULT_GAS_LIMIT, + chain_api::ChainApi, + contract_api::ContractApi, + pallet_contracts_debugging::DebugExt, + runtime::{AccountIdFor, Runtime}, + EventRecordOf, Sandbox, DEFAULT_GAS_LIMIT, }; const ZERO_TRANSFER: u128 = 0; @@ -104,13 +107,13 @@ pub enum SessionError { pub struct Session { sandbox: Sandbox, - actor: AccountId32, + actor: AccountIdFor, gas_limit: Weight, transcoder: Option>, - deploy_results: Vec>>, - deploy_returns: Vec, + deploy_results: Vec, u128, EventRecordOf>>, + deploy_returns: Vec>, call_results: Vec>>, call_returns: Vec, } @@ -120,7 +123,7 @@ impl Session { pub fn new(transcoder: Option>) -> Result { Ok(Self { sandbox: Sandbox::new().map_err(SessionError::Drink)?, - actor: DEFAULT_ACTOR, + actor: R::default_actor(), gas_limit: DEFAULT_GAS_LIMIT, transcoder, deploy_results: vec![], @@ -131,12 +134,12 @@ impl Session { } /// Sets a new actor and returns updated `self`. - pub fn with_actor(self, actor: AccountId32) -> Self { + pub fn with_actor(self, actor: AccountIdFor) -> Self { Self { actor, ..self } } /// Sets a new actor and returns the old one. - pub fn set_actor(&mut self, actor: AccountId32) -> AccountId32 { + pub fn set_actor(&mut self, actor: AccountIdFor) -> AccountIdFor { mem::replace(&mut self.actor, actor) } @@ -194,7 +197,7 @@ impl Session { constructor: &str, args: &[String], salt: Vec, - ) -> Result { + ) -> Result, SessionError> { let data = self .transcoder .as_ref() @@ -236,7 +239,7 @@ impl Session { /// Calls the last deployed contract. In case of a successful call, returns `self`. pub fn call_with_address_and( mut self, - address: AccountId32, + address: AccountIdFor, message: &str, args: &[String], ) -> Result { @@ -253,7 +256,7 @@ impl Session { /// result. pub fn call_with_address( &mut self, - address: AccountId32, + address: AccountIdFor, message: &str, args: &[String], ) -> Result { @@ -262,7 +265,7 @@ impl Session { fn call_internal( &mut self, - address: Option, + address: Option>, message: &str, args: &[String], ) -> Result { @@ -314,12 +317,12 @@ impl Session { /// Returns the last result of deploying a contract. pub fn last_deploy_result( &self, - ) -> Option<&ContractInstantiateResult>> { + ) -> Option<&ContractInstantiateResult, u128, EventRecordOf>> { self.deploy_results.last() } /// Returns the address of the last deployed contract. - pub fn last_deploy_return(&self) -> Option { + pub fn last_deploy_return(&self) -> Option> { self.deploy_returns.last().cloned() }