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

Contracts Add deposit for dependencies #14079

Merged
merged 77 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from 76 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
304d84b
wip
pgherveou Jul 3, 2023
4e80ea6
fixes
pgherveou Jul 3, 2023
dc744af
rm comment
pgherveou Jul 3, 2023
5f9a226
join fns
pgherveou Jul 3, 2023
b6def6d
clippy
pgherveou Jul 4, 2023
76c43c2
Fix limits
pgherveou Jul 4, 2023
83e5f37
reduce diff
pgherveou Jul 4, 2023
e3c51ec
fix
pgherveou Jul 4, 2023
8c15372
fix
pgherveou Jul 4, 2023
c97708b
fix typo
pgherveou Jul 4, 2023
0180777
refactor store to use self
pgherveou Jul 4, 2023
89accc8
refactor run to take self by value
pgherveou Jul 4, 2023
0e61306
pass tests
pgherveou Jul 4, 2023
49c174e
rm comment
pgherveou Jul 4, 2023
9f53e36
fixes
pgherveou Jul 5, 2023
5036e88
fix typo
pgherveou Jul 5, 2023
09a9971
rm
pgherveou Jul 5, 2023
6248a64
fix fmt
pgherveou Jul 5, 2023
e137f0e
clippy
pgherveou Jul 5, 2023
672e92e
Merge branch 'master' of https:/paritytech/substrate into…
Jul 5, 2023
68ba74d
".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts
Jul 5, 2023
e8ceb0d
Update frame/contracts/src/lib.rs
pgherveou Jul 6, 2023
9eb7833
Update frame/contracts/src/wasm/mod.rs
pgherveou Jul 6, 2023
96e3dcf
Update frame/contracts/src/wasm/mod.rs
pgherveou Jul 6, 2023
a9df0cc
PR review, rm duplicate increment_refcount
pgherveou Jul 6, 2023
b291902
PR review
pgherveou Jul 6, 2023
bc2057d
Update frame/contracts/src/wasm/prepare.rs
pgherveou Jul 6, 2023
bbf2c5b
Add test for failing storage_deposit
pgherveou Jul 6, 2023
dff4758
fix lint
pgherveou Jul 6, 2023
5873b6f
wip
pgherveou Jul 3, 2023
679bb88
Delegate update take 2
pgherveou Jul 4, 2023
9664297
update
pgherveou Jul 4, 2023
ddaba76
fix migration
pgherveou Jul 4, 2023
d45c793
fix migration
pgherveou Jul 4, 2023
33a9d79
doc
pgherveou Jul 4, 2023
b5f35fc
fix lint
pgherveou Jul 5, 2023
f941e2a
update migration
pgherveou Jul 5, 2023
4ccb853
fix warning
pgherveou Jul 5, 2023
16744ba
Merge branch 'master' into pg/delegate_deposit
pgherveou Jul 7, 2023
30f5472
reformat comment
pgherveou Jul 7, 2023
649011d
regenerate weightInfo trait
pgherveou Jul 7, 2023
3d126ac
fix merge
pgherveou Jul 7, 2023
d9d85a2
Merge remote-tracking branch 'origin/master' into pg/delegate_deposit
Jul 7, 2023
4354a7f
Merge remote-tracking branch 'origin/master' into pg/delegate_deposit
Jul 11, 2023
7e811b2
Merge remote-tracking branch 'origin/master' into pg/delegate_deposit
Jul 11, 2023
81d674f
PR review
pgherveou Jul 14, 2023
16cab18
PR review
pgherveou Jul 14, 2023
f18194b
PR review remove optimisation
pgherveou Jul 14, 2023
0ddaacd
PR review fix return type
pgherveou Jul 14, 2023
b12319c
Apply suggestions from code review
pgherveou Jul 14, 2023
0b761d6
PR review pass CodeInfo and update docstring
pgherveou Jul 14, 2023
59af50e
Merge branch 'master' into pg/delegate_deposit
pgherveou Jul 14, 2023
c6ce4ba
PR review add code_info to the executable
pgherveou Jul 14, 2023
fe05151
rename info -> contract_info
pgherveou Jul 14, 2023
bdd7889
Update frame/contracts/src/exec.rs
pgherveou Jul 14, 2023
46a9617
Update frame/contracts/fixtures/add_remove_delegate_dependency.wat
pgherveou Jul 21, 2023
b224362
Update frame/contracts/src/migration/v13.rs
pgherveou Jul 21, 2023
f7d6b99
fix tests
pgherveou Jul 14, 2023
fdd4613
Fmt & fix tests
pgherveou Jul 21, 2023
a876168
Test Result<(), _> return type
pgherveou Jul 24, 2023
c81d6a0
Update frame/contracts/src/migration.rs
pgherveou Jul 24, 2023
3cbb616
Revert "Test Result<(), _> return type"
pgherveou Jul 24, 2023
de00196
add / update doc comments
pgherveou Jul 24, 2023
2ff6425
fix backticks
pgherveou Jul 24, 2023
564169b
Revert "Revert "Test Result<(), _> return type""
pgherveou Jul 24, 2023
a1da123
fix bench
pgherveou Jul 24, 2023
a8e8fa4
fix bench
pgherveou Jul 24, 2023
2cbe99f
fix
pgherveou Jul 24, 2023
59755eb
Update frame/contracts/src/storage/meter.rs
pgherveou Jul 24, 2023
6316417
rm stale comments
pgherveou Jul 24, 2023
0248734
Apply suggestions from code review
pgherveou Jul 25, 2023
e7862f0
PR suggestion
pgherveou Jul 25, 2023
25be4b0
Add missing doc
pgherveou Jul 25, 2023
9627c4c
fx lint
pgherveou Jul 25, 2023
ebb49fe
Merge branch 'master' of https:/paritytech/substrate into…
Jul 25, 2023
e0fe397
".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime…
Jul 25, 2023
9a888e5
Update frame/contracts/src/lib.rs
pgherveou Jul 26, 2023
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
3 changes: 3 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,7 @@ parameter_types! {
pub const DepositPerByte: Balance = deposit(0, 1);
pub const DefaultDepositLimit: Balance = deposit(1024, 1024 * 1024);
pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(30);
}

impl pallet_contracts::Config for Runtime {
Expand Down Expand Up @@ -1255,6 +1256,8 @@ impl pallet_contracts::Config for Runtime {
type Migrations = ();
#[cfg(feature = "runtime-benchmarks")]
type Migrations = (NoopMigration<1>, NoopMigration<2>);
type MaxDelegateDependencies = ConstU32<32>;
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
}

impl pallet_sudo::Config for Runtime {
Expand Down
111 changes: 111 additions & 0 deletions frame/contracts/fixtures/add_remove_delegate_dependency.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
;; This contract tests the behavior of adding / removing delegate_dependencies when delegate calling into a contract.
(module
(import "seal0" "add_delegate_dependency" (func $add_delegate_dependency (param i32)))
(import "seal0" "remove_delegate_dependency" (func $remove_delegate_dependency (param i32)))
(import "seal0" "input" (func $input (param i32 i32)))
(import "seal1" "terminate" (func $terminate (param i32)))
(import "seal0" "delegate_call" (func $delegate_call (param i32 i32 i32 i32 i32 i32) (result i32)))
(import "env" "memory" (memory 1 1))

;; [100, 132) Address of Alice
(data (i32.const 100)
"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01"
"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01"
)

(func $assert (param i32)
(block $ok
(br_if $ok
(get_local 0)
)
(unreachable)
)
)

;; This function loads input data and performs the action specified.
;; The first 4 bytes of the input specify the action to perform.
;; The next 32 bytes specify the code hash to use when calling add_delegate_dependency or remove_delegate_dependency.
;; Actions are:
;; 1: call add_delegate_dependency
;; 2: call remove_delegate_dependency.
;; 3: call terminate.
;; Any other value is a no-op.
(func $load_input
(local $action i32)
(local $code_hash_ptr i32)

;; Store available input size at offset 0.
(i32.store (i32.const 0) (i32.const 512))

;; Read input data.
(call $input (i32.const 4) (i32.const 0))

;; Input data layout.
;; [0..4) - size of the call
;; [4..8) - action to perform
;; [8..42) - code hash of the callee
(set_local $action (i32.load (i32.const 4)))
(set_local $code_hash_ptr (i32.const 8))

;; Assert input size == 36 (4 for action + 32 for code_hash).
(call $assert
(i32.eq
(i32.load (i32.const 0))
(i32.const 36)
)
)

;; Call add_delegate_dependency when action == 1.
(if (i32.eq (get_local $action) (i32.const 1))
(then
(call $add_delegate_dependency (get_local $code_hash_ptr))
)
(else)
)

;; Call remove_delegate_dependency when action == 2.
(if (i32.eq (get_local $action) (i32.const 2))
(then
(call $remove_delegate_dependency
(get_local $code_hash_ptr)
)
)
(else)
)

;; Call terminate when action == 3.
(if (i32.eq (get_local $action) (i32.const 3))
(then
(call $terminate
(i32.const 100) ;; Pointer to beneficiary address
)
(unreachable) ;; terminate never returns
)
(else)
)
)

(func (export "deploy")
(call $load_input)
)

(func (export "call")
(call $load_input)

;; Delegate call into passed code hash.
(call $assert
(i32.eq
(call $delegate_call
(i32.const 0) ;; Set no call flags.
(i32.const 8) ;; Pointer to "callee" code_hash.
(i32.const 0) ;; Input is ignored.
(i32.const 0) ;; Length of the input.
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output.
(i32.const 0) ;; Length is ignored in this case.
)
(i32.const 0)
)
)
)

)
138 changes: 131 additions & 7 deletions frame/contracts/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use self::{
};
use crate::{
exec::{AccountIdOf, Key},
migration::{v09, v10, v11, v12, MigrationStep},
migration::{v09, v10, v11, v12, v13, MigrationStep},
wasm::CallFlags,
Pallet as Contracts, *,
};
Expand Down Expand Up @@ -257,6 +257,19 @@ benchmarks! {
m.step();
}

// This benchmarks the v13 migration step (Add delegate_dependencies field).
#[pov_mode = Measured]
v13_migration_step {
let contract = <Contract<T>>::with_caller(
whitelisted_caller(), WasmModule::dummy(), vec![],
)?;

v13::store_old_contract_info::<T>(contract.account_id.clone(), contract.info()?);
let mut m = v13::Migration::<T>::default();
}: {
m.step();
}

// This benchmarks the weight of executing Migration::migrate to execute a noop migration.
#[pov_mode = Measured]
migration_noop {
Expand Down Expand Up @@ -832,20 +845,48 @@ benchmarks! {
let beneficiary = account::<T::AccountId>("beneficiary", 0, 0);
let beneficiary_bytes = beneficiary.encode();
let beneficiary_len = beneficiary_bytes.len();

// Maximize the delegate_dependencies to account for the worst-case scenario.
let code_hashes = (0..T::MaxDelegateDependencies::get())
.map(|i| {
let new_code = WasmModule::<T>::dummy_with_bytes(65 + i);
Contracts::<T>::store_code_raw(new_code.code, whitelisted_caller())?;
Ok(new_code.hash)
})
.collect::<Result<Vec<_>, &'static str>>()?;
let code_hash_len = code_hashes.get(0).map(|x| x.encode().len()).unwrap_or(0);
let code_hashes_bytes = code_hashes.iter().flat_map(|x| x.encode()).collect::<Vec<_>>();

let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "seal_terminate",
params: vec![ValueType::I32, ValueType::I32],
return_type: None,
}],
imported_functions: vec![
ImportedFunction {
module: "seal0",
name: "seal_terminate",
params: vec![ValueType::I32, ValueType::I32],
return_type: None,
},
ImportedFunction {
module: "seal0",
name: "add_delegate_dependency",
params: vec![ValueType::I32],
return_type: None,
}
],
data_segments: vec![
DataSegment {
offset: 0,
value: beneficiary_bytes,
},
DataSegment {
offset: beneficiary_len as u32,
value: code_hashes_bytes,
},
],
deploy_body: Some(body::repeated_dyn(r, vec![
Counter(beneficiary_len as u32, code_hash_len as u32), // code_hash_ptr
Regular(Instruction::Call(1)),
])),
call_body: Some(body::repeated(r, &[
Instruction::I32Const(0), // beneficiary_ptr
Instruction::I32Const(beneficiary_len as i32), // beneficiary_len
Expand Down Expand Up @@ -2327,6 +2368,89 @@ benchmarks! {
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])

#[pov_mode = Measured]
add_delegate_dependency {
let r in 0 .. T::MaxDelegateDependencies::get();
let code_hashes = (0..r)
.map(|i| {
let new_code = WasmModule::<T>::dummy_with_bytes(65 + i);
Contracts::<T>::store_code_raw(new_code.code, whitelisted_caller())?;
Ok(new_code.hash)
})
.collect::<Result<Vec<_>, &'static str>>()?;
let code_hash_len = code_hashes.get(0).map(|x| x.encode().len()).unwrap_or(0);
let code_hashes_bytes = code_hashes.iter().flat_map(|x| x.encode()).collect::<Vec<_>>();

let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "add_delegate_dependency",
params: vec![ValueType::I32],
return_type: None,
}],
data_segments: vec![
DataSegment {
offset: 0,
value: code_hashes_bytes,
},
],
call_body: Some(body::repeated_dyn(r, vec![
Counter(0, code_hash_len as u32), // code_hash_ptr
Regular(Instruction::Call(0)),
])),
.. Default::default()
});
let instance = Contract::<T>::new(code, vec![])?;
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])

remove_delegate_dependency {
let r in 0 .. T::MaxDelegateDependencies::get();
let code_hashes = (0..r)
.map(|i| {
let new_code = WasmModule::<T>::dummy_with_bytes(65 + i);
Contracts::<T>::store_code_raw(new_code.code, whitelisted_caller())?;
Ok(new_code.hash)
})
.collect::<Result<Vec<_>, &'static str>>()?;

let code_hash_len = code_hashes.get(0).map(|x| x.encode().len()).unwrap_or(0);
let code_hashes_bytes = code_hashes.iter().flat_map(|x| x.encode()).collect::<Vec<_>>();

let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "remove_delegate_dependency",
params: vec![ValueType::I32],
return_type: None,
}, ImportedFunction {
module: "seal0",
name: "add_delegate_dependency",
params: vec![ValueType::I32],
return_type: None
}],
data_segments: vec![
DataSegment {
offset: 0,
value: code_hashes_bytes,
},
],
deploy_body: Some(body::repeated_dyn(r, vec![
Counter(0, code_hash_len as u32), // code_hash_ptr
Regular(Instruction::Call(1)),
])),
call_body: Some(body::repeated_dyn(r, vec![
Counter(0, code_hash_len as u32), // code_hash_ptr
Regular(Instruction::Call(0)),
])),
.. Default::default()
});
let instance = Contract::<T>::new(code, vec![])?;
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])

#[pov_mode = Measured]
seal_reentrance_count {
let r in 0 .. API_BENCHMARK_RUNS;
Expand Down
Loading