contracts: Add RPC that allows instantiating of a contract (#8451)

* contracts: Add RPC that allows instantiating of a contract

* Encode `debug_message` as bytes because usage of `String` is forbidden

* Remove erroneous derive attribute

* Fix rpc tests for new `debug_message` encoding

* Fix typo

Co-authored-by: Andrew Jones <ascjones@gmail.com>

Co-authored-by: Andrew Jones <ascjones@gmail.com>
This commit is contained in:
Alexander Theißen
2021-04-13 13:26:52 +02:00
committed by GitHub
parent 24311eee3e
commit f854194139
16 changed files with 471 additions and 191 deletions
+47 -11
View File
@@ -32,17 +32,52 @@ use frame_support::{
weights::Weight,
ensure,
};
use pallet_contracts_primitives::{ErrorOrigin, ExecError, ExecReturnValue, ExecResult, ReturnFlags};
use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags};
pub type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
pub type MomentOf<T> = <<T as Config>::Time as Time>::Moment;
pub type SeedOf<T> = <T as frame_system::Config>::Hash;
pub type BlockNumberOf<T> = <T as frame_system::Config>::BlockNumber;
pub type StorageKey = [u8; 32];
pub type ExecResult = Result<ExecReturnValue, ExecError>;
/// A type that represents a topic of an event. At the moment a hash is used.
pub type TopicOf<T> = <T as frame_system::Config>::Hash;
/// Origin of the error.
///
/// Call or instantiate both called into other contracts and pass through errors happening
/// in those to the caller. This enum is for the caller to distinguish whether the error
/// happened during the execution of the callee or in the current execution context.
#[cfg_attr(test, derive(Debug, PartialEq))]
pub enum ErrorOrigin {
/// Caller error origin.
///
/// The error happened in the current exeuction context rather than in the one
/// of the contract that is called into.
Caller,
/// The error happened during execution of the called contract.
Callee,
}
/// Error returned by contract exection.
#[cfg_attr(test, derive(Debug, PartialEq))]
pub struct ExecError {
/// The reason why the execution failed.
pub error: DispatchError,
/// Origin of the error.
pub origin: ErrorOrigin,
}
impl<T: Into<DispatchError>> From<T> for ExecError {
fn from(error: T) -> Self {
Self {
error: error.into(),
origin: ErrorOrigin::Caller,
}
}
}
/// Information needed for rent calculations that can be requested by a contract.
#[derive(codec::Encode)]
#[cfg_attr(test, derive(Debug, PartialEq))]
@@ -945,6 +980,7 @@ mod tests {
exec::ExportedFunction::*,
Error, Weight, CurrentSchedule,
};
use sp_core::Bytes;
use frame_support::assert_noop;
use sp_runtime::DispatchError;
use assert_matches::assert_matches;
@@ -1123,7 +1159,7 @@ mod tests {
}
fn exec_success() -> ExecResult {
Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() })
Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Bytes(Vec::new()) })
}
#[test]
@@ -1186,7 +1222,7 @@ mod tests {
let return_ch = MockLoader::insert(
Call,
|_, _| Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: Vec::new() })
|_, _| Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: Bytes(Vec::new()) })
);
ExtBuilder::default().build().execute_with(|| {
@@ -1246,7 +1282,7 @@ mod tests {
let dest = BOB;
let return_ch = MockLoader::insert(
Call,
|_, _| Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: vec![1, 2, 3, 4] })
|_, _| Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Bytes(vec![1, 2, 3, 4]) })
);
ExtBuilder::default().build().execute_with(|| {
@@ -1263,7 +1299,7 @@ mod tests {
let output = result.unwrap();
assert!(output.0.is_success());
assert_eq!(output.0.data, vec![1, 2, 3, 4]);
assert_eq!(output.0.data, Bytes(vec![1, 2, 3, 4]));
});
}
@@ -1275,7 +1311,7 @@ mod tests {
let dest = BOB;
let return_ch = MockLoader::insert(
Call,
|_, _| Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: vec![1, 2, 3, 4] })
|_, _| Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: Bytes(vec![1, 2, 3, 4]) })
);
ExtBuilder::default().build().execute_with(|| {
@@ -1292,7 +1328,7 @@ mod tests {
let output = result.unwrap();
assert!(!output.0.is_success());
assert_eq!(output.0.data, vec![1, 2, 3, 4]);
assert_eq!(output.0.data, Bytes(vec![1, 2, 3, 4]));
});
}
@@ -1512,7 +1548,7 @@ mod tests {
fn instantiation_work_with_success_output() {
let dummy_ch = MockLoader::insert(
Constructor,
|_, _| Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: vec![80, 65, 83, 83] })
|_, _| Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Bytes(vec![80, 65, 83, 83]) })
);
ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
@@ -1532,7 +1568,7 @@ mod tests {
vec![],
&[],
),
Ok((address, ref output)) if output.data == vec![80, 65, 83, 83] => address
Ok((address, ref output)) if output.data == Bytes(vec![80, 65, 83, 83]) => address
);
// Check that the newly created account has the expected code hash and
@@ -1548,7 +1584,7 @@ mod tests {
fn instantiation_fails_with_failing_output() {
let dummy_ch = MockLoader::insert(
Constructor,
|_, _| Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: vec![70, 65, 73, 76] })
|_, _| Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: Bytes(vec![70, 65, 73, 76]) })
);
ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
@@ -1568,7 +1604,7 @@ mod tests {
vec![],
&[],
),
Ok((address, ref output)) if output.data == vec![70, 65, 73, 76] => address
Ok((address, ref output)) if output.data == Bytes(vec![70, 65, 73, 76]) => address
);
// Check that the account has not been created.
+1 -2
View File
@@ -15,7 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::{Config, Error};
use crate::{Config, Error, exec::ExecError};
use sp_std::marker::PhantomData;
use sp_runtime::traits::Zero;
use frame_support::{
@@ -24,7 +24,6 @@ use frame_support::{
},
weights::Weight,
};
use pallet_contracts_primitives::ExecError;
use sp_core::crypto::UncheckedFrom;
#[cfg(test)]
+62 -4
View File
@@ -112,7 +112,7 @@ use crate::{
weights::WeightInfo,
wasm::PrefabWasmModule,
};
use sp_core::crypto::UncheckedFrom;
use sp_core::{Bytes, crypto::UncheckedFrom};
use sp_std::prelude::*;
use sp_runtime::{
traits::{
@@ -127,6 +127,7 @@ use frame_support::{
use frame_system::Pallet as System;
use pallet_contracts_primitives::{
RentProjectionResult, GetStorageResult, ContractAccessError, ContractExecResult,
ContractInstantiateResult, Code, InstantiateReturnValue,
};
type CodeHash<T> = <T as frame_system::Config>::Hash;
@@ -666,8 +667,8 @@ where
{
/// Perform a call to a specified contract.
///
/// This function is similar to `Self::call`, but doesn't perform any address lookups and better
/// suitable for calling directly from Rust.
/// This function is similar to [`Self::call`], but doesn't perform any address lookups
/// and better suitable for calling directly from Rust.
///
/// It returns the execution result and the amount of used weight.
pub fn bare_call(
@@ -683,8 +684,65 @@ where
let result = ctx.call(dest, value, &mut gas_meter, input_data);
let gas_consumed = gas_meter.gas_spent();
ContractExecResult {
exec_result: result.map(|r| r.0).map_err(|r| r.0),
result: result.map(|r| r.0).map_err(|r| r.0.error),
gas_consumed,
debug_message: Bytes(Vec::new()),
}
}
/// Instantiate a new contract.
///
/// This function is similar to [`Self::instantiate`], but doesn't perform any address lookups
/// and better suitable for calling directly from Rust.
///
/// It returns the execution result, account id and the amount of used weight.
///
/// If `compute_projection` is set to `true` the result also contains the rent projection.
/// This is optional because some non trivial and stateful work is performed to compute
/// the projection. See [`Self::rent_projection`].
pub fn bare_instantiate(
origin: T::AccountId,
endowment: BalanceOf<T>,
gas_limit: Weight,
code: Code<CodeHash<T>>,
data: Vec<u8>,
salt: Vec<u8>,
compute_projection: bool,
) -> ContractInstantiateResult<T::AccountId, T::BlockNumber> {
let mut gas_meter = GasMeter::new(gas_limit);
let schedule = <CurrentSchedule<T>>::get();
let mut ctx = ExecutionContext::<T, PrefabWasmModule<T>>::top_level(origin, &schedule);
let executable = match code {
Code::Upload(Bytes(binary)) => PrefabWasmModule::from_code(binary, &schedule),
Code::Existing(hash) => PrefabWasmModule::from_storage(hash, &schedule, &mut gas_meter),
};
let executable = match executable {
Ok(executable) => executable,
Err(error) => return ContractInstantiateResult {
result: Err(error.into()),
gas_consumed: gas_meter.gas_spent(),
debug_message: Bytes(Vec::new()),
}
};
let result = ctx.instantiate(endowment, &mut gas_meter, executable, data, &salt)
.and_then(|(account_id, result)| {
let rent_projection = if compute_projection {
Some(Rent::<T, PrefabWasmModule<T>>::compute_projection(&account_id)
.map_err(|_| <Error<T>>::NewContractNotFunded)?)
} else {
None
};
Ok(InstantiateReturnValue {
result,
account_id,
rent_projection,
})
});
ContractInstantiateResult {
result: result.map_err(|e| e.error),
gas_consumed: gas_meter.gas_spent(),
debug_message: Bytes(Vec::new()),
}
}
+5 -2
View File
@@ -388,7 +388,7 @@ where
None | Some(ContractInfo::Tombstone(_)) => return Err(IsTombstone),
Some(ContractInfo::Alive(contract)) => contract,
};
let module = PrefabWasmModule::from_storage_noinstr(alive_contract_info.code_hash)
let module = <PrefabWasmModule<T>>::from_storage_noinstr(alive_contract_info.code_hash)
.map_err(|_| IsTombstone)?;
let code_size = module.occupied_storage();
let current_block_number = <frame_system::Pallet<T>>::block_number();
@@ -399,8 +399,11 @@ where
&alive_contract_info,
code_size,
);
// We skip the eviction in case one is in order.
// Evictions should only be performed by [`try_eviction`].
let new_contract_info = Self::enact_verdict(
account, alive_contract_info, current_block_number, verdict, Some(module),
account, alive_contract_info, current_block_number, verdict, None,
);
// Check what happened after enaction of the verdict.
+22 -21
View File
@@ -30,6 +30,7 @@ use crate::{
};
use assert_matches::assert_matches;
use codec::Encode;
use sp_core::Bytes;
use sp_runtime::{
traits::{BlakeTwo256, Hash, IdentityLookup, Convert},
testing::{Header, H256},
@@ -1886,7 +1887,7 @@ fn crypto_hashes() {
0,
GAS_LIMIT,
params,
).exec_result.unwrap();
).result.unwrap();
assert!(result.is_success());
let expected = hash_fn(input.as_ref());
assert_eq!(&result.data[..*expected_size], &*expected);
@@ -1921,7 +1922,7 @@ fn transfer_return_code() {
0,
GAS_LIMIT,
vec![],
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::BelowSubsistenceThreshold);
// Contract has enough total balance in order to not go below the subsistence
@@ -1935,7 +1936,7 @@ fn transfer_return_code() {
0,
GAS_LIMIT,
vec![],
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::TransferFailed);
});
}
@@ -1969,7 +1970,7 @@ fn call_return_code() {
0,
GAS_LIMIT,
AsRef::<[u8]>::as_ref(&DJANGO).to_vec(),
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::NotCallable);
assert_ok!(
@@ -1992,7 +1993,7 @@ fn call_return_code() {
0,
GAS_LIMIT,
AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&0u32.to_le_bytes()).cloned().collect(),
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::BelowSubsistenceThreshold);
// Contract has enough total balance in order to not go below the subsistence
@@ -2006,7 +2007,7 @@ fn call_return_code() {
0,
GAS_LIMIT,
AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&0u32.to_le_bytes()).cloned().collect(),
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::TransferFailed);
// Contract has enough balance but callee reverts because "1" is passed.
@@ -2017,7 +2018,7 @@ fn call_return_code() {
0,
GAS_LIMIT,
AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&1u32.to_le_bytes()).cloned().collect(),
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::CalleeReverted);
// Contract has enough balance but callee traps because "2" is passed.
@@ -2027,7 +2028,7 @@ fn call_return_code() {
0,
GAS_LIMIT,
AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&2u32.to_le_bytes()).cloned().collect(),
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::CalleeTrapped);
});
@@ -2074,7 +2075,7 @@ fn instantiate_return_code() {
0,
GAS_LIMIT,
callee_hash.clone(),
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::BelowSubsistenceThreshold);
// Contract has enough total balance in order to not go below the subsistence
@@ -2088,7 +2089,7 @@ fn instantiate_return_code() {
0,
GAS_LIMIT,
callee_hash.clone(),
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::TransferFailed);
// Contract has enough balance but the passed code hash is invalid
@@ -2099,7 +2100,7 @@ fn instantiate_return_code() {
0,
GAS_LIMIT,
vec![0; 33],
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::CodeNotFound);
// Contract has enough balance but callee reverts because "1" is passed.
@@ -2109,7 +2110,7 @@ fn instantiate_return_code() {
0,
GAS_LIMIT,
callee_hash.iter().chain(&1u32.to_le_bytes()).cloned().collect(),
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::CalleeReverted);
// Contract has enough balance but callee traps because "2" is passed.
@@ -2119,7 +2120,7 @@ fn instantiate_return_code() {
0,
GAS_LIMIT,
callee_hash.iter().chain(&2u32.to_le_bytes()).cloned().collect(),
).exec_result.unwrap();
).result.unwrap();
assert_return_code!(result, RuntimeReturnCode::CalleeTrapped);
});
@@ -2209,7 +2210,7 @@ fn chain_extension_works() {
);
let gas_consumed = result.gas_consumed;
assert_eq!(TestExtension::last_seen_buffer(), vec![0, 99]);
assert_eq!(result.exec_result.unwrap().data, vec![0, 99]);
assert_eq!(result.result.unwrap().data, Bytes(vec![0, 99]));
// 1 = treat inputs as integer primitives and store the supplied integers
Contracts::bare_call(
@@ -2218,7 +2219,7 @@ fn chain_extension_works() {
0,
GAS_LIMIT,
vec![1],
).exec_result.unwrap();
).result.unwrap();
// those values passed in the fixture
assert_eq!(TestExtension::last_seen_inputs(), (4, 1, 16, 12));
@@ -2230,7 +2231,7 @@ fn chain_extension_works() {
GAS_LIMIT,
vec![2, 42],
);
assert_ok!(result.exec_result);
assert_ok!(result.result);
assert_eq!(result.gas_consumed, gas_consumed + 42);
// 3 = diverging chain extension call that sets flags to 0x1 and returns a fixed buffer
@@ -2240,9 +2241,9 @@ fn chain_extension_works() {
0,
GAS_LIMIT,
vec![3],
).exec_result.unwrap();
).result.unwrap();
assert_eq!(result.flags, ReturnFlags::REVERT);
assert_eq!(result.data, vec![42, 99]);
assert_eq!(result.data, Bytes(vec![42, 99]));
});
}
@@ -2767,7 +2768,7 @@ fn reinstrument_does_charge() {
GAS_LIMIT,
zero.clone(),
);
assert!(result0.exec_result.unwrap().is_success());
assert!(result0.result.unwrap().is_success());
let result1 = Contracts::bare_call(
ALICE,
@@ -2776,7 +2777,7 @@ fn reinstrument_does_charge() {
GAS_LIMIT,
zero.clone(),
);
assert!(result1.exec_result.unwrap().is_success());
assert!(result1.result.unwrap().is_success());
// They should match because both where called with the same schedule.
assert_eq!(result0.gas_consumed, result1.gas_consumed);
@@ -2794,7 +2795,7 @@ fn reinstrument_does_charge() {
GAS_LIMIT,
zero.clone(),
);
assert!(result2.exec_result.unwrap().is_success());
assert!(result2.result.unwrap().is_success());
assert!(result2.gas_consumed > result1.gas_consumed);
assert_eq!(
result2.gas_consumed,
+36 -16
View File
@@ -27,14 +27,13 @@ mod runtime;
use crate::{
CodeHash, Schedule, Config,
wasm::env_def::FunctionImplProvider,
exec::{Ext, Executable, ExportedFunction},
exec::{Ext, Executable, ExportedFunction, ExecResult},
gas::GasMeter,
};
use sp_std::prelude::*;
use sp_core::crypto::UncheckedFrom;
use codec::{Encode, Decode};
use frame_support::dispatch::DispatchError;
use pallet_contracts_primitives::ExecResult;
pub use self::runtime::{ReturnCode, Runtime, RuntimeToken};
#[cfg(feature = "runtime-benchmarks")]
pub use self::code_cache::reinstrument;
@@ -246,17 +245,20 @@ mod tests {
use super::*;
use crate::{
CodeHash, BalanceOf, Error, Pallet as Contracts,
exec::{Ext, StorageKey, AccountIdOf, Executable, SeedOf, BlockNumberOf, RentParams},
exec::{
Ext, StorageKey, AccountIdOf, Executable, SeedOf, BlockNumberOf,
RentParams, ExecError, ErrorOrigin,
},
gas::GasMeter,
tests::{Test, Call, ALICE, BOB},
};
use std::collections::HashMap;
use sp_core::H256;
use sp_core::{Bytes, H256};
use hex_literal::hex;
use sp_runtime::DispatchError;
use frame_support::{assert_ok, dispatch::DispatchResult, weights::Weight};
use assert_matches::assert_matches;
use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags, ExecError, ErrorOrigin};
use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags};
use pretty_assertions::assert_eq;
const GAS_LIMIT: Weight = 10_000_000_000;
@@ -336,7 +338,7 @@ mod tests {
Contracts::<Test>::contract_address(&ALICE, &code_hash, salt),
ExecReturnValue {
flags: ReturnFlags::empty(),
data: Vec::new(),
data: Bytes(Vec::new()),
},
0,
))
@@ -367,7 +369,7 @@ mod tests {
});
// Assume for now that it was just a plain transfer.
// TODO: Add tests for different call outcomes.
Ok((ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() }, 0))
Ok((ExecReturnValue { flags: ReturnFlags::empty(), data: Bytes(Vec::new()) }, 0))
}
fn terminate(
&mut self,
@@ -946,7 +948,10 @@ mod tests {
&mut GasMeter::new(GAS_LIMIT),
).unwrap();
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: [0x22; 32].to_vec() });
assert_eq!(output, ExecReturnValue {
flags: ReturnFlags::empty(),
data: Bytes([0x22; 32].to_vec())
});
}
/// calls `seal_caller` and compares the result with the constant 42.
@@ -1209,7 +1214,7 @@ mod tests {
&mut gas_meter,
).unwrap();
let gas_left = Weight::decode(&mut output.data.as_slice()).unwrap();
let gas_left = Weight::decode(&mut &*output.data).unwrap();
assert!(gas_left < GAS_LIMIT, "gas_left must be less than initial");
assert!(gas_left > gas_meter.gas_left(), "gas_left must be greater than final");
}
@@ -1299,7 +1304,13 @@ mod tests {
&mut GasMeter::new(GAS_LIMIT),
).unwrap();
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: vec![1, 2, 3, 4] });
assert_eq!(
output,
ExecReturnValue {
flags: ReturnFlags::empty(),
data: Bytes(vec![1, 2, 3, 4])
}
);
}
const CODE_TIMESTAMP_NOW: &str = r#"
@@ -1526,7 +1537,10 @@ mod tests {
output,
ExecReturnValue {
flags: ReturnFlags::empty(),
data: hex!("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F").to_vec(),
data: Bytes(
hex!("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F")
.to_vec()
),
},
);
}
@@ -1601,10 +1615,10 @@ mod tests {
output,
ExecReturnValue {
flags: ReturnFlags::empty(),
data: (
data: Bytes((
hex!("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F"),
42u64,
).encode(),
).encode()),
},
);
}
@@ -1837,7 +1851,10 @@ mod tests {
&mut GasMeter::new(GAS_LIMIT),
).unwrap();
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: hex!("445566778899").to_vec() });
assert_eq!(output, ExecReturnValue {
flags: ReturnFlags::empty(),
data: Bytes(hex!("445566778899").to_vec()),
});
assert!(output.is_success());
}
@@ -1850,7 +1867,10 @@ mod tests {
&mut GasMeter::new(GAS_LIMIT),
).unwrap();
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::REVERT, data: hex!("5566778899").to_vec() });
assert_eq!(output, ExecReturnValue {
flags: ReturnFlags::REVERT,
data: Bytes(hex!("5566778899").to_vec()),
});
assert!(!output.is_success());
}
@@ -1962,7 +1982,7 @@ mod tests {
MockExt::default(),
&mut GasMeter::new(GAS_LIMIT),
).unwrap();
let rent_params = <RentParams<Test>>::default().encode();
let rent_params = Bytes(<RentParams<Test>>::default().encode());
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: rent_params });
}
}
@@ -19,7 +19,7 @@
use crate::{
Config, CodeHash, BalanceOf, Error,
exec::{Ext, StorageKey, TopicOf},
exec::{Ext, StorageKey, TopicOf, ExecResult, ExecError},
gas::{GasMeter, Token, ChargedAmount},
wasm::env_def::ConvertibleToWasm,
schedule::HostFnWeights,
@@ -29,14 +29,14 @@ use frame_support::{dispatch::DispatchError, ensure, traits::Get, weights::Weigh
use sp_std::prelude::*;
use codec::{Decode, DecodeAll, Encode};
use sp_runtime::traits::SaturatedConversion;
use sp_core::crypto::UncheckedFrom;
use sp_core::{Bytes, crypto::UncheckedFrom};
use sp_io::hashing::{
keccak_256,
blake2_256,
blake2_128,
sha2_256,
};
use pallet_contracts_primitives::{ExecResult, ExecReturnValue, ReturnFlags, ExecError};
use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags};
/// Every error that can be returned to a contract when it calls any of the host functions.
///
@@ -347,19 +347,19 @@ where
)?;
Ok(ExecReturnValue {
flags,
data,
data: Bytes(data),
})
},
TrapReason::Termination => {
Ok(ExecReturnValue {
flags: ReturnFlags::empty(),
data: Vec::new(),
data: Bytes(Vec::new()),
})
},
TrapReason::Restoration => {
Ok(ExecReturnValue {
flags: ReturnFlags::empty(),
data: Vec::new(),
data: Bytes(Vec::new()),
})
},
TrapReason::SupervisorError(error) => Err(error)?,
@@ -370,7 +370,7 @@ where
match sandbox_result {
// No traps were generated. Proceed normally.
Ok(_) => {
Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() })
Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Bytes(Vec::new()) })
}
// `Error::Module` is returned only if instantiation or linking failed (i.e.
// wasm binary tried to import a function that is not provided by the host).
@@ -596,7 +596,7 @@ where
/// Fallible conversion of a `ExecResult` to `ReturnCode`.
fn exec_into_return_code(from: ExecResult) -> Result<ReturnCode, DispatchError> {
use pallet_contracts_primitives::ErrorOrigin::Callee;
use crate::exec::ErrorOrigin::Callee;
let ExecError { error, origin } = match from {
Ok(retval) => return Ok(retval.into()),