Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed
- Fix decoding of `HostFn::minimum_balance` return value - [#2656](https://github.com/use-ink/ink/pull/2656)
- Fix handling of `HostFn::code_hash` and `HostFn::weight_to_fee` - [#2672](https://github.com/use-ink/ink/pull/2672)

### Fixed
- `name` override fixes for message id computation and trait definitions - [#2649](https://github.com/use-ink/ink/pull/2649)
Expand Down
1 change: 1 addition & 0 deletions crates/e2e/src/contract_results.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ where
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.debug_struct("CallDryRunResult")
.field("exec_result", &self.exec_result)
.field("trace", &self.trace)
.finish()
}
}
Expand Down
12 changes: 12 additions & 0 deletions crates/e2e/src/subxt_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,10 @@ where
let dispatch_error =
DispatchError::decode_from(evt.field_bytes(), metadata)
.map_err(|e| Error::Decoding(e.to_string()))?;
log_error(&format!(
"Attempt to stringify returned data: {:?}",
String::from_utf8_lossy(&trace.clone().unwrap().output[..])
));
log_error(&format!(
"extrinsic for `raw_call` failed: {dispatch_error} {trace:?}"
));
Expand Down Expand Up @@ -841,6 +845,14 @@ where
.await;
log_info(&format!("call dry run result: {:?}", &exec_result.result));

if exec_result.result.is_ok() && exec_result.clone().result.unwrap().did_revert()
{
log_error(&format!(
"Attempt to stringify returned data: {:?}",
String::from_utf8_lossy(&exec_result.clone().result.unwrap().data[..])
));
}

let exec_result = self
.contract_result_to_result(exec_result)
.map_err(Error::CallDryRun)?;
Expand Down
26 changes: 9 additions & 17 deletions crates/env/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

use ink_primitives::{
Address,
CodeHashErr,
H256,
U256,
abi::{
Expand Down Expand Up @@ -86,12 +87,9 @@ pub fn transferred_value() -> U256 {
/// # Errors
///
/// If the returned value cannot be properly decoded.
pub fn weight_to_fee<E>(gas: Gas) -> E::Balance
where
E: Environment,
{
pub fn weight_to_fee(gas: Gas) -> U256 {
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnvBackend::weight_to_fee::<E>(instance, gas)
TypedEnvBackend::weight_to_fee(instance, gas)
})
}

Expand Down Expand Up @@ -705,7 +703,7 @@ pub fn is_contract(account: &Address) -> bool {
///
/// - If no code hash was found for the specified account id.
/// - If the returned value cannot be properly decoded.
pub fn code_hash(addr: &Address) -> Result<H256> {
pub fn code_hash(addr: &Address) -> core::result::Result<H256, CodeHashErr> {
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnvBackend::code_hash(instance, addr)
})
Expand All @@ -716,7 +714,7 @@ pub fn code_hash(addr: &Address) -> Result<H256> {
/// # Errors
///
/// If the returned value cannot be properly decoded.
pub fn own_code_hash() -> Result<H256> {
pub fn own_code_hash() -> H256 {
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnvBackend::own_code_hash(instance)
})
Expand All @@ -735,12 +733,9 @@ pub fn own_code_hash() -> Result<H256> {
/// # Errors
///
/// If the returned value cannot be properly decoded.
pub fn caller_is_origin<E>() -> bool
where
E: Environment,
{
pub fn caller_is_origin() -> bool {
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnvBackend::caller_is_origin::<E>(instance)
TypedEnvBackend::caller_is_origin(instance)
})
}

Expand All @@ -755,12 +750,9 @@ where
/// # Errors
///
/// If the returned value cannot be properly decoded.
pub fn caller_is_root<E>() -> bool
where
E: Environment,
{
pub fn caller_is_root() -> bool {
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnvBackend::caller_is_root::<E>(instance)
TypedEnvBackend::caller_is_root(instance)
})
}

Expand Down
16 changes: 7 additions & 9 deletions crates/env/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use ink_primitives::{
Address,
CodeHashErr,
H256,
U256,
abi::AbiEncodeWith,
Expand Down Expand Up @@ -237,7 +238,7 @@ pub trait TypedEnvBackend: EnvBackend {
/// # Note
///
/// For more details visit: [`weight_to_fee`][`crate::weight_to_fee`]
fn weight_to_fee<E: Environment>(&mut self, gas: u64) -> E::Balance;
fn weight_to_fee(&mut self, gas: u64) -> U256;

/// Returns the timestamp of the current block.
///
Expand Down Expand Up @@ -381,32 +382,29 @@ pub trait TypedEnvBackend: EnvBackend {
/// # Note
///
/// For more details visit: [`caller_is_origin`][`crate::caller_is_origin`]
fn caller_is_origin<E>(&mut self) -> bool
where
E: Environment;
fn caller_is_origin(&mut self) -> bool;

/// Checks whether the caller of the current contract is root.
///
/// # Note
///
/// For more details visit: [`caller_is_root`][`crate::caller_is_root`]
fn caller_is_root<E>(&mut self) -> bool
where
E: Environment;
fn caller_is_root(&mut self) -> bool;

/// Retrieves the code hash of the contract at the given `account` id.
///
/// # Note
///
/// For more details visit: [`code_hash`][`crate::code_hash`]
fn code_hash(&mut self, account: &Address) -> Result<H256>;
fn code_hash(&mut self, account: &Address)
-> core::result::Result<H256, CodeHashErr>;

/// Retrieves the code hash of the currently executing contract.
///
/// # Note
///
/// For more details visit: [`own_code_hash`][`crate::own_code_hash`]
fn own_code_hash(&mut self) -> Result<H256>;
fn own_code_hash(&mut self) -> H256;

/// Execute an XCM message locally, using the contract's address as the origin.
///
Expand Down
29 changes: 11 additions & 18 deletions crates/env/src/engine/off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use ink_engine::ext::Engine;
use ink_primitives::{
Address,
CodeHashErr,
H256,
U256,
abi::{
Expand Down Expand Up @@ -752,7 +753,7 @@ impl TypedEnvBackend for EnvInstance {
.map_err(Into::into)
}

fn weight_to_fee<E: Environment>(&mut self, gas: u64) -> E::Balance {
fn weight_to_fee(&mut self, gas: u64) -> U256 {
let mut output: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
self.engine.weight_to_fee(gas, &mut &mut output[..]);
scale::Decode::decode(&mut &output[..]).unwrap_or_else(|error| {
Expand All @@ -764,39 +765,31 @@ impl TypedEnvBackend for EnvInstance {
self.engine.is_contract(account)
}

fn caller_is_origin<E>(&mut self) -> bool
where
E: Environment,
{
fn caller_is_origin(&mut self) -> bool {
unimplemented!("off-chain environment does not support cross-contract calls")
}

fn caller_is_root<E>(&mut self) -> bool
where
E: Environment,
{
fn caller_is_root(&mut self) -> bool {
unimplemented!("off-chain environment does not support `caller_is_root`")
}

fn code_hash(&mut self, addr: &Address) -> Result<H256> {
fn code_hash(&mut self, addr: &Address) -> core::result::Result<H256, CodeHashErr> {
let code_hash = self.engine.database.get_code_hash(addr);
if let Some(code_hash) = code_hash {
// todo
let code_hash = H256::decode(&mut &code_hash[..]).unwrap();
Ok(code_hash)
} else {
Err(ReturnErrorCode::KeyNotFound.into())
Err(CodeHashErr::AddressNotFound)
}
}

fn own_code_hash(&mut self) -> Result<H256> {
fn own_code_hash(&mut self) -> H256 {
let callee = &self.engine.get_callee();
let code_hash = self.engine.database.get_code_hash(callee);
if let Some(code_hash) = code_hash {
Ok(code_hash)
} else {
Err(ReturnErrorCode::KeyNotFound.into())
}
self.engine
.database
.get_code_hash(callee)
.expect("own code hash not found")
}

#[cfg(all(feature = "xcm", feature = "unstable-hostfn"))]
Expand Down
61 changes: 33 additions & 28 deletions crates/env/src/engine/on_chain/pallet_revive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use ink_primitives::{
Address,
CodeHashErr,
H256,
U256,
abi::{
Expand Down Expand Up @@ -76,6 +77,19 @@ use crate::{
types::FromLittleEndian,
};

/// The code hash of an existing account without code.
/// This is the `keccak256` hash of empty data.
/// ```no_compile
/// const EMPTY_CODE_HASH: H256 =
/// H256(sp_core::hex2array!("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
/// ````
const EMPTY_CODE_HASH: H256 = H256([
197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182,
83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112,
]);

const H256_ZERO: H256 = H256::zero();

impl CryptoHash for Blake2x128 {
fn hash(input: &[u8], output: &mut <Self as HashOutput>::Type) {
type OutputType = [u8; 16];
Expand Down Expand Up @@ -927,12 +941,9 @@ impl TypedEnvBackend for EnvInstance {

fn address(&mut self) -> Address {
let mut scope = self.scoped_buffer();

let h160: &mut [u8; 20] = scope.take(20).try_into().unwrap();
ext::address(h160);

scale::Decode::decode(&mut &h160[..])
.expect("A contract being executed must have a valid address.")
Address::from_slice(h160)
}

fn balance(&mut self) -> U256 {
Expand Down Expand Up @@ -1193,54 +1204,49 @@ impl TypedEnvBackend for EnvInstance {
}
}

fn weight_to_fee<E: Environment>(&mut self, gas: u64) -> E::Balance {
fn weight_to_fee(&mut self, gas: u64) -> U256 {
let mut scope = self.scoped_buffer();
let u256: &mut [u8; 32] = scope.take(32).try_into().unwrap();
// TODO: needs ref and proof
ext::weight_to_fee(gas, gas, u256);
let mut result = <E::Balance as FromLittleEndian>::Bytes::default();
let len = result.as_ref().len();
result.as_mut().copy_from_slice(&u256[..len]);
<E::Balance as FromLittleEndian>::from_le_bytes(result)
U256::from_le_bytes(*u256)
}

fn is_contract(&mut self, addr: &Address) -> bool {
ext::code_size(&addr.0) > 0
}

fn caller_is_origin<E>(&mut self) -> bool
where
E: Environment,
{
fn caller_is_origin(&mut self) -> bool {
let sel = const { solidity_selector("callerIsOrigin()") };
let output: &mut [u8; 32] =
&mut self.scoped_buffer().take(32).try_into().unwrap();
call_bool_precompile(sel, output)
}

fn caller_is_root<E>(&mut self) -> bool
where
E: Environment,
{
fn caller_is_root(&mut self) -> bool {
let sel = const { solidity_selector("callerIsRoot()") };
let output: &mut [u8; 32] =
&mut self.scoped_buffer().take(32).try_into().unwrap();
call_bool_precompile(sel, output)
}

fn code_hash(&mut self, addr: &Address) -> Result<H256> {
fn code_hash(&mut self, addr: &Address) -> core::result::Result<H256, CodeHashErr> {
let mut scope = self.scoped_buffer();
// todo can be simplified
let enc_addr: &mut [u8; 20] =
scope.take_encoded(addr)[..20].as_mut().try_into().unwrap();
let output: &mut [u8; 32] =
scope.take_max_encoded_len::<H256>().try_into().unwrap();
ext::code_hash(enc_addr, output);
let hash = scale::Decode::decode(&mut &output[..])?;
Ok(hash)
ext::code_hash(&addr.0, output);
let hash = H256::from_slice(output);
// If not a contract, but account exists, then `keccak_256([])` is returned.
// Otherwise `zero`.
if hash == H256_ZERO {
Err(CodeHashErr::AddressNotFound)
} else if hash == EMPTY_CODE_HASH {
Err(CodeHashErr::NotContractButAccount)
} else {
Ok(hash)
}
}

fn own_code_hash(&mut self) -> Result<H256> {
fn own_code_hash(&mut self) -> H256 {
let sel = const { solidity_selector("ownCodeHash()") };
let output: &mut [u8; 32] = &mut self
.scoped_buffer()
Expand All @@ -1260,8 +1266,7 @@ impl TypedEnvBackend for EnvInstance {
Some(&mut &mut output[..]),
);
call_result.expect("call host function failed");
let hash = scale::Decode::decode(&mut &output[..])?;
Ok(hash)
H256::from_slice(output)
}

#[cfg(all(feature = "xcm", feature = "unstable-hostfn"))]
Expand Down
Loading
Loading