Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

contracts: Move Schedule from Storage to Config #8773

Merged
12 commits merged into from
May 13, 2021
16 changes: 16 additions & 0 deletions frame/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ Contracts can emit messages to the client when called as RPC through the `seal_d
API. This is exposed in ink! via
[`ink_env::debug_println()`](https://docs.rs/ink_env/latest/ink_env/fn.debug_println.html).

Those messages are gathered into an internal buffer and send to the RPC client.
It is up the the individual client if and how those messages are presented to the user.

This buffer is also printed as a debug message. In order to see these messages on the node
console the log level for the `runtime::contracts` target needs to be raised to at least
the `debug` level. However, those messages are easy to overlook because of the noise generated
by block production. A good starting point for observing them on the console is:

```bash
cargo run --release -- --dev --tmp -lerror,runtime::contracts=debug
athei marked this conversation as resolved.
Show resolved Hide resolved
```

This raises the log level of `runtime::contracts` to `debug` and all other targets
to `error` in order to prevent them from spamming the console.

`--dev`: Use a dev chain spec
`--tmp`: Use temporary storage for chain data (the chain state is deleted on exit)

License: Apache-2.0
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
(i32.const 0) ;; Pointer to the text buffer
(i32.const 12) ;; The size of the buffer
)
(i32.const 9)
(i32.const 9) ;; LoggingDisabled return code
)
)

Expand Down
2 changes: 1 addition & 1 deletion frame/contracts/fixtures/debug_message_works.wat
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
(i32.const 0) ;; Pointer to the text buffer
(i32.const 12) ;; The size of the buffer
)
(i32.const 0)
(i32.const 0) ;; success return code
)
)

Expand Down
2 changes: 1 addition & 1 deletion frame/contracts/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ where
}
} else {
if let Some(message) = &self.debug_message {
athei marked this conversation as resolved.
Show resolved Hide resolved
log::trace!(
log::debug!(
target: "runtime::contracts",
"Debug Message: {}",
core::str::from_utf8(message).unwrap_or("<Invalid UTF8>"),
Expand Down
1 change: 1 addition & 0 deletions frame/contracts/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2900,6 +2900,7 @@ fn debug_message_logging_disabled() {
GAS_LIMIT,
vec![],
));
ascjones marked this conversation as resolved.
Show resolved Hide resolved
assert!(result.debug_message.is_empty());
});
}

Expand Down
10 changes: 4 additions & 6 deletions frame/contracts/src/wasm/code_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,9 @@ where
prefab_module.code_hash = code_hash;

if let Some((schedule, gas_meter)) = reinstrument {
if prefab_module.schedule_version < schedule.instruction_weights.version {
// The current schedule version is greater than the version of the one cached
// in the storage.
//
// We need to re-instrument the code with the latest schedule here.
if prefab_module.instruction_weights_version < schedule.instruction_weights.version {
// The instruction weights have changed.
// We need to re-instrument the code with the new instruction weights.
gas_meter.charge(InstrumentToken(prefab_module.original_code_len))?;
private::reinstrument(&mut prefab_module, schedule)?;
}
Expand All @@ -158,7 +156,7 @@ mod private {
let original_code = <PristineCode<T>>::get(&prefab_module.code_hash)
.ok_or_else(|| Error::<T>::CodeNotFound)?;
prefab_module.code = prepare::reinstrument_contract::<T>(original_code, schedule)?;
prefab_module.schedule_version = schedule.instruction_weights.version;
prefab_module.instruction_weights_version = schedule.instruction_weights.version;
<CodeStorage<T>>::insert(&prefab_module.code_hash, &*prefab_module);
Ok(())
}
Expand Down
16 changes: 8 additions & 8 deletions frame/contracts/src/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@ pub use tests::MockExt;
/// # Note
///
/// This data structure is mostly immutable once created and stored. The exceptions that
/// can be changed by calling a contract are `refcount`, `schedule_version` and `code`.
/// can be changed by calling a contract are `refcount`, `instruction_weights_version` and `code`.
/// `refcount` can change when a contract instantiates a new contract or self terminates.
/// `schedule_version` and `code` when a contract with an outdated instrumention is called.
/// Therefore one must be careful when holding any in-memory representation of this type while
/// calling into a contract as those fields can get out of date.
/// `instruction_weights_version` and `code` when a contract with an outdated instrumention is
/// called. Therefore one must be careful when holding any in-memory representation of this
/// type while calling into a contract as those fields can get out of date.
#[derive(Clone, Encode, Decode)]
pub struct PrefabWasmModule<T: Config> {
/// Version of the schedule with which the code was instrumented.
/// Version of the instruction weights with which the code was instrumented.
#[codec(compact)]
schedule_version: u32,
instruction_weights_version: u32,
/// Initial memory size of a contract's sandbox.
#[codec(compact)]
initial: u32,
Expand Down Expand Up @@ -141,10 +141,10 @@ where
self.refcount
}

/// Decrement schedule_version by 1. Panics if it is already 0.
/// Decrement instruction_weights_version by 1. Panics if it is already 0.
#[cfg(test)]
pub fn decrement_version(&mut self) {
self.schedule_version = self.schedule_version.checked_sub(1).unwrap();
self.instruction_weights_version = self.instruction_weights_version.checked_sub(1).unwrap();
}
}

Expand Down
4 changes: 2 additions & 2 deletions frame/contracts/src/wasm/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ fn do_preparation<C: ImportSatisfyCheck, T: Config>(
schedule,
)?;
Ok(PrefabWasmModule {
schedule_version: schedule.instruction_weights.version,
instruction_weights_version: schedule.instruction_weights.version,
initial,
maximum,
_reserved: None,
Expand Down Expand Up @@ -499,7 +499,7 @@ pub mod benchmarking {
let contract_module = ContractModule::new(&original_code, schedule)?;
let memory_limits = get_memory_limits(contract_module.scan_imports::<()>(&[])?, schedule)?;
Ok(PrefabWasmModule {
schedule_version: schedule.instruction_weights.version,
instruction_weights_version: schedule.instruction_weights.version,
initial: memory_limits.0,
maximum: memory_limits.1,
_reserved: None,
Expand Down
2 changes: 1 addition & 1 deletion frame/contracts/src/wasm/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ 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 to effect because debug message
/// The call to `seal_debug_message` had no effect because debug message
/// recording was disabled.
LoggingDisabled = 9,
}
Expand Down