-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Upgradable contracts using set_code function
#10690
Changes from 10 commits
b1dd3d7
3d525a2
4eb26af
0120c35
0a8b745
49250c5
a4c479c
e36d5e5
a5a3ec8
01987ea
a6f3f44
516d29a
759dcc1
d6a1445
f8f708c
12c91d8
15e3901
08f67ea
3bc8008
c6f1645
9d190a5
3e2a1a4
ae5b1a4
168dc95
5e79310
e96341e
6f925a9
7a64c0c
b8e5314
33e7075
b5d25a0
b32e4ec
769a3f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| (module | ||
| (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) | ||
| (import "env" "memory" (memory 1 1)) | ||
|
|
||
| ;; [0, 32) return value | ||
| (data (i32.const 0) "\02") | ||
|
|
||
| (func (export "deploy")) | ||
|
|
||
| (func (export "call") | ||
| (call $seal_return (i32.const 0) (i32.const 0) (i32.const 4)) | ||
| ) | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| (module | ||
| (import "seal0" "seal_input" (func $seal_input (param i32 i32))) | ||
| (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) | ||
| (import "__unstable__" "seal_set_code_hash" (func $seal_set_code_hash (param i32) (result i32))) | ||
|
|
||
| (import "env" "memory" (memory 1 1)) | ||
|
|
||
| ;; [0, 32) here we store input | ||
|
|
||
| ;; [32, 36) input size | ||
| (data (i32.const 32) "\20") | ||
|
|
||
| ;; [36, 40) return value | ||
| (data (i32.const 36) "\01") | ||
|
|
||
| (func $assert (param i32) | ||
| (block $ok | ||
| (br_if $ok | ||
| (get_local 0) | ||
| ) | ||
| (unreachable) | ||
| ) | ||
| ) | ||
|
|
||
| (func (export "call") | ||
| (local $exit_code i32) | ||
|
|
||
| (call $seal_input (i32.const 0) (i32.const 32)) | ||
|
|
||
| (set_local $exit_code | ||
| (call $seal_set_code_hash (i32.const 0)) ;; Pointer to the input data. | ||
| ) | ||
| (call $assert | ||
| (i32.eq (get_local $exit_code) (i32.const 0)) ;; ReturnCode::Success | ||
| ) | ||
|
|
||
| ;; we return 1 after setting new code_hash | ||
| ;; next `call` will NOT return this value, because contract code has been changed | ||
| (call $seal_return (i32.const 0) (i32.const 36) (i32.const 4)) | ||
| ) | ||
|
|
||
| (func (export "deploy")) | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -808,6 +808,47 @@ benchmarks! { | |
| let origin = RawOrigin::Signed(instance.caller.clone()); | ||
| }: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![]) | ||
|
|
||
| #[skip_meta] | ||
| seal_set_code_hash { | ||
| let r in 0 .. API_BENCHMARK_BATCHES; | ||
| let code_hashes = (0..r * API_BENCHMARK_BATCH_SIZE) | ||
| .map(|i| { | ||
| let new_code = WasmModule::<T>::dummy_with_bytes(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_hashes_len = code_hashes_bytes.len(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unused variable.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Easy to miss things here. Do you have any special tricks or setup for working with this macro?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope. Just reading the code. I think the benchmarking macro will become a attribute macro eventually. |
||
|
|
||
| let code = WasmModule::<T>::from(ModuleDefinition { | ||
| memory: Some(ImportedMemory::max::<T>()), | ||
| imported_functions: vec![ImportedFunction { | ||
| module: "__unstable__", | ||
| name: "seal_set_code_hash", | ||
| params: vec![ | ||
| ValueType::I32, | ||
| ], | ||
| return_type: Some(ValueType::I32), | ||
| }], | ||
| data_segments: vec![ | ||
| DataSegment { | ||
| offset: 0 as u32, | ||
|
yarikbratashchuk marked this conversation as resolved.
Outdated
|
||
| value: code_hashes_bytes, | ||
| }, | ||
| ], | ||
| call_body: Some(body::repeated_dyn(r * API_BENCHMARK_BATCH_SIZE, vec![ | ||
| Counter(0 as u32, code_hash_len as u32), // code_hash_ptr | ||
|
yarikbratashchuk marked this conversation as resolved.
Outdated
|
||
| Regular(Instruction::Call(0)), | ||
| Regular(Instruction::Drop), | ||
| ])), | ||
| .. 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![]) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a verify block that checks whether the contracts were really switched to the new code hash. |
||
|
|
||
| seal_set_storage_per_kb { | ||
| let n in 0 .. T::Schedule::get().limits.payload_len / 1024; | ||
| let key = T::Hashing::hash_of(&1u32).as_ref().to_vec(); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.