contracts: Move Schedule from Storage to Config (#8773)

* Move `Schedule` from Storage to Config

* Updated CHANGELOG

* Fix nits from review

* Fix migration

* Print the debug buffer as tracing message

* Use `debug` instead of `trace` and update README

* Add additional assert to test

* Rename `schedule_version` to `instruction_weights_version`

* Fixed typo

* Added more comments to wat fixtures

* Add clarification for the `debug_message` field
This commit is contained in:
Alexander Theißen
2021-05-13 21:56:11 +02:00
committed by GitHub
parent 3c0270fe57
commit 1ac95b6ba6
23 changed files with 1465 additions and 1056 deletions
+40 -12
View File
@@ -71,6 +71,9 @@ pub enum ReturnCode {
/// The contract that was called is either no contract at all (a plain account)
/// or is a tombstone.
NotCallable = 8,
/// The call to `seal_debug_message` had no effect because debug message
/// recording was disabled.
LoggingDisabled = 9,
}
impl ConvertibleToWasm for ReturnCode {
@@ -175,6 +178,8 @@ pub enum RuntimeCosts {
Random,
/// Weight of calling `seal_deposit_event` with the given number of topics and event size.
DepositEvent{num_topic: u32, len: u32},
/// Weight of calling `seal_debug_message`.
DebugMessage,
/// Weight of calling `seal_set_rent_allowance`.
SetRentAllowance,
/// Weight of calling `seal_set_storage` for the given storage item size.
@@ -255,6 +260,7 @@ impl RuntimeCosts {
DepositEvent{num_topic, len} => s.deposit_event
.saturating_add(s.deposit_event_per_topic.saturating_mul(num_topic.into()))
.saturating_add(s.deposit_event_per_byte.saturating_mul(len.into())),
DebugMessage => s.debug_message,
SetRentAllowance => s.set_rent_allowance,
SetStorage(len) => s.set_storage
.saturating_add(s.set_storage_per_byte.saturating_mul(len.into())),
@@ -802,7 +808,7 @@ define_env!(Env, <E: Ext>,
ctx.charge_gas(RuntimeCosts::CallSurchargeTransfer)?;
}
let charged = ctx.charge_gas(
RuntimeCosts::CallSurchargeCodeSize(<E::T as Config>::MaxCodeSize::get())
RuntimeCosts::CallSurchargeCodeSize(<E::T as Config>::Schedule::get().limits.code_len)
)?;
let ext = &mut ctx.ext;
let call_outcome = ext.call(gas, callee, value, input_data);
@@ -887,7 +893,9 @@ define_env!(Env, <E: Ext>,
let input_data = ctx.read_sandbox_memory(input_data_ptr, input_data_len)?;
let salt = ctx.read_sandbox_memory(salt_ptr, salt_len)?;
let charged = ctx.charge_gas(
RuntimeCosts::InstantiateSurchargeCodeSize(<E::T as Config>::MaxCodeSize::get())
RuntimeCosts::InstantiateSurchargeCodeSize(
<E::T as Config>::Schedule::get().limits.code_len
)
)?;
let ext = &mut ctx.ext;
let instantiate_outcome = ext.instantiate(gas, code_hash, value, input_data, &salt);
@@ -937,7 +945,9 @@ define_env!(Env, <E: Ext>,
ctx.read_sandbox_memory_as(beneficiary_ptr, beneficiary_len)?;
let charged = ctx.charge_gas(
RuntimeCosts::TerminateSurchargeCodeSize(<E::T as Config>::MaxCodeSize::get())
RuntimeCosts::TerminateSurchargeCodeSize(
<E::T as Config>::Schedule::get().limits.code_len
)
)?;
let (result, code_len) = match ctx.ext.terminate(&beneficiary) {
Ok(len) => (Ok(()), len),
@@ -1266,7 +1276,7 @@ define_env!(Env, <E: Ext>,
delta
};
let max_len = <E::T as Config>::MaxCodeSize::get();
let max_len = <E::T as Config>::Schedule::get().limits.code_len;
let charged = ctx.charge_gas(RuntimeCosts::RestoreToSurchargeCodeSize {
caller_code: max_len,
tombstone_code: max_len,
@@ -1380,15 +1390,33 @@ define_env!(Env, <E: Ext>,
)?)
},
// Prints utf8 encoded string from the data buffer.
// Only available on `--dev` chains.
// This function may be removed at any time, superseded by a more general contract debugging feature.
[seal0] seal_println(ctx, str_ptr: u32, str_len: u32) => {
let data = ctx.read_sandbox_memory(str_ptr, str_len)?;
if let Ok(utf8) = core::str::from_utf8(&data) {
log::info!(target: "runtime::contracts", "seal_println: {}", utf8);
// Emit a custom debug message.
//
// No newlines are added to the supplied message.
// Specifying invalid UTF-8 triggers a trap.
//
// This is a no-op if debug message recording is disabled which is always the case
// when the code is executing on-chain. The message is interpreted as UTF-8 and
// appended to the debug buffer which is then supplied to the calling RPC client.
//
// # Note
//
// Even though no action is taken when debug message recording is disabled there is still
// a non trivial overhead (and weight cost) associated with calling this function. Contract
// languages should remove calls to this function (either at runtime or compile time) when
// not being executed as an RPC. For example, they could allow users to disable logging
// through compile time flags (cargo features) for on-chain deployment. Additionally, the
// return value of this function can be cached in order to prevent further calls at runtime.
[seal0] seal_debug_message(ctx, str_ptr: u32, str_len: u32) -> ReturnCode => {
ctx.charge_gas(RuntimeCosts::DebugMessage)?;
if ctx.ext.append_debug_buffer("") {
let data = ctx.read_sandbox_memory(str_ptr, str_len)?;
let msg = core::str::from_utf8(&data)
.map_err(|_| <Error<E::T>>::DebugMessageInvalidUTF8)?;
ctx.ext.append_debug_buffer(msg);
return Ok(ReturnCode::Success);
}
Ok(())
Ok(ReturnCode::LoggingDisabled)
},
// Stores the current block number of the current contract into the supplied buffer.