Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
5966a01
Include immutable deposit in base deposit
athei Jan 7, 2025
ba7d704
Update from athei running command 'prdoc --audience runtime_dev'
Jan 18, 2025
1a6feb7
Remove left over debug logging
athei Jan 18, 2025
2f1a825
Correct prdoc bumps
athei Jan 18, 2025
131e622
Add ResetPallet
athei Jan 22, 2025
0d0ec0d
Merge branch 'master' into at/deposit
athei Jan 23, 2025
09b80be
Refine ResetRuntime
athei Jan 23, 2025
76bc3a3
Merge branch 'master' into at/deposit
athei Jan 23, 2025
d0f5327
Merge branch 'master' into at/deposit
athei Jan 23, 2025
1f2f51e
Update from athei running command 'bench-omni --runtime asset-hub-wes…
github-actions[bot] Jan 23, 2025
73d42f8
Update from athei running command 'bench-omni --dev --pallet pallet_r…
github-actions[bot] Jan 23, 2025
716c494
Merge branch 'master' into at/deposit
athei Jan 24, 2025
e833c2f
Make refcounting fallible
athei Jan 24, 2025
b8e4b31
No need to reference into the frame
athei Jan 24, 2025
0073daf
Update substrate/frame/revive/src/wasm/mod.rs
athei Jan 24, 2025
7f5ab96
Merge branch 'master' into at/deposit
athei Jan 24, 2025
7b492cb
Remove unused weight file
athei Jan 24, 2025
0b8c8a6
Merge branch 'master' into at/deposit
athei Jan 24, 2025
1dcc86d
Move ResetPallet to pallet_migration
athei Jan 24, 2025
8b49073
Add benchmark
athei Jan 24, 2025
e5ec326
Merge branch 'master' into at/deposit
athei Jan 25, 2025
e775901
Update from athei running command 'bench-omni --runtime asset-hub-wes…
github-actions[bot] Jan 25, 2025
52c4d34
Remove no longer needed 64bit check on call
athei Jan 25, 2025
abbbb7f
Manually add new weights to the substrate weight file
athei Jan 25, 2025
c998988
Manually add new benchmark to all runtimes
athei Jan 25, 2025
c137bd7
clippy: Simplify boolean expression
athei Jan 26, 2025
d273bbe
Use benchmarked weight in migration
athei Jan 26, 2025
99abd13
Use value size of 32bytes
athei Jan 27, 2025
a259955
Clippy
athei Jan 27, 2025
fee7935
Update docs
athei Jan 27, 2025
283d802
Merge branch 'master' into at/deposit
athei Jan 27, 2025
dba9a1f
Update from mordamax running command 'bench-omni --runtime dev asset-…
github-actions[bot] Jan 27, 2025
7585e2d
Merge branch 'master' into at/deposit
athei Jan 27, 2025
3091457
Import `frame` is necessary for benchmark template
athei Jan 27, 2025
bb2dfc7
Update from athei running command 'fmt'
github-actions[bot] Jan 27, 2025
d5a7b0b
Merge branch 'master' into at/deposit
athei Jan 28, 2025
551bb9b
Return correct amount of weight when erroring out early
athei Jan 28, 2025
9abc232
Remove not needed GenesisBuild functionality
athei Jan 28, 2025
e13c470
Add stricter check in try-runtime
athei Jan 28, 2025
52537b4
Apply suggestions from code review
athei Jan 28, 2025
e507e92
Fixes after applying suggestions
athei Jan 28, 2025
740876f
Merge branch 'master' into at/deposit
athei Feb 3, 2025
9017422
Use try_consume
athei Feb 3, 2025
2ebf592
Update substrate/frame/migrations/src/migrations.rs
athei Feb 3, 2025
bf284d4
Fix benchmarking assertions
athei Feb 3, 2025
a0123d2
Don't use OnGenesis
athei Feb 3, 2025
c8febcf
Add checks back to benchmarks
athei Feb 4, 2025
3d5b9b5
Merge branch 'master' into at/deposit
athei Feb 4, 2025
1efd67d
Update from athei running command 'fmt'
github-actions[bot] Feb 4, 2025
a5c6d27
Remove commit because the benchmarking infra does this
athei Feb 4, 2025
9d00085
Fix warning
athei Feb 4, 2025
3726ddf
Don't add new trait
athei Feb 4, 2025
cfbfdfd
Merge branch 'master' into at/deposit
athei Feb 4, 2025
ff02ca0
Update from athei running command 'bench --runtime dev --pallet palle…
github-actions[bot] Feb 4, 2025
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
46 changes: 46 additions & 0 deletions prdoc/pr_7230.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
title: 'revive: Include immutable storage deposit into the contracts `storage_base_deposit`'
doc:
- audience: Runtime Dev
description: |-
This PR is centered around a main fix regarding the base deposit and a bunch of drive by or related fixtures that make sense to resolve in one go. It could be broken down more but I am constantly rebasing this PR and would appreciate getting those fixes in as-one.

