|
1 | 1 | (module
|
2 |
| - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) |
3 |
| - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) |
4 |
| - (import "env" "ext_balance" (func $ext_balance)) |
5 |
| - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) |
6 |
| - (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) |
| 2 | + (import "env" "ext_input" (func $ext_input (param i32 i32))) |
| 3 | + (import "env" "ext_balance" (func $ext_balance (param i32 i32))) |
| 4 | + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) |
| 5 | + (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) |
7 | 6 | (import "env" "ext_println" (func $ext_println (param i32 i32)))
|
8 | 7 | (import "env" "memory" (memory 1 1))
|
9 | 8 |
|
|
17 | 16 | )
|
18 | 17 |
|
19 | 18 | (func $current_balance (param $sp i32) (result i64)
|
20 |
| - (call $ext_balance) |
21 |
| - (call $assert |
22 |
| - (i32.eq (call $ext_scratch_size) (i32.const 8)) |
| 19 | + (i32.store |
| 20 | + (i32.sub (get_local $sp) (i32.const 16)) |
| 21 | + (i32.const 8) |
23 | 22 | )
|
24 |
| - (call $ext_scratch_read |
| 23 | + (call $ext_balance |
25 | 24 | (i32.sub (get_local $sp) (i32.const 8))
|
26 |
| - (i32.const 0) |
27 |
| - (i32.const 8) |
| 25 | + (i32.sub (get_local $sp) (i32.const 16)) |
| 26 | + ) |
| 27 | + (call $assert |
| 28 | + (i32.eq (i32.load (i32.sub (get_local $sp) (i32.const 16))) (i32.const 8)) |
28 | 29 | )
|
29 | 30 | (i64.load (i32.sub (get_local $sp) (i32.const 8)))
|
30 | 31 | )
|
|
36 | 37 | (local $exit_code i32)
|
37 | 38 | (local $balance i64)
|
38 | 39 |
|
| 40 | + ;; Length of the buffer |
| 41 | + (i32.store (i32.const 20) (i32.const 32)) |
| 42 | + |
| 43 | + ;; Copy input to this contracts memory |
| 44 | + (call $ext_input (i32.const 24) (i32.const 20)) |
| 45 | + |
39 | 46 | ;; Input data is the code hash of the contract to be deployed.
|
40 | 47 | (call $assert
|
41 | 48 | (i32.eq
|
42 |
| - (call $ext_scratch_size) |
| 49 | + (i32.load (i32.const 20)) |
43 | 50 | (i32.const 32)
|
44 | 51 | )
|
45 | 52 | )
|
46 | 53 |
|
47 |
| - ;; Copy code hash from scratch buffer into this contract's memory. |
48 |
| - (call $ext_scratch_read |
49 |
| - (i32.const 24) ;; The pointer where to store the scratch buffer contents, |
50 |
| - (i32.const 0) ;; Offset from the start of the scratch buffer. |
51 |
| - (i32.const 32) ;; Count of bytes to copy. |
52 |
| - ) |
53 |
| - |
54 | 54 | ;; Read current balance into local variable.
|
55 | 55 | (set_local $sp (i32.const 1024))
|
56 | 56 | (set_local $balance
|
|
67 | 67 | (i32.const 8) ;; Length of the buffer with value to transfer.
|
68 | 68 | (i32.const 9) ;; Pointer to input data buffer address
|
69 | 69 | (i32.const 7) ;; Length of input data buffer
|
| 70 | + (i32.const 4294967295) ;; u32 max sentinel value: do not copy address |
| 71 | + (i32.const 0) ;; Length is ignored in this case |
| 72 | + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output |
| 73 | + (i32.const 0) ;; Length is ignored in this case |
70 | 74 | )
|
71 | 75 | )
|
72 | 76 |
|
73 | 77 | ;; Check non-zero exit status.
|
74 | 78 | (call $assert
|
75 |
| - (i32.eq (get_local $exit_code) (i32.const 0x11)) |
76 |
| - ) |
77 |
| - |
78 |
| - ;; Check that scratch buffer is empty since contract instantiation failed. |
79 |
| - (call $assert |
80 |
| - (i32.eq (call $ext_scratch_size) (i32.const 0)) |
| 79 | + (i32.eq (get_local $exit_code) (i32.const 2)) ;; ReturnCode::CalleeReverted |
81 | 80 | )
|
82 | 81 |
|
83 | 82 | ;; Check that balance has not changed.
|
|
95 | 94 | (i32.const 8) ;; Length of the buffer with value to transfer.
|
96 | 95 | (i32.const 8) ;; Pointer to input data buffer address
|
97 | 96 | (i32.const 8) ;; Length of input data buffer
|
| 97 | + (i32.const 4294967295) ;; u32 max sentinel value: do not copy address |
| 98 | + (i32.const 0) ;; Length is ignored in this case |
| 99 | + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output |
| 100 | + (i32.const 0) ;; Length is ignored in this case |
98 | 101 | )
|
99 | 102 | )
|
100 | 103 |
|
101 | 104 | ;; Check for special trap exit status.
|
102 | 105 | (call $assert
|
103 |
| - (i32.eq (get_local $exit_code) (i32.const 0x0100)) |
104 |
| - ) |
105 |
| - |
106 |
| - ;; Check that scratch buffer is empty since contract instantiation failed. |
107 |
| - (call $assert |
108 |
| - (i32.eq (call $ext_scratch_size) (i32.const 0)) |
| 106 | + (i32.eq (get_local $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped |
109 | 107 | )
|
110 | 108 |
|
111 | 109 | ;; Check that balance has not changed.
|
112 | 110 | (call $assert
|
113 | 111 | (i64.eq (get_local $balance) (call $current_balance (get_local $sp)))
|
114 | 112 | )
|
115 | 113 |
|
| 114 | + ;; Length of the output buffer |
| 115 | + (i32.store |
| 116 | + (i32.sub (get_local $sp) (i32.const 4)) |
| 117 | + (i32.const 8) |
| 118 | + ) |
| 119 | + |
116 | 120 | ;; Deploy the contract successfully.
|
117 | 121 | (set_local $exit_code
|
118 | 122 | (call $ext_instantiate
|
|
123 | 127 | (i32.const 8) ;; Length of the buffer with value to transfer.
|
124 | 128 | (i32.const 8) ;; Pointer to input data buffer address
|
125 | 129 | (i32.const 8) ;; Length of input data buffer
|
| 130 | + (i32.const 16) ;; Pointer to the address output buffer |
| 131 | + (i32.sub (get_local $sp) (i32.const 4)) ;; Pointer to the address buffer length |
| 132 | + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output |
| 133 | + (i32.const 0) ;; Length is ignored in this case |
| 134 | + |
126 | 135 | )
|
127 | 136 | )
|
128 | 137 |
|
129 | 138 | ;; Check for success exit status.
|
130 | 139 | (call $assert
|
131 |
| - (i32.eq (get_local $exit_code) (i32.const 0x00)) |
| 140 | + (i32.eq (get_local $exit_code) (i32.const 0)) ;; ReturnCode::Success |
132 | 141 | )
|
133 | 142 |
|
134 |
| - ;; Check that scratch buffer contains the address of the new contract. |
| 143 | + ;; Check that address has the expected length |
135 | 144 | (call $assert
|
136 |
| - (i32.eq (call $ext_scratch_size) (i32.const 8)) |
137 |
| - ) |
138 |
| - |
139 |
| - ;; Copy contract address from scratch buffer into this contract's memory. |
140 |
| - (call $ext_scratch_read |
141 |
| - (i32.const 16) ;; The pointer where to store the scratch buffer contents, |
142 |
| - (i32.const 0) ;; Offset from the start of the scratch buffer. |
143 |
| - (i32.const 8) ;; Count of bytes to copy. |
| 145 | + (i32.eq (i32.load (i32.sub (get_local $sp) (i32.const 4))) (i32.const 8)) |
144 | 146 | )
|
145 | 147 |
|
146 | 148 | ;; Check that balance has been deducted.
|
|
151 | 153 | (i64.eq (get_local $balance) (call $current_balance (get_local $sp)))
|
152 | 154 | )
|
153 | 155 |
|
| 156 | + ;; Zero out destination buffer of output |
| 157 | + (i32.store |
| 158 | + (i32.sub (get_local $sp) (i32.const 4)) |
| 159 | + (i32.const 0) |
| 160 | + ) |
| 161 | + |
| 162 | + ;; Length of the output buffer |
| 163 | + (i32.store |
| 164 | + (i32.sub (get_local $sp) (i32.const 8)) |
| 165 | + (i32.const 4) |
| 166 | + ) |
| 167 | + |
154 | 168 | ;; Call the new contract and expect it to return failing exit code.
|
155 | 169 | (set_local $exit_code
|
156 | 170 | (call $ext_call
|
|
161 | 175 | (i32.const 8) ;; Length of the buffer with value to transfer.
|
162 | 176 | (i32.const 9) ;; Pointer to input data buffer address
|
163 | 177 | (i32.const 7) ;; Length of input data buffer
|
| 178 | + (i32.sub (get_local $sp) (i32.const 4)) ;; Ptr to output buffer |
| 179 | + (i32.sub (get_local $sp) (i32.const 8)) ;; Ptr to output buffer len |
164 | 180 | )
|
165 | 181 | )
|
166 | 182 |
|
167 | 183 | ;; Check non-zero exit status.
|
168 | 184 | (call $assert
|
169 |
| - (i32.eq (get_local $exit_code) (i32.const 0x11)) |
| 185 | + (i32.eq (get_local $exit_code) (i32.const 2)) ;; ReturnCode::CalleeReverted |
170 | 186 | )
|
171 | 187 |
|
172 |
| - ;; Check that scratch buffer contains the expected return data. |
| 188 | + ;; Check that output buffer contains the expected return data. |
173 | 189 | (call $assert
|
174 |
| - (i32.eq (call $ext_scratch_size) (i32.const 3)) |
175 |
| - ) |
176 |
| - (i32.store |
177 |
| - (i32.sub (get_local $sp) (i32.const 4)) |
178 |
| - (i32.const 0) |
179 |
| - ) |
180 |
| - (call $ext_scratch_read |
181 |
| - (i32.sub (get_local $sp) (i32.const 4)) |
182 |
| - (i32.const 0) |
183 |
| - (i32.const 3) |
| 190 | + (i32.eq (i32.load (i32.sub (get_local $sp) (i32.const 8))) (i32.const 3)) |
184 | 191 | )
|
185 | 192 | (call $assert
|
186 | 193 | (i32.eq
|
|
204 | 211 | (i32.const 8) ;; Length of the buffer with value to transfer.
|
205 | 212 | (i32.const 8) ;; Pointer to input data buffer address
|
206 | 213 | (i32.const 8) ;; Length of input data buffer
|
| 214 | + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output |
| 215 | + (i32.const 0) ;; Length is ignored in this cas |
207 | 216 | )
|
208 | 217 | )
|
209 | 218 |
|
210 | 219 | ;; Check for special trap exit status.
|
211 | 220 | (call $assert
|
212 |
| - (i32.eq (get_local $exit_code) (i32.const 0x0100)) |
213 |
| - ) |
214 |
| - |
215 |
| - ;; Check that scratch buffer is empty since call trapped. |
216 |
| - (call $assert |
217 |
| - (i32.eq (call $ext_scratch_size) (i32.const 0)) |
| 221 | + (i32.eq (get_local $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped |
218 | 222 | )
|
219 | 223 |
|
220 | 224 | ;; Check that balance has not changed.
|
221 | 225 | (call $assert
|
222 | 226 | (i64.eq (get_local $balance) (call $current_balance (get_local $sp)))
|
223 | 227 | )
|
224 | 228 |
|
| 229 | + ;; Zero out destination buffer of output |
| 230 | + (i32.store |
| 231 | + (i32.sub (get_local $sp) (i32.const 4)) |
| 232 | + (i32.const 0) |
| 233 | + ) |
| 234 | + |
| 235 | + ;; Length of the output buffer |
| 236 | + (i32.store |
| 237 | + (i32.sub (get_local $sp) (i32.const 8)) |
| 238 | + (i32.const 4) |
| 239 | + ) |
| 240 | + |
225 | 241 | ;; Call the contract successfully.
|
226 | 242 | (set_local $exit_code
|
227 | 243 | (call $ext_call
|
|
232 | 248 | (i32.const 8) ;; Length of the buffer with value to transfer.
|
233 | 249 | (i32.const 8) ;; Pointer to input data buffer address
|
234 | 250 | (i32.const 8) ;; Length of input data buffer
|
| 251 | + (i32.sub (get_local $sp) (i32.const 4)) ;; Ptr to output buffer |
| 252 | + (i32.sub (get_local $sp) (i32.const 8)) ;; Ptr to output buffer len |
235 | 253 | )
|
236 | 254 | )
|
237 | 255 |
|
238 | 256 | ;; Check for success exit status.
|
239 | 257 | (call $assert
|
240 |
| - (i32.eq (get_local $exit_code) (i32.const 0x00)) |
| 258 | + (i32.eq (get_local $exit_code) (i32.const 0)) ;; ReturnCode::Success |
241 | 259 | )
|
242 | 260 |
|
243 |
| - ;; Check that scratch buffer contains the expected return data. |
| 261 | + ;; Check that the output buffer contains the expected return data. |
244 | 262 | (call $assert
|
245 |
| - (i32.eq (call $ext_scratch_size) (i32.const 4)) |
246 |
| - ) |
247 |
| - (i32.store |
248 |
| - (i32.sub (get_local $sp) (i32.const 4)) |
249 |
| - (i32.const 0) |
250 |
| - ) |
251 |
| - (call $ext_scratch_read |
252 |
| - (i32.sub (get_local $sp) (i32.const 4)) |
253 |
| - (i32.const 0) |
254 |
| - (i32.const 4) |
| 263 | + (i32.eq (i32.load (i32.sub (get_local $sp) (i32.const 8))) (i32.const 4)) |
255 | 264 | )
|
256 | 265 | (call $assert
|
257 | 266 | (i32.eq
|
|
271 | 280 |
|
272 | 281 | (data (i32.const 0) "\00\80") ;; The value to transfer on instantiation and calls.
|
273 | 282 | ;; Chosen to be greater than existential deposit.
|
274 |
| - (data (i32.const 8) "\00\11\22\33\44\55\66\77") ;; The input data to instantiations and calls. |
| 283 | + (data (i32.const 8) "\00\01\22\33\44\55\66\77") ;; The input data to instantiations and calls. |
275 | 284 | )
|
0 commit comments