Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8321883
Transition getter functions to not use scratch buffer
athei Jun 24, 2020
92fe839
Remove scratch buffer from ext_get_storage
athei Jun 26, 2020
e1c0e26
Remove scratch buffer from ext_call
athei Jun 29, 2020
6f94941
Remove scratch buffer from ext_instantiate
athei Jun 29, 2020
0b27908
Add ext_input and remove scratch buffer
athei Jun 29, 2020
46191f5
Remove the no longer used `Dispatched` event
athei Jul 1, 2020
fa6bf8c
Rework error handling (changes RPC exposed data)
athei Jun 30, 2020
c86c2ad
Updated inline documentation
athei Jul 2, 2020
ddf69ab
Prevent skipping of copying the output for getter API
athei Jul 3, 2020
868668c
Return gas_consumed from the RPC contracts call interface
athei Jul 3, 2020
84973b0
Updated COMPLEXTITY.md
athei Jul 3, 2020
d205f60
Rename ext_gas_price to ext_weight_to_fee
athei Jul 3, 2020
e096945
Align comments with spaces
athei Jul 7, 2020
6b0c1f0
Removed no longer used `ExecError`
athei Jul 7, 2020
8e5170c
Remove possible panic in `from_typed_value`
athei Jul 7, 2020
08edc84
Use a struct as associated data for SpecialTrap::Return
athei Jul 7, 2020
792c942
Fix nits in COMPLEXITY.md
athei Jul 7, 2020
41f1d55
Renamed SpecialTrap to TrapReason
athei Jul 7, 2020
3977032
Merge remote-tracking branch 'origin/master' into at-remove-scratch-b…
athei Jul 7, 2020
8373842
Fix test
athei Jul 7, 2020
cf72226
Merge branch 'master' into at-remove-scratch-buffer
athei Jul 9, 2020
9021d20
Finish renaming special_trap -> trap_reason
athei Jul 9, 2020
9ef80e1
Remove no longer used get_runtime_storage
athei Jul 9, 2020
fe110ed
fixup! Remove no longer used get_runtime_storage
athei Jul 9, 2020
9deebd3
Removed tabs for comment aligment
athei Jul 9, 2020
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
Prev Previous commit
Next Next commit
Renamed SpecialTrap to TrapReason
  • Loading branch information
athei committed Jul 7, 2020
commit 41f1d552fea6c1da7e8daae10238b9efd7644689
6 changes: 5 additions & 1 deletion frame/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,11 @@ decl_error! {
/// Tombstones don't match.
InvalidTombstone,
/// An origin TrieId written in the current block.
InvalidContractOrigin
InvalidContractOrigin,
/// The executed contract exhausted its gas limit.
OutOfGas,
/// The output buffer supplied to a contract API call was too small.
OutputBufferTooSmall,
}
}

Expand Down
49 changes: 24 additions & 25 deletions frame/contracts/src/wasm/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

//! Environment definition of the wasm smart-contract runtime.

use crate::{Schedule, Trait, CodeHash, BalanceOf};
use crate::{Schedule, Trait, CodeHash, BalanceOf, Error};
use crate::exec::{
Ext, ExecResult, ExecReturnValue, StorageKey, TopicOf, ReturnFlags,
};
Expand All @@ -25,6 +25,7 @@ use crate::wasm::env_def::ConvertibleToWasm;
use sp_sandbox;
use parity_wasm::elements::ValueType;
use frame_system;
use frame_support::dispatch::DispatchError;
use sp_std::prelude::*;
use codec::{Decode, Encode};
use sp_runtime::traits::{Bounded, SaturatedConversion};
Expand Down Expand Up @@ -83,22 +84,23 @@ struct ReturnData {
data: Vec<u8>,
}

