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

Dry running contract interactions #106

Merged
merged 5 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
42 changes: 5 additions & 37 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.12.0]
## [0.12.1]

### Pull requests
### Added

- https://github.com/inkdevhub/drink/pull/110
- Support dry running contract interactions

## [0.12.0]

### Changed

Expand All @@ -20,20 +22,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [0.11.1]

### Pull requests

- https://github.com/inkdevhub/drink/pull/104

### Added

- Respect features for the contract dependencies when building contracts via drink macros

## [0.11.0]

### Pull requests

- https://github.com/inkdevhub/drink/pull/109

### Changed

- Support `[email protected]`
Expand All @@ -43,11 +37,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [0.10.0]

### Pull requests

- https://github.com/inkdevhub/drink/pull/100
- https://github.com/inkdevhub/drink/pull/101

### Changed

- Update toolchain to `1.74.0`
Expand All @@ -56,20 +45,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [0.9.0]

### Pull requests

- https://github.com/inkdevhub/drink/pull/99

### Changed

- Rework `Sandbox` API to ease working with custom runtimes

## [0.8.7]

### Pull requests

- https://github.com/inkdevhub/drink/pull/112

### Changed

- Migrate examples back to `[email protected]`
Expand All @@ -82,33 +63,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [0.8.6] [YANKED]

### Pull requests

- https://github.com/inkdevhub/drink/pull/92
- https://github.com/inkdevhub/drink/pull/94

### Added

- Accessing events emitted by contracts
- `#[drink::test]` creates and adds a `session: Session` argument to the test function

## [0.8.5] [YANKED]

### Pull requests

- https://github.com/inkdevhub/drink/pull/91

### Changed

- Update `contract-*` crates from `3.x.x` to `4.0.0-rc.1`
- Migrate examples from `[email protected]` to `[email protected]`

## [0.8.4]

### Pull requests

- https://github.com/inkdevhub/drink/pull/90

### Added

- `NO_SALT`, `NO_ENDOWMENT` contstants added
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ homepage = "https://github.com/Cardinal-Cryptography/drink"
license = "Apache-2.0"
readme = "README.md"
repository = "https://github.com/Cardinal-Cryptography/drink"
version = "0.12.0"
version = "0.12.1"

[workspace.dependencies]
anyhow = { version = "1.0.71" }
Expand Down Expand Up @@ -57,5 +57,5 @@ sp-runtime-interface = { version = "24.0.0" }

# Local dependencies

drink = { version = "=0.12.0", path = "drink" }
drink-test-macro = { version = "=0.12.0", path = "drink/test-macro" }
drink = { version = "=0.12.1", path = "drink" }
drink-test-macro = { version = "=0.12.1", path = "drink/test-macro" }
22 changes: 18 additions & 4 deletions drink/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,44 @@ 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,
};
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};

pub use crate::runtime::minimal::{self, MinimalRuntime};
use crate::runtime::AccountIdFor;

/// Alias for `frame-system`'s `RuntimeCall` type.
pub type RuntimeCall<R> = <R as frame_system::Config>::RuntimeCall;
pub type RuntimeCall<Runtime> = <Runtime as frame_system::Config>::RuntimeCall;

/// Alias for `pallet-balances`'s Balance type.
pub type BalanceOf<R> = <R as pallet_balances::Config>::Balance;
pub type BalanceOf<Runtime> =
pmikolajczyk41 marked this conversation as resolved.
Show resolved Hide resolved
<<Runtime as pallet_contracts::Config>::Currency as Inspect<AccountIdFor<Runtime>>>::Balance;

/// Main result type for the drink crate.
pub type DrinkResult<T> = std::result::Result<T, Error>;

/// Copied from pallet-contracts.
pub type EventRecordOf<T> =
EventRecord<<T as frame_system::Config>::RuntimeEvent, <T as frame_system::Config>::Hash>;
pub type EventRecordOf<Runtime> = EventRecord<
<Runtime as frame_system::Config>::RuntimeEvent,
<Runtime as frame_system::Config>::Hash,
>;

/// Copied from pallet-contracts.
pub type ContractInstantiateResultFor<Runtime> =
ContractInstantiateResult<AccountIdFor<Runtime>, BalanceOf<Runtime>, EventRecordOf<Runtime>>;

/// Copied from pallet-contracts.
pub type ContractExecResultFor<Runtime> =
ContractExecResult<BalanceOf<Runtime>, EventRecordOf<Runtime>>;

/// Default gas limit.
pub const DEFAULT_GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024);
4 changes: 3 additions & 1 deletion drink/src/sandbox/balance_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
use frame_support::{sp_runtime::DispatchError, traits::fungible::Mutate};

use super::Sandbox;
use crate::{runtime::AccountIdFor, BalanceOf, SandboxConfig};
use crate::{runtime::AccountIdFor, SandboxConfig};

type BalanceOf<R> = <R as pallet_balances::Config>::Balance;

impl<Config: SandboxConfig> Sandbox<Config>
where
Expand Down
21 changes: 8 additions & 13 deletions drink/src/sandbox/contracts_api.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
//! Contracts API for the sandbox.
use std::ops::Not;

use frame_support::{traits::fungible::Inspect, weights::Weight};
use frame_support::weights::Weight;
use frame_system::Config as SysConfig;
use pallet_contracts::{
Code, CodeUploadResult, CollectEvents, ContractExecResult, ContractInstantiateResult,
DebugInfo, Determinism,
Code, CodeUploadResult, CollectEvents, ContractInstantiateResult, DebugInfo, Determinism,
};
use parity_scale_codec::Decode as _;

