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

Be generic over account and block number #47

Merged
merged 8 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
21 changes: 11 additions & 10 deletions Cargo.lock

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

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ 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" }
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" }
Expand All @@ -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" }
12 changes: 8 additions & 4 deletions drink-cli/src/app_state/mod.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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,
}
}
Expand All @@ -49,8 +53,8 @@ pub struct UiState {

impl UiState {
pub fn new(pwd_override: Option<PathBuf>) -> Self {
let pwd = pwd_override.unwrap_or_else(
|| env::current_dir().expect("Failed to get current directory"));
let pwd = pwd_override
kostekIV marked this conversation as resolved.
Show resolved Hide resolved
.unwrap_or_else(|| env::current_dir().expect("Failed to get current directory"));

UiState {
pwd,
Expand Down
6 changes: 4 additions & 2 deletions drink-cli/src/executor/error.rs
Original file line number Diff line number Diff line change
@@ -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")]
Expand Down
5 changes: 3 additions & 2 deletions drink-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::path::PathBuf;

use anyhow::Result;
use clap::Parser;
use std::path::PathBuf;

use crate::ui::run_ui;

Expand All @@ -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<PathBuf>,
}

Expand Down
3 changes: 1 addition & 2 deletions drink-cli/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down
1 change: 1 addition & 0 deletions drink/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down
62 changes: 35 additions & 27 deletions drink/src/chain_api.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
//! Basic chain API.

use std::ops::Add;

use frame_support::{
dispatch::Dispatchable,
sp_runtime::{AccountId32, DispatchResultWithInfo},
traits::tokens::currency::Currency,
dispatch::Dispatchable, sp_runtime::DispatchResultWithInfo, traits::tokens::currency::Currency,
};
use frame_system::pallet_prelude::BlockNumberFor;

use crate::{DrinkResult, Error, EventRecordOf, Runtime, Sandbox};
use crate::{runtime::AccountId, DrinkResult, Error, EventRecordOf, Runtime, Sandbox};

/// The runtime call type for a particular runtime.
pub type RuntimeCall<R> = <R as frame_system::Config>::RuntimeCall;

/// Interface for basic chain operations.
pub trait ChainApi<R: Runtime> {
/// Return the current height of the chain.
fn current_height(&mut self) -> u64;
fn current_height(&mut self) -> BlockNumberFor<R>;

/// Build a new empty block and return the new height.
fn build_block(&mut self) -> DrinkResult<u64>;
fn build_block(&mut self) -> DrinkResult<BlockNumberFor<R>>;

/// 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<u64> {
fn build_blocks(&mut self, n: BlockNumberFor<R>) -> DrinkResult<BlockNumberFor<R>> {
kostekIV marked this conversation as resolved.
Show resolved Hide resolved
let mut last_block = None;
for _ in 0..n {

let mut iter = BlockNumberFor::<R>::from(0u32);
while iter < n {
kostekIV marked this conversation as resolved.
Show resolved Hide resolved
last_block = Some(self.build_block()?);
iter = iter.add(BlockNumberFor::<R>::from(1u32));
}
Ok(last_block.unwrap_or_else(|| self.current_height()))
}
Expand All @@ -38,14 +42,14 @@ pub trait ChainApi<R: Runtime> {
///
/// * `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: AccountId<R>, 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: &AccountId<R>) -> u128;

/// Run an action without modifying the storage.
///
Expand Down Expand Up @@ -74,27 +78,28 @@ pub trait ChainApi<R: Runtime> {
}

impl<R: Runtime> ChainApi<R> for Sandbox<R> {
fn current_height(&mut self) -> u64 {
fn current_height(&mut self) -> BlockNumberFor<R> {
self.externalities
.execute_with(|| frame_system::Pallet::<R>::block_number())
}

fn build_block(&mut self) -> DrinkResult<u64> {
fn build_block(&mut self) -> DrinkResult<BlockNumberFor<R>> {
let 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)
let new_number = current_block + BlockNumberFor::<R>::from(1u32);
kostekIV marked this conversation as resolved.
Show resolved Hide resolved
R::initialize_block(new_number, block_hash).map_err(Error::BlockInitialize)?;
Ok(new_number)
})
}

fn add_tokens(&mut self, address: AccountId32, amount: u128) {
fn add_tokens(&mut self, address: AccountId<R>, amount: u128) {
self.externalities.execute_with(|| {
let _ = pallet_balances::Pallet::<R>::deposit_creating(&address, amount);
});
}

fn balance(&mut self, address: &AccountId32) -> u128 {
fn balance(&mut self, address: &AccountId<R>) -> u128 {
self.externalities
.execute_with(|| pallet_balances::Pallet::<R>::free_balance(address))
}
Expand Down Expand Up @@ -141,8 +146,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(
Expand All @@ -153,28 +158,29 @@ mod tests {
let call = RuntimeCall::<MinimalRuntime>::Balances(
pallet_balances::Call::<MinimalRuntime>::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::<MinimalRuntime>::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]
fn runtime_call_works() {
let mut sandbox = Sandbox::<MinimalRuntime>::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);
Expand All @@ -191,7 +197,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);
Expand All @@ -201,14 +208,15 @@ mod tests {
#[test]
fn resetting_events() {
let mut sandbox = Sandbox::<MinimalRuntime>::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());
}
}
Loading
Loading