Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment agnostic contract invocation API #2219

Merged
merged 37 commits into from
Apr 26, 2024
Merged
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
fca4e05
WIP ideas
ascjones Apr 8, 2024
840aa43
Add invocation
ascjones Apr 11, 2024
9c88b33
SP
ascjones Apr 11, 2024
e12d262
Warnings
ascjones Apr 11, 2024
081d718
WIP add info trait
ascjones Apr 16, 2024
6b500cf
Revert "WIP add info trait"
ascjones Apr 16, 2024
667ad39
WIP TraitCallBuilder
ascjones Apr 19, 2024
08da1a0
Revert "WIP TraitCallBuilder"
ascjones Apr 19, 2024
95b8591
Generate and wire up TraitMessageBuilder
ascjones Apr 19, 2024
56ce1a7
trait impl
ascjones Apr 22, 2024
ebde85d
Utilize message builder from call builder
ascjones Apr 22, 2024
19b4dca
Use type inference
ascjones Apr 22, 2024
53eb64d
Try to use new API...
ascjones Apr 22, 2024
d9ed700
Add storage deposit limit
ascjones Apr 23, 2024
cf1b94f
Add sandbox err message
ascjones Apr 23, 2024
bf06c85
Revert "Add sandbox err message"
ascjones Apr 23, 2024
9174a14
message_builder!
ascjones Apr 23, 2024
d198e6b
Invoker Error type
ascjones Apr 23, 2024
1a09074
Invoker -> Executor
ascjones Apr 23, 2024
e0a6d5e
Extract executor to separate file
ascjones Apr 24, 2024
ce6cbbe
Merge branch 'master' into aj/hybrid-ink-api
ascjones Apr 24, 2024
80d5f27
Access TraitCallBuilder from as-dependency call builder
ascjones Apr 24, 2024
a3f21ba
docs
ascjones Apr 24, 2024
054d415
executor ref and move message_builder to own file + docs
ascjones Apr 25, 2024
ae430f7
executor ref and move message_builder to own file + docs
ascjones Apr 25, 2024
574c253
remove message_builder
ascjones Apr 25, 2024
35e633d
message_builder docs
ascjones Apr 25, 2024
6f4022a
fix message_builder doc tests
ascjones Apr 25, 2024
2bacee0
remove conflicting message builder impl
ascjones Apr 25, 2024
0c9480b
fmt
ascjones Apr 25, 2024
75811af
UI tests
ascjones Apr 25, 2024
8753ded
docs
ascjones Apr 25, 2024
12e01c1
Merge branch 'master' into aj/hybrid-ink-api
ascjones Apr 25, 2024
caa0fce
update copypasta comments
ascjones Apr 25, 2024
0aea636
Merge branch 'master' into aj/hybrid-ink-api
ascjones Apr 26, 2024
a34849c
license headers
ascjones Apr 26, 2024
aa9e29f
CHANGELOG.md
ascjones Apr 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Extract executor to separate file
ascjones committed Apr 24, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit e0a6d5e25a662d502bfc8c5621767036b191617b
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use crate::{
AccountIdOf,
BalanceOf,
};
use frame_support::pallet_prelude::Weight;
use ink::env::{
call::{
ExecutionInput,
Executor,
},
Environment,
};

pub struct PalletContractsExecutor<E: Environment, Runtime: pallet_contracts::Config> {
pub origin: AccountIdOf<Runtime>,
pub contract: AccountIdOf<Runtime>,
pub value: BalanceOf<Runtime>,
pub gas_limit: Weight,
pub storage_deposit_limit: Option<BalanceOf<Runtime>>,
pub marker: core::marker::PhantomData<E>,
}

impl<E, R> Executor<E> for PalletContractsExecutor<E, R>
where
E: Environment,
R: pallet_contracts::Config,
{
type Error = sp_runtime::DispatchError;

fn exec<Args, Output>(
self,
input: &ExecutionInput<Args>,
) -> Result<ink::MessageResult<Output>, Self::Error>
where
Args: codec::Encode,
Output: codec::Decode,
{
let data = codec::Encode::encode(&input);

let result = pallet_contracts::Pallet::<R>::bare_call(
self.origin,
self.contract,
self.value,
self.gas_limit,
self.storage_deposit_limit,
data,
pallet_contracts::DebugInfo::UnsafeDebug,
pallet_contracts::CollectEvents::Skip,
pallet_contracts::Determinism::Enforced,
);

let output = result.result?.data;
let result = codec::Decode::decode(&mut &output[..]).map_err(|_| {
sp_runtime::DispatchError::Other("Failed to decode contract output")
})?;

Ok(result)
}
}
Original file line number Diff line number Diff line change
@@ -4,17 +4,12 @@

#![cfg_attr(not(feature = "std"), no_std)]

mod executor;

use frame_support::{
pallet_prelude::Weight,
traits::fungible::Inspect,
};
use ink::env::{
call::{
ExecutionInput,
Executor,
},
Environment,
};
pub use pallet::*;

type AccountIdOf<R> = <R as frame_system::Config>::AccountId;
@@ -60,85 +55,22 @@ pub mod pallet {
) -> DispatchResult {
let who = ensure_signed(origin)?;

let executor = PalletContractsExecutor::<ink::env::DefaultEnvironment, T> {
origin: who.clone(),
contract: contract.clone(),
value: 0.into(),
gas_limit,
storage_deposit_limit,
marker: Default::default(),
};
let executor =
executor::PalletContractsExecutor::<ink::env::DefaultEnvironment, T> {
origin: who.clone(),
contract: contract.clone(),
value: 0.into(),
gas_limit,
storage_deposit_limit,
marker: Default::default(),
};

let mut flipper = ink::message_builder!(Flip);
let flip = flipper.flip();

let result = flip.exec(executor).unwrap();
let result = flipper.flip().exec(executor)?;

assert!(result.is_ok());

Ok(())
}
}
}

struct PalletContractsExecutor<E: Environment, Runtime: pallet_contracts::Config> {
origin: AccountIdOf<Runtime>,
contract: AccountIdOf<Runtime>,
value: BalanceOf<Runtime>,
gas_limit: Weight,
storage_deposit_limit: Option<BalanceOf<Runtime>>,
marker: core::marker::PhantomData<E>,
}

impl<E, R> Executor<E> for PalletContractsExecutor<E, R>
where
E: Environment,
R: pallet_contracts::Config,
{
type Error = PalletContractsExecutorError;

fn exec<Args, Output>(
self,
input: &ExecutionInput<Args>,
) -> Result<ink::MessageResult<Output>, Self::Error>
where
Args: codec::Encode,
Output: codec::Decode,
{
let data = codec::Encode::encode(&input);

let result = pallet_contracts::Pallet::<R>::bare_call(
self.origin,
self.contract,
self.value,
self.gas_limit,
self.storage_deposit_limit,
data,
pallet_contracts::DebugInfo::UnsafeDebug,
pallet_contracts::CollectEvents::Skip,
pallet_contracts::Determinism::Enforced,
);

let output = result.result?.data;

Ok(codec::Decode::decode(&mut &output[..])?)
}
}

#[derive(Debug)]
pub enum PalletContractsExecutorError {
Codec(codec::Error),
Dispatch(sp_runtime::DispatchError),
}

impl From<codec::Error> for PalletContractsExecutorError {
fn from(err: codec::Error) -> Self {
PalletContractsExecutorError::Codec(err)
}
}

impl From<sp_runtime::DispatchError> for PalletContractsExecutorError {
fn from(err: sp_runtime::DispatchError) -> Self {
PalletContractsExecutorError::Dispatch(err)
}
}