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

Implemented contract instantiation and invocation for integration tests #1988

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e7f1b8f
Implementing stuff needed for instantiate_contract().
Helios-vmg Oct 27, 2023
506e95d
Implemented return_value() on integration tests.
Helios-vmg Oct 27, 2023
bc8688b
A couple fixes for E2E environment.
Helios-vmg Oct 27, 2023
6ccd54b
Forgot to delete some fluff.
Helios-vmg Oct 27, 2023
34854c5
Fixed dead code warnings.
Helios-vmg Oct 27, 2023
c75ed7d
Added tests.
Helios-vmg Oct 27, 2023
3ccb01f
Fixed-up tomls.
Helios-vmg Oct 27, 2023
2d1950a
Updated stderr test files.
Helios-vmg Oct 27, 2023
2d13b21
Updated CHANGELOG.
Helios-vmg Oct 27, 2023
817f3cc
Passed through rustfmt.
Helios-vmg Oct 27, 2023
6c4efc6
Passed through clippy.
Helios-vmg Oct 27, 2023
25e1810
Passed through rustfmt again.
Helios-vmg Oct 30, 2023
3042f4d
Fixed failing contract builds.
Helios-vmg Oct 31, 2023
8f78fdd
Revert "Updated stderr test files."
Helios-vmg Oct 31, 2023
b350252
Fixed format errors.
Helios-vmg Oct 31, 2023
2dfb9ed
Fixed failing test.
Helios-vmg Oct 31, 2023
a715026
Updated stderr test values.
Helios-vmg Oct 31, 2023
9c74b08
Fixed some dependencies for doc tests.
Helios-vmg Oct 31, 2023
ea15b62
Fixed rustfmt issues.
Helios-vmg Oct 31, 2023
4e8fdc9
Implemented code_hash() and set_code_hash().
Helios-vmg Nov 7, 2023
9981c7f
Minor behavior correction for instantiate_contract().
Helios-vmg Nov 7, 2023
12297f8
Merge branch 'code_hash-implementation' into invoke_contract-implemen…
Helios-vmg Nov 7, 2023
b6478d9
Tentative invoke_contract() implementation.
Helios-vmg Nov 7, 2023
4c04eba
Added invoke_contract_delegate() skeleton.
Helios-vmg Nov 7, 2023
7d4f265
Obviated unsafe block.
Helios-vmg Nov 7, 2023
94f3484
own_code_hash implementation
ramirez7358 Nov 8, 2023
4de3aa0
Add own-code-hash integration test
ramirez7358 Nov 8, 2023
439e90c
Remove unused use.
Helios-vmg Nov 8, 2023
1c33d83
Merge branch 'code_hash-implementation' into invoke_contract-implemen…
Helios-vmg Nov 8, 2023
057e98c
Added some missing semantics.
Helios-vmg Nov 8, 2023
b684b74
Passed through rustfmt.
Helios-vmg Nov 9, 2023
cd6e687
Passed through clippy.
Helios-vmg Nov 9, 2023
c9c7d85
Fixed own_code_hash test.
Helios-vmg Nov 9, 2023
7a8f98d
Tightening up code.
Helios-vmg Nov 9, 2023
37a00d9
Improved contract invokation tests. Fixed some things.
Helios-vmg Nov 9, 2023
3c1d66f
Added tests.
Helios-vmg Nov 10, 2023
6cc180c
Removed unused type parameter.
Helios-vmg Nov 10, 2023
4e87e30
Updated changelog.
Helios-vmg Nov 13, 2023
3e32419
Fixed clippy errors.
Helios-vmg Nov 15, 2023
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [E2E] Call builders and extra gas margin option - [#1917](https://github.com/paritytech/ink/pull/1917)
- Make `set_code_hash` generic - [#1906](https://github.com/paritytech/ink/pull/1906)
- Clean E2E configuration parsing - [#1922](https://github.com/paritytech/ink/pull/1922)
- Implement contract invokation in off-chain environment engine - [#1957](https://github.com/paritytech/ink/pull/1988)

### Changed
- Fail when decoding from storage and not all bytes consumed - [#1897](https://github.com/paritytech/ink/pull/1897)
Expand Down
58 changes: 58 additions & 0 deletions crates/engine/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ use std::collections::HashMap;

const BALANCE_OF: &[u8] = b"balance:";
const STORAGE_OF: &[u8] = b"contract-storage:";
const CONTRACT_PREFIX: &[u8] = b"contract:";
const MSG_HANDLER_OF: &[u8] = b"message-handler:";
const CODE_HASH_OF: &[u8] = b"code-hash:";

/// Returns the database key under which to find the balance for account `who`.
pub fn balance_of_key(who: &[u8]) -> [u8; 32] {
Expand All @@ -35,20 +38,47 @@ pub fn storage_of_contract_key(who: &[u8], key: &[u8]) -> [u8; 32] {
hashed_key
}

pub type MessageHandler = fn(Vec<u8>) -> Vec<u8>;

pub fn contract_key(f: MessageHandler) -> [u8; 32] {
let f = f as usize;
let f = f.to_le_bytes();
let keyed = f.to_vec().to_keyed_vec(CONTRACT_PREFIX);
let mut ret: [u8; 32] = [0; 32];
super::hashing::blake2b_256(&keyed[..], &mut ret);
ret
}

pub fn message_handler_of_contract_key(key: &[u8]) -> [u8; 32] {
let keyed = key.to_vec().to_keyed_vec(MSG_HANDLER_OF);
let mut hashed_key: [u8; 32] = [0; 32];
super::hashing::blake2b_256(&keyed[..], &mut hashed_key);
hashed_key
}

pub fn code_hash_of_key(key: &Vec<u8>) -> [u8; 32] {
let keyed = key.to_keyed_vec(CODE_HASH_OF);
let mut hashed_key: [u8; 32] = [0; 32];
super::hashing::blake2b_256(&keyed[..], &mut hashed_key);
hashed_key
}

/// The chain database.
///
/// Everything is stored in here: accounts, balances, contract storage, etc..
/// Just like in Substrate a prefix hash is computed for every contract.
#[derive(Default)]
pub struct Database {
hmap: HashMap<Vec<u8>, Vec<u8>>,
fmap: HashMap<Vec<u8>, MessageHandler>,
}

impl Database {
/// Creates a new database instance.
pub fn new() -> Self {
Database {
hmap: HashMap::new(),
fmap: HashMap::new(),
}
}

Expand Down Expand Up @@ -128,6 +158,34 @@ impl Database {
.and_modify(|v| *v = encoded_balance.clone())
.or_insert(encoded_balance);
}

pub fn set_contract_message_handler(&mut self, handler: MessageHandler) -> [u8; 32] {
let key = contract_key(handler);
let hashed_key = message_handler_of_contract_key(&key);
self.fmap
.entry(hashed_key.to_vec())
.and_modify(|x| *x = handler)
.or_insert(handler);
key
}

pub fn get_contract_message_handler(&mut self, key: &[u8]) -> MessageHandler {
let hashed_key = message_handler_of_contract_key(key);
*self.fmap.get(&hashed_key.to_vec()).unwrap()
}

pub fn set_code_hash(&mut self, account: &Vec<u8>, code_hash: &[u8]) {
let hashed_key = code_hash_of_key(account);
self.hmap
.entry(hashed_key.to_vec())
.and_modify(|x| *x = code_hash.to_vec())
.or_insert(code_hash.to_vec());
}

pub fn get_code_hash(&self, account: &Vec<u8>) -> Option<Vec<u8>> {
let hashed_key = code_hash_of_key(account);
self.get(&hashed_key).cloned()
}
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion crates/engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub mod test_api;
mod chain_extension;
mod database;
mod exec_context;
mod hashing;
pub mod hashing;
mod types;

#[cfg(test)]
Expand Down
2 changes: 2 additions & 0 deletions crates/env/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ ink = { path = "../ink" }
[features]
default = ["std"]
std = [
"ink/std",
"ink_allocator/std",
"ink_prelude/std",
"ink_primitives/std",
Expand All @@ -77,6 +78,7 @@ std = [
"sha3",
"blake2",
]
test_instantiate = []

# Enable contract debug messages via `debug_print!` and `debug_println!`.
ink-debug = []
Expand Down
27 changes: 24 additions & 3 deletions crates/env/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ use crate::{
CryptoHash,
HashOutput,
},
types::Gas,
Environment,
types::{
Environment,
Gas,
},
Result,
};
use ink_storage_traits::Storable;
Expand Down Expand Up @@ -336,7 +338,9 @@ pub fn instantiate_contract<E, ContractRef, Args, Salt, R>(
>
where
E: Environment,
ContractRef: FromAccountId<E>,
ContractRef: FromAccountId<E> + crate::ContractReverseReference,
<ContractRef as crate::ContractReverseReference>::Type:
crate::reflect::ContractConstructorDecoder,
Args: scale::Encode,
Salt: AsRef<[u8]>,
R: ConstructorReturnType<ContractRef>,
Expand Down Expand Up @@ -426,6 +430,7 @@ where
/// # Note
///
/// This function stops the execution of the contract immediately.
#[cfg(not(feature = "test_instantiate"))]
pub fn return_value<R>(return_flags: ReturnFlags, return_value: &R) -> !
where
R: scale::Encode,
Expand All @@ -435,6 +440,22 @@ where
})
}

/// Returns the value back to the caller of the executed contract.
///
/// # Note
///
/// When the test_instantiate feature is used, the contract is allowed to
/// return normally. This feature should only be used for integration tests.
#[cfg(feature = "test_instantiate")]
pub fn return_value<R>(return_flags: ReturnFlags, return_value: &R)
where
R: scale::Encode,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
EnvBackend::return_value::<R>(instance, return_flags, return_value)
})
}

/// Appends the given message to the debug message buffer.
pub fn debug_message(message: &str) {
<EnvInstance as OnInstance>::on_instance(|instance| {
Expand Down
21 changes: 19 additions & 2 deletions crates/env/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{
CryptoHash,
HashOutput,
},
Environment,
types::Environment,
Result,
};
use ink_storage_traits::Storable;
Expand Down Expand Up @@ -247,10 +247,25 @@ pub trait EnvBackend {
///
/// The `flags` parameter can be used to revert the state changes of the
/// entire execution if necessary.
#[cfg(not(feature = "test_instantiate"))]
fn return_value<R>(&mut self, flags: ReturnFlags, return_value: &R) -> !
where
R: scale::Encode;

/// Returns the value back to the caller of the executed contract.
///
/// # Note
///
/// When the test_instantiate feature is used, the contract is allowed to
/// return normally. This feature should only be used for integration tests.
///
/// The `flags` parameter can be used to revert the state changes of the
/// entire execution if necessary.
#[cfg(feature = "test_instantiate")]
fn return_value<R>(&mut self, flags: ReturnFlags, return_value: &R)
where
R: scale::Encode;

/// Emit a custom debug message.
///
/// The message is appended to the debug buffer which is then supplied to the calling
Expand Down Expand Up @@ -469,7 +484,9 @@ pub trait TypedEnvBackend: EnvBackend {
>
where
E: Environment,
ContractRef: FromAccountId<E>,
ContractRef: FromAccountId<E> + crate::ContractReverseReference,
<ContractRef as crate::ContractReverseReference>::Type:
crate::reflect::ContractConstructorDecoder,
Args: scale::Encode,
Salt: AsRef<[u8]>,
R: ConstructorReturnType<ContractRef>;
Expand Down
6 changes: 4 additions & 2 deletions crates/env/src/call/call_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ use crate::{
},
ExecutionInput,
},
types::Gas,
Environment,
types::{
Environment,
Gas,
},
Error,
};
use core::marker::PhantomData;
Expand Down
14 changes: 11 additions & 3 deletions crates/env/src/call/create_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use crate::{
ExecutionInput,
Selector,
},
types::Environment,
ContractEnv,
Environment,
Error,
};
use core::marker::PhantomData;
Expand Down Expand Up @@ -240,7 +240,11 @@ where
impl<E, ContractRef, Args, Salt, R> CreateParams<E, ContractRef, Args, Salt, R>
where
E: Environment,
ContractRef: FromAccountId<E>,
ContractRef: FromAccountId<E> + crate::ContractReverseReference,
<ContractRef as crate::ContractReverseReference>::Type:
crate::reflect::ContractConstructorDecoder,
<ContractRef as crate::ContractReverseReference>::Type:
crate::reflect::ContractMessageDecoder,
Args: scale::Encode,
Salt: AsRef<[u8]>,
R: ConstructorReturnType<ContractRef>,
Expand Down Expand Up @@ -721,7 +725,11 @@ impl<E, ContractRef, GasLimit, Args, Salt, RetType>
>
where
E: Environment,
ContractRef: FromAccountId<E>,
ContractRef: FromAccountId<E> + crate::ContractReverseReference,
<ContractRef as crate::ContractReverseReference>::Type:
crate::reflect::ContractConstructorDecoder,
<ContractRef as crate::ContractReverseReference>::Type:
crate::reflect::ContractMessageDecoder,
GasLimit: Unwrap<Output = u64>,
Args: scale::Encode,
Salt: AsRef<[u8]>,
Expand Down
4 changes: 2 additions & 2 deletions crates/env/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub(crate) fn decode_instantiate_result<I, E, ContractRef, R>(
) -> EnvResult<ConstructorResult<<R as ConstructorReturnType<ContractRef>>::Output>>
where
I: scale::Input,
E: crate::Environment,
E: crate::types::Environment,
ContractRef: FromAccountId<E>,
R: ConstructorReturnType<ContractRef>,
{
Expand All @@ -102,7 +102,7 @@ fn decode_instantiate_err<I, E, ContractRef, R>(
) -> EnvResult<ConstructorResult<<R as ConstructorReturnType<ContractRef>>::Output>>
where
I: scale::Input,
E: crate::Environment,
E: crate::types::Environment,
ContractRef: FromAccountId<E>,
R: ConstructorReturnType<ContractRef>,
{
Expand Down
Loading