/// Enumerates all possible *special* trap conditions.
/// Enumerates all possible reasons why a trap was generated.
///
/// In this runtime traps used not only for signaling about errors but also
/// to just terminate quickly in some cases.
enum SpecialTrap {
/// This is either used to supply the caller with more information about why an error
/// occurred (the SupervisorError variant).
/// The other case is where the trap does not constitute an error but rather was invoked
/// as a quick way to terminate the application (all other variants).
enum TrapReason {
/// The supervisor trapped the contract because of an error condition occurred during
/// execution in privileged code.
SupervisorError(DispatchError),
/// Signals that trap was generated in response to call `ext_return` host function.
Return(ReturnData),
/// Signals that trap was generated because the contract exhausted its gas limit.
OutOfGas,
/// Signals that a trap was generated in response to a succesful call to the
/// `ext_terminate` host function.
Termination,
/// Signals that a trap was generated because of a successful restoration.
Restoration,
/// Signals that a buffer supplied by the caller is too small to fit the output.
OutputBufferTooSmall,
}

/// Can only be used for one call.
Expand All @@ -108,7 +110,7 @@ pub(crate) struct Runtime<'a, E: Ext + 'a> {
schedule: &'a Schedule,
memory: sp_sandbox::Memory,
gas_meter: &'a mut GasMeter<E::T>,
special_trap: Option<SpecialTrap>,
special_trap: Option<TrapReason>,
}
impl<'a, E: Ext + 'a> Runtime<'a, E> {
pub(crate) fn new(
Expand All @@ -135,7 +137,7 @@ pub(crate) fn to_execution_result<E: Ext>(
) -> ExecResult {
match runtime.special_trap {
// The trap was the result of the execution `return` host function.
Some(SpecialTrap::Return(ReturnData{ flags, data })) => {
Some(TrapReason::Return(ReturnData{ flags, data })) => {
let flags = ReturnFlags::from_bits(flags).ok_or_else(||
"used reserved bit in return flags"
)?;
Expand All @@ -144,24 +146,19 @@ pub(crate) fn to_execution_result<E: Ext>(
data,
})
},
Some(SpecialTrap::Termination) => {
Some(TrapReason::Termination) => {
return Ok(ExecReturnValue {
flags: ReturnFlags::empty(),
data: Vec::new(),
})
},
Some(SpecialTrap::Restoration) => {
Some(TrapReason::Restoration) => {
return Ok(ExecReturnValue {
flags: ReturnFlags::empty(),
data: Vec::new(),
})
}
Some(SpecialTrap::OutOfGas) => {
Err("ran out of gas during contract execution")?
},
Some(SpecialTrap::OutputBufferTooSmall) => {
Err("output buffer too small")?
},
Some(TrapReason::SupervisorError(error)) => Err(error)?,
None => (),
}

Expand Down Expand Up @@ -250,13 +247,13 @@ impl<T: Trait> Token<T> for RuntimeToken {
fn charge_gas<T: Trait, Tok: Token<T>>(
gas_meter: &mut GasMeter<T>,
metadata: &Tok::Metadata,
special_trap: &mut Option<SpecialTrap>,
special_trap: &mut Option<TrapReason>,
token: Tok,
) -> Result<(), sp_sandbox::HostError> {
match gas_meter.charge(metadata, token) {
GasMeterResult::Proceed => Ok(()),
GasMeterResult::OutOfGas => {
*special_trap = Some(SpecialTrap::OutOfGas);
*special_trap = Some(TrapReason::SupervisorError(Error::<T>::OutOfGas.into()));
Err(sp_sandbox::HostError)
},
}
Expand Down Expand Up @@ -382,7 +379,9 @@ fn write_sandbox_output<E: Ext>(
let len: u32 = read_sandbox_memory_as(ctx, out_len_ptr, 4)?;

if len < buf_len {
ctx.special_trap = Some(SpecialTrap::OutputBufferTooSmall);
ctx.special_trap = Some(TrapReason::SupervisorError(
Error::<E::T>::OutputBufferTooSmall.into()
));
return Err(sp_sandbox::HostError);
}

Expand Down Expand Up @@ -722,7 +721,7 @@ define_env!(Env, <E: Ext>,
read_sandbox_memory_as(ctx, beneficiary_ptr, beneficiary_len)?;

if let Ok(_) = ctx.ext.terminate(&beneficiary, ctx.gas_meter) {
ctx.special_trap = Some(SpecialTrap::Termination);
ctx.special_trap = Some(TrapReason::Termination);
}
Err(sp_sandbox::HostError)
},
Expand Down Expand Up @@ -760,7 +759,7 @@ define_env!(Env, <E: Ext>,
RuntimeToken::ReturnData(data_len)
)?;

ctx.special_trap = Some(SpecialTrap::Return(ReturnData {
ctx.special_trap = Some(TrapReason::Return(ReturnData {
flags,
data: read_sandbox_memory(ctx, data_ptr, data_len)?,
}));
Expand Down Expand Up @@ -974,7 +973,7 @@ define_env!(Env, <E: Ext>,
rent_allowance,
delta,
) {
ctx.special_trap = Some(SpecialTrap::Restoration);
ctx.special_trap = Some(TrapReason::Restoration);
}
Err(sp_sandbox::HostError)
},
Expand Down