Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_vm_syscall_fd_vm_syscall_h
2 : #define HEADER_fd_src_flamenco_vm_syscall_fd_vm_syscall_h
3 :
4 : #include "../fd_vm_private.h"
5 : #include "fd_vm_syscall_macros.h"
6 : #include "fd_vm_cpi.h" /* FIXME: REFINE THIS MORE */
7 : #include "../../runtime/fd_runtime.h" /* FIXME: REFINE THIS MORE */
8 : #include "../../runtime/context/fd_exec_instr_ctx.h"
9 : #include "../../log_collector/fd_log_collector.h"
10 :
11 : #define FD_VM_RETURN_DATA_MAX (1024UL) /* FIXME: DOCUMENT AND DOES THIS BELONG HERE? */
12 :
13 : /* The maximum number of seeds a PDA can have
14 : https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/sdk/program/src/pubkey.rs#L21 */
15 : #define FD_VM_PDA_SEEDS_MAX (16UL)
16 : /* The maximum length of a PDA seed
17 : https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/sdk/program/src/pubkey.rs#L19 */
18 : #define FD_VM_PDA_SEED_MEM_MAX (32UL)
19 :
20 : /* PYTHON3 CODE FOR COMPUTING THE SYSCALL MURMUR3 HASH (e.g. sol_get_epoch_stake):
21 : ```
22 : import mmh3
23 : import ctypes
24 :
25 : def compute_murmur3_hash(input_string):
26 : # Compute the Murmur3 hash of the input string
27 : hash_value = mmh3.hash(input_string)
28 : # Convert the hash value to a 32-bit unsigned integer
29 : u32_hash_value = ctypes.c_uint32(hash_value).value
30 : return u32_hash_value
31 :
32 : input_string = b"sol_get_epoch_stake"
33 : hash_value = compute_murmur3_hash(input_string)
34 : print(f"The Murmur3 hash of '{input_string}' as u32 is: {hex(hash_value)}")
35 :
36 : Output:
37 : The Murmur3 hash of 'b'sol_get_epoch_stake'' as u32 is: 0x5be92f4a
38 : ```
39 : */
40 :
41 : /* https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/sdk/program/src/pubkey.rs#L22 */
42 :
43 : /* FIXME: CONSIDER NOT PREFIXING SYSCALLS WITH SOL_? (OR MAYBE THIS
44 : IS NECESSARY TO DISAMBIGUATE SOLANA SYSCALLS FROM NON-SOLANA?
45 : SYSCALLS? */
46 :
47 : /* FD_VM_SYSCALL_DECL declares a prototype of a syscall. When a
48 : syscall implementation is called, the syscall will see a precise
49 : reporting VM's state at time of the syscall. Notably:
50 :
51 : - vm->pc will be at the syscall instruction
52 : - vm->ic will include the syscall instruction
53 : - vm->cu will include the 1 cu cost of the syscall instruction.
54 : Further, it will be positive.
55 :
56 : r1,r2,r3,r4,r5 are the values in r1,r2,r3,r4,r5 at time of the
57 : syscall.
58 :
59 : When a syscall implementation returns FD_VM_SUCCESS, *_r0 should hold
60 : the application return error value it wants to place in r0.
61 :
62 : When an syscall implementation returns FD_VM_SYSCALL_ERR*, the syscall is
63 : considered to have faulted the VM. It ideally should not have set
64 : *_r0 (or changed any vm state, except vm->cu, though that often isn't
65 : practical).
66 :
67 : It is the syscall's responsibility to deduct from vm->cu its specific
68 : cost model (not including the syscall instruction itself). As such,
69 : when a syscall returns COMPUTE_BUDGET_EXCEEDED, it should have set
70 : vm->cu to zero. When it returns anything else, it should have set cu
71 : to something in [1,cu_at_function_entry].
72 :
73 : To mitigate risks of from syscall implementations that do not
74 : strictly enforce this and other similar risks that can affect
75 : bookkeeping, on return from a syscall, the VM will:
76 :
77 : - Ignore updates to pc, ic and frame_cnt.
78 : - Ignore updates to cu that increase it.
79 : - Treat updates to cu that zero it as SIGCOST.
80 : - Treat SIGCOST returns that didn't update cu to zero as zeroing it.
81 :
82 : FIXME: ADD NO SETTING OF R0 ON VM_ERR IN VM_INTERP. */
83 :
84 : #define FD_VM_SYSCALL_DECL(name) \
85 : int \
86 : fd_vm_syscall_##name( void * _vm, \
87 : ulong r1, \
88 : ulong r2, \
89 : ulong r3, \
90 : ulong r4, \
91 : ulong r5, \
92 : ulong * _ret )
93 :
94 : FD_PROTOTYPES_BEGIN
95 :
96 : /* fd_vm_syscall_util *************************************************/
97 :
98 : /* syscall(b6fc1a11) "abort"
99 : Abort program execution and fail transaction.
100 :
101 : Inputs:
102 :
103 : r1 - ignored
104 : r2 - ignored
105 : r3 - ignored
106 : r4 - ignored
107 : r5 - ignored
108 :
109 : Return:
110 :
111 : FD_VM_SYSCALL_ERR_ABORT: *_ret unchanged. vm->cu unchanged.
112 :
113 : FIXME: SHOULD THIS BE NAMED "SOL_ABORT"? */
114 :
115 : FD_VM_SYSCALL_DECL( abort );
116 :
117 : /* syscall(686093bb) "sol_panic_"
118 : Log panic message, abort program execution, and fail transaction.
119 :
120 : Inputs:
121 :
122 : r1 - msg, byte VM pointer, indexed [0,msg_sz), FIXME: WHEN IS NULL OKAY?
123 : r2 - msg_sz, FIXME: IS 0 OKAY?
124 : r3 - ignored
125 : r4 - ignored
126 : r5 - ignored
127 :
128 : Return:
129 :
130 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
131 : *_ret unchanged. vm->cu==0.
132 :
133 : FD_VM_SYSCALL_ERR_INVALID_STRING: Bad filepath string
134 :
135 : FD_VM_SYSCALL_ERR_PANIC: *_ret unchanged. *_ret unchanged. vm->cu
136 : decremented and vm->cu>0. */
137 :
138 : FD_VM_SYSCALL_DECL( sol_panic );
139 :
140 : /* syscall(207559bd) "sol_log_"
141 : Write message to log.
142 :
143 : Inputs:
144 :
145 : r1 - msg, byte VM pointer, indexed [0,msg_sz), FIXME: WHEN IS NULL OKAY?
146 : r2 - msg_sz, FIXME: IS 0 OKAY?
147 : r3 - ignored
148 : r4 - ignored
149 : r5 - ignored
150 :
151 : Return:
152 :
153 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
154 : *_ret unchanged. vm->cu==0.
155 :
156 : FD_VM_SYSCALL_ERR_INVALID_STRING: bad message string. *_ret=1.
157 :
158 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0.
159 :
160 : IMPORTANT SAFETY TIP! The log message will be silently truncated
161 : if there was not enough room for the message in the syscall log
162 : when called. */
163 :
164 : FD_VM_SYSCALL_DECL( sol_log );
165 :
166 : /* syscall(5c2a3178) "sol_log_64_"
167 : Write r1:5 to the log as a hexadecimal
168 :
169 : Inputs:
170 :
171 : r1 - ulong
172 : r2 - ulong
173 : r3 - ulong
174 : r4 - ulong
175 : r5 - ulong
176 :
177 : Return:
178 :
179 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
180 : *_ret unchanged. vm->cu==0.
181 :
182 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0.
183 :
184 : IMPORTANT SAFETY TIP! The log message will be silently truncated
185 : if there was not enough room for the message in the syscall log
186 : when called. */
187 :
188 : FD_VM_SYSCALL_DECL( sol_log_64 );
189 :
190 : /* syscall(7ef088ca) "sol_log_pubkey"
191 : Write the base58 encoding of 32 byte array to the log.
192 :
193 : Inputs:
194 :
195 : r1 - pubkey, byte VM pointer, indexed [0,32)
196 : r2 - ignored
197 : r3 - ignored
198 : r4 - ignored
199 : r5 - ignored
200 :
201 : Return:
202 :
203 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
204 : *_ret unchanged. vm->cu==0.
205 :
206 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. *_ret unchanged. vm->cu
207 : decremented and vm->cu>0.
208 :
209 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0.
210 :
211 : IMPORTANT SAFETY TIP! The log message will be silently truncated
212 : if there was not enough room for the message in the syscall log
213 : when called. */
214 :
215 : FD_VM_SYSCALL_DECL( sol_log_pubkey );
216 :
217 : /* syscall(52ba5096) "sol_log_compute_units_"
218 : Write remaining compute unit count to log.
219 :
220 : Inputs:
221 :
222 : r1 - ignored
223 : r2 - ignored
224 : r3 - ignored
225 : r4 - ignored
226 : r5 - ignored
227 :
228 : Return:
229 :
230 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
231 : *_ret unchanged. vm->cu==0.
232 :
233 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0.
234 : The value logged will be the value of cu when between when the
235 : syscall completed and the next interation starts and will be
236 : postive.
237 :
238 : IMPORTANT SAFETY TIP! The log message will be silently truncated
239 : if there was not enough room for the message in the syscall log
240 : when called. */
241 :
242 : FD_VM_SYSCALL_DECL( sol_log_compute_units );
243 :
244 : /* syscall(7317b434) "sol_log_data"
245 : Write the base64 encoded cnt data slices to the log.
246 :
247 : Inputs:
248 :
249 : r1 - slice, ulong pair VM pointer, indexed [0,cnt), FIXME: WHEN IS NULL OKAY?
250 : r2 - cnt, FIXME: IS 0 OKAY?
251 : r3 - ignored
252 : r4 - ignored
253 : r5 - ignored
254 :
255 : slice[i] holds the ulong pair:
256 : mem, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
257 : sz, FIXME: IS 0 OKAY?
258 :
259 : Return:
260 :
261 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
262 : *_ret unchanged. vm->cu==0.
263 :
264 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. *_ret unchanged. vm->cu
265 : decremented and vm->cu>0.
266 :
267 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0.
268 :
269 : IMPORTANT SAFETY TIP! The log message will be silently truncated
270 : if there was not enough room for the message in the syscall log
271 : when called. */
272 :
273 : FD_VM_SYSCALL_DECL( sol_log_data );
274 :
275 : /* syscall(83f00e8f) "sol_alloc_free_"
276 : DEPRECATED ... dynamic heap allocation support
277 :
278 : Inputs:
279 :
280 : r1 - sz, ignored if vaddr is not 0
281 : r2 - free_vaddr, byte VM pointer
282 : r3 - ignored
283 : r4 - ignored
284 : r5 - ignored
285 :
286 : Return:
287 :
288 : All cases return FD_VM_SUCCESS and leave vm->cu unchanged.
289 :
290 : If free_vaddr is 0, this is "malloc"-like:
291 :
292 : Let the VM heap region cover bytes [heap_start,heap_end) with
293 : heap_start<=heap_end. If the request was satisfied, on return,
294 : *_ret will point to a range of heap bytes [*_ret,*_ret+sz) that
295 : does not overlap with any other current allocation such that
296 : heap_start<=*_ret<=*_ret+sz<=heap_end. This includes the zero sz
297 : case (note that the zero sz case might return the same value as a
298 : previous zero sz case and/or return the exact value of heap_end).
299 :
300 : If the request cannot be satisfied, *_ret=0 on return and the
301 : heap unchanged.
302 :
303 : IMPORTANT SAFETY TIP! If the VM has check_align set, this
304 : location will have at least 8 byte alignment. Otherwise, this
305 : location will have no particular alignment. Note that this
306 : implies allocations done by this syscall do not conform to the
307 : usual alignment requirements of a standard malloc call for older
308 : VM code.
309 :
310 : If vaddr is not-zero, this is "free"-like. Since the underlying
311 : implementation is necessarily a bump allocator (see implementation
312 : for more details), the specific value is ignored and *_ret=0 on
313 : return. */
314 :
315 : FD_VM_SYSCALL_DECL( sol_alloc_free );
316 :
317 : /* syscall(717cc4a3) "sol_memcpy_"
318 : Copy sz bytes from src to dst. src and dst should not overlap.
319 :
320 : Inputs:
321 :
322 : r1 - dst, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
323 : r2 - src, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY? FIXME: WHEN IS SRC==DST OKAY?
324 : r3 - sz, FIXME: IS 0 okay?
325 : r4 - ignored
326 : r5 - ignored
327 :
328 : Return:
329 :
330 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
331 : *_ret unchanged. vm->cu==0.
332 :
333 : FD_VM_SYSCALL_ERR_COPY_OVERLAPPING: address ranges for src and dst overlap
334 : (either partially or fully). Empty address ranges are considered
335 : to never overlap (FIXME: CHECK THIS IS DESIRED). *_ret unchanged.
336 : vm->cu decremented and vm->cu>0. FIXME: CONSIDER USING A DIFFERENT
337 : ERR CODE?
338 :
339 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. *_ret unchanged. vm->cu
340 : decremented and vm->cu>0.
341 :
342 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0.
343 : On return, dst[i]==src[i] for i in [0,sz). */
344 :
345 : FD_VM_SYSCALL_DECL( sol_memcpy );
346 :
347 : /* syscall(5fdcde31) "sol_memcmp_"
348 : Compare sz bytes at m0 to m1
349 :
350 : Inputs:
351 :
352 : r1 - m0, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
353 : r2 - m1, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
354 : r3 - sz, FIXME: IS SZ 0 OKAY?
355 : r4 - out, int VM pointer
356 : r5 - ignored
357 :
358 : Return:
359 :
360 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
361 : *_ret unchanged. vm->cu==0.
362 :
363 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range (including out not 4 byte
364 : aligned). *_ret unchanged. vm->cu decremented and vm->cu>0.
365 : Strict alignment is only required when the VM has check_align set.
366 :
367 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0.
368 : On return, *_out will hold a positive / zero / negative number if
369 : the region at m0 lexicographically compares strictly greater than /
370 : equal to / strictly less than the region at m1 when treated as
371 : uchars. Specifically, if the regions are different, *_out will be
372 : (int)m0[i] - (int)m1[i] where i is the first differing byte.
373 :
374 : IMPORANT SAFETY TIP! Note that, strangely, this returns the result
375 : in memory instead via *_ret like a libc-style memcmp would. */
376 :
377 : FD_VM_SYSCALL_DECL( sol_memcmp );
378 :
379 : /* syscall(3770fb22) "sol_memset_"
380 : Set sz bytes at dst to the byte value c.
381 :
382 : Inputs:
383 :
384 : r1 - dst, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
385 : r2 - c, bits [8,64) ignored (FIXME: CHECK SOLANA DOES THIS)
386 : r3 - sz, FIXME: IS SZ 0 OKAY?
387 : r4 - ignored
388 : r5 - ignored
389 :
390 : Return:
391 :
392 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
393 : *_ret unchanged. vm->cu==0.
394 :
395 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. *_ret unchanged. vm->cu
396 : decremented and vm->cu>0.
397 :
398 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0.
399 : On return, dst[i]==(uchar)(c & 255UL) for i in [0,sz). */
400 :
401 : FD_VM_SYSCALL_DECL( sol_memset );
402 :
403 : /* syscall(434371f8) "sol_memmove_"
404 : Copy sz bytes from src to dst. src and dst can overlap.
405 :
406 : Inputs:
407 :
408 : r1 - dst, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
409 : r2 - src, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
410 : r3 - sz, FIXME: IS SZ 0 OKAY?
411 : r4 - ignored
412 : r5 - ignored
413 :
414 : Return:
415 :
416 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
417 : *_ret unchanged. vm->cu==0.
418 :
419 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. *_ret unchanged. vm->cu
420 : decremented and vm->cu>0.
421 :
422 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0.
423 : On return, dst[i]==src_as_it_was_before_the_call[i] for i in
424 : [0,sz). */
425 :
426 : FD_VM_SYSCALL_DECL( sol_memmove );
427 :
428 : /* fd_vm_syscall_runtime **********************************************/
429 :
430 : /* syscall(d56b5fe9) "sol_get_clock_sysvar"
431 : syscall(23a29a61) "sol_get_epoch_schedule_sysvar"
432 : syscall(3b97b73c) "sol_get_fees_sysvar"
433 : syscall(bf7188f6) "sol_get_rent_sysvar"
434 : syscall(77f9b9d0) "sol_get_last_restart_slot_sysvar"
435 : Get various sysvar values
436 :
437 : Inputs:
438 :
439 : r1 - out, {clock,schedule,fees,rent,last_restart_slot} VM pointer
440 : r2 - ignored
441 : r3 - ignored
442 : r4 - ignored
443 : r5 - ignored
444 :
445 : Return:
446 :
447 : FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within the Solana runtime.
448 : *_ret unchanged. vm->cu unchanged.
449 :
450 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget. *_ret unchanged.
451 : vm->cu==0.
452 :
453 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. *_ret unchanged. vm->cu
454 : decremented and vm->cu>0. out should have:
455 : | align | sz
456 : clock | 8 | 40
457 : schedule | 1 | 40 ... FIXME: CHECK THIS IS CORRECT!
458 : fees | 8 | 8
459 : rent | 8 | 24
460 : last restart slot | 8 | 8
461 : Strict alignment is only required when the VM has check_align set.
462 :
463 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0.
464 : On return, *out will hold the value of the appropriate sysvar. */
465 :
466 : FD_VM_SYSCALL_DECL( sol_get_clock_sysvar );
467 : FD_VM_SYSCALL_DECL( sol_get_epoch_schedule_sysvar );
468 : FD_VM_SYSCALL_DECL( sol_get_fees_sysvar );
469 : FD_VM_SYSCALL_DECL( sol_get_rent_sysvar );
470 : FD_VM_SYSCALL_DECL( sol_get_last_restart_slot_sysvar );
471 : FD_VM_SYSCALL_DECL( sol_get_epoch_rewards_sysvar );
472 :
473 : /* syscall(13c1b505) "sol_get_sysvar"
474 :
475 : Get a slice of a sysvar account's data.
476 :
477 : Inputs:
478 :
479 : r1 - sysvar_id_vaddr, sysvar pubkey VM pointer
480 : r2 - out_vaddr, byte VM pointer
481 : r3 - offset, ulong
482 : r4 - sz, num bytes to store
483 : r5 - ignored
484 :
485 : Return:
486 :
487 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
488 : *_ret unchanged. vm->cu==0.
489 :
490 : FD_VM_SYSCALL_ERR_SEGFAULT: bad sysvar_id_vaddr, bad out_vaddr, requested
491 : slice outside of sysvar data buffer. _ret unchanged. vm->cu unchanged.
492 :
493 : FD_VM_SYSCALL_ERR_ABORT: offset+sz overflow. *_ret unchanged.
494 :
495 : FD_VM_SUCCESS: success. vm->cu decremented and vm->cu>0.
496 : - *_ret = 2 if sysvar id is not in {clock,schedule,rewards,rent,slot hashes,stake history,last restart slot}
497 : OR sysvar account does not exist.
498 : - *_ret = 1 if [offset,offset+sz) is outside of sysvar data buffer.
499 : - *_ret = 0 if success.
500 :
501 : On return, sz bytes of appropriate offset sysvar data will be copied into
502 : haddr belonging to out_vaddr. */
503 : FD_VM_SYSCALL_DECL( sol_get_sysvar );
504 :
505 : /* syscall(5be92f4a) "sol_get_epoch_stake"
506 :
507 : Gets a vote account's delegated stake for the current epoch, or the total active stake
508 : on the cluster for the current epoch.
509 :
510 : Inputs:
511 :
512 : r1 - var_addr, vote pubkey VM pointer
513 : r2 - ignored
514 : r3 - ignored
515 : r4 - ignored
516 : r5 - ignored
517 :
518 : Return:
519 :
520 : FD_VM_ERR_SIGCALL: the VM is not running within the Solana runtime.
521 : *_ret unchanged. vm->cu unchanged.
522 :
523 : FD_VM_ERR_SIGCOST: insufficient compute budget. *_ret unchanged.
524 : vm->cu==0.
525 :
526 : FD_VM_ERR_SIGSEGV: bad var_addr. _ret unchanged. vm->cu unchanged.
527 :
528 : FD_VM_ERR_ABORT: offset+sz overflow. *_ret unchanged.
529 :
530 : FD_VM_SUCCESS: success. vm->cu decremented and vm->cu>0.
531 : - *_ret = 0 if success.
532 : - if var_addr == 0, returns the total active stake on the cluster. Otherwise,
533 : returns the vote account's delegated stake. */
534 :
535 : FD_VM_SYSCALL_DECL( sol_get_epoch_stake );
536 :
537 : /* syscall(85532d94) "sol_get_stack_height"
538 :
539 : Inputs:
540 :
541 : r1 - ignored
542 : r2 - ignored
543 : r3 - ignored
544 : r4 - ignored
545 : r5 - ignored
546 :
547 : Return:
548 :
549 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
550 : *_ret unchanged. vm->cu==0.
551 :
552 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. *_ret unchanged. vm->cu
553 : decremented and vm->cu>0.
554 :
555 : FD_VM_SUCCESS: success. *_ret=stack_height. vm->cu decremented
556 : and vm->cu>0. */
557 :
558 : FD_VM_SYSCALL_DECL( sol_get_stack_height );
559 :
560 : /* syscall(5d2245e4) "sol_get_return_data"
561 : Get the return data and program id associated with it.
562 :
563 : Inputs:
564 :
565 : r1 - dst, byte VM pointer, indexed [0,dst_max), FIXME: WHEN IS NULL OKAY?
566 : r2 - dst_max, FIXME: IS 0 OKAY?
567 : r3 - program_id, byte VM pointer, indexed [0,32)
568 : r4 - ignored
569 : r5 - ignored
570 :
571 : Return:
572 :
573 : FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within the Solana runtime.
574 : *_ret unchanged. vm->cu unchanged.
575 :
576 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
577 : *_ret unchanged. vm->cu==0.
578 :
579 : FD_VM_SYSCALL_ERR_COPY_OVERLAPPING: dst and program_id address ranges overlap.
580 : *_ret unchanged. vm->cu decremented and vm->cu>0. (FIXME: ERR
581 : CODE) (FIXME: overlap currently checked against the acutal amount
582 : copied into dst which is <=dst_max ... DOUBLE CHECK THIS AGAINST
583 : THE SOLANA IMPLEMENTATION.)
584 :
585 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for dst and/or program_id.
586 : *_ret unchanged. Compute budget decremented. (FIXME: dst address
587 : range currently checked aginst the actual amount copied into dst,
588 : which is <=dst_max ... DOUBLE CHECK THIS AGAINST THE SOLANA
589 : IMPLEMENTATION.)
590 :
591 : FD_VM_SUCCESS: success. *_ret=return_data_sz. vm->cu decremented
592 : and vm->cu>0. On return, if dst_max was non-zero, dst holds the
593 : leading min(return_data_sz,dst_max) bytes of return data (as such,
594 : if return_data_sz>dst_max, the value returned in the buffer was
595 : truncated). Any trailing bytes of dst are unchanged. program_id
596 : holds the program_id associated with the return data.
597 :
598 : If dst_max was zero, dst and program_id are untouched. (FIXME: IS
599 : THIS CORRECT BEHAVIOR FOR PROGRAM_ID?) */
600 :
601 : FD_VM_SYSCALL_DECL( sol_get_return_data );
602 :
603 : /* syscall(a226d3eb) "sol_set_return_data"
604 : Set the return data. The return data will be associated with the
605 : caller's program ID.
606 :
607 : Inputs:
608 :
609 : r1 - src, byte VM pointer, indexed [0,src_sz), FIXME: WHEN IS NULL OKAY?
610 : r2 - src_sz, FIXME: IS 0 OKAY?
611 : r3 - ignored
612 : r4 - ignored
613 : r5 - ignored
614 :
615 : Return:
616 : FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within the Solana runtime.
617 : *_ret unchanged. vm->cu unchanged.
618 :
619 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
620 : *_ret unchanged. vm->cu decremented and vm->cu>0.
621 :
622 : FD_VM_SYSCALL_ERR_RETURN_DATA_TOO_LARGE: src_sz too large. *_ret
623 : unchanged. vm->cu decremented and vm->cu>0.
624 :
625 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for src. *_ret unchanged.
626 : vm->cu decremented and vm->cu>0.
627 :
628 : FD_VM_SUCCESS: success. *_ret=0. vm->cu decremented and vm->cu>0. */
629 :
630 : FD_VM_SYSCALL_DECL( sol_set_return_data );
631 :
632 : /* FIXME: NOT IMPLEMENTED YET ... IGNORES ALL ARGUMENTS AND RETURNS
633 : FD_VM_ERR_UNSUP. (MAYBE GROUP WITH CPI OR PDA?)*/
634 :
635 : FD_VM_SYSCALL_DECL( sol_get_processed_sibling_instruction );
636 :
637 : /* fd_vm_syscall_pda **************************************************/
638 :
639 : /* syscall(9377323c) "sol_create_program_address"
640 :
641 : Compute SHA-256 hash of <program ID> .. &[&[u8]] .. <PDA Marker>
642 : and check whether result is an Ed25519 curve point.
643 :
644 : Inputs:
645 :
646 : arg0 - seed, ulong pair (FIXME: TRIPLE?) VM pointer, indexed [0,seed_cnt), FIXME: WHEN IS NULL OKAY?
647 : arg1 - seed_cnt, FIXME: IS 0 OKAY?
648 : arg2 - program_id, byte VM pointer, indexed [0,32) (FIXME: DOUBLE CHECK SIZE / ALIGN REQ)
649 : arg3 - out, byte VM pointer, indexed [0,32) (FIXME: DOUBLE CHECK SIZE)
650 : arg4 - ignored
651 :
652 : seed[i] holds the ulong pair (FIXME: TRIPLE?):
653 : mem, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
654 : sz, FIXME: IS 0 OKAY?
655 :
656 : Return:
657 :
658 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
659 : *_ret unchanged. Compute budget decremented.
660 :
661 : FD_VM_SYSCALL_ERR_BAD_SEEDS: seed_cnt and/or seed[i].sz too large,
662 : bad address range for program_id, seed,
663 : seed[i].mem and/or out (including 8-byte alignment for seed if the
664 : VM has check_align set). *_ret unchanged. Compute budget
665 : decremented.
666 :
667 : FD_VM_SUCCESS: success. If *_ret==0, a PDA was created and
668 : stored at out. If *_ret==1, create failed and out was unchanged.
669 : Compute budget decremented. */
670 :
671 : FD_VM_SYSCALL_DECL( sol_create_program_address );
672 :
673 : /* syscall(48504a38) "sol_try_find_program_address"
674 :
675 : Repeatedly derive program address while incrementing nonce in seed
676 : list until a point is found that is not a valid Ed25519 curve point.
677 :
678 : Inputs:
679 :
680 : arg0 - seed, ulong pair (FIXME: TRIPLE?) VM pointer, indexed [0,seed_cnt), FIXME: WHEN IS NULL OKAY?
681 : arg1 - seed_cnt, FIXME: IS 0 OKAY?
682 : arg2 - program_id, byte VM pointer, indexed [0,32) (FIXME: DOUBLE CHECK SIZE / ALIGN REQ)
683 : arg3 - out, byte VM pointer, indexed [0,32) (FIXME: DOUBLE CHECK SIZE)
684 : arg4 - bump_seed, byte VM pointer, indexed [0,1)
685 :
686 : seed[i] holds the ulong pair (FIXME: TRIPLE?):
687 : mem, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
688 : sz, FIXME: IS 0 OKAY?
689 :
690 : Return:
691 :
692 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
693 : *_ret unchanged. Compute budget decremented.
694 :
695 : FD_VM_SYSCALL_ERR_BAD_SEEDS: seed_cnt and/or seed[i].sz too large,
696 : bad address range for program_id, seed,
697 : seed[i].mem, out and/or bump_seed (including 8-byte alignment for
698 : seed if the VM has check_align set). *_ret unchanged. Compute
699 : budget decremented.
700 :
701 : FD_VM_SUCCESS: success. If *_ret==0, a PDA was found and stored at
702 : out and the suffix stored at bump_seed. If *_ret==1, no PDA was
703 : found and out and bump_seed were unchanged. Compute budget
704 : decremented. */
705 :
706 : FD_VM_SYSCALL_DECL( sol_try_find_program_address );
707 :
708 : /* fd_vm_syscall_cpi **************************************************/
709 :
710 : /* Represents an account for a CPI */
711 : /* FIXME: DOES THIS GO HERE? MAYBE GROUP WITH ADMIN OR OUTSIDE SYSCALL? */
712 :
713 : struct fd_instruction_account {
714 : ushort index_in_transaction;
715 : ushort index_in_caller;
716 : ushort index_in_callee;
717 : uint is_signer;
718 : uint is_writable;
719 : };
720 :
721 : typedef struct fd_instruction_account fd_instruction_account_t;
722 :
723 : /* Prepare instruction method */
724 : /* FIXME: DOES THIS GO HERE? MAYBE GROUP WITH ADMIN OR OUTSIDE SYSCALL? */
725 :
726 : int
727 : fd_vm_prepare_instruction( fd_instr_info_t const * caller_instr,
728 : fd_instr_info_t * callee_instr,
729 : fd_exec_instr_ctx_t * instr_ctx,
730 : fd_instruction_account_t instruction_accounts[256],
731 : ulong * instruction_accounts_cnt,
732 : fd_pubkey_t const * signers,
733 : ulong signers_cnt );
734 :
735 : /* syscall(a22b9c85) "sol_invoke_signed_c"
736 : Dispatch a cross program invocation. Inputs are in C ABI.
737 :
738 : FIXME: BELT SAND AND DOCUMENT */
739 :
740 : FD_VM_SYSCALL_DECL( cpi_c );
741 :
742 : /* syscall(d7449092) "sol_invoke_signed_rust"
743 : Dispatch a cross program invocation. Inputs are in Rust ABI.
744 :
745 : FIXME: BELT SAND AND DOCUMENT */
746 :
747 : FD_VM_SYSCALL_DECL( cpi_rust );
748 :
749 : /* fd_vm_syscall_crypto ***********************************************/
750 :
751 : /* FD_VM_SYSCALL_SOL_ALT_BN128_{ADD,SUB,MUL,PAIRING} specifies the curve operation. */
752 :
753 99 : #define FD_VM_SYSCALL_SOL_ALT_BN128_ADD ( 0UL) /* add */
754 : #define FD_VM_SYSCALL_SOL_ALT_BN128_SUB ( 1UL) /* add inverse */
755 10743 : #define FD_VM_SYSCALL_SOL_ALT_BN128_MUL ( 2UL) /* scalar mult */
756 2865 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING ( 3UL) /* pairing */
757 :
758 : /* FD_VM_SYSCALL_SOL_ALT_BN128_{...}COMPRESS specifies the (de)compress operation. */
759 :
760 1203 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESS ( 0UL) /* compress point in G1 */
761 1203 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_DECOMPRESS ( 1UL) /* decompress point in G1 */
762 1587 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESS ( 2UL) /* compress point in G2 */
763 1587 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_DECOMPRESS ( 3UL) /* decompress point in G2 */
764 :
765 : /* FD_VM_SYSCALL_SOL_ALT_BN128_{...}_SZ specifies the size of inputs/outputs for the Alt_BN128 curve. */
766 :
767 6450 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_SZ ( 64UL) /* size of a point in G1 */
768 792 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESSED_SZ ( 32UL) /* size of a compressed point in G2 */
769 1200 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_SZ (128UL) /* size of a point in G2 */
770 912 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESSED_SZ ( 64UL) /* size of a compressed point in G2 */
771 : #define FD_VM_SYSCALL_SOL_ALT_BN128_SCALAR_SZ ( 32UL) /* size of a scalar */
772 1437 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_INPUT_EL_SZ (192UL) /* size of G1 + G2 */
773 2874 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_OUTPUT_SZ ( 32UL) /* size of pairing syscall result, i.e. 0 or 1 as 256-bit int ¯\_(ツ)_/¯ */
774 :
775 : /* syscall(ae0c318b) sol_alt_bn128_group_op computes operations on the Alt_BN128 curve,
776 : including point addition in G1, scalar multiplication in G1, and pairing.
777 : See SIMD-0129.
778 :
779 : FIXME: DOCUMENT */
780 :
781 : FD_VM_SYSCALL_DECL( sol_alt_bn128_group_op );
782 :
783 : /* syscall(334fd5ed) sol_alt_bn128_compression allows to compress or decompress points
784 : in G1 or G2 groups over the Alt_BN128 curve.
785 : See SIMD-0129.
786 :
787 : FIXME: DOCUMENT */
788 :
789 : FD_VM_SYSCALL_DECL( sol_alt_bn128_compression );
790 :
791 : /* syscall(174c5122) "sol_blake3"
792 : syscall(d7793abb) "sol_keccak256"
793 : syscall(11f49d86) "sol_sha256"
794 :
795 : Inputs:
796 :
797 : arg0 - slice, ulong pair VM pointer, indexed [0,cnt), FIXME: WHEN IS NULL OKAY?
798 : arg1 - cnt, FIXME: IS 0 OKAY?
799 : arg2 - hash, byte VM pointer, indexed [0,32)
800 : arg3 - ignored
801 : arg4 - ignored
802 :
803 : slice[i] holds the ulong pair:
804 : mem, byte vector VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
805 : sz, FIXME: IS 0 OKAY?
806 :
807 : Return:
808 :
809 : FD_VM_ERR_INVAL: cnt too large. *_ret unchanged.
810 :
811 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
812 : *_ret unchanged. Compute budget decremented.
813 :
814 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for slice, hash and/or
815 : slice[i].addr (including slice not 8 byte aligned if the VM has
816 : check_align set). *_ret unchanged. Compute budget decremented.
817 :
818 : FD_VM_SUCCESS: success. *_ret=0 and hash[i] holds the hash of the
819 : concatentation of the slices. Compute budget decremented. */
820 :
821 : FD_VM_SYSCALL_DECL( sol_blake3 );
822 : FD_VM_SYSCALL_DECL( sol_keccak256 );
823 : FD_VM_SYSCALL_DECL( sol_sha256 );
824 :
825 : /* syscall(c4947c21) sol_poseidon computes the Poseidon hash on an array of input values.
826 : See SIMD-0129.
827 :
828 : FIXME: DOCUMENT */
829 :
830 : #define FD_VM_SYSCALL_SOL_POSEIDON_MAX_VALS 12UL
831 :
832 : FD_VM_SYSCALL_DECL( sol_poseidon ); /* Light protocol flavor */
833 :
834 : /* syscall(17e40350) "sol_secp256k1_recover"
835 :
836 : FIXME: BELT SAND AND DOCUMENT */
837 :
838 : FD_VM_SYSCALL_DECL( sol_secp256k1_recover );
839 :
840 : /* fd_vm_syscall_curve ************************************************/
841 :
842 : /* FD_VM_SYSCALL_SOL_CURVE_CURVE25519_{...} specifies the curve ID */
843 :
844 165 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_EDWARDS ( 0UL) /* ed25519 */
845 174 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_RISTRETTO ( 1UL) /* ristretto255 */
846 :
847 : /* FD_VM_SYSCALL_SOL_CURVE_{...} specifies the curve operation */
848 :
849 48 : #define FD_VM_SYSCALL_SOL_CURVE_ADD ( 0UL) /* add */
850 45 : #define FD_VM_SYSCALL_SOL_CURVE_SUB ( 1UL) /* add inverse */
851 141 : #define FD_VM_SYSCALL_SOL_CURVE_MUL ( 2UL) /* scalar mul */
852 :
853 : /* FD_VM_SYSCALL_SOL_CURVE_CURVE25519_{...}_SZ specifies the size of inputs/outputs. */
854 :
855 12 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ (32UL) /* point (compressed) */
856 12 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_SCALAR_SZ (32UL) /* scalar */
857 :
858 : /* syscall(aa2607ca) sol_curve_validate_point
859 :
860 : FIXME: BELT SAND AND DOCUMENT */
861 :
862 : FD_VM_SYSCALL_DECL( sol_curve_validate_point );
863 :
864 : /* syscall(dd1c41a6) sol_curve_validate_point
865 :
866 : FIXME: BELT SAND AND DOCUMENT */
867 :
868 : FD_VM_SYSCALL_DECL( sol_curve_group_op );
869 :
870 : /* syscall(60a40880) sol_curve_validate_point
871 :
872 : FIXME: BELT SAND AND DOCUMENT */
873 :
874 : FD_VM_SYSCALL_DECL( sol_curve_multiscalar_mul );
875 :
876 : int
877 : fd_vm_derive_pda( fd_vm_t * vm,
878 : fd_pubkey_t const * program_id,
879 : void const * * seed_haddrs,
880 : ulong * seed_szs,
881 : ulong seeds_cnt,
882 : uchar * bump_seed,
883 : fd_pubkey_t * out );
884 :
885 : int
886 : fd_vm_translate_and_check_program_address_inputs( fd_vm_t * vm,
887 : ulong seeds_vaddr,
888 : ulong seeds_cnt,
889 : ulong program_id_vaddr,
890 : void const * * out_seed_haddrs,
891 : ulong * out_seed_szs,
892 : fd_pubkey_t const * * out_program_id );
893 : FD_PROTOTYPES_END
894 :
895 : #endif /* HEADER_src_flamenco_vm_syscall_fd_vm_syscall_h */
|