From 4cff1205edd97d7211895d5a8569be2f8710115b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 28 Aug 2023 13:01:58 +0200 Subject: [PATCH] Call runtime (#40) --- drink/src/chain_api.rs | 54 ++++++++++++++++++++++++++++++++++++++---- drink/src/session.rs | 2 +- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/drink/src/chain_api.rs b/drink/src/chain_api.rs index bf8829e..3452f6c 100644 --- a/drink/src/chain_api.rs +++ b/drink/src/chain_api.rs @@ -1,11 +1,16 @@ //! Basic chain API. +use frame_support::dispatch::Dispatchable; +use frame_support::sp_runtime::DispatchResultWithInfo; use frame_support::{sp_runtime::AccountId32, traits::tokens::currency::Currency}; use crate::{DrinkResult, Error, Runtime, Sandbox}; +/// The runtime call type for a particular runtime. +pub type RuntimeCall = ::RuntimeCall; + /// Interface for basic chain operations. -pub trait ChainApi { +pub trait ChainApi { /// Return the current height of the chain. fn current_height(&mut self) -> u64; @@ -46,9 +51,21 @@ pub trait ChainApi { /// /// * `action` - The action to run. fn dry_run(&mut self, action: impl FnOnce(&mut Self) -> T) -> T; + + /// Execute a runtime call (dispatchable). + /// + /// # Arguments + /// + /// * `call` - The runtime call to execute. + /// * `origin` - The origin of the call. + fn runtime_call( + &mut self, + call: RuntimeCall, + origin: as Dispatchable>::RuntimeOrigin, + ) -> DispatchResultWithInfo< as Dispatchable>::PostInfo>; } -impl ChainApi for Sandbox { +impl ChainApi for Sandbox { fn current_height(&mut self) -> u64 { self.externalities .execute_with(|| frame_system::Pallet::::block_number()) @@ -90,12 +107,20 @@ impl ChainApi for Sandbox { result } + + fn runtime_call( + &mut self, + call: RuntimeCall, + origin: as Dispatchable>::RuntimeOrigin, + ) -> DispatchResultWithInfo< as Dispatchable>::PostInfo> { + self.externalities.execute_with(|| call.dispatch(origin)) + } } #[cfg(test)] mod tests { - use crate::chain_api::ChainApi; - use crate::{runtime::MinimalRuntime, Sandbox, DEFAULT_ACTOR}; + use crate::chain_api::{ChainApi, RuntimeCall}; + use crate::{runtime::MinimalRuntime, AccountId32, Sandbox, DEFAULT_ACTOR}; #[test] fn dry_run_works() { @@ -109,4 +134,25 @@ mod tests { assert_eq!(sandbox.balance(&DEFAULT_ACTOR), initial_balance); } + + #[test] + fn runtime_call_works() { + let mut sandbox = Sandbox::::new().expect("Failed to create sandbox"); + + const RECIPIENT: AccountId32 = AccountId32::new([2u8; 32]); + assert_ne!(DEFAULT_ACTOR, RECIPIENT); + let initial_balance = sandbox.balance(&RECIPIENT); + + let call = RuntimeCall::::Balances( + pallet_balances::Call::::transfer { + dest: RECIPIENT, + value: 100, + }, + ); + let result = sandbox.runtime_call(call, Some(DEFAULT_ACTOR).into()); + assert!(result.is_ok()); + + let expected_balance = initial_balance + 100; + assert_eq!(sandbox.balance(&RECIPIENT), expected_balance); + } } diff --git a/drink/src/session.rs b/drink/src/session.rs index 76dca03..203a4c6 100644 --- a/drink/src/session.rs +++ b/drink/src/session.rs @@ -164,7 +164,7 @@ impl Session { } /// Returns a reference for basic chain API. - pub fn chain_api(&mut self) -> &mut impl ChainApi { + pub fn chain_api(&mut self) -> &mut impl ChainApi { &mut self.sandbox }