## Record the deposit for immutable data into the `storage_base_deposit`

The `storage_base_deposit` are all the deposit a contract has to pay for existing. It included the deposit for its own metadata and a deposit proportional (< 1.0x) to the size of its code. However, the immutable code size was not recorded there. This would lead to the situation where on terminate this portion wouldn't be refunded staying locked into the contract. It would also make the calculation of the deposit changes on `set_code_hash` more complicated when it updates the immutable data (to be done in #6985). Reason is because it didn't know how much was payed before since the storage prices could have changed in the mean time.

In order for this solution to work I needed to delay the deposit calculation for a new contract for after the contract is done executing is constructor as only then we know the immutable data size. Before, we just charged this eagerly in `charge_instantiate` before we execute the constructor. Now, we merely send the ED as free balance before the constructor in order to create the account. After the constructor is done we calculate the contract base deposit and charge it. This will make `set_code_hash` much easier to implement.

As a side effect it is now legal to call `set_immutable_data` multiple times per constructor (even though I see no reason to do so). It simply overrides the immutable data with the new value. The deposit accounting will be done after the constructor returns (as mentioned above) instead of when setting the immutable data.

## Don't pre-charge for reading immutable data

I noticed that we were pre-charging weight for the max allowable immutable data when reading those values and then refunding after read. This is not necessary as we know its length without reading the storage as we store it out of band in contract metadata. This makes reading it free. Less pre-charging less problems.

## Remove delegate locking

Fixes #7092

This is also in the spirit of making #6985 easier to implement. The locking complicates `set_code_hash` as we might need to block settings the code hash when locks exist. Check #7092 for further rationale.

## Enforce "no terminate in constructor" eagerly

We used to enforce this rule after the contract execution returned. Now we error out early in the host call. This makes it easier to be sure to argue that a contract info still exists (wasn't terminated) when a constructor successfully returns. All around this his just much simpler than dealing this check.

## Moved refcount functions to `CodeInfo`

They never really made sense to exist on `Stack`. But now with the locking gone this makes even less sense. The refcount is stored inside `CodeInfo` to lets just move them there.

## Set `CodeHashLockupDepositPercent` for test runtime

The test runtime was setting `CodeHashLockupDepositPercent` to zero. This was trivializing many code paths and excluded them from testing. I set it to `30%` which is our default value and fixed up all the tests that broke. This should give us confidence that the lockup doeposit collections properly works.

## Reworked the `MockExecutable` to have both a `deploy` and a `call` entry point

This type used for testing could only have either entry points but not both. In order to fix the `immutable_data_set_overrides` I needed to a new function `add_both` to `MockExecutable` that allows to have both entry points. Make sure to make use of it in the future :)
crates:
- name: pallet-revive-fixtures
bump: major
- name: pallet-revive
bump: major
- name: pallet-revive-uapi
bump: major
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
#![no_main]

use common::{input, u256_bytes};
use uapi::{HostFn, HostFnImpl as api};
use uapi::{HostFn, HostFnImpl as api, StorageFlags};

static BUFFER: [u8; 16 * 1024 + 1] = [0u8; 16 * 1024 + 1];

