ckb_script/syscalls/
generator.rs

1use crate::{
2    syscalls::{
3        Close, CurrentCycles, Debugger, Exec, ExecV2, InheritedFd, LoadBlockExtension, LoadCell,
4        LoadCellData, LoadHeader, LoadInput, LoadScript, LoadScriptHash, LoadTx, LoadWitness, Pipe,
5        ProcessID, Read, Spawn, VMVersion, Wait, Write,
6    },
7    types::{DebugPrinter, ScriptVersion, SgData, VmContext, VmId},
8};
9use ckb_traits::{CellDataProvider, ExtensionProvider, HeaderProvider};
10use ckb_vm::{SupportMachine, Syscalls};
11
12/// Generate RISC-V syscalls in CKB environment
13pub fn generate_ckb_syscalls<DL, M>(
14    vm_id: &VmId,
15    sg_data: &SgData<DL>,
16    vm_context: &VmContext<DL>,
17    debug_printer: &DebugPrinter,
18) -> Vec<Box<(dyn Syscalls<M>)>>
19where
20    DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + Clone + 'static,
21    M: SupportMachine,
22{
23    let mut syscalls: Vec<Box<(dyn Syscalls<M>)>> = vec![
24        Box::new(LoadScriptHash::new(sg_data)),
25        Box::new(LoadTx::new(sg_data)),
26        Box::new(LoadCell::new(sg_data)),
27        Box::new(LoadInput::new(sg_data)),
28        Box::new(LoadHeader::new(sg_data)),
29        Box::new(LoadWitness::new(sg_data)),
30        Box::new(LoadScript::new(sg_data)),
31        Box::new(LoadCellData::new(vm_context)),
32        Box::new(Debugger::new(sg_data, debug_printer)),
33    ];
34    let script_version = &sg_data.sg_info.script_version;
35    if script_version >= &ScriptVersion::V1 {
36        syscalls.append(&mut vec![
37            Box::new(VMVersion::new()),
38            Box::new(CurrentCycles::new(vm_context)),
39        ]);
40    }
41    if script_version == &ScriptVersion::V1 {
42        syscalls.push(Box::new(Exec::new(sg_data)));
43    }
44    if script_version >= &ScriptVersion::V2 {
45        syscalls.append(&mut vec![
46            Box::new(ExecV2::new(vm_id, vm_context)),
47            Box::new(LoadBlockExtension::new(sg_data)),
48            Box::new(Spawn::new(vm_id, vm_context)),
49            Box::new(ProcessID::new(vm_id)),
50            Box::new(Pipe::new(vm_id, vm_context)),
51            Box::new(Wait::new(vm_id, vm_context)),
52            Box::new(Write::new(vm_id, vm_context)),
53            Box::new(Read::new(vm_id, vm_context)),
54            Box::new(InheritedFd::new(vm_id, vm_context)),
55            Box::new(Close::new(vm_id, vm_context)),
56        ]);
57    }
58    syscalls
59}