-
Notifications
You must be signed in to change notification settings - Fork 452
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
integration-test
for calling a contract from a runtime pallet (#…
…2189) * Add files for integration test * WIP call contract from runtime * mv to new folder structure * basic e2e test compiles and works * WIP register pallet * WIP add pallets to sandbox runtime * Add pallet to own crate * WIP rearrange workspace * Fix errors * Fix imports * Fix contract * Fix contract manifest * Test passes * Copy full test over * Implement traits to fix test * revert * Remove println! * Put contract back at workspace root again
- Loading branch information
Showing
10 changed files
with
346 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
[workspace] | ||
members = ["sandbox-runtime", "traits"] | ||
|
||
[workspace.package] | ||
authors = ["Parity Technologies <[email protected]>"] | ||
edition = "2021" | ||
homepage = "https://www.parity.io/" | ||
keywords = ["wasm", "parity", "webassembly", "blockchain", "edsl"] | ||
license = "Apache-2.0" | ||
repository = "https://github.com/paritytech/ink" | ||
|
||
[workspace.dependencies] | ||
frame-support = { version = "31.0.0", default-features = false } | ||
frame-system = { version = "31.0.0", default-features = false } | ||
pallet-contracts = { version = "30.0.0", default-features = false } | ||
codec = { package = "parity-scale-codec", version = "3.6.9", default-features = false } | ||
scale-info = { version = "2.11.1", default-features = false } | ||
|
||
[package] | ||
name = "runtime-call-contract" | ||
version = "5.0.0" | ||
authors = ["Parity Technologies <[email protected]>"] | ||
edition = "2021" | ||
publish = false | ||
|
||
[dependencies] | ||
ink = { path = "../../../crates/ink", default-features = false } | ||
flipper-traits = { path = "traits", default-features = false } | ||
|
||
[dev-dependencies] | ||
ink_e2e = { path = "../../../crates/e2e", features = ["sandbox"] } | ||
sandbox-runtime = { path = "sandbox-runtime", default-features = false } | ||
scale-value = "0.14.1" | ||
# can't use workspace dependency because of `cargo-contract` build not | ||
# working with workspace dependencies | ||
frame-support = { version = "31.0.0", default-features = false } | ||
|
||
[lib] | ||
path = "lib.rs" | ||
|
||
[features] | ||
default = ["std"] | ||
std = [ | ||
"ink/std", | ||
"sandbox-runtime/std", | ||
"flipper-traits/std", | ||
] | ||
ink-as-dependency = [] |
60 changes: 60 additions & 0 deletions
60
integration-tests/public/runtime-call-contract/e2e_tests.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
use super::{ | ||
Flipper, | ||
FlipperRef, | ||
}; | ||
use ink_e2e::{ | ||
ChainBackend, | ||
ContractsBackend, | ||
}; | ||
|
||
type E2EResult<T> = Result<T, Box<dyn std::error::Error>>; | ||
|
||
/// Just instantiate a contract using non-default runtime. | ||
#[ink_e2e::test(backend(runtime_only(sandbox = sandbox_runtime::ContractCallerSandbox)))] | ||
async fn instantiate_and_get<Client: E2EBackend>(mut client: Client) -> E2EResult<()> { | ||
use flipper_traits::Flip; | ||
|
||
let initial_value = false; | ||
let mut constructor = FlipperRef::new(initial_value); | ||
|
||
let contract = client | ||
.instantiate("runtime-call-contract", &ink_e2e::alice(), &mut constructor) | ||
.submit() | ||
.await | ||
.expect("instantiate failed"); | ||
|
||
let mut call_builder = contract.call_builder::<Flipper>(); | ||
let flip_dry_run = client | ||
.call(&ink_e2e::bob(), &call_builder.flip()) | ||
.dry_run() | ||
.await?; | ||
let gas_required = flip_dry_run.exec_result.gas_required; | ||
|
||
// call pallet dispatchable | ||
client | ||
.runtime_call( | ||
&ink_e2e::alice(), | ||
"ContractCaller", | ||
"contract_call_flip", | ||
vec![ | ||
scale_value::Value::from_bytes(contract.account_id), | ||
scale_value::serde::to_value(frame_support::weights::Weight::from_parts( | ||
gas_required.ref_time(), | ||
gas_required.proof_size(), | ||
)) | ||
.unwrap(), | ||
], | ||
) | ||
.await | ||
.expect("runtime call failed"); | ||
|
||
// now check that the flip was executed via the pallet | ||
let get_result = client | ||
.call(&ink_e2e::alice(), &call_builder.get()) | ||
.dry_run() | ||
.await?; | ||
|
||
assert_eq!(get_result.return_value(), !initial_value); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#![cfg_attr(not(feature = "std"), no_std, no_main)] | ||
|
||
pub use flipper::{ | ||
Flipper, | ||
FlipperRef, | ||
}; | ||
|
||
#[ink::contract] | ||
mod flipper { | ||
#[ink(storage)] | ||
pub struct Flipper { | ||
value: bool, | ||
} | ||
|
||
impl Flipper { | ||
#[ink(constructor)] | ||
pub fn new(init_value: bool) -> Self { | ||
Self { value: init_value } | ||
} | ||
} | ||
|
||
impl flipper_traits::Flip for Flipper { | ||
#[ink(message)] | ||
fn flip(&mut self) { | ||
self.value = !self.value; | ||
} | ||
|
||
#[ink(message)] | ||
fn get(&self) -> bool { | ||
self.value | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod e2e_tests; |
23 changes: 23 additions & 0 deletions
23
integration-tests/public/runtime-call-contract/sandbox-runtime/Cargo.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "sandbox-runtime" | ||
version = "0.1.0" | ||
authors.workspace = true | ||
edition.workspace = true | ||
homepage.workspace = true | ||
keywords.workspace = true | ||
license.workspace = true | ||
repository.workspace = true | ||
|
||
[dependencies] | ||
ink_sandbox = { path = "../../../../crates/e2e/sandbox" } | ||
pallet-contract-caller = { path = "pallet-contract-caller", default-features = false } | ||
frame-support = { workspace = true } | ||
frame-system = { workspace = true } | ||
codec = { workspace = true } | ||
scale-info = { workspace = true } | ||
|
||
[features] | ||
default = ["std"] | ||
std = [ | ||
"pallet-contract-caller/std", | ||
] |
34 changes: 34 additions & 0 deletions
34
...tion-tests/public/runtime-call-contract/sandbox-runtime/pallet-contract-caller/Cargo.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
[package] | ||
name = "pallet-contract-caller" | ||
version = "0.1.0" | ||
description = "Demonstrate calling an ink! contract from a pallet" | ||
authors = ["Substrate DevHub <https://github.com/substrate-developer-hub>"] | ||
homepage = "https://substrate.io" | ||
edition.workspace = true | ||
license = "MIT-0" | ||
publish = false | ||
repository = "https://github.com/paritytech/ink" | ||
|
||
[package.metadata.docs.rs] | ||
targets = ["x86_64-unknown-linux-gnu"] | ||
|
||
[dependencies] | ||
codec = { workspace = true, default-features = false, features = ["derive"] } | ||
scale-info = { workspace = true, default-features = false, features = ["derive"] } | ||
frame-support = { workspace = true, default-features = false } | ||
frame-system = { workspace = true, default-features = false } | ||
|
||
pallet-contracts = { workspace = true, default-features = false } | ||
flipper-traits = { path = "../../traits", default-features = false } | ||
ink = { path = "../../../../../crates/ink", features = ["no-panic-handler", "no-allocator"] } | ||
|
||
[features] | ||
default = ["std"] | ||
std = [ | ||
"codec/std", | ||
"frame-support/std", | ||
"frame-system/std", | ||
"scale-info/std", | ||
"pallet-contracts/std", | ||
"ink/std" | ||
] |
87 changes: 87 additions & 0 deletions
87
...tion-tests/public/runtime-call-contract/sandbox-runtime/pallet-contract-caller/src/lib.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
//! # Contract Caller | ||
//! | ||
//! Demonstrates calling into an `ink!` contract from a pallet. | ||
#![cfg_attr(not(feature = "std"), no_std)] | ||
|
||
pub use pallet::*; | ||
|
||
#[frame_support::pallet] | ||
pub mod pallet { | ||
use super::*; | ||
use flipper_traits::Flip; | ||
use frame_support::{ | ||
pallet_prelude::*, | ||
traits::fungible::Inspect, | ||
}; | ||
use frame_system::pallet_prelude::*; | ||
use ink::codegen::TraitCallBuilder; | ||
|
||
type AccountIdOf<Runtime> = <Runtime as frame_system::Config>::AccountId; | ||
|
||
#[pallet::pallet] | ||
pub struct Pallet<T>(_); | ||
|
||
#[pallet::config] | ||
pub trait Config: frame_system::Config + pallet_contracts::Config {} | ||
|
||
#[pallet::error] | ||
pub enum Error<T> {} | ||
|
||
#[pallet::call] | ||
impl<T: Config> Pallet<T> | ||
where | ||
[u8; 32]: From<<T as frame_system::Config>::AccountId>, | ||
<<T as pallet_contracts::Config>::Currency as Inspect< | ||
<T as frame_system::Config>::AccountId, | ||
>>::Balance: From<u128>, | ||
{ | ||
/// Call the flip method on the contract at the given `contract` account. | ||
#[pallet::call_index(0)] | ||
#[pallet::weight(<T::WeightInfo as pallet_contracts::WeightInfo>::call().saturating_add(*gas_limit))] | ||
pub fn contract_call_flip( | ||
origin: OriginFor<T>, | ||
contract: AccountIdOf<T>, | ||
gas_limit: Weight, | ||
) -> DispatchResult { | ||
let who = ensure_signed(origin)?; | ||
|
||
let ink_account_id = | ||
ink::primitives::AccountId::from(<[u8; 32]>::from(contract.clone())); | ||
let mut flipper: ink::contract_ref!(Flip, ink::env::DefaultEnvironment) = | ||
ink_account_id.into(); | ||
let call_builder = flipper.call_mut(); | ||
|
||
let params = call_builder | ||
.flip() | ||
.ref_time_limit(gas_limit.ref_time()) | ||
.proof_size_limit(gas_limit.proof_size()) | ||
.params(); | ||
|
||
// Next step is to explore ways to encapsulate the following into the call | ||
// builder. | ||
let value = *params.transferred_value(); | ||
let data = params.exec_input().encode(); | ||
let weight = | ||
Weight::from_parts(params.ref_time_limit(), params.proof_size_limit()); | ||
let storage_deposit_limit = | ||
params.storage_deposit_limit().map(|limit| (*limit).into()); | ||
|
||
let result = pallet_contracts::Pallet::<T>::bare_call( | ||
who.clone(), | ||
contract.clone(), | ||
value.into(), | ||
weight, | ||
storage_deposit_limit, | ||
data, | ||
pallet_contracts::DebugInfo::UnsafeDebug, | ||
pallet_contracts::CollectEvents::Skip, | ||
pallet_contracts::Determinism::Enforced, | ||
); | ||
|
||
assert!(!result.result?.did_revert()); | ||
|
||
Ok(()) | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
integration-tests/public/runtime-call-contract/sandbox-runtime/src/lib.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
//! # Contract Caller | ||
//! | ||
//! Demonstrates calling into an `ink!` contract from a pallet. | ||
#![cfg_attr(not(feature = "std"), no_std)] | ||
|
||
ink_sandbox::create_sandbox!(ContractCallerSandbox, ContractCallerSandboxRuntime, (), (), { | ||
ContractCaller: pallet_contract_caller, | ||
}); | ||
|
||
impl pallet_contract_caller::Config for ContractCallerSandboxRuntime {} |
18 changes: 18 additions & 0 deletions
18
integration-tests/public/runtime-call-contract/traits/Cargo.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "flipper-traits" | ||
version = "5.0.0" | ||
authors = ["Parity Technologies <[email protected]>"] | ||
edition = "2021" | ||
publish = false | ||
|
||
[dependencies] | ||
ink = { path = "../../../../crates/ink", default-features = false } | ||
|
||
[lib] | ||
path = "lib.rs" | ||
|
||
[features] | ||
default = ["std"] | ||
std = [ | ||
"ink/std", | ||
] |
14 changes: 14 additions & 0 deletions
14
integration-tests/public/runtime-call-contract/traits/lib.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#![cfg_attr(not(feature = "std"), no_std, no_main)] | ||
|
||
/// Allows to flip and get a bool value. | ||
#[ink::trait_definition] | ||
pub trait Flip { | ||
/// Flip the value of the stored `bool` from `true` | ||
/// to `false` and vice versa. | ||
#[ink(message)] | ||
fn flip(&mut self); | ||
|
||
/// Returns the current value of our `bool`. | ||
#[ink(message)] | ||
fn get(&self) -> bool; | ||
} |