forked from paritytech/substrate
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
seal_delegate_call
api function (support for library contracts) (pa…
…ritytech#10617) * seal_call_code implementation - tests - benchmark * Addressing @xgreenx's comments * Fix test-linux-stable-int * Rename seal_call_code to seal_delegate_call * Pass value unchanged into lib contract * Address @athei's comments - whitespace .wat issues - wrong/missing .wat comments - redundant .wat calls/declarations - change order of functions (seal_delegate_call right after seal_call) in decls, tests, benchmark - fix comments, move doc comments to enum variants - remove unnecessary empty lines - rename runtime cost DelegateCall to DelegateCallBase - do not set CallFlags::ALLOW_REENTRY for delegate_call * Do not pass CallFlags::ALLOWS_REENTRY for delegate_call * Update comment for seal_delegate_call and CallFlags * Addressing @athei's comments (minor) * Allow reentry for a new frame after delegate_call (revert) * Same seal_caller and seal_value_transferred for lib contract - test - refactor frame args due to review - logic for seal_caller (please review) * Put caller on frame for delegate_call, minor fixes * Update comment for delegate_call * Addressing @athei's comments * Update weights generated by benchmark * Improve comments * Address @HCastano's comments * Update weights, thanks @joao-paulo-parity * Improve InvalidCallFlags error comment
- Loading branch information
1 parent
20a8ff6
commit ce7e6c9
Showing
10 changed files
with
576 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
(module | ||
(import "seal0" "seal_input" (func $seal_input (param i32 i32))) | ||
(import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32))) | ||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) | ||
(import "__unstable__" "seal_delegate_call" (func $seal_delegate_call (param i32 i32 i32 i32 i32 i32) (result i32))) | ||
(import "env" "memory" (memory 3 3)) | ||
|
||
;; [0, 32) storage key | ||
(data (i32.const 0) "\01") | ||
|
||
;; [32, 64) storage key | ||
(data (i32.const 32) "\02") | ||
|
||
;; [64, 96) buffer where input is copied | ||
|
||
;; [96, 100) size of the input buffer | ||
(data (i32.const 96) "\20") | ||
|
||
;; [100, 104) size of buffer for seal_get_storage | ||
(data (i32.const 100) "\20") | ||
|
||
;; [104, 136) seal_get_storage buffer | ||
|
||
(func $assert (param i32) | ||
(block $ok | ||
(br_if $ok | ||
(get_local 0) | ||
) | ||
(unreachable) | ||
) | ||
) | ||
|
||
(func (export "call") | ||
(local $exit_code i32) | ||
|
||
;; Reading "callee" code_hash | ||
(call $seal_input (i32.const 64) (i32.const 96)) | ||
|
||
;; assert input size == 32 | ||
(call $assert | ||
(i32.eq | ||
(i32.load (i32.const 96)) | ||
(i32.const 32) | ||
) | ||
) | ||
|
||
;; place a value in storage, the size of which is specified by the call input. | ||
(call $seal_set_storage | ||
(i32.const 0) ;; Pointer to storage key | ||
(i32.const 32) ;; Pointer to initial value | ||
(i32.load (i32.const 100)) ;; Size of value | ||
) | ||
|
||
(call $assert | ||
(i32.eq | ||
(call $seal_get_storage | ||
(i32.const 0) ;; Pointer to storage key | ||
(i32.const 104) ;; buffer where to copy result | ||
(i32.const 100) ;; pointer to size of buffer | ||
) | ||
(i32.const 0) ;; ReturnCode::Success | ||
) | ||
) | ||
|
||
(call $assert | ||
(i32.eq | ||
(i32.load (i32.const 104)) ;; value received from storage | ||
(i32.load (i32.const 32)) ;; initial value | ||
) | ||
) | ||
|
||
;; Call deployed library contract code. | ||
(set_local $exit_code | ||
(call $seal_delegate_call | ||
(i32.const 0) ;; Set no call flags | ||
(i32.const 64) ;; 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 | ||
) | ||
) | ||
|
||
;; Check for success exit status. | ||
(call $assert | ||
(i32.eq (get_local $exit_code) (i32.const 0)) ;; ReturnCode::Success | ||
) | ||
|
||
(call $assert | ||
(i32.eq | ||
(call $seal_get_storage | ||
(i32.const 0) ;; Pointer to storage key | ||
(i32.const 104) ;; buffer where to copy result | ||
(i32.const 100) ;; pointer to size of buffer | ||
) | ||
(i32.const 0) ;; ReturnCode::Success | ||
) | ||
) | ||
|
||
;; Make sure that 'callee' code changed the value | ||
(call $assert | ||
(i32.eq | ||
(i32.load (i32.const 104)) | ||
(i32.const 1) | ||
) | ||
) | ||
) | ||
|
||
(func (export "deploy")) | ||
|
||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
(module | ||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) | ||
(import "seal0" "seal_caller" (func $seal_caller (param i32 i32))) | ||
(import "seal0" "seal_value_transferred" (func $seal_value_transferred (param i32 i32))) | ||
(import "env" "memory" (memory 1 1)) | ||
|
||
;; [0, 32) storage key | ||
(data (i32.const 0) "\01") | ||
|
||
;; [32, 64) buffer for transferred value | ||
|
||
;; [64, 96) size of the buffer for transferred value | ||
(data (i32.const 64) "\20") | ||
|
||
;; [96, 128) buffer for the caller | ||
|
||
;; [128, 160) size of the buffer for caller | ||
(data (i32.const 128) "\20") | ||
|
||
(func $assert (param i32) | ||
(block $ok | ||
(br_if $ok | ||
(get_local 0) | ||
) | ||
(unreachable) | ||
) | ||
) | ||
|
||
(func (export "call") | ||
;; place a value in storage | ||
(call $seal_set_storage | ||
(i32.const 0) ;; Pointer to storage key | ||
(i32.const 0) ;; Pointer to value | ||
(i32.const 32) ;; Size of value | ||
) | ||
|
||
;; This stores the value transferred in the buffer | ||
(call $seal_value_transferred (i32.const 32) (i32.const 64)) | ||
|
||
;; assert len == 8 | ||
(call $assert | ||
(i32.eq | ||
(i32.load (i32.const 64)) | ||
(i32.const 8) | ||
) | ||
) | ||
|
||
;; assert that contents of the buffer is equal to the value | ||
;; passed to the `caller` contract: 1337 | ||
(call $assert | ||
(i64.eq | ||
(i64.load (i32.const 32)) | ||
(i64.const 1337) | ||
) | ||
) | ||
|
||
;; fill the buffer with the caller. | ||
(call $seal_caller (i32.const 96) (i32.const 128)) | ||
|
||
;; assert len == 32 | ||
(call $assert | ||
(i32.eq | ||
(i32.load (i32.const 128)) | ||
(i32.const 32) | ||
) | ||
) | ||
|
||
;; assert that the first 64 byte are the beginning of "ALICE", | ||
;; who is the caller of the `caller` contract | ||
(call $assert | ||
(i64.eq | ||
(i64.load (i32.const 96)) | ||
(i64.const 0x0101010101010101) | ||
) | ||
) | ||
) | ||
|
||
(func (export "deploy")) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.