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, vm->reg[0] holds
60 : the application return value.
61 :
62 : When an syscall implementation returns FD_VM_SYSCALL_ERR*, the
63 : syscall is considered to have faulted the VM. It ideally should not
64 : have set vm->reg[0] (or changed any vm state, except vm->cu, though
65 : that often isn't practical, and not critical to consensus).
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 [0,cu_at_function_entry] (upper bound inclusive,
72 : despite most syscalls deducing base CUs first thing, some don't,
73 : e.g., sol_sha256).
74 :
75 : To mitigate risks of from syscall implementations that do not
76 : strictly enforce this and other similar risks that can affect
77 : bookkeeping, on return from a syscall, the VM will:
78 :
79 : - Ignore updates to pc, ic and frame_cnt.
80 : - Ignore updates to cu that increase it.
81 : - Treat updates to cu that zero it as SIGCOST.
82 : - Treat SIGCOST returns that didn't update cu to zero as zeroing it.
83 :
84 : FIXME: ADD NO SETTING OF R0 ON VM_ERR IN VM_INTERP. */
85 :
86 : #define FD_VM_SYSCALL_DECL(name) \
87 : int \
88 : fd_vm_syscall_##name( void * _vm, \
89 : ulong r1, \
90 : ulong r2, \
91 : ulong r3, \
92 : ulong r4, \
93 : ulong r5 )
94 :
95 : FD_PROTOTYPES_BEGIN
96 :
97 : /* fd_vm_syscall_util *************************************************/
98 :
99 : /* syscall(b6fc1a11) "abort"
100 : Abort program execution and fail transaction.
101 :
102 : Inputs:
103 :
104 : r1 - ignored
105 : r2 - ignored
106 : r3 - ignored
107 : r4 - ignored
108 : r5 - ignored
109 :
110 : Return:
111 :
112 : FD_VM_SYSCALL_ERR_ABORT: vm->reg[0] unchanged. vm->cu unchanged.
113 :
114 : FIXME: SHOULD THIS BE NAMED "SOL_ABORT"? */
115 :
116 : FD_VM_SYSCALL_DECL( abort );
117 :
118 : /* syscall(686093bb) "sol_panic_"
119 : Log panic message, abort program execution, and fail transaction.
120 :
121 : Inputs:
122 :
123 : r1 - msg, byte VM pointer, indexed [0,msg_sz), msg doesn't have to
124 : be \0 terminated and can contain \0 within,
125 : r2 - msg_sz, may be 0,
126 : r3 - ignored
127 : r4 - ignored
128 : r5 - ignored
129 :
130 : Return:
131 :
132 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
133 : budget. vm->reg[0] unchanged. vm->cu==0.
134 :
135 : FD_VM_SYSCALL_ERR_INVALID_STRING: Bad filepath string, msg is not
136 : a valid sequence of utf8 bytes. vm->reg[0] unchanged and vm->cu>=0.
137 :
138 : FD_VM_SYSCALL_ERR_PANIC: vm->reg[0] unchanged. vm->cu
139 : decremented and vm->cu>=0. */
140 :
141 : FD_VM_SYSCALL_DECL( sol_panic );
142 :
143 : /* syscall(207559bd) "sol_log_"
144 : Write message encoded as (msg, msg_sz) to log, prefixed with
145 : "Program log: ".
146 :
147 : Inputs:
148 :
149 : r1 - msg, byte VM pointer, indexed [0,msg_sz),
150 : r2 - msg_sz, may be 0,
151 : r3 - ignored
152 : r4 - ignored
153 : r5 - ignored
154 :
155 : Return:
156 :
157 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
158 : budget. vm->reg[0] unchanged. vm->cu==0.
159 :
160 : FD_VM_SYSCALL_ERR_INVALID_STRING: bad message string. vm->reg[0]
161 : unchanged. vm->cu decremented and vm->cu>=0.
162 :
163 : FD_VM_SUCCESS: success. vm->reg[0]==0. vm->cu decremented and
164 : vm->cu>=0.
165 :
166 : IMPORTANT SAFETY TIP! The log message will be silently truncated
167 : if there was not enough room for the message in the syscall log
168 : when called. */
169 :
170 : FD_VM_SYSCALL_DECL( sol_log );
171 :
172 : /* syscall(5c2a3178) "sol_log_64_"
173 : Write r1:5 to the log as a hexadecimal
174 :
175 : Inputs:
176 :
177 : r1 - ulong
178 : r2 - ulong
179 : r3 - ulong
180 : r4 - ulong
181 : r5 - ulong
182 :
183 : Return:
184 :
185 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
186 : budget. vm->reg[0] unchanged. vm->cu==0.
187 :
188 : FD_VM_SUCCESS: success. vm->reg[0]=0. vm->cu decremented and
189 : vm->cu>=0.
190 :
191 : IMPORTANT SAFETY TIP! The log message will be silently truncated
192 : if there was not enough room for the message in the syscall log
193 : when called. */
194 :
195 : FD_VM_SYSCALL_DECL( sol_log_64 );
196 :
197 : /* syscall(7ef088ca) "sol_log_pubkey"
198 : Write the base58 encoding of 32 byte array to the log.
199 :
200 : Inputs:
201 :
202 : r1 - pubkey, byte VM pointer, indexed [0,32)
203 : r2 - ignored
204 : r3 - ignored
205 : r4 - ignored
206 : r5 - ignored
207 :
208 : Return:
209 :
210 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
211 : budget. vm->reg[0] unchanged. vm->cu==0.
212 :
213 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. vm->reg[0] unchanged.
214 : vm->cu decremented and vm->cu>=0.
215 :
216 : FD_VM_SUCCESS: success. vm->reg[0]==0. vm->cu decremented and
217 : vm->cu>=0.
218 :
219 : IMPORTANT SAFETY TIP! The log message will be silently truncated
220 : if there was not enough room for the message in the syscall log
221 : when called. */
222 :
223 : FD_VM_SYSCALL_DECL( sol_log_pubkey );
224 :
225 : /* syscall(52ba5096) "sol_log_compute_units_"
226 : Write remaining compute unit count to log.
227 :
228 : Inputs:
229 :
230 : r1 - ignored
231 : r2 - ignored
232 : r3 - ignored
233 : r4 - ignored
234 : r5 - ignored
235 :
236 : Return:
237 :
238 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
239 : budget. vm->reg[0] unchanged. vm->cu==0.
240 :
241 : FD_VM_SUCCESS: success. vm->reg[0]=0. vm->cu decremented
242 : and vm->cu>=0. The value logged will be the value of cu when
243 : between when the syscall completed and the next iteration starts
244 : and will be >=0.
245 :
246 : IMPORTANT SAFETY TIP! The log message will be silently truncated
247 : if there was not enough room for the message in the syscall log
248 : when called. */
249 :
250 : FD_VM_SYSCALL_DECL( sol_log_compute_units );
251 :
252 : /* syscall(7317b434) "sol_log_data"
253 : Write the base64 encoded cnt data slices to the log.
254 :
255 : Inputs:
256 :
257 : r1 - slice, ulong pair VM pointer, indexed [0,cnt),
258 : r2 - cnt, may be 0,
259 : r3 - ignored
260 : r4 - ignored
261 : r5 - ignored
262 :
263 : slice[i] holds the ulong pair:
264 : mem, byte VM pointer, indexed [0,sz),
265 : sz, may be 0
266 :
267 : Return:
268 :
269 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
270 : vm->reg[0] unchanged. vm->cu==0.
271 :
272 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. vm->reg[0] unchanged. vm->cu
273 : decremented and vm->cu>0.
274 :
275 : FD_VM_SUCCESS: success. vm->reg[0]=0. vm->cu decremented and vm->cu>0.
276 :
277 : IMPORTANT SAFETY TIP! The log message will be silently truncated
278 : if there was not enough room for the message in the syscall log
279 : when called. */
280 :
281 : FD_VM_SYSCALL_DECL( sol_log_data );
282 :
283 : /* syscall(83f00e8f) "sol_alloc_free_"
284 : DEPRECATED ... dynamic heap allocation support
285 :
286 : Inputs:
287 :
288 : r1 - sz, ignored if vaddr is not 0
289 : r2 - free_vaddr, byte VM pointer
290 : r3 - ignored
291 : r4 - ignored
292 : r5 - ignored
293 :
294 : Return:
295 :
296 : All cases return FD_VM_SUCCESS and leave vm->cu unchanged.
297 :
298 : If free_vaddr is 0, this is "malloc"-like:
299 :
300 : Let the VM heap region cover bytes [heap_start,heap_end) with
301 : heap_start<=heap_end. If the request was satisfied, on return,
302 : vm->reg[0] will point to a range of heap bytes [vm->reg[0],vm->reg[0]+sz) that
303 : does not overlap with any other current allocation such that
304 : heap_start<=vm->reg[0]<=vm->reg[0]+sz<=heap_end. This includes the zero sz
305 : case (note that the zero sz case might return the same value as a
306 : previous zero sz case and/or return the exact value of heap_end).
307 :
308 : If the request cannot be satisfied, vm->reg[0]=0 on return and the
309 : heap unchanged.
310 :
311 : IMPORTANT SAFETY TIP! If the VM has check_align set, this
312 : location will have at least 8 byte alignment. Otherwise, this
313 : location will have no particular alignment. Note that this
314 : implies allocations done by this syscall do not conform to the
315 : usual alignment requirements of a standard malloc call for older
316 : VM code.
317 :
318 : If vaddr is not-zero, this is "free"-like. Since the underlying
319 : implementation is necessarily a bump allocator (see implementation
320 : for more details), the specific value is ignored and vm->reg[0]=0 on
321 : return. */
322 :
323 : FD_VM_SYSCALL_DECL( sol_alloc_free );
324 :
325 : /* syscall(717cc4a3) "sol_memcpy_"
326 : Copy sz bytes from src to dst. src and dst should not overlap.
327 :
328 : Inputs:
329 :
330 : r1 - dst, byte VM pointer, indexed [0,sz),
331 : r2 - src, byte VM pointer, indexed [0,sz),
332 : r3 - sz,
333 : r4 - ignored
334 : r5 - ignored
335 :
336 : Return:
337 :
338 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
339 : budget. vm->reg[0] unchanged. vm->cu==0.
340 :
341 : FD_VM_SYSCALL_ERR_COPY_OVERLAPPING: address ranges for src and dst
342 : overlap (either partially or fully). Empty address ranges are
343 : considered to **never** overlap. vm->reg[0]==0. vm->cu decremented and
344 : vm->cu>=0.
345 :
346 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. vm->reg[0]==0. vm->cu
347 : decremented and vm->cu>=0.
348 :
349 : FD_VM_SUCCESS: success. vm->reg[0]==0. vm->cu decremented and
350 : vm->cu>=0. On return, dst[i]==src[i] for i in [0,sz). */
351 :
352 : FD_VM_SYSCALL_DECL( sol_memcpy );
353 :
354 : /* syscall(5fdcde31) "sol_memcmp_"
355 : Compare sz bytes at m0 to m1
356 :
357 : Inputs:
358 :
359 : r1 - m0, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
360 : r2 - m1, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
361 : r3 - sz, FIXME: IS SZ 0 OKAY?
362 : r4 - out, int VM pointer
363 : r5 - ignored
364 :
365 : Return:
366 :
367 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
368 : vm->reg[0]==0. vm->cu==0.
369 :
370 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range (including out not 4 byte
371 : aligned). vm->reg[0]==0. vm->cu decremented and vm->cu>0.
372 : Strict alignment is only required when the VM has check_align set.
373 :
374 : FD_VM_SUCCESS: success. vm->reg[0]=0. vm->cu decremented and vm->cu>0.
375 : On return, *_out will hold a positive / zero / negative number if
376 : the region at m0 lexicographically compares strictly greater than /
377 : equal to / strictly less than the region at m1 when treated as
378 : uchars. Specifically, if the regions are different, *_out will be
379 : (int)m0[i] - (int)m1[i] where i is the first differing byte.
380 :
381 : IMPORTANT SAFETY TIP! Note that, strangely, this returns the result
382 : in memory instead of via vm->reg[0] like a libc-style memcmp would. */
383 :
384 : FD_VM_SYSCALL_DECL( sol_memcmp );
385 :
386 : /* syscall(3770fb22) "sol_memset_"
387 : Set sz bytes at dst to the byte value c.
388 :
389 : Inputs:
390 :
391 : r1 - dst, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
392 : r2 - c, bits [8,64) ignored (FIXME: CHECK SOLANA DOES THIS)
393 : r3 - sz, may be 0,
394 : r4 - ignored
395 : r5 - ignored
396 :
397 : Return:
398 :
399 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
400 : vm->reg[0]==0. vm->cu==0.
401 :
402 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. vm->reg[0]==0. vm->cu
403 : decremented and vm->cu>0.
404 :
405 : FD_VM_SUCCESS: success. vm->reg[0]=0. vm->cu decremented and vm->cu>0.
406 : On return, dst[i]==(uchar)(c & 255UL) for i in [0,sz). */
407 :
408 : FD_VM_SYSCALL_DECL( sol_memset );
409 :
410 : /* syscall(434371f8) "sol_memmove_"
411 : Copy sz bytes from src to dst. src and dst can overlap.
412 :
413 : Inputs:
414 :
415 : r1 - dst, byte VM pointer, indexed [0,sz),
416 : r2 - src, byte VM pointer, indexed [0,sz),
417 : r3 - sz, may be 0,
418 : r4 - ignored
419 : r5 - ignored
420 :
421 : Return:
422 :
423 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
424 : vm->reg[0] unchanged. vm->cu==0.
425 :
426 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. vm->reg[0]==0. vm->cu
427 : decremented and vm->cu>0.
428 :
429 : FD_VM_SUCCESS: success. vm->reg[0]=0. vm->cu decremented and vm->cu>0.
430 : On return, dst[i]==src_as_it_was_before_the_call[i] for i in
431 : [0,sz). */
432 :
433 : FD_VM_SYSCALL_DECL( sol_memmove );
434 :
435 : /* fd_vm_syscall_runtime **********************************************/
436 :
437 : /* syscall(d56b5fe9) "sol_get_clock_sysvar"
438 : syscall(23a29a61) "sol_get_epoch_schedule_sysvar"
439 : syscall(bf7188f6) "sol_get_rent_sysvar"
440 : syscall(188a0031) "sol_get_last_restart_slot"
441 : Get various sysvar values
442 :
443 : Inputs:
444 :
445 : r1 - out, {clock,schedule,fees,rent,last_restart_slot} VM pointer
446 : r2 - ignored
447 : r3 - ignored
448 : r4 - ignored
449 : r5 - ignored
450 :
451 : Return:
452 :
453 : FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within the
454 : Solana runtime. vm->reg[0] unchanged. vm->cu unchanged.
455 :
456 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
457 : budget. vm->reg[0] unchanged. vm->cu==0.
458 :
459 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. vm->reg[0] unchanged.
460 : vm->cu decremented and vm->cu>=0. out should have:
461 : | align | sz
462 : clock | 8 | 40
463 : schedule | 8 | 40
464 : rent | 8 | 24
465 : last restart slot | 8 | 8
466 : Strict alignment is only required when the VM has check_align set.
467 :
468 : FD_VM_SUCCESS: success. vm->reg[0]=0. vm->cu decremented and vm->cu>0.
469 : On return, *out will hold the value of the appropriate sysvar. */
470 :
471 : FD_VM_SYSCALL_DECL( sol_get_clock_sysvar );
472 : FD_VM_SYSCALL_DECL( sol_get_epoch_schedule_sysvar );
473 : FD_VM_SYSCALL_DECL( sol_get_rent_sysvar );
474 : FD_VM_SYSCALL_DECL( sol_get_last_restart_slot_sysvar );
475 : FD_VM_SYSCALL_DECL( sol_get_epoch_rewards_sysvar );
476 :
477 : /* syscall(13c1b505) "sol_get_sysvar"
478 :
479 : Get a slice of a sysvar account's data.
480 :
481 : Inputs:
482 :
483 : r1 - sysvar_id_vaddr, sysvar pubkey VM pointer
484 : r2 - out_vaddr, byte VM pointer
485 : r3 - offset, ulong
486 : r4 - sz, num bytes to store
487 : r5 - ignored
488 :
489 : Return:
490 :
491 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
492 : budget. vm->reg[0] unchanged. vm->cu==0.
493 :
494 : FD_VM_SYSCALL_ERR_SEGFAULT: bad sysvar_id_vaddr, bad out_vaddr,
495 : requested slice outside of sysvar data buffer. vm->reg[0] unchanged.
496 : vm->cu decremented and vm->cu>=0.
497 :
498 : FD_VM_SYSCALL_ERR_ABORT: offset+sz overflow. vm->reg[0] unchanged.
499 : vm->cu decremented and vm->cu>=0.
500 :
501 : FD_VM_SUCCESS: success. vm->cu decremented and vm->cu>=0.
502 : - vm->reg[0] = 2 if sysvar id is not in {clock,schedule,rewards,rent,
503 : slot hashes,stake history, last restart slot}
504 : OR sysvar account does not exist.
505 : - vm->reg[0] = 1 if [offset,offset+sz) is outside of sysvar data
506 : buffer.
507 : - vm->reg[0] = 0 if success.
508 :
509 : On return, sz bytes of appropriate offset sysvar data will be
510 : copied into haddr belonging to out_vaddr. */
511 : FD_VM_SYSCALL_DECL( sol_get_sysvar );
512 :
513 : /* syscall(5be92f4a) "sol_get_epoch_stake"
514 :
515 : This syscall is meant to return the latest frozen stakes at an epoch
516 : boundary. So for instance, when we are executing in epoch 7, this
517 : should return the stakes at the end of epoch 6. Note that this is
518 : also the stakes that determined the leader schedule for the upcoming
519 : epoch, namely epoch 8.
520 :
521 : Inputs:
522 :
523 : r1 - var_addr, vote pubkey VM pointer, or zero to get the total
524 : active stake on the cluster.
525 : r2 - ignored
526 : r3 - ignored
527 : r4 - ignored
528 : r5 - ignored
529 :
530 : Return:
531 :
532 : FD_VM_ERR_SIGCOST: insufficient compute budget. vm->reg[0] unchanged.
533 : vm->cu==0.
534 :
535 : FD_VM_ERR_SIGSEGV: bad var_addr. vm->reg[0] unchanged. vm->cu
536 : decremented and vm->cu>=0.
537 :
538 : FD_VM_ERR_ABORT: offset+sz overflow. vm->reg[0] unchanged.
539 :
540 : FD_VM_SUCCESS: success. vm->cu decremented and vm->cu>=0.
541 : If var_addr == 0, vm->reg[0] is the total active stake on the
542 : cluster. Else, it is the vote account's delegated stake if
543 : var_addr is an existing vote account, and 0 otherwise. */
544 :
545 : FD_VM_SYSCALL_DECL( sol_get_epoch_stake );
546 :
547 : /* syscall(85532d94) "sol_get_stack_height"
548 :
549 : Inputs:
550 :
551 : r1 - ignored
552 : r2 - ignored
553 : r3 - ignored
554 : r4 - ignored
555 : r5 - ignored
556 :
557 : Return:
558 :
559 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
560 : budget. vm->reg[0] unchanged. vm->cu==0.
561 :
562 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. vm->reg[0] unchanged.
563 : vm->cu decremented and vm->cu>=0.
564 :
565 : FD_VM_SUCCESS: success. vm->reg[0]==stack_height. vm->cu decremented
566 : and vm->cu>=0. */
567 :
568 : FD_VM_SYSCALL_DECL( sol_get_stack_height );
569 :
570 : /* syscall(5d2245e4) "sol_get_return_data"
571 : Get the return data and program id associated with it.
572 :
573 : Inputs:
574 :
575 : r1 - dst, byte VM pointer, indexed [0,dst_max),
576 : r2 - dst_max, may be 0,
577 : r3 - program_id, byte VM pointer, indexed [0,32)
578 : r4 - ignored
579 : r5 - ignored
580 :
581 : Return:
582 :
583 : FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within
584 : the Solana runtime. vm->reg[0] unchanged. vm->cu unchanged.
585 :
586 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
587 : budget. vm->reg[0] unchanged. vm->cu==0.
588 :
589 : FD_VM_SYSCALL_ERR_COPY_OVERLAPPING: dst and program_id address
590 : ranges overlap. vm->reg[0] unchanged. vm->cu decremented and
591 : vm->cu>=0.
592 :
593 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for dst and/or
594 : program_id. vm->reg[0] unchanged. Compute budget decremented.
595 :
596 : FD_VM_SUCCESS: success. vm->reg[0]=return_data_sz. vm->cu decremented
597 : and vm->cu>=0. On return, if dst_max was non-zero, dst holds the
598 : leading min(return_data_sz,dst_max) bytes of return data (as such,
599 : if return_data_sz>dst_max, the value returned in the buffer was
600 : truncated). Any trailing bytes of dst are unchanged. program_id
601 : holds the program_id associated with the return data.
602 :
603 : If dst_max was zero, dst and program_id are untouched. */
604 :
605 : FD_VM_SYSCALL_DECL( sol_get_return_data );
606 :
607 : /* syscall(a226d3eb) "sol_set_return_data"
608 : Set the return data. The return data will be associated with the
609 : caller's program ID.
610 :
611 : Inputs:
612 :
613 : r1 - src, byte VM pointer, indexed [0,src_sz),
614 : r2 - src_sz, may be 0,
615 : r3 - ignored
616 : r4 - ignored
617 : r5 - ignored
618 :
619 : Return:
620 : FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within the
621 : Solana runtime. vm->reg[0] unchanged. vm->cu unchanged.
622 :
623 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
624 : budget. vm->reg[0] unchanged. vm->cu==0.
625 :
626 : FD_VM_SYSCALL_ERR_RETURN_DATA_TOO_LARGE: src_sz too large. vm->reg[0]
627 : unchanged. vm->cu decremented and vm->cu>0.
628 :
629 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for src. vm->reg[0] unchanged.
630 : vm->cu decremented and vm->cu>=0.
631 :
632 : FD_VM_SUCCESS: success. vm->reg[0]=0. vm->cu decremented and vm->cu>0. */
633 :
634 : FD_VM_SYSCALL_DECL( sol_set_return_data );
635 :
636 : /* syscall(adb8efc8) "sol_get_processed_sibling_instruction"
637 : Returns the last element from a reverse-ordered list of successfully
638 : processed sibling instructions: the "processed sibling instruction
639 : list".
640 :
641 : For example, given the call flow:
642 : A
643 : B -> C -> D
644 : B -> E
645 : B -> F (current execution point)
646 :
647 : B's processed sibling instruction list is [A]
648 : F's processed sibling instruction list is [E, C]
649 :
650 : This allows the current instruction to know what the last processed
651 : sibling instruction was. This is useful to check that critical
652 : preceding instructions have actually executed: for example, ensuring
653 : that an assert instruction has successfully executed.
654 :
655 : Inputs:
656 :
657 : r1 - index
658 : r2 - result_meta_vaddr, byte VM pointer of the object where
659 : metadata about the last processed sibling instruction will be
660 : stored upon successful execution (the length of the arrays in
661 : the result). Has the type
662 : solana_program::instruction::ProcessedSiblingInstruction
663 : https://github.com/anza-xyz/agave/blob/70089cce5119c9afaeb2986e2ecaa6d4505ec15d/sdk/program/src/instruction.rs#L672-L681
664 : r3 - result_program_id_vaddr, byte VM pointer where the pubkey of
665 : the program ID of the last processed sibling instruction will
666 : be stored upon successful execution
667 : r4 - result_data_vaddr, byte VM pointer where the instruction
668 : data of the last processed sibling instruction will be stored
669 : upon successful execution. The length of the data will be
670 : stored in ProcessedSiblingInstruction.data_len
671 : r5 - result_accounts_vaddr, byte VM pointer where an array of
672 : account meta structures will be stored into upon successful
673 : execution. The length of the data will be stored in
674 : ProcessedSiblingInstruction.accounts_len. Each account meta
675 : has the type solana_program::instruction::AccountMeta
676 : https://github.com/anza-xyz/agave/blob/70089cce5119c9afaeb2986e2ecaa6d4505ec15d/sdk/program/src/instruction.rs#L525-L548
677 :
678 : Return:
679 :
680 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
681 : budget. vm->reg[0] unchanged. vm->cu==0.
682 :
683 : FD_VM_SUCCESS: vm->reg[0]==1 if the instruction was found and, vm->reg[0]==0
684 : otherwise. vm->cu decremented and vm->cu>=0. */
685 :
686 :
687 : FD_VM_SYSCALL_DECL( sol_get_processed_sibling_instruction );
688 :
689 : /* fd_vm_syscall_pda **************************************************/
690 :
691 : /* syscall(9377323c) "sol_create_program_address"
692 :
693 : Compute SHA-256 hash of &[&[u8]] .. <program ID> .. <PDA Marker>
694 : and check whether result is an Ed25519 curve point.
695 :
696 : Inputs:
697 :
698 : r1 - seeds, bytes VM pointer, indexed [0,seed_cnt),
699 : r2 - seed_cnt, may be 0,
700 : r3 - program_id, byte VM pointer, indexed [0,32), 8 byte aligned
701 : r4 - out, byte VM pointer, indexed [0,32), 8 byte aligned
702 : r5 - ignored
703 :
704 : seed[i] holds the ulong pair
705 : mem, byte VM pointer, indexed [0,sz),
706 : sz, may be 0
707 :
708 : Return:
709 :
710 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
711 : budget. vm->reg[0] unchanged. vm->cu==0.
712 :
713 : FD_VM_SYSCALL_ERR_BAD_SEEDS: seed_cnt and/or seed[i].sz too large,
714 : bad address range for program_id, seed,
715 : seed[i].mem and/or out (including 8-byte alignment for seed if the
716 : VM has check_align set). vm->reg[0] unchanged. Compute budget
717 : decremented.
718 :
719 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. vm->reg[0] unchanged.
720 : vm->cu decremented and vm->cu>=0.
721 :
722 : FD_VM_SUCCESS: success. If vm->reg[0]==0, a PDA was created and
723 : stored at out. If vm->reg[0]==1, create failed and out was unchanged.
724 : Compute budget decremented. */
725 :
726 : FD_VM_SYSCALL_DECL( sol_create_program_address );
727 :
728 : /* syscall(48504a38) "sol_try_find_program_address"
729 :
730 : Repeatedly derive program address while incrementing nonce in seed
731 : list until a point is found that is not a valid Ed25519 curve point.
732 :
733 : Inputs:
734 :
735 : r1 - seed, ulong pair VM pointer, indexed [0,seed_cnt),
736 : r2 - seed_cnt, may be 0,
737 : r3 - program_id, byte VM pointer, indexed [0,32), 8 byte aligned
738 : r4 - out, byte VM pointer, indexed [0,32), 8 byte aligned
739 : r5 - bump_seed, byte VM pointer, indexed [0,1)
740 :
741 : seed[i] holds the ulong pair
742 : mem, byte VM pointer, indexed [0,sz),
743 : sz, may be 0
744 :
745 : Return:
746 :
747 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
748 : budget. vm->reg[0] unchanged. vm->cu==0.
749 :
750 : FD_VM_SYSCALL_ERR_BAD_SEEDS: seed_cnt and/or seed[i].sz too large,
751 : bad address range for program_id, seed,
752 : seed[i].mem, out and/or bump_seed (including 8-byte alignment for
753 : seed if the VM has check_align set). vm->reg[0] unchanged. Compute
754 : budget decremented.
755 :
756 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range. vm->reg[0] unchanged.
757 : vm->cu decremented and vm->cu>=0.
758 :
759 : FD_VM_SUCCESS: success. If vm->reg[0]==0, a PDA was found and stored at
760 : out and the suffix stored at bump_seed. If vm->reg[0]==1, no PDA was
761 : found and out and bump_seed were unchanged. Compute budget
762 : decremented. */
763 :
764 : FD_VM_SYSCALL_DECL( sol_try_find_program_address );
765 :
766 : /* fd_vm_syscall_cpi **************************************************/
767 :
768 : /* Prepare instruction method */
769 : /* FIXME: DOES THIS GO HERE? MAYBE GROUP WITH ADMIN OR OUTSIDE SYSCALL? */
770 :
771 : int
772 : fd_vm_prepare_instruction( fd_instr_info_t * callee_instr,
773 : fd_exec_instr_ctx_t * instr_ctx,
774 : fd_pubkey_t const * callee_program_id_pubkey,
775 : fd_pubkey_t const instr_acct_keys[ FD_TXN_INSTR_ACCT_MAX ],
776 : fd_instruction_account_t instruction_accounts[ FD_TXN_INSTR_ACCT_MAX ],
777 : ulong * instruction_accounts_cnt,
778 : fd_pubkey_t const * signers,
779 : ulong signers_cnt );
780 :
781 : /* syscall(a22b9c85) "sol_invoke_signed_c"
782 : Dispatch a cross program invocation. Inputs are in C ABI.
783 :
784 : FIXME: BELT SAND AND DOCUMENT */
785 :
786 : FD_VM_SYSCALL_DECL( cpi_c );
787 :
788 : /* syscall(d7449092) "sol_invoke_signed_rust"
789 : Dispatch a cross program invocation. Inputs are in Rust ABI.
790 :
791 : FIXME: BELT SAND AND DOCUMENT */
792 :
793 : FD_VM_SYSCALL_DECL( cpi_rust );
794 :
795 : /* fd_vm_syscall_crypto ***********************************************/
796 :
797 : /* FD_VM_SYSCALL_SOL_ALT_BN128_{ADD,SUB,MUL,PAIRING} specifies the curve operation. */
798 :
799 310 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_ADD_BE ( 0UL) /* add */
800 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_SUB_BE ( 1UL) /* add inverse */
801 7333 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_MUL_BE ( 2UL) /* scalar mult */
802 2156 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_BE ( 3UL) /* pairing */
803 187 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_ADD_BE ( 4UL) /* add */
804 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_SUB_BE ( 5UL) /* add inverse */
805 153 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_MUL_BE ( 6UL) /* scalar mult */
806 11422 : #define FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG ( 0x80) /* little endian (SIMD-0284) */
807 187 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_ADD_LE ( FD_VM_SYSCALL_SOL_ALT_BN128_G1_ADD_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
808 3701 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_MUL_LE ( FD_VM_SYSCALL_SOL_ALT_BN128_G1_MUL_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
809 1108 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_LE ( FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
810 125 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_ADD_LE ( FD_VM_SYSCALL_SOL_ALT_BN128_G2_ADD_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
811 105 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_MUL_LE ( FD_VM_SYSCALL_SOL_ALT_BN128_G2_MUL_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
812 :
813 : /* FD_VM_SYSCALL_SOL_ALT_BN128_{...}COMPRESS specifies the (de)compress operation. */
814 :
815 1019 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESS_BE ( 0UL) /* compress point in G1 */
816 1010 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_DECOMPRESS_BE ( 1UL) /* decompress point in G1 */
817 1250 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESS_BE ( 2UL) /* compress point in G2 */
818 1282 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_DECOMPRESS_BE ( 3UL) /* decompress point in G2 */
819 544 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESS_LE ( FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESS_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
820 537 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_DECOMPRESS_LE ( FD_VM_SYSCALL_SOL_ALT_BN128_G1_DECOMPRESS_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
821 660 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESS_LE ( FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESS_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
822 669 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_DECOMPRESS_LE ( FD_VM_SYSCALL_SOL_ALT_BN128_G2_DECOMPRESS_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
823 :
824 : /* FD_VM_SYSCALL_SOL_ALT_BN128_{...}_SZ specifies the size of inputs/outputs for the Alt_BN128 curve. */
825 :
826 2213 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_SZ ( 64UL) /* size of a point in G1 */
827 275 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESSED_SZ ( 32UL) /* size of a compressed point in G2 */
828 454 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_SZ (128UL) /* size of a point in G2 */
829 332 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESSED_SZ ( 64UL) /* size of a compressed point in G2 */
830 559 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_INPUT_EL_SZ (192UL) /* size of G1 + G2 */
831 1118 : #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 ¯\_(ツ)_/¯ */
832 :
833 : /* syscall(ae0c318b) sol_alt_bn128_group_op computes operations on the Alt_BN128 curve,
834 : including point addition in G1, scalar multiplication in G1, and pairing.
835 : See SIMD-0129.
836 :
837 : FIXME: DOCUMENT */
838 :
839 : FD_VM_SYSCALL_DECL( sol_alt_bn128_group_op );
840 :
841 : /* syscall(334fd5ed) sol_alt_bn128_compression allows to compress or decompress points
842 : in G1 or G2 groups over the Alt_BN128 curve.
843 : See SIMD-0129.
844 :
845 : FIXME: DOCUMENT */
846 :
847 : FD_VM_SYSCALL_DECL( sol_alt_bn128_compression );
848 :
849 : /* syscall(d7793abb) "sol_keccak256"
850 : syscall(11f49d86) "sol_sha256"
851 :
852 : Inputs:
853 :
854 : arg0 - slice, ulong pair VM pointer, indexed [0,cnt), FIXME: WHEN IS NULL OKAY?
855 : arg1 - cnt, FIXME: IS 0 OKAY?
856 : arg2 - hash, byte VM pointer, indexed [0,32)
857 : arg3 - ignored
858 : arg4 - ignored
859 :
860 : slice[i] holds the ulong pair:
861 : mem, byte vector VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
862 : sz, FIXME: IS 0 OKAY?
863 :
864 : Return:
865 :
866 : FD_VM_ERR_INVAL: cnt too large. vm->reg[0] unchanged.
867 :
868 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
869 : vm->reg[0] unchanged. Compute budget decremented.
870 :
871 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for slice, hash and/or
872 : slice[i].addr (including slice not 8 byte aligned if the VM has
873 : check_align set). vm->reg[0] unchanged. Compute budget decremented.
874 :
875 : FD_VM_SUCCESS: success. vm->reg[0]=0 and hash[i] holds the hash of the
876 : concatenation of the slices. Compute budget decremented. */
877 :
878 : FD_VM_SYSCALL_DECL( sol_keccak256 );
879 : FD_VM_SYSCALL_DECL( sol_sha256 );
880 : FD_VM_SYSCALL_DECL( sol_sha512 );
881 :
882 : /* syscall(c4947c21) sol_poseidon computes the Poseidon hash on an array of input values.
883 : See SIMD-0129.
884 :
885 : FIXME: DOCUMENT */
886 :
887 : #define FD_VM_SYSCALL_SOL_POSEIDON_MAX_VALS 12UL
888 :
889 : FD_VM_SYSCALL_DECL( sol_poseidon ); /* Light protocol flavor */
890 :
891 : /* syscall(17e40350) "sol_secp256k1_recover"
892 :
893 : FIXME: BELT SAND AND DOCUMENT */
894 :
895 : FD_VM_SYSCALL_DECL( sol_secp256k1_recover );
896 :
897 : /* syscall "sol_big_mod_exp" (SIMD-0529)
898 :
899 : result := (base ^ exponent) mod modulus, where all operands are
900 : little-endian and the modulus is odd and > 1. r1 is a vaddr to a
901 : BigModExpParams record; r2 is a vaddr to the result buffer. Gated
902 : behind the enable_big_mod_exp_syscall feature. */
903 :
904 : FD_VM_SYSCALL_DECL( sol_big_mod_exp );
905 :
906 : /* fd_vm_syscall_curve ************************************************/
907 :
908 : /* FD_VM_SYSCALL_SOL_CURVE_CURVE25519_{...} specifies the curve ID */
909 :
910 810 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_EDWARDS ( 0UL ) /* ed25519 */
911 768 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_RISTRETTO ( 1UL ) /* ristretto255 */
912 65 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_BE ( 4UL | 0x80 ) /* bls12-381 big endian */
913 138 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_LE ( 4UL ) /* bls12-381 little endian */
914 147 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_BE ( 5UL | 0x80 ) /* bls12-381 G1 big endian */
915 313 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_LE ( 5UL ) /* bls12-381 G1 little endian */
916 145 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_BE ( 6UL | 0x80 ) /* bls12-381 G2 big endian */
917 319 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_LE ( 6UL ) /* bls12-381 G2 little endian */
918 :
919 : /* FD_VM_SYSCALL_SOL_CURVE_{...} specifies the curve operation */
920 :
921 194 : #define FD_VM_SYSCALL_SOL_CURVE_ADD ( 0UL) /* add */
922 197 : #define FD_VM_SYSCALL_SOL_CURVE_SUB ( 1UL) /* add inverse */
923 248 : #define FD_VM_SYSCALL_SOL_CURVE_MUL ( 2UL) /* scalar mul */
924 :
925 : /* FD_VM_SYSCALL_SOL_CURVE_{...}_SZ specifies the size of inputs/outputs. */
926 :
927 315 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ (32UL) /* point (compressed) */
928 315 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_SCALAR_SZ (32UL) /* scalar */
929 0 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_COMPRESSED_SZ (48UL) /* G1 point (compressed) */
930 518 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ (96UL) /* G1 point (uncompressed) */
931 0 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_COMPRESSED_SZ (2*48UL) /* G2 point (compressed) */
932 514 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ (2*96UL) /* G2 point (uncompressed) */
933 90 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_GT_ELE_SZ (12*48UL) /* GT element */
934 :
935 : /* syscall(aa2607ca) sol_curve_validate_point
936 :
937 : Inputs:
938 :
939 : arg0 - curve_id
940 : arg1 - point_addr
941 : arg2 - ignored
942 : arg3 - ignored
943 : arg4 - ignored
944 :
945 : Return:
946 :
947 : FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE: invalid curve_id.
948 :
949 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
950 : vm->reg[0] unchanged. Compute budget decremented.
951 :
952 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for point_addr
953 : vm->reg[0] unchanged. Compute budget decremented.
954 :
955 : FD_VM_SUCCESS: success. vm->reg[0]=0 point is valid.
956 : vm->reg[0]=1 point is invalid. */
957 :
958 : FD_VM_SYSCALL_DECL( sol_curve_validate_point );
959 :
960 : /* syscall(dd1c41a6) sol_curve_group_op
961 :
962 : Inputs:
963 :
964 : arg0 - curve_id
965 : arg1 - group_op
966 : arg2 - left_input_addr
967 : arg3 - right_input_addr
968 : arg4 - result_point_addr
969 :
970 : Return:
971 :
972 : FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE: invalid curve_id/group_op.
973 :
974 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
975 : vm->reg[0] unchanged. Compute budget decremented.
976 :
977 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for left_input_addr,
978 : right_input_addr or result_point_addr.
979 : vm->reg[0] unchanged. Compute budget decremented.
980 :
981 : FD_VM_SUCCESS: success. vm->reg[0]=0 success, result written at result_point_addr.
982 : vm->reg[0]=1 input validation failed, memory at
983 : result_point_addr unchanged. */
984 :
985 : FD_VM_SYSCALL_DECL( sol_curve_group_op );
986 :
987 : /* syscall(60a40880) sol_curve_multiscalar_mul
988 :
989 : Inputs:
990 :
991 : arg0 - curve_id
992 : arg1 - scalars_addr
993 : arg2 - points_addr
994 : arg3 - points_len
995 : arg4 - result_point_addr
996 :
997 : Return:
998 :
999 : FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE: invalid curve_id/group_op.
1000 :
1001 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
1002 : vm->reg[0] unchanged. Compute budget decremented.
1003 :
1004 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for scalars_addr or
1005 : points_addr.
1006 : vm->reg[0] unchanged. Compute budget decremented.
1007 :
1008 : FD_VM_SUCCESS: success. vm->reg[0]=0 success, result written at result_point_addr.
1009 : vm->reg[0]=1 input validation failed, memory at
1010 : result_point_addr unchanged. */
1011 :
1012 : FD_VM_SYSCALL_DECL( sol_curve_multiscalar_mul );
1013 :
1014 : /* syscall(80c98b0) sol_curve_decompress
1015 :
1016 : Inputs:
1017 :
1018 : arg0 - curve_id
1019 : arg1 - point_addr, compressed BLS12-381 point selected by curve_id
1020 : arg2 - result_addr, uncompressed BLS12-381 point
1021 : arg3 - ignored
1022 : arg4 - ignored
1023 :
1024 : Return:
1025 :
1026 : FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE: invalid curve_id/group_op.
1027 :
1028 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
1029 : vm->reg[0] unchanged. Compute budget decremented.
1030 :
1031 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for point_addr or
1032 : result_addr.
1033 : vm->reg[0] unchanged. Compute budget decremented.
1034 :
1035 : FD_VM_SUCCESS: success. vm->reg[0]=0 success, result written at result_addr.
1036 : vm->reg[0]=1 input validation failed, memory at
1037 : result_addr unchanged. */
1038 :
1039 : FD_VM_SYSCALL_DECL( sol_curve_decompress );
1040 :
1041 : /* syscall(f111a47e) sol_curve_pairing_map
1042 :
1043 : Inputs:
1044 :
1045 : arg0 - curve_id
1046 : arg1 - num_pairs
1047 : arg2 - g1_points_addr
1048 : arg3 - g2_points_addr
1049 : arg4 - result_addr
1050 :
1051 : Return:
1052 :
1053 : FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE: invalid curve_id/group_op.
1054 :
1055 : FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
1056 : vm->reg[0] unchanged. Compute budget decremented.
1057 :
1058 : FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for g1_points_addr,
1059 : g2_points_addr or result_addr.
1060 : vm->reg[0] unchanged. Compute budget decremented.
1061 :
1062 : FD_VM_SUCCESS: success. vm->reg[0]=0 success, result written at result_addr.
1063 : vm->reg[0]=1 input validation failed, memory at
1064 : result_addr unchanged. */
1065 :
1066 : FD_VM_SYSCALL_DECL( sol_curve_pairing_map );
1067 :
1068 : int
1069 : fd_vm_derive_pda( fd_vm_t * vm,
1070 : fd_pubkey_t const * program_id,
1071 : void const * * seed_haddrs,
1072 : ulong * seed_szs,
1073 : ulong seeds_cnt,
1074 : uchar * bump_seed,
1075 : fd_pubkey_t * out );
1076 :
1077 : int
1078 : fd_vm_translate_and_check_program_address_inputs( fd_vm_t * vm,
1079 : ulong seeds_vaddr,
1080 : ulong seeds_cnt,
1081 : ulong program_id_vaddr,
1082 : void const * * out_seed_haddrs,
1083 : ulong * out_seed_szs,
1084 : fd_pubkey_t const * * out_program_id,
1085 : uchar is_syscall );
1086 : FD_PROTOTYPES_END
1087 :
1088 : #endif /* HEADER_src_flamenco_vm_syscall_fd_vm_syscall_h */
|