use crate::{runtime::AccountIdFor, EventRecordOf, Sandbox};

type BalanceOf<R> =
<<R as pallet_contracts::Config>::Currency as Inspect<AccountIdFor<R>>>::Balance;
use crate::{
runtime::AccountIdFor, BalanceOf, ContractExecResultFor, ContractInstantiateResultFor,
EventRecordOf, Sandbox,
};

impl<Config: crate::SandboxConfig> Sandbox<Config>
where
Expand All @@ -39,11 +38,7 @@ where
origin: AccountIdFor<Config::Runtime>,
gas_limit: Weight,
storage_deposit_limit: Option<BalanceOf<Config::Runtime>>,
) -> ContractInstantiateResult<
AccountIdFor<Config::Runtime>,
BalanceOf<Config::Runtime>,
EventRecordOf<Config::Runtime>,
> {
) -> ContractInstantiateResultFor<Config::Runtime> {
self.externalities.execute_with(|| {
pallet_contracts::Pallet::<Config::Runtime>::bare_instantiate(
origin,
Expand Down Expand Up @@ -149,7 +144,7 @@ where
gas_limit: Weight,
storage_deposit_limit: Option<BalanceOf<Config::Runtime>>,
determinism: Determinism,
) -> ContractExecResult<BalanceOf<Config::Runtime>, EventRecordOf<Config::Runtime>> {
) -> ContractExecResultFor<Config::Runtime> {
self.externalities.execute_with(|| {
pallet_contracts::Pallet::<Config::Runtime>::bare_call(
origin,
Expand Down
69 changes: 62 additions & 7 deletions drink/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,21 @@ use std::{

pub use contract_transcode;
use contract_transcode::ContractMessageTranscoder;
use error::SessionError;
use frame_support::{traits::fungible::Inspect, weights::Weight};
use pallet_contracts::Determinism;
use parity_scale_codec::Decode;
pub use record::{EventBatch, Record};

use self::mocking_api::MockingApi;
use crate::{
runtime::{
pallet_contracts_debugging::{InterceptingExt, TracingExt},
AccountIdFor, HashFor,
AccountIdFor, HashFor, MinimalRuntime,
},
sandbox::SandboxConfig,
session::mock::MockRegistry,
Sandbox, DEFAULT_GAS_LIMIT,
ContractExecResultFor, ContractInstantiateResultFor, Sandbox, DEFAULT_GAS_LIMIT,
};

pub mod mock;
Expand All @@ -33,12 +35,8 @@ mod record;
mod transcoding;

pub use bundle::ContractBundle;
use error::SessionError;

use self::mocking_api::MockingApi;
use crate::{
errors::MessageResult, runtime::MinimalRuntime, session::transcoding::TranscoderRegistry,
};
use crate::{errors::MessageResult, session::transcoding::TranscoderRegistry};

type BalanceOf<R> =
<<R as pallet_contracts::Config>::Currency as Inspect<AccountIdFor<R>>>::Balance;
Expand Down Expand Up @@ -272,6 +270,7 @@ where
)
.map(|_| self)
}

fn record_events<T>(&mut self, recording: impl FnOnce(&mut Self) -> T) -> T {
let start = self.sandbox.events().len();
let result = recording(self);
Expand Down Expand Up @@ -346,6 +345,33 @@ where
)
}

/// Performs a dry run of the deployment of a contract.
pub fn dry_run_deployment<S: AsRef<str> + Debug>(
&mut self,
contract_file: ContractBundle,
constructor: &str,
args: &[S],
salt: Vec<u8>,
endowment: Option<BalanceOf<Config::Runtime>>,
) -> Result<ContractInstantiateResultFor<Config::Runtime>, SessionError> {
let data = contract_file
.transcoder
.encode(constructor, args)
.map_err(|err| SessionError::Encoding(err.to_string()))?;

Ok(self.sandbox.dry_run(|sandbox| {
sandbox.deploy_contract(
contract_file.wasm,
endowment.unwrap_or_default(),
data,
salt,
self.actor.clone(),
self.gas_limit,
None,
)
}))
}

/// Similar to `deploy_and` but takes the parsed contract file (`ContractBundle`) as a first argument.
///
/// You can get it with `ContractBundle::load("some/path/your.contract")` or `local_contract_file!()`
Expand Down Expand Up @@ -449,6 +475,35 @@ where
self.call_internal(Some(address), message, args, endowment)
}

/// Performs a dry run of a contract call.
pub fn dry_run_call<S: AsRef<str> + Debug>(
&mut self,
address: AccountIdFor<Config::Runtime>,
message: &str,
args: &[S],
endowment: Option<BalanceOf<Config::Runtime>>,
) -> Result<ContractExecResultFor<Config::Runtime>, SessionError> {
let data = self
.transcoders
.get(&address)
.as_ref()
.ok_or(SessionError::NoTranscoder)?
.encode(message, args)
.map_err(|err| SessionError::Encoding(err.to_string()))?;

Ok(self.sandbox.dry_run(|sandbox| {
sandbox.call_contract(
address,
endowment.unwrap_or_default(),
data,
self.actor.clone(),
self.gas_limit,
None,
self.determinism,
)
}))
}

fn call_internal<S: AsRef<str> + Debug, T: Decode>(
&mut self,
address: Option<AccountIdFor<Config::Runtime>>,
Expand Down
4 changes: 2 additions & 2 deletions examples/chain-extension/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading