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

Commit af504bc

Browse files
agryaznovpgherveou
andauthored
[contracts] Port host functions to Weight V2 and storage deposit limit (#13565)
* added [unstable][seal2] call() * updated test to cover new seal_call proof_limit * docs updated * add [seal2][unstable] instantiate() and test * add [seal2][unstable] weight_to_fee() + docs and test * add [seal2][unstable] gas_left() + docs and test * update benchmarks * add DefaultDepositLimit to pallet Config * specify deposit limit for nested call add test for nested call deposit limit save: separate deposit limit for nested calls * specify deposit limit for nested instantiate save: works with test cleaned up debugging outputs * update benchmarks * added missing fixtures * fix benches * pass explicit deposit limit to storage bench * explicit deposit limit for another set_storage bench * add more deposit limit for storage benches * moving to simplified benchmarks * moved to simplified benchmarks * fix seal_weight_to_fee bench * fix seal_instantiate benchmark * doc typo fix * default dl for benchmarking more dl for tests dl for tests to max deposit_limit fix in instantiate bench fix instantiate bench fix instantiate benchmark fix instantiate bench again remove dbg fix seal bench again fixing it still seal_instantiate zero deposit less runs to check if deposit enough try try 2 try 3 try 4 * max_runtime_mem to Schedule limits * add default deposit limit fallback check to test * weight params renaming * fmt * Update frame/contracts/src/benchmarking/mod.rs Co-authored-by: PG Herveou <[email protected]> * prettify inputs in tests * typestate param refactored --------- Co-authored-by: PG Herveou <[email protected]>
1 parent c4f425b commit af504bc

File tree

16 files changed

+948
-274
lines changed

16 files changed

+948
-274
lines changed

bin/node/runtime/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,7 @@ impl pallet_tips::Config for Runtime {
12151215
parameter_types! {
12161216
pub const DepositPerItem: Balance = deposit(1, 0);
12171217
pub const DepositPerByte: Balance = deposit(0, 1);
1218+
pub const DefaultDepositLimit: Balance = deposit(1024, 1024 * 1024);
12181219
pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
12191220
}
12201221

@@ -1233,6 +1234,7 @@ impl pallet_contracts::Config for Runtime {
12331234
type CallFilter = Nothing;
12341235
type DepositPerItem = DepositPerItem;
12351236
type DepositPerByte = DepositPerByte;
1237+
type DefaultDepositLimit = DefaultDepositLimit;
12361238
type CallStack = [pallet_contracts::Frame<Self>; 5];
12371239
type WeightPrice = pallet_transaction_payment::Pallet<Self>;
12381240
type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;

frame/contracts/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Contract Module
1+
# Contracts Module
22

3-
The Contract module provides functionality for the runtime to deploy and execute WebAssembly smart-contracts.
3+
The Contracts module provides functionality for the runtime to deploy and execute WebAssembly smart-contracts.
44

55
- [`Call`](https://paritytech.github.io/substrate/master/pallet_contracts/pallet/enum.Call.html)
66
- [`Config`](https://paritytech.github.io/substrate/master/pallet_contracts/pallet/trait.Config.html)
@@ -63,9 +63,9 @@ directly. This makes sure that by default `pallet-contracts` does not expose any
6363
When setting up the `Schedule` for your runtime make sure to set `InstructionWeights::fallback`
6464
to a non zero value. The default is `0` and prevents the upload of any non deterministic code.
6565

66-
An indeterministic code can be deployed on-chain by passing `Determinism::AllowIndeterministic`
66+
An indeterministic code can be deployed on-chain by passing `Determinism::Relaxed`
6767
to `upload_code`. A deterministic contract can then delegate call into it if and only if it
68-
is ran by using `bare_call` and passing `Determinism::AllowIndeterministic` to it. **Never use
68+
is ran by using `bare_call` and passing `Determinism::Relaxed` to it. **Never use
6969
this argument when the contract is called from an on-chain transaction.**
7070

7171
## Interface

frame/contracts/fixtures/call_with_limit.wat

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
;; This expects [account_id, gas_limit] as input and calls the account_id with the supplied gas_limit.
1+
;; This expects [account_id, ref_time, proof_size] as input and calls the account_id with the supplied 2D Weight limit.
22
;; It returns the result of the call as output data.
33
(module
44
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
5-
(import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32)))
5+
(import "seal2" "call" (func $seal_call (param i32 i32 i64 i64 i32 i32 i32 i32 i32 i32) (result i32)))
66
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
77
(import "env" "memory" (memory 1 1))
88

@@ -13,24 +13,25 @@
1313
(func (export "deploy"))
1414

1515
(func (export "call")
16-
;; Receive the encoded call + gas_limit
16+
;; Receive the encoded account_id, ref_time, proof_size
1717
(call $seal_input
1818
(i32.const 4) ;; Pointer to the input buffer
19-
(i32.const 0) ;; Size of the length buffer
19+
(i32.const 0) ;; Pointer to the length of the input buffer
2020
)
2121
(i32.store
2222
(i32.const 0)
2323
(call $seal_call
24+
(i32.const 0) ;; Set no flag.
2425
(i32.const 4) ;; Pointer to "callee" address.
25-
(i32.const 32) ;; Length of "callee" address.
26-
(i64.load (i32.const 36)) ;; How much gas to devote for the execution.
26+
(i64.load (i32.const 36)) ;; How much ref_time to devote for the execution.
27+
(i64.load (i32.const 44)) ;; How much proof_size to devote for the execution.
28+
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
2729
(i32.const 0) ;; Pointer to the buffer with value to transfer
28-
(i32.const 0) ;; Length of the buffer with value to transfer.
2930
(i32.const 0) ;; Pointer to input data buffer address
30-
(i32.const 0) ;; Length of input data buffer
31+
(i32.const 0) ;; Length of input data buffer
3132
(i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output
32-
(i32.const 0) ;; Ptr to output buffer len
33-
)
33+
(i32.const 0) ;; Length is ignored in this case
34+
)
3435
)
3536
(call $seal_return (i32.const 0) (i32.const 0) (i32.const 4))
3637
)

frame/contracts/fixtures/caller_contract.wat

Lines changed: 93 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
(module
22
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
33
(import "seal0" "seal_balance" (func $seal_balance (param i32 i32)))
4-
(import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32)))
5-
(import "seal0" "seal_instantiate" (func $seal_instantiate
6-
(param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32)
4+
(import "seal2" "call" (func $seal_call (param i32 i32 i64 i64 i32 i32 i32 i32 i32 i32) (result i32)))
5+
(import "seal2" "instantiate" (func $seal_instantiate
6+
(param i32 i64 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32)
77
))
88
(import "env" "memory" (memory 1 1))
99

@@ -43,18 +43,18 @@
4343
(set_local $exit_code
4444
(call $seal_instantiate
4545
(i32.const 24) ;; Pointer to the code hash.
46-
(i32.const 32) ;; Length of the code hash.
47-
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
46+
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
47+
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
48+
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
4849
(i32.const 0) ;; Pointer to the buffer with value to transfer
49-
(i32.const 8) ;; Length of the buffer with value to transfer.
5050
(i32.const 9) ;; Pointer to input data buffer address
5151
(i32.const 7) ;; Length of input data buffer
52-
(i32.const 4294967295) ;; u32 max sentinel value: do not copy address
53-
(i32.const 0) ;; Length is ignored in this case
52+
(i32.const 4294967295) ;; u32 max sentinel value: do not copy address
53+
(i32.const 0) ;; Length is ignored in this case
5454
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
55-
(i32.const 0) ;; Length is ignored in this case
56-
(i32.const 0) ;; salt_ptr
57-
(i32.const 0) ;; salt_le
55+
(i32.const 0) ;; Length is ignored in this case
56+
(i32.const 0) ;; salt_ptr
57+
(i32.const 0) ;; salt_le
5858
)
5959
)
6060

@@ -63,22 +63,47 @@
6363
(i32.eq (get_local $exit_code) (i32.const 2)) ;; ReturnCode::CalleeReverted
6464
)
6565

66-
;; Fail to deploy the contract due to insufficient gas.
66+
;; Fail to deploy the contract due to insufficient ref_time weight.
6767
(set_local $exit_code
6868
(call $seal_instantiate
6969
(i32.const 24) ;; Pointer to the code hash.
70-
(i32.const 32) ;; Length of the code hash.
71-
(i64.const 1) ;; Supply too little gas
70+
(i64.const 1) ;; Supply too little ref_time weight
71+
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
72+
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
7273
(i32.const 0) ;; Pointer to the buffer with value to transfer
73-
(i32.const 8) ;; Length of the buffer with value to transfer.
7474
(i32.const 8) ;; Pointer to input data buffer address
7575
(i32.const 8) ;; Length of input data buffer
7676
(i32.const 4294967295) ;; u32 max sentinel value: do not copy address
77-
(i32.const 0) ;; Length is ignored in this case
77+
(i32.const 0) ;; Length is ignored in this case
7878
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
79-
(i32.const 0) ;; Length is ignored in this case
80-
(i32.const 0) ;; salt_ptr
81-
(i32.const 0) ;; salt_le
79+
(i32.const 0) ;; Length is ignored in this case
80+
(i32.const 0) ;; salt_ptr
81+
(i32.const 0) ;; salt_le
82+
83+
)
84+
)
85+
86+
;; Check for special trap exit status.
87+
(call $assert
88+
(i32.eq (get_local $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped
89+
)
90+
91+
;; Fail to deploy the contract due to insufficient ref_time weight.
92+
(set_local $exit_code
93+
(call $seal_instantiate
94+
(i32.const 24) ;; Pointer to the code hash.
95+
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
96+
(i64.const 1) ;; Supply too little proof_size weight
97+
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
98+
(i32.const 0) ;; Pointer to the buffer with value to transfer
99+
(i32.const 8) ;; Pointer to input data buffer address
100+
(i32.const 8) ;; Length of input data buffer
101+
(i32.const 4294967295) ;; u32 max sentinel value: do not copy address
102+
(i32.const 0) ;; Length is ignored in this case
103+
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
104+
(i32.const 0) ;; Length is ignored in this case
105+
(i32.const 0) ;; salt_ptr
106+
(i32.const 0) ;; salt_le
82107

83108
)
84109
)
@@ -98,18 +123,18 @@
98123
(set_local $exit_code
99124
(call $seal_instantiate
100125
(i32.const 24) ;; Pointer to the code hash.
101-
(i32.const 32) ;; Length of the code hash.
102-
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
126+
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
127+
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
128+
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
103129
(i32.const 0) ;; Pointer to the buffer with value to transfer
104-
(i32.const 8) ;; Length of the buffer with value to transfer.
105130
(i32.const 8) ;; Pointer to input data buffer address
106131
(i32.const 8) ;; Length of input data buffer
107-
(i32.const 16) ;; Pointer to the address output buffer
108-
(i32.sub (get_local $sp) (i32.const 4)) ;; Pointer to the address buffer length
109-
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
110-
(i32.const 0) ;; Length is ignored in this case
111-
(i32.const 0) ;; salt_ptr
112-
(i32.const 0) ;; salt_le
132+
(i32.const 16) ;; Pointer to the address output buffer
133+
(i32.sub (get_local $sp) (i32.const 4)) ;; Pointer to the address buffer length
134+
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
135+
(i32.const 0) ;; Length is ignored in this case
136+
(i32.const 0) ;; salt_ptr
137+
(i32.const 0) ;; salt_le
113138

114139
)
115140
)
@@ -139,15 +164,16 @@
139164
;; Call the new contract and expect it to return failing exit code.
140165
(set_local $exit_code
141166
(call $seal_call
167+
(i32.const 0) ;; Set no flag
142168
(i32.const 16) ;; Pointer to "callee" address.
143-
(i32.const 32) ;; Length of "callee" address.
144-
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
169+
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
170+
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
171+
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
145172
(i32.const 0) ;; Pointer to the buffer with value to transfer
146-
(i32.const 8) ;; Length of the buffer with value to transfer.
147173
(i32.const 9) ;; Pointer to input data buffer address
148174
(i32.const 7) ;; Length of input data buffer
149-
(i32.sub (get_local $sp) (i32.const 4)) ;; Ptr to output buffer
150-
(i32.sub (get_local $sp) (i32.const 8)) ;; Ptr to output buffer len
175+
(i32.sub (get_local $sp) (i32.const 4)) ;; Ptr to output buffer
176+
(i32.sub (get_local $sp) (i32.const 8)) ;; Ptr to output buffer len
151177
)
152178
)
153179

@@ -167,18 +193,40 @@
167193
)
168194
)
169195

170-
;; Fail to call the contract due to insufficient gas.
196+
;; Fail to call the contract due to insufficient ref_time weight.
171197
(set_local $exit_code
172198
(call $seal_call
199+
(i32.const 0) ;; Set no flag
173200
(i32.const 16) ;; Pointer to "callee" address.
174-
(i32.const 32) ;; Length of "callee" address.
175-
(i64.const 1) ;; Supply too little gas
201+
(i64.const 1) ;; Supply too little ref_time weight
202+
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
203+
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
176204
(i32.const 0) ;; Pointer to the buffer with value to transfer
177-
(i32.const 8) ;; Length of the buffer with value to transfer.
178205
(i32.const 8) ;; Pointer to input data buffer address
179206
(i32.const 8) ;; Length of input data buffer
180-
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
181-
(i32.const 0) ;; Length is ignored in this cas
207+
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
208+
(i32.const 0) ;; Length is ignored in this cas
209+
)
210+
)
211+
212+
;; Check for special trap exit status.
213+
(call $assert
214+
(i32.eq (get_local $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped
215+
)
216+
217+
;; Fail to call the contract due to insufficient proof_size weight.
218+
(set_local $exit_code
219+
(call $seal_call
220+
(i32.const 0) ;; Set no flag
221+
(i32.const 16) ;; Pointer to "callee" address.
222+
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
223+
(i64.const 1) ;; Supply too little proof_size weight
224+
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
225+
(i32.const 0) ;; Pointer to the buffer with value to transfer
226+
(i32.const 8) ;; Pointer to input data buffer address
227+
(i32.const 8) ;; Length of input data buffer
228+
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
229+
(i32.const 0) ;; Length is ignored in this cas
182230
)
183231
)
184232

@@ -202,15 +250,16 @@
202250
;; Call the contract successfully.
203251
(set_local $exit_code
204252
(call $seal_call
253+
(i32.const 0) ;; Set no flag
205254
(i32.const 16) ;; Pointer to "callee" address.
206-
(i32.const 32) ;; Length of "callee" address.
207-
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
255+
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
256+
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
257+
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
208258
(i32.const 0) ;; Pointer to the buffer with value to transfer
209-
(i32.const 8) ;; Length of the buffer with value to transfer.
210259
(i32.const 8) ;; Pointer to input data buffer address
211260
(i32.const 8) ;; Length of input data buffer
212-
(i32.sub (get_local $sp) (i32.const 4)) ;; Ptr to output buffer
213-
(i32.sub (get_local $sp) (i32.const 8)) ;; Ptr to output buffer len
261+
(i32.sub (get_local $sp) (i32.const 4)) ;; Ptr to output buffer
262+
(i32.sub (get_local $sp) (i32.const 8)) ;; Ptr to output buffer len
214263
)
215264
)
216265

frame/contracts/fixtures/create_storage_and_call.wat

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
(module
33
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
44
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
5-
(import "seal1" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32) (result i32)))
5+
(import "seal2" "call" (func $seal_call (param i32 i32 i64 i64 i32 i32 i32 i32 i32 i32) (result i32)))
66
(import "env" "memory" (memory 1 1))
77

88
(func $assert (param i32)
@@ -20,7 +20,10 @@
2020
;; store length of input buffer
2121
(i32.store (i32.const 0) (i32.const 512))
2222

23-
;; copy input at address 4
23+
;; copy input at address 4:
24+
;; first 4 bytes for the size of the storage to be created in callee
25+
;; next 32 bytes are for the callee address
26+
;; next bytes for the encoded deposit limit
2427
(call $seal_input (i32.const 4) (i32.const 0))
2528

2629
;; create 4 byte of storage before calling
@@ -34,8 +37,10 @@
3437
(call $assert (i32.eqz
3538
(call $seal_call
3639
(i32.const 0) ;; No flags
37-
(i32.const 8) ;; Pointer to "callee" address.
38-
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
40+
(i32.const 8) ;; Pointer to "callee" address
41+
(i64.const 0) ;; How much ref_time to devote for the execution. 0 = all
42+
(i64.const 0) ;; How much proof_limit to devote for the execution. 0 = all
43+
(i32.const 40) ;; Pointer to the storage deposit limit
3944
(i32.const 512) ;; Pointer to the buffer with value to transfer
4045
(i32.const 4) ;; Pointer to input data buffer address
4146
(i32.const 4) ;; Length of input data buffer
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
;; This instantiates another contract and passes some input to its constructor.
2+
(module
3+
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
4+
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
5+
(import "seal2" "instantiate" (func $seal_instantiate
6+
(param i32 i64 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32)
7+
))
8+
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
9+
(import "env" "memory" (memory 1 1))
10+
11+
;; [0, 8) send 10_000 balance
12+
(data (i32.const 48) "\10\27\00\00\00\00\00\00")
13+
14+
(func $assert (param i32)
15+
(block $ok
16+
(br_if $ok
17+
(get_local 0)
18+
)
19+
(unreachable)
20+
)
21+
)
22+
23+
(func (export "deploy"))
24+
25+
(func (export "call")
26+
;; store length of input buffer
27+
(i32.store (i32.const 0) (i32.const 512))
28+
;; store length of contract address
29+
(i32.store (i32.const 84) (i32.const 32))
30+
31+
;; copy input at address 4
32+
(call $seal_input (i32.const 4) (i32.const 0))
33+
34+
;; memory layout is:
35+
;; [0,4): size of input buffer
36+
;; [4,8): size of the storage to be created in callee
37+
;; [8,40): the code hash of the contract to instantiate
38+
;; [40,48): for the encoded deposit limit
39+
;; [48,52): value to transfer
40+
;; [52,84): address of the deployed contract
41+
;; [84,88): len of the address
42+
43+
;; instantiate a contract
44+
(call $assert (i32.eqz
45+
;; (i32.store
46+
;; (i32.const 64)
47+
(call $seal_instantiate
48+
(i32.const 8) ;; Pointer to the code hash.
49+
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
50+
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
51+
(i32.const 40) ;; Pointer to the storage deposit limit
52+
(i32.const 48) ;; Pointer to the buffer with value to transfer
53+
(i32.const 4) ;; Pointer to input data buffer address
54+
(i32.const 4) ;; Length of input data buffer
55+
(i32.const 52) ;; Pointer to where to copy address
56+
(i32.const 84) ;; Pointer to address len ptr
57+
(i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output
58+
(i32.const 0) ;; Length is ignored in this case
59+
(i32.const 0) ;; salt_ptr
60+
(i32.const 0) ;; salt_len
61+
)
62+
))
63+
;; return the deployed contract address
64+
(call $seal_return (i32.const 0) (i32.const 52) (i32.const 32))
65+
)
66+
)
File renamed without changes.

0 commit comments

Comments
 (0)