#[no_mangle]
#[polkavm_derive::polkavm_export]
Expand All @@ -30,11 +32,16 @@ pub extern "C" fn deploy() {}
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {
input!(
input: [u8; 4],
len: u32,
code_hash: &[u8; 32],
deposit_limit: &[u8; 32],
);

let data = &BUFFER[..len as usize];
let mut key = [0u8; 32];
key[0] = 1;
api::set_storage(StorageFlags::empty(), &key, data);

let value = u256_bytes(10_000u64);
let salt = [0u8; 32];
let mut address = [0u8; 20];
Expand All @@ -45,7 +52,7 @@ pub extern "C" fn call() {
u64::MAX, // How much proof_size weight to devote for the execution. u64::MAX = use all.
deposit_limit,
&value,
input,
&len.to_le_bytes(),
Some(&mut address),
None,
Some(&salt),
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ const DJANGO_FALLBACK: [u8; 20] = [4u8; 20];

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn deploy() {}
pub extern "C" fn deploy() {
// make sure that the deposit for the immutable data is refunded
api::set_immutable_data(&[1, 2, 3, 4, 5])
}

#[no_mangle]
#[polkavm_derive::polkavm_export]
Expand Down
54 changes: 2 additions & 52 deletions substrate/frame/revive/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mod code;
use self::{call_builder::CallSetup, code::WasmModule};
use crate::{
evm::runtime::GAS_PRICE,
exec::{Key, MomentOf},
exec::{Ext, Key, MomentOf},
limits,
storage::WriteOutcome,
Pallet as Contracts, *,
Expand Down Expand Up @@ -1011,24 +1011,11 @@ mod benchmarks {
}

#[benchmark(pov_mode = Measured)]
fn seal_terminate(
n: Linear<0, { limits::DELEGATE_DEPENDENCIES }>,
) -> Result<(), BenchmarkError> {
fn seal_terminate() -> Result<(), BenchmarkError> {
let beneficiary = account::<T::AccountId>("beneficiary", 0, 0);
let caller = whitelisted_caller();
T::Currency::set_balance(&caller, caller_funding::<T>());
let origin = RawOrigin::Signed(caller);
let storage_deposit = default_deposit_limit::<T>();

build_runtime!(runtime, memory: [beneficiary.encode(),]);

(0..n).for_each(|i| {
let new_code = WasmModule::dummy_unique(65 + i);
Contracts::<T>::bare_upload_code(origin.clone().into(), new_code.code, storage_deposit)
.unwrap();
runtime.ext().lock_delegate_dependency(new_code.hash).unwrap();
});

let result;
#[block]
{
Expand Down Expand Up @@ -1930,43 +1917,6 @@ mod benchmarks {
Ok(())
}

#[benchmark(pov_mode = Measured)]
fn lock_delegate_dependency() -> Result<(), BenchmarkError> {
let code_hash = Contract::<T>::with_index(1, WasmModule::dummy_unique(1), vec![])?
.info()?
.code_hash;

build_runtime!(runtime, memory: [ code_hash.encode(),]);

let result;
#[block]
{
result = runtime.bench_lock_delegate_dependency(memory.as_mut_slice(), 0);
}

assert_ok!(result);
Ok(())
}

#[benchmark]
fn unlock_delegate_dependency() -> Result<(), BenchmarkError> {
let code_hash = Contract::<T>::with_index(1, WasmModule::dummy_unique(1), vec![])?
.info()?
.code_hash;

build_runtime!(runtime, memory: [ code_hash.encode(),]);
runtime.bench_lock_delegate_dependency(memory.as_mut_slice(), 0).unwrap();

let result;
#[block]
{
result = runtime.bench_unlock_delegate_dependency(memory.as_mut_slice(), 0);
}

assert_ok!(result);
Ok(())
}

// Benchmark the execution of instructions.
#[benchmark(pov_mode = Ignored)]
fn instr(r: Linear<0, INSTR_BENCHMARK_RUNS>) {
Expand Down
Loading