From 5b03a26d62965602e6a78fcba1fd599b0b81153f Mon Sep 17 00:00:00 2001 From: mohanson Date: Tue, 8 Nov 2022 14:05:42 +0800 Subject: [PATCH 1/6] Add script version 2 --- Cargo.lock | 8 +- script/Cargo.toml | 2 +- script/src/cost_model.rs | 54 -- script/src/error.rs | 2 +- script/src/lib.rs | 2 +- script/src/syscalls/exec.rs | 22 +- script/src/syscalls/get_memory_limit.rs | 30 + script/src/syscalls/mod.rs | 17 + script/src/syscalls/set_content.rs | 51 ++ script/src/syscalls/spawn.rs | 265 ++++++++ .../syscalls/tests/vm_latest/syscalls_2.rs | 45 +- script/src/syscalls/utils.rs | 39 +- script/src/types.rs | 12 +- script/src/verify.rs | 305 ++++++---- script/src/verify/tests/ckb_2019.rs | 2 + script/src/verify/tests/ckb_2021.rs | 8 + .../tests/ckb_latest/features_since_v2021.rs | 7 +- .../tests/ckb_latest/features_since_v2023.rs | 569 ++++++++++++++++++ script/src/verify/tests/ckb_latest/mod.rs | 1 + script/src/verify/tests/mod.rs | 3 +- script/testdata/Makefile | 43 +- script/testdata/get_memory_limit | Bin 0 -> 3968 bytes script/testdata/get_memory_limit.c | 8 + script/testdata/set_content | Bin 0 -> 4064 bytes script/testdata/set_content.c | 12 + script/testdata/spawn_big_content_length | Bin 0 -> 3992 bytes script/testdata/spawn_big_content_length.c | 13 + script/testdata/spawn_big_memory_size | Bin 0 -> 3976 bytes script/testdata/spawn_big_memory_size.c | 12 + script/testdata/spawn_callee_exec_callee | Bin 0 -> 3936 bytes script/testdata/spawn_callee_exec_callee.c | 1 + script/testdata/spawn_callee_exec_caller | Bin 0 -> 3960 bytes script/testdata/spawn_callee_exec_caller.c | 6 + script/testdata/spawn_callee_get_memory_limit | Bin 0 -> 3960 bytes .../testdata/spawn_callee_get_memory_limit.c | 3 + script/testdata/spawn_callee_out_of_cycles | Bin 0 -> 4800 bytes script/testdata/spawn_callee_out_of_cycles.c | 8 + script/testdata/spawn_callee_set_content | Bin 0 -> 4768 bytes script/testdata/spawn_callee_set_content.c | 18 + script/testdata/spawn_callee_strcat | Bin 0 -> 4440 bytes script/testdata/spawn_callee_strcat.c | 17 + script/testdata/spawn_caller_exec | Bin 0 -> 3976 bytes script/testdata/spawn_caller_exec.c | 6 + script/testdata/spawn_caller_get_memory_limit | Bin 0 -> 4112 bytes .../testdata/spawn_caller_get_memory_limit.c | 40 ++ script/testdata/spawn_caller_out_of_cycles | Bin 0 -> 3976 bytes script/testdata/spawn_caller_out_of_cycles.c | 12 + .../testdata/spawn_caller_out_of_cycles_wrap | Bin 0 -> 3992 bytes .../spawn_caller_out_of_cycles_wrap.c | 13 + script/testdata/spawn_caller_set_content | Bin 0 -> 4352 bytes script/testdata/spawn_caller_set_content.c | 80 +++ script/testdata/spawn_caller_strcat | Bin 0 -> 4568 bytes script/testdata/spawn_caller_strcat.c | 27 + script/testdata/spawn_caller_strcat_data_hash | Bin 0 -> 7008 bytes .../testdata/spawn_caller_strcat_data_hash.c | 33 + script/testdata/spawn_caller_strcat_wrap | Bin 0 -> 3992 bytes script/testdata/spawn_caller_strcat_wrap.c | 13 + script/testdata/spawn_peak_memory_2m_to_32m | Bin 0 -> 63264 bytes script/testdata/spawn_peak_memory_2m_to_32m.c | 30 + script/testdata/spawn_peak_memory_4m_to_32m | Bin 0 -> 63264 bytes script/testdata/spawn_peak_memory_4m_to_32m.c | 30 + script/testdata/spawn_recursive | Bin 0 -> 3992 bytes script/testdata/spawn_recursive.c | 13 + script/testdata/vm_version_2 | Bin 0 -> 11696 bytes script/testdata/vm_version_2.c | 8 + spec/src/lib.rs | 9 + util/jsonrpc-types/src/blockchain.rs | 5 + util/types/src/core/blockchain.rs | 6 +- 68 files changed, 1703 insertions(+), 207 deletions(-) create mode 100644 script/src/syscalls/get_memory_limit.rs create mode 100644 script/src/syscalls/set_content.rs create mode 100644 script/src/syscalls/spawn.rs create mode 100644 script/src/verify/tests/ckb_2021.rs create mode 100644 script/src/verify/tests/ckb_latest/features_since_v2023.rs create mode 100755 script/testdata/get_memory_limit create mode 100644 script/testdata/get_memory_limit.c create mode 100755 script/testdata/set_content create mode 100644 script/testdata/set_content.c create mode 100755 script/testdata/spawn_big_content_length create mode 100644 script/testdata/spawn_big_content_length.c create mode 100755 script/testdata/spawn_big_memory_size create mode 100644 script/testdata/spawn_big_memory_size.c create mode 100755 script/testdata/spawn_callee_exec_callee create mode 100644 script/testdata/spawn_callee_exec_callee.c create mode 100755 script/testdata/spawn_callee_exec_caller create mode 100644 script/testdata/spawn_callee_exec_caller.c create mode 100755 script/testdata/spawn_callee_get_memory_limit create mode 100644 script/testdata/spawn_callee_get_memory_limit.c create mode 100755 script/testdata/spawn_callee_out_of_cycles create mode 100644 script/testdata/spawn_callee_out_of_cycles.c create mode 100755 script/testdata/spawn_callee_set_content create mode 100644 script/testdata/spawn_callee_set_content.c create mode 100755 script/testdata/spawn_callee_strcat create mode 100644 script/testdata/spawn_callee_strcat.c create mode 100755 script/testdata/spawn_caller_exec create mode 100644 script/testdata/spawn_caller_exec.c create mode 100755 script/testdata/spawn_caller_get_memory_limit create mode 100644 script/testdata/spawn_caller_get_memory_limit.c create mode 100755 script/testdata/spawn_caller_out_of_cycles create mode 100644 script/testdata/spawn_caller_out_of_cycles.c create mode 100755 script/testdata/spawn_caller_out_of_cycles_wrap create mode 100644 script/testdata/spawn_caller_out_of_cycles_wrap.c create mode 100755 script/testdata/spawn_caller_set_content create mode 100644 script/testdata/spawn_caller_set_content.c create mode 100755 script/testdata/spawn_caller_strcat create mode 100644 script/testdata/spawn_caller_strcat.c create mode 100755 script/testdata/spawn_caller_strcat_data_hash create mode 100644 script/testdata/spawn_caller_strcat_data_hash.c create mode 100755 script/testdata/spawn_caller_strcat_wrap create mode 100644 script/testdata/spawn_caller_strcat_wrap.c create mode 100755 script/testdata/spawn_peak_memory_2m_to_32m create mode 100644 script/testdata/spawn_peak_memory_2m_to_32m.c create mode 100755 script/testdata/spawn_peak_memory_4m_to_32m create mode 100644 script/testdata/spawn_peak_memory_4m_to_32m.c create mode 100755 script/testdata/spawn_recursive create mode 100644 script/testdata/spawn_recursive.c create mode 100755 script/testdata/vm_version_2 create mode 100644 script/testdata/vm_version_2.c diff --git a/Cargo.lock b/Cargo.lock index 3897cead3e..03a410d8ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1525,9 +1525,9 @@ dependencies = [ [[package]] name = "ckb-vm" -version = "0.23.2" +version = "0.24.0-beta" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fee7eb8d6525a0d3a4f113414c1b51dd3aaf75ef7b54fe7ce306e545c87cdd" +checksum = "0c0cdbbf781e743153bfdae8690ba5246a5a026426f22fe865336ee75b18b1c2" dependencies = [ "byteorder", "bytes 1.4.0", @@ -1543,9 +1543,9 @@ dependencies = [ [[package]] name = "ckb-vm-definitions" -version = "0.23.2" +version = "0.24.0-beta" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9403cda7180a8203facf05e96537f0038d188b2efdcef13c84538bfbdfcbcbf" +checksum = "19f7db57ea5cffd9d310ecdb5bc96512a1f0e420ba1f3244d7a2f3baaf0b8dac" [[package]] name = "clang-sys" diff --git a/script/Cargo.toml b/script/Cargo.toml index 3c77668bd8..4e7e2fc35b 100644 --- a/script/Cargo.toml +++ b/script/Cargo.toml @@ -22,7 +22,7 @@ ckb-traits = { path = "../traits", version = "= 0.109.0-pre" } byteorder = "1.3.1" ckb-types = { path = "../util/types", version = "= 0.109.0-pre" } ckb-hash = { path = "../util/hash", version = "= 0.109.0-pre" } -ckb-vm = { version = "=0.23.2", default-features = false } +ckb-vm = { version = "=0.24.0-beta", default-features = false } faster-hex = "0.6" ckb-logger = { path = "../util/logger", version = "= 0.109.0-pre", optional = true } serde = { version = "1.0", features = ["derive"] } diff --git a/script/src/cost_model.rs b/script/src/cost_model.rs index 60ae1f2010..41869c22d4 100644 --- a/script/src/cost_model.rs +++ b/script/src/cost_model.rs @@ -1,10 +1,6 @@ //! CKB VM cost model. //! //! The cost model assign cycles to instructions. -use ckb_vm::{ - instructions::{extract_opcode, insts}, - Instruction, -}; /// How many bytes can transfer when VM costs one cycle. // 0.25 cycles per byte @@ -15,53 +11,3 @@ pub fn transferred_byte_cycles(bytes: u64) -> u64 { // Compiler will optimize the divisin here to shifts. (bytes + BYTES_PER_CYCLE - 1) / BYTES_PER_CYCLE } - -/// Returns the spent cycles to execute the secific instruction. -pub fn instruction_cycles(i: Instruction) -> u64 { - match extract_opcode(i) { - // IMC - insts::OP_JALR => 3, - insts::OP_LD => 2, - insts::OP_LW => 3, - insts::OP_LH => 3, - insts::OP_LB => 3, - insts::OP_LWU => 3, - insts::OP_LHU => 3, - insts::OP_LBU => 3, - insts::OP_SB => 3, - insts::OP_SH => 3, - insts::OP_SW => 3, - insts::OP_SD => 2, - insts::OP_BEQ => 3, - insts::OP_BGE => 3, - insts::OP_BGEU => 3, - insts::OP_BLT => 3, - insts::OP_BLTU => 3, - insts::OP_BNE => 3, - insts::OP_EBREAK => 500, - insts::OP_ECALL => 500, - insts::OP_JAL => 3, - insts::OP_MUL => 5, - insts::OP_MULW => 5, - insts::OP_MULH => 5, - insts::OP_MULHU => 5, - insts::OP_MULHSU => 5, - insts::OP_DIV => 32, - insts::OP_DIVW => 32, - insts::OP_DIVU => 32, - insts::OP_DIVUW => 32, - insts::OP_REM => 32, - insts::OP_REMW => 32, - insts::OP_REMU => 32, - insts::OP_REMUW => 32, - // MOP - insts::OP_WIDE_MUL => 5, - insts::OP_WIDE_MULU => 5, - insts::OP_WIDE_MULSU => 5, - insts::OP_WIDE_DIV => 32, - insts::OP_WIDE_DIVU => 32, - insts::OP_FAR_JUMP_REL => 3, - insts::OP_FAR_JUMP_ABS => 3, - _ => 1, - } -} diff --git a/script/src/error.rs b/script/src/error.rs index 6c42e37393..74d91014a4 100644 --- a/script/src/error.rs +++ b/script/src/error.rs @@ -99,7 +99,7 @@ impl ScriptError { /// Creates a script error originated the script and its exit code. pub fn validation_failure(script: &Script, exit_code: i8) -> ScriptError { let url_path = match ScriptHashType::try_from(script.hash_type()).expect("checked data") { - ScriptHashType::Data | ScriptHashType::Data1 => { + ScriptHashType::Data | ScriptHashType::Data1 | ScriptHashType::Data2 => { format!("by-data-hash/{:x}", script.code_hash()) } ScriptHashType::Type => { diff --git a/script/src/lib.rs b/script/src/lib.rs index b8c2d84a40..5adfd1fc9c 100644 --- a/script/src/lib.rs +++ b/script/src/lib.rs @@ -12,5 +12,5 @@ pub use crate::types::{ CoreMachine, ScriptGroup, ScriptGroupType, ScriptVersion, TransactionSnapshot, TransactionState, VerifyResult, VmIsa, VmVersion, }; -pub use crate::verify::TransactionScriptsVerifier; +pub use crate::verify::{TransactionScriptsSyscallsGenerator, TransactionScriptsVerifier}; pub use crate::verify_env::TxVerifyEnv; diff --git a/script/src/syscalls/exec.rs b/script/src/syscalls/exec.rs index 292f15266f..2c33a52165 100644 --- a/script/src/syscalls/exec.rs +++ b/script/src/syscalls/exec.rs @@ -1,4 +1,5 @@ use crate::cost_model::transferred_byte_cycles; +use crate::syscalls::utils::load_c_string; use crate::syscalls::{ Place, Source, SourceEntry, EXEC, INDEX_OUT_OF_BOUND, SLICE_OUT_OF_BOUND, WRONG_FORMAT, }; @@ -9,7 +10,7 @@ use ckb_types::packed::{Bytes as PackedBytes, BytesVec}; use ckb_vm::Memory; use ckb_vm::{ registers::{A0, A1, A2, A3, A4, A5, A7}, - Bytes, Error as VMError, Register, SupportMachine, Syscalls, + Error as VMError, Register, SupportMachine, Syscalls, }; use ckb_vm::{DEFAULT_STACK_SIZE, RISCV_MAX_MEMORY}; use std::sync::Arc; @@ -99,25 +100,6 @@ impl Exec
{ } } -fn load_c_string(machine: &mut Mac, addr: u64) -> Result { - let mut buffer = Vec::new(); - let mut addr = addr; - - loop { - let byte = machine - .memory_mut() - .load8(&Mac::REG::from_u64(addr))? - .to_u8(); - if byte == 0 { - break; - } - buffer.push(byte); - addr += 1; - } - - Ok(Bytes::from(buffer)) -} - impl Syscalls for Exec
{ fn initialize(&mut self, _machine: &mut Mac) -> Result<(), VMError> { Ok(()) diff --git a/script/src/syscalls/get_memory_limit.rs b/script/src/syscalls/get_memory_limit.rs new file mode 100644 index 0000000000..7b28887ce1 --- /dev/null +++ b/script/src/syscalls/get_memory_limit.rs @@ -0,0 +1,30 @@ +use crate::syscalls::GET_MEMORY_LIMIT; +use ckb_vm::{ + registers::{A0, A7}, + Error as VMError, Register, SupportMachine, Syscalls, +}; + +#[derive(Debug)] +pub struct GetMemoryLimit { + memory_limit: u64, +} + +impl GetMemoryLimit { + pub fn new(memory_limit: u64) -> Self { + Self { memory_limit } + } +} + +impl Syscalls for GetMemoryLimit { + fn initialize(&mut self, _machine: &mut Mac) -> Result<(), VMError> { + Ok(()) + } + + fn ecall(&mut self, machine: &mut Mac) -> Result { + if machine.registers()[A7].to_u64() != GET_MEMORY_LIMIT { + return Ok(false); + } + machine.set_register(A0, Mac::REG::from_u64(self.memory_limit)); + Ok(true) + } +} diff --git a/script/src/syscalls/mod.rs b/script/src/syscalls/mod.rs index a546b64000..495d937702 100644 --- a/script/src/syscalls/mod.rs +++ b/script/src/syscalls/mod.rs @@ -1,6 +1,7 @@ mod current_cycles; mod debugger; mod exec; +mod get_memory_limit; mod load_cell; mod load_cell_data; mod load_header; @@ -9,6 +10,8 @@ mod load_script; mod load_script_hash; mod load_tx; mod load_witness; +mod set_content; +mod spawn; mod utils; mod vm_version; @@ -21,6 +24,7 @@ mod tests; pub use self::current_cycles::CurrentCycles; pub use self::debugger::Debugger; pub use self::exec::Exec; +pub use self::get_memory_limit::GetMemoryLimit; pub use self::load_cell::LoadCell; pub use self::load_cell_data::LoadCellData; pub use self::load_header::LoadHeader; @@ -29,6 +33,8 @@ pub use self::load_script::LoadScript; pub use self::load_script_hash::LoadScriptHash; pub use self::load_tx::LoadTx; pub use self::load_witness::LoadWitness; +pub use self::set_content::SetContent; +pub use self::spawn::Spawn; pub use self::vm_version::VMVersion; #[cfg(test)] @@ -45,6 +51,9 @@ pub const INDEX_OUT_OF_BOUND: u8 = 1; pub const ITEM_MISSING: u8 = 2; pub const SLICE_OUT_OF_BOUND: u8 = 3; pub const WRONG_FORMAT: u8 = 4; +pub const SPAWN_EXCEEDED_MAX_CONTENT_LENGTH: u8 = 5; +pub const SPAWN_WRONG_MEMORY_LIMIT: u8 = 6; +pub const SPAWN_EXCEEDED_MAX_PEAK_MEMORY: u8 = 7; pub const VM_VERSION: u64 = 2041; pub const CURRENT_CYCLES: u64 = 2042; @@ -62,10 +71,18 @@ pub const LOAD_HEADER_BY_FIELD_SYSCALL_NUMBER: u64 = 2082; pub const LOAD_INPUT_BY_FIELD_SYSCALL_NUMBER: u64 = 2083; pub const LOAD_CELL_DATA_AS_CODE_SYSCALL_NUMBER: u64 = 2091; pub const LOAD_CELL_DATA_SYSCALL_NUMBER: u64 = 2092; +pub const SPAWN: u64 = 2101; +pub const GET_MEMORY_LIMIT: u64 = 2102; +pub const SET_CONTENT: u64 = 2103; pub const DEBUG_PRINT_SYSCALL_NUMBER: u64 = 2177; #[cfg(test)] pub const DEBUG_PAUSE: u64 = 2178; +pub const SPAWN_MAX_MEMORY: u64 = 8; +pub const SPAWN_MAX_PEAK_MEMORY: u64 = 64; // 64 * 0.5M = 32M +pub const SPAWN_MEMORY_PAGE_SIZE: u64 = 512 * 1024; // 0.5M +pub const SPAWN_MAX_CONTENT_LENGTH: u64 = 256 * 1024; // 256K + #[derive(Debug, PartialEq, Clone, Copy, Eq)] enum CellField { Capacity = 0, diff --git a/script/src/syscalls/set_content.rs b/script/src/syscalls/set_content.rs new file mode 100644 index 0000000000..c1442c30c9 --- /dev/null +++ b/script/src/syscalls/set_content.rs @@ -0,0 +1,51 @@ +use crate::cost_model::transferred_byte_cycles; +use crate::syscalls::utils::load_bytes; +use crate::syscalls::SET_CONTENT; +use ckb_vm::{ + registers::{A0, A1, A7}, + Error as VMError, Memory, Register, SupportMachine, Syscalls, +}; +use std::sync::{Arc, Mutex}; + +#[derive(Debug)] +pub struct SetContent { + content: Arc>>, + content_size: u64, +} + +impl SetContent { + pub fn new(content: Arc>>, content_size: u64) -> Self { + Self { + content, + content_size, + } + } +} + +impl Syscalls for SetContent { + fn initialize(&mut self, _machine: &mut Mac) -> Result<(), VMError> { + Ok(()) + } + + fn ecall(&mut self, machine: &mut Mac) -> Result { + if machine.registers()[A7].to_u64() != SET_CONTENT { + return Ok(false); + } + let content_addr = machine.registers()[A0].to_u64(); + let request_size_addr = machine.registers()[A1].to_u64(); + let request_size = machine + .memory_mut() + .load64(&Mac::REG::from_u64(request_size_addr))?; + let size = std::cmp::min(self.content_size, request_size.to_u64()); + self.content.lock().unwrap().resize(size as usize, 0); + let content = load_bytes(machine, content_addr, size)?; + self.content.lock().unwrap().copy_from_slice(&content); + machine.memory_mut().store64( + &Mac::REG::from_u64(request_size_addr), + &Mac::REG::from_u64(size), + )?; + machine.add_cycles_no_checking(transferred_byte_cycles(size))?; + machine.set_register(A0, Mac::REG::from_u64(0)); + Ok(true) + } +} diff --git a/script/src/syscalls/spawn.rs b/script/src/syscalls/spawn.rs new file mode 100644 index 0000000000..9a01c11df8 --- /dev/null +++ b/script/src/syscalls/spawn.rs @@ -0,0 +1,265 @@ +use crate::cost_model::transferred_byte_cycles; +use crate::syscalls::utils::load_c_string; +use crate::syscalls::{ + Source, SourceEntry, INDEX_OUT_OF_BOUND, SLICE_OUT_OF_BOUND, SPAWN, + SPAWN_EXCEEDED_MAX_CONTENT_LENGTH, SPAWN_EXCEEDED_MAX_PEAK_MEMORY, SPAWN_MAX_CONTENT_LENGTH, + SPAWN_MAX_MEMORY, SPAWN_MAX_PEAK_MEMORY, SPAWN_MEMORY_PAGE_SIZE, SPAWN_WRONG_MEMORY_LIMIT, + WRONG_FORMAT, +}; +use crate::types::Indices; +use crate::types::{set_vm_max_cycles, CoreMachineType, Machine}; +use crate::TransactionScriptsSyscallsGenerator; +use crate::{ScriptGroup, ScriptVersion}; +use ckb_traits::{CellDataProvider, HeaderProvider}; +use ckb_types::core::cell::{CellMeta, ResolvedTransaction}; +use ckb_vm::{ + cost_model::estimate_cycles, + registers::{A0, A1, A2, A3, A4, A5, A7}, + DefaultMachineBuilder, Error as VMError, Memory, Register, SupportMachine, Syscalls, +}; +use std::sync::{Arc, Mutex}; + +pub struct Spawn
{ + data_loader: DL, + group_inputs: Indices, + group_outputs: Indices, + rtx: Arc, + script_group: ScriptGroup, + script_version: ScriptVersion, + syscalls_generator: TransactionScriptsSyscallsGenerator
, + outputs: Arc>, + peak_memory: u64, +} + +impl Spawn
{ + pub fn new( + data_loader: DL, + group_inputs: Indices, + group_outputs: Indices, + rtx: Arc, + script_group: ScriptGroup, + script_version: ScriptVersion, + syscalls_generator: TransactionScriptsSyscallsGenerator
, + outputs: Arc>, + peak_memory: u64, + ) -> Self { + Self { + data_loader, + group_inputs, + group_outputs, + rtx, + script_group, + script_version, + syscalls_generator, + outputs, + peak_memory, + } + } + + #[inline] + fn resolved_inputs(&self) -> &Vec { + &self.rtx.resolved_inputs + } + + #[inline] + fn resolved_cell_deps(&self) -> &Vec { + &self.rtx.resolved_cell_deps + } + + fn fetch_cell(&self, source: Source, index: usize) -> Result<&CellMeta, u8> { + let cell_opt = match source { + Source::Transaction(SourceEntry::Input) => self.resolved_inputs().get(index), + Source::Transaction(SourceEntry::Output) => self.outputs.get(index), + Source::Transaction(SourceEntry::CellDep) => self.resolved_cell_deps().get(index), + Source::Group(SourceEntry::Input) => self + .group_inputs + .get(index) + .and_then(|actual_index| self.resolved_inputs().get(*actual_index)), + Source::Group(SourceEntry::Output) => self + .group_outputs + .get(index) + .and_then(|actual_index| self.outputs.get(*actual_index)), + Source::Transaction(SourceEntry::HeaderDep) + | Source::Group(SourceEntry::CellDep) + | Source::Group(SourceEntry::HeaderDep) => { + return Err(INDEX_OUT_OF_BOUND); + } + }; + + cell_opt.ok_or(INDEX_OUT_OF_BOUND) + } +} + +impl Syscalls for Spawn
+where + Mac: SupportMachine, + DL: CellDataProvider + HeaderProvider + Send + Sync + Clone + 'static, +{ + fn initialize(&mut self, _machine: &mut Mac) -> Result<(), VMError> { + Ok(()) + } + + fn ecall(&mut self, machine: &mut Mac) -> Result { + if machine.registers()[A7].to_u64() != SPAWN { + return Ok(false); + } + // Arguments for positioning child programs. + let index = machine.registers()[A0].to_u64(); + let source = Source::parse_from_u64(machine.registers()[A1].to_u64())?; + let bounds = machine.registers()[A2].to_u64(); + let offset = (bounds >> 32) as usize; + let length = bounds as u32 as usize; + // Arguments for childs. + let argc = machine.registers()[A3].to_u64(); + let argv_addr = machine.registers()[A4].to_u64(); + let spgs_addr = machine.registers()[A5].to_u64(); + let memory_limit_addr = spgs_addr; + let exit_code_addr_addr = spgs_addr.wrapping_add(8); + let content_addr_addr = spgs_addr.wrapping_add(16); + let content_length_addr_addr = spgs_addr.wrapping_add(24); + // Arguments for limiting. + let memory_limit = machine + .memory_mut() + .load64(&Mac::REG::from_u64(memory_limit_addr))? + .to_u64(); + let cycles_limit = machine.max_cycles() - machine.cycles(); + // Arguments for saving outputs from child programs. + let exit_code_addr = machine + .memory_mut() + .load64(&Mac::REG::from_u64(exit_code_addr_addr))?; + let content_addr = machine + .memory_mut() + .load64(&Mac::REG::from_u64(content_addr_addr))?; + let content_length_addr = machine + .memory_mut() + .load64(&Mac::REG::from_u64(content_length_addr_addr))?; + let content_length = machine.memory_mut().load64(&content_length_addr)?.to_u64(); + // Arguments check. + if content_length > SPAWN_MAX_CONTENT_LENGTH { + machine.set_register(A0, Mac::REG::from_u8(SPAWN_EXCEEDED_MAX_CONTENT_LENGTH)); + return Ok(true); + } + if memory_limit > SPAWN_MAX_MEMORY || memory_limit == 0 { + machine.set_register(A0, Mac::REG::from_u8(SPAWN_WRONG_MEMORY_LIMIT)); + return Ok(true); + } + if self.peak_memory + memory_limit > SPAWN_MAX_PEAK_MEMORY { + machine.set_register(A0, Mac::REG::from_u8(SPAWN_EXCEEDED_MAX_PEAK_MEMORY)); + return Ok(true); + } + // Build child machine. + let machine_content = Arc::new(Mutex::new(Vec::::new())); + let mut machine_child = { + let machine_isa = self.script_version.vm_isa(); + let machine_version = self.script_version.vm_version(); + let machine_core = CoreMachineType::new_with_memory( + machine_isa, + machine_version, + cycles_limit, + (memory_limit * SPAWN_MEMORY_PAGE_SIZE) as usize, + ); + let machine_builder = DefaultMachineBuilder::new(machine_core) + .instruction_cycle_func(Box::new(estimate_cycles)); + let machine_syscalls = self + .syscalls_generator + .generate_same_syscalls(self.script_version, &self.script_group); + let machine_builder = machine_syscalls + .into_iter() + .fold(machine_builder, |builder, syscall| builder.syscall(syscall)); + let machine_builder = machine_builder.syscall(Box::new( + self.syscalls_generator.build_get_memory_limit(memory_limit), + )); + let machine_builder = machine_builder.syscall(Box::new( + self.syscalls_generator + .build_set_content(machine_content.clone(), content_length.to_u64()), + )); + let machine_builder = machine_builder.syscall(Box::new(Spawn::new( + self.data_loader.clone(), + Arc::clone(&self.group_inputs), + Arc::clone(&self.group_outputs), + Arc::clone(&self.rtx), + self.script_group.clone(), + self.script_version, + self.syscalls_generator.clone(), + Arc::clone(&self.outputs), + self.peak_memory + memory_limit, + ))); + let mut machine_child = Machine::new(machine_builder.build()); + set_vm_max_cycles(&mut machine_child, cycles_limit); + machine_child + }; + // Get binary. + let program = { + let cell = self.fetch_cell(source, index as usize); + if let Err(err) = cell { + machine.set_register(A0, Mac::REG::from_u8(err)); + return Ok(true); + } + let cell = cell.unwrap(); + let data = self.data_loader.load_cell_data(cell).ok_or_else(|| { + VMError::Unexpected(format!( + "Unexpected load_cell_data failed {}", + cell.out_point, + )) + })?; + let size = data.len(); + if offset >= size { + machine.set_register(A0, Mac::REG::from_u8(SLICE_OUT_OF_BOUND)); + return Ok(true); + }; + if length == 0 { + data.slice(offset..size) + } else { + let end = offset.checked_add(length).ok_or(VMError::MemOutOfBound)?; + if end > size { + machine.set_register(A0, Mac::REG::from_u8(SLICE_OUT_OF_BOUND)); + return Ok(true); + } + data.slice(offset..end) + } + }; + // Build arguments. + let mut addr = argv_addr.to_u64(); + let mut argv_vec = Vec::new(); + for _ in 0..argc { + let target_addr = machine + .memory_mut() + .load64(&Mac::REG::from_u64(addr))? + .to_u64(); + let cstr = load_c_string(machine, target_addr)?; + argv_vec.push(cstr); + addr += 8; + } + // Run child machine. + match machine_child.load_program(&program, &argv_vec) { + Ok(size) => { + machine_child + .machine + .add_cycles_no_checking(transferred_byte_cycles(size))?; + } + Err(_) => { + machine.set_register(A0, Mac::REG::from_u8(WRONG_FORMAT)); + return Ok(true); + } + } + // Check result. + match machine_child.run() { + Ok(data) => { + machine.set_register(A0, Mac::REG::from_u32(0)); + machine + .memory_mut() + .store8(&exit_code_addr, &Mac::REG::from_i8(data))?; + machine + .memory_mut() + .store_bytes(content_addr.to_u64(), &machine_content.lock().unwrap())?; + machine.memory_mut().store64( + &content_length_addr, + &Mac::REG::from_u64(machine_content.lock().unwrap().len() as u64), + )?; + machine.add_cycles_no_checking(machine_child.machine.cycles())?; + Ok(true) + } + Err(err) => Err(err), + } + } +} diff --git a/script/src/syscalls/tests/vm_latest/syscalls_2.rs b/script/src/syscalls/tests/vm_latest/syscalls_2.rs index feb65a3dbc..b27418c156 100644 --- a/script/src/syscalls/tests/vm_latest/syscalls_2.rs +++ b/script/src/syscalls/tests/vm_latest/syscalls_2.rs @@ -1,7 +1,8 @@ use ckb_vm::{ registers::{A0, A1, A2, A3, A4, A5, A7}, - CoreMachine, SupportMachine, Syscalls, + CoreMachine, Memory, SupportMachine, Syscalls, }; +use std::sync::{Arc, Mutex}; use super::SCRIPT_VERSION; use crate::syscalls::*; @@ -45,3 +46,45 @@ fn test_current_cycles() { assert!(result.unwrap()); assert_eq!(machine.registers()[A0], cycles); } + +#[test] +fn test_get_memory_limit() { + let mut machine = SCRIPT_VERSION.init_core_machine_without_limit(); + + machine.set_register(A0, 0); + machine.set_register(A1, 0); + machine.set_register(A2, 0); + machine.set_register(A3, 0); + machine.set_register(A4, 0); + machine.set_register(A5, 0); + machine.set_register(A7, GET_MEMORY_LIMIT); + + let result = GetMemoryLimit::new(8).ecall(&mut machine); + + assert!(result.unwrap()); + assert_eq!(machine.registers()[A0], 8); +} + +#[test] +fn test_set_content() { + let mut machine = SCRIPT_VERSION.init_core_machine_without_limit(); + machine.memory_mut().store64(&20000, &10).unwrap(); + machine + .memory_mut() + .store_bytes(30000, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + .unwrap(); + + machine.set_register(A0, 30000); + machine.set_register(A1, 20000); + machine.set_register(A2, 0); + machine.set_register(A3, 0); + machine.set_register(A4, 0); + machine.set_register(A5, 0); + machine.set_register(A7, SET_CONTENT); + + let content_data = Arc::new(Mutex::new(vec![])); + let result = SetContent::new(content_data.clone(), 5).ecall(&mut machine); + + assert!(result.unwrap()); + assert_eq!(machine.memory_mut().load64(&20000).unwrap(), 5); +} diff --git a/script/src/syscalls/utils.rs b/script/src/syscalls/utils.rs index 8729e82759..cacfdfa0fb 100644 --- a/script/src/syscalls/utils.rs +++ b/script/src/syscalls/utils.rs @@ -1,7 +1,7 @@ use byteorder::{ByteOrder, LittleEndian}; use ckb_vm::{ registers::{A0, A1, A2}, - Error as VMError, Memory, Register, SupportMachine, + Bytes, Error as VMError, Memory, Register, SupportMachine, }; use std::cmp; @@ -28,3 +28,40 @@ pub fn store_u64(machine: &mut Mac, v: u64) -> Result(machine: &mut Mac, addr: u64) -> Result { + let mut buffer = Vec::new(); + let mut addr = addr; + + loop { + let byte = machine + .memory_mut() + .load8(&Mac::REG::from_u64(addr))? + .to_u8(); + if byte == 0 { + break; + } + buffer.push(byte); + addr += 1; + } + + Ok(Bytes::from(buffer)) +} + +pub fn load_bytes( + machine: &mut Mac, + addr: u64, + size: u64, +) -> Result { + let mut buffer = Vec::new(); + let mut addr = addr; + for _ in 0..size { + let byte = machine + .memory_mut() + .load8(&Mac::REG::from_u64(addr))? + .to_u8(); + buffer.push(byte); + addr += 1; + } + Ok(Bytes::from(buffer)) +} diff --git a/script/src/types.rs b/script/src/types.rs index a4ccd3cf75..6a5525dc2d 100644 --- a/script/src/types.rs +++ b/script/src/types.rs @@ -5,9 +5,9 @@ use ckb_types::{ packed::{Byte32, Script}, }; use ckb_vm::{ - machine::{VERSION0, VERSION1}, + machine::{VERSION0, VERSION1, VERSION2}, snapshot::{make_snapshot, Snapshot}, - Error as VMInternalError, SupportMachine, ISA_B, ISA_IMC, ISA_MOP, + Error as VMInternalError, SupportMachine, ISA_A, ISA_B, ISA_IMC, ISA_MOP, }; use serde::{Deserialize, Serialize}; use std::fmt; @@ -51,12 +51,14 @@ pub enum ScriptVersion { V0 = 0, /// CKB VM 1 with Syscall version 1 and version 2. V1 = 1, + /// /// CKB VM 1 with Syscall version 1, version 2 and version 3. + V2 = 2, } impl ScriptVersion { /// Returns the latest version. pub const fn latest() -> Self { - Self::V1 + Self::V2 } /// Returns the ISA set of CKB VM in current script version. @@ -64,6 +66,7 @@ impl ScriptVersion { match self { Self::V0 => ISA_IMC, Self::V1 => ISA_IMC | ISA_B | ISA_MOP, + Self::V2 => ISA_IMC | ISA_A | ISA_B | ISA_MOP, } } @@ -72,6 +75,7 @@ impl ScriptVersion { match self { Self::V0 => VERSION0, Self::V1 => VERSION1, + Self::V2 => VERSION2, } } @@ -84,6 +88,7 @@ impl ScriptVersion { match self { Self::V0 => ScriptHashType::Data, Self::V1 => ScriptHashType::Data1, + Self::V2 => ScriptHashType::Data2, } } @@ -160,6 +165,7 @@ pub(crate) fn set_vm_max_cycles(vm: &mut Machine, cycles: Cycle) { /// A script group will only be executed once per transaction, the /// script itself should check against all inputs/outputs in its group /// if needed. +#[derive(Clone)] pub struct ScriptGroup { /// The script. /// diff --git a/script/src/verify.rs b/script/src/verify.rs index 2dddb0ff01..f73b8b1e1d 100644 --- a/script/src/verify.rs +++ b/script/src/verify.rs @@ -1,11 +1,11 @@ #[cfg(test)] use crate::syscalls::Pause; use crate::{ - cost_model::{instruction_cycles, transferred_byte_cycles}, + cost_model::transferred_byte_cycles, error::{ScriptError, TransactionScriptError}, syscalls::{ - CurrentCycles, Debugger, Exec, LoadCell, LoadCellData, LoadHeader, LoadInput, LoadScript, - LoadScriptHash, LoadTx, LoadWitness, VMVersion, + CurrentCycles, Debugger, Exec, GetMemoryLimit, LoadCell, LoadCellData, LoadHeader, + LoadInput, LoadScript, LoadScriptHash, LoadTx, LoadWitness, SetContent, Spawn, VMVersion, }, type_id::TypeIdSystemScript, types::{ @@ -28,12 +28,13 @@ use ckb_types::{ prelude::*, }; use ckb_vm::{ + cost_model::estimate_cycles, snapshot::{resume, Snapshot}, DefaultMachineBuilder, Error as VMInternalError, SupportMachine, Syscalls, }; use std::cell::RefCell; use std::collections::{BTreeMap, HashMap}; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; #[cfg(test)] use core::sync::atomic::{AtomicBool, Ordering}; @@ -115,6 +116,179 @@ impl Binaries { } } +/// Syscalls can be generated individually by TransactionScriptsSyscallsGenerator. +/// +/// TransactionScriptsSyscallsGenerator can be cloned. +#[derive(Clone)] +pub struct TransactionScriptsSyscallsGenerator
{ + data_loader: DL, + debug_printer: DebugPrinter, + outputs: Arc>, + rtx: Arc, + #[cfg(test)] + skip_pause: Arc, +} + +impl + TransactionScriptsSyscallsGenerator
+{ + pub fn build_current_cycles(&self) -> CurrentCycles { + CurrentCycles::new() + } + + pub fn build_vm_version(&self) -> VMVersion { + VMVersion::new() + } + + pub fn build_exec(&self, group_inputs: Indices, group_outputs: Indices) -> Exec
{ + Exec::new( + self.data_loader.clone(), + Arc::clone(&self.rtx), + Arc::clone(&self.outputs), + group_inputs, + group_outputs, + ) + } + + pub fn build_load_tx(&self) -> LoadTx { + LoadTx::new(Arc::clone(&self.rtx)) + } + + pub fn build_load_cell(&self, group_inputs: Indices, group_outputs: Indices) -> LoadCell
{ + LoadCell::new( + self.data_loader.clone(), + Arc::clone(&self.rtx), + Arc::clone(&self.outputs), + group_inputs, + group_outputs, + ) + } + + pub fn build_load_cell_data( + &self, + group_inputs: Indices, + group_outputs: Indices, + ) -> LoadCellData
{ + LoadCellData::new( + self.data_loader.clone(), + Arc::clone(&self.rtx), + Arc::clone(&self.outputs), + group_inputs, + group_outputs, + ) + } + + pub fn build_load_input(&self, group_inputs: Indices) -> LoadInput { + LoadInput::new(Arc::clone(&self.rtx), group_inputs) + } + + pub fn build_load_script_hash(&self, hash: Byte32) -> LoadScriptHash { + LoadScriptHash::new(hash) + } + + pub fn build_load_header(&self, group_inputs: Indices) -> LoadHeader
{ + LoadHeader::new( + self.data_loader.clone(), + Arc::clone(&self.rtx), + group_inputs, + ) + } + + pub fn build_load_witness(&self, group_inputs: Indices, group_outputs: Indices) -> LoadWitness { + LoadWitness::new(Arc::clone(&self.rtx), group_inputs, group_outputs) + } + + pub fn build_load_script(&self, script: Script) -> LoadScript { + LoadScript::new(script) + } + + pub fn build_get_memory_limit(&self, memory_limit: u64) -> GetMemoryLimit { + GetMemoryLimit::new(memory_limit) + } + + pub fn build_set_content( + &self, + content: Arc>>, + content_length: u64, + ) -> SetContent { + SetContent::new(content, content_length) + } + + pub fn generate_same_syscalls( + &self, + script_version: ScriptVersion, + script_group: &ScriptGroup, + ) -> Vec)>> { + let current_script_hash = script_group.script.calc_script_hash(); + let script_group_input_indices = Arc::new(script_group.input_indices.clone()); + let script_group_output_indices = Arc::new(script_group.output_indices.clone()); + let mut syscalls: Vec)>> = vec![ + Box::new(self.build_load_script_hash(current_script_hash.clone())), + Box::new(self.build_load_tx()), + Box::new(self.build_load_cell( + Arc::clone(&script_group_input_indices), + Arc::clone(&script_group_output_indices), + )), + Box::new(self.build_load_input(Arc::clone(&script_group_input_indices))), + Box::new(self.build_load_header(Arc::clone(&script_group_input_indices))), + Box::new(self.build_load_witness( + Arc::clone(&script_group_input_indices), + Arc::clone(&script_group_output_indices), + )), + Box::new(self.build_load_script(script_group.script.clone())), + Box::new(self.build_load_cell_data( + Arc::clone(&script_group_input_indices), + Arc::clone(&script_group_output_indices), + )), + Box::new(Debugger::new( + current_script_hash, + Arc::clone(&self.debug_printer), + )), + ]; + #[cfg(test)] + syscalls.push(Box::new(Pause::new(Arc::clone(&self.skip_pause)))); + if script_version >= ScriptVersion::V1 { + syscalls.append(&mut vec![ + Box::new(self.build_vm_version()), + Box::new(self.build_current_cycles()), + Box::new(self.build_exec( + Arc::clone(&script_group_input_indices), + Arc::clone(&script_group_output_indices), + )), + ]); + } + syscalls + } + + pub fn generate_root_syscalls( + &self, + script_version: ScriptVersion, + script_group: &ScriptGroup, + ) -> Vec)>> { + let script_group_input_indices = Arc::new(script_group.input_indices.clone()); + let script_group_output_indices = Arc::new(script_group.output_indices.clone()); + let mut syscalls = self.generate_same_syscalls(script_version, script_group); + if script_version >= ScriptVersion::V2 { + syscalls.append(&mut vec![ + Box::new(self.build_get_memory_limit(8)), + Box::new(self.build_set_content(Arc::new(Mutex::new(vec![])), 0)), + Box::new(Spawn::new( + self.data_loader.clone(), + Arc::clone(&script_group_input_indices), + Arc::clone(&script_group_output_indices), + Arc::clone(&self.rtx), + script_group.clone(), + script_version, + self.clone(), + Arc::clone(&self.outputs), + 8, + )), + ]) + } + syscalls + } +} + /// This struct leverages CKB VM to verify transaction inputs. /// /// FlatBufferBuilder owned `Vec` that grows as needed, in the @@ -259,82 +433,12 @@ impl self.rtx.transaction.hash() } - fn build_current_cycles(&self) -> CurrentCycles { - CurrentCycles::new() - } - - fn build_vm_version(&self) -> VMVersion { - VMVersion::new() - } - - fn build_exec(&self, group_inputs: Indices, group_outputs: Indices) -> Exec
{ - Exec::new( - self.data_loader.clone(), - Arc::clone(&self.rtx), - Arc::clone(&self.outputs), - group_inputs, - group_outputs, - ) - } - - fn build_load_tx(&self) -> LoadTx { - LoadTx::new(Arc::clone(&self.rtx)) - } - - fn build_load_cell(&self, group_inputs: Indices, group_outputs: Indices) -> LoadCell
{ - LoadCell::new( - self.data_loader.clone(), - Arc::clone(&self.rtx), - Arc::clone(&self.outputs), - group_inputs, - group_outputs, - ) - } - - fn build_load_cell_data( - &self, - group_inputs: Indices, - group_outputs: Indices, - ) -> LoadCellData
{ - LoadCellData::new( - self.data_loader.clone(), - Arc::clone(&self.rtx), - Arc::clone(&self.outputs), - group_inputs, - group_outputs, - ) - } - - fn build_load_input(&self, group_inputs: Indices) -> LoadInput { - LoadInput::new(Arc::clone(&self.rtx), group_inputs) - } - - fn build_load_script_hash(&self, hash: Byte32) -> LoadScriptHash { - LoadScriptHash::new(hash) - } - - fn build_load_header(&self, group_inputs: Indices) -> LoadHeader
{ - LoadHeader::new( - self.data_loader.clone(), - Arc::clone(&self.rtx), - group_inputs, - ) - } - - fn build_load_witness(&self, group_inputs: Indices, group_outputs: Indices) -> LoadWitness { - LoadWitness::new(Arc::clone(&self.rtx), group_inputs, group_outputs) - } - - fn build_load_script(&self, script: Script) -> LoadScript { - LoadScript::new(script) - } - /// Extracts actual script binary either in dep cells. pub fn extract_script(&self, script: &Script) -> Result { let script_hash_type = ScriptHashType::try_from(script.hash_type()) .map_err(|err| ScriptError::InvalidScriptHashType(err.to_string()))?; match script_hash_type { - ScriptHashType::Data | ScriptHashType::Data1 => { + ScriptHashType::Data | ScriptHashType::Data1 | ScriptHashType::Data2 => { if let Some(lazy) = self.binaries_by_data_hash.get(&script.code_hash()) { Ok(lazy.access(&self.data_loader)) } else { @@ -362,6 +466,7 @@ impl match script_hash_type { ScriptHashType::Data => Ok(ScriptVersion::V0), ScriptHashType::Data1 => Ok(ScriptVersion::V1), + ScriptHashType::Data2 => Ok(ScriptVersion::V2), ScriptHashType::Type => Ok(ScriptVersion::V1), } } @@ -803,45 +908,15 @@ impl script_version: ScriptVersion, script_group: &ScriptGroup, ) -> Vec)>> { - let current_script_hash = script_group.script.calc_script_hash(); - let script_group_input_indices = Arc::new(script_group.input_indices.clone()); - let script_group_output_indices = Arc::new(script_group.output_indices.clone()); - let mut syscalls: Vec)>> = vec![ - Box::new(self.build_load_script_hash(current_script_hash.clone())), - Box::new(self.build_load_tx()), - Box::new(self.build_load_cell( - Arc::clone(&script_group_input_indices), - Arc::clone(&script_group_output_indices), - )), - Box::new(self.build_load_input(Arc::clone(&script_group_input_indices))), - Box::new(self.build_load_header(Arc::clone(&script_group_input_indices))), - Box::new(self.build_load_witness( - Arc::clone(&script_group_input_indices), - Arc::clone(&script_group_output_indices), - )), - Box::new(self.build_load_script(script_group.script.clone())), - Box::new(self.build_load_cell_data( - Arc::clone(&script_group_input_indices), - Arc::clone(&script_group_output_indices), - )), - Box::new(Debugger::new( - current_script_hash, - Arc::clone(&self.debug_printer), - )), - ]; - #[cfg(test)] - syscalls.push(Box::new(Pause::new(Arc::clone(&self.skip_pause)))); - if script_version >= ScriptVersion::V1 { - syscalls.append(&mut vec![ - Box::new(self.build_vm_version()), - Box::new(self.build_current_cycles()), - Box::new(self.build_exec( - Arc::clone(&script_group_input_indices), - Arc::clone(&script_group_output_indices), - )), - ]) - } - syscalls + let generator = TransactionScriptsSyscallsGenerator { + data_loader: self.data_loader.clone(), + debug_printer: self.debug_printer.clone(), + outputs: self.outputs.clone(), + rtx: self.rtx.clone(), + #[cfg(test)] + skip_pause: self.skip_pause.clone(), + }; + generator.generate_root_syscalls(script_version, script_group) } fn build_machine( @@ -852,7 +927,7 @@ impl let script_version = self.select_version(&script_group.script)?; let core_machine = script_version.init_core_machine(max_cycles); let machine_builder = DefaultMachineBuilder::::new(core_machine) - .instruction_cycle_func(Box::new(instruction_cycles)); + .instruction_cycle_func(Box::new(estimate_cycles)); let machine_builder = self .generate_syscalls(script_version, script_group) .into_iter() diff --git a/script/src/verify/tests/ckb_2019.rs b/script/src/verify/tests/ckb_2019.rs index ab2029d3ac..3b4d058bf4 100644 --- a/script/src/verify/tests/ckb_2019.rs +++ b/script/src/verify/tests/ckb_2019.rs @@ -4,3 +4,5 @@ const SCRIPT_VERSION: crate::ScriptVersion = crate::ScriptVersion::V0; mod features_since_v2019; #[path = "ckb_latest/features_since_v2021.rs"] mod features_since_v2021; +#[path = "ckb_latest/features_since_v2023.rs"] +mod features_since_v2023; diff --git a/script/src/verify/tests/ckb_2021.rs b/script/src/verify/tests/ckb_2021.rs new file mode 100644 index 0000000000..2ea92325d7 --- /dev/null +++ b/script/src/verify/tests/ckb_2021.rs @@ -0,0 +1,8 @@ +const SCRIPT_VERSION: crate::ScriptVersion = crate::ScriptVersion::V1; + +#[path = "ckb_latest/features_since_v2019.rs"] +mod features_since_v2019; +#[path = "ckb_latest/features_since_v2021.rs"] +mod features_since_v2021; +#[path = "ckb_latest/features_since_v2023.rs"] +mod features_since_v2023; diff --git a/script/src/verify/tests/ckb_latest/features_since_v2021.rs b/script/src/verify/tests/ckb_latest/features_since_v2021.rs index 40e8d087f6..bd368402e4 100644 --- a/script/src/verify/tests/ckb_latest/features_since_v2021.rs +++ b/script/src/verify/tests/ckb_latest/features_since_v2021.rs @@ -17,6 +17,7 @@ use crate::syscalls::SOURCE_GROUP_FLAG; use crate::{ type_id::TYPE_ID_CYCLES, verify::{tests::utils::*, *}, + ScriptError, }; #[test] @@ -254,7 +255,7 @@ fn check_vm_version() { let verifier = TransactionScriptsVerifierWithEnv::new(); let result = verifier.verify_without_limit(script_version, &rtx); - assert_eq!(result.is_ok(), script_version >= ScriptVersion::V1); + assert_eq!(result.is_ok(), script_version == ScriptVersion::V1); } #[test] @@ -289,9 +290,9 @@ fn check_vm_version_with_snapshot() { let max_cycles = Cycle::MAX; let result = verifier.verify_without_pause(script_version, &rtx, max_cycles); - assert_eq!(result.is_ok(), script_version >= ScriptVersion::V1); + assert_eq!(result.is_ok(), script_version == ScriptVersion::V1); - if script_version < ScriptVersion::V1 { + if script_version != ScriptVersion::V1 { return; } diff --git a/script/src/verify/tests/ckb_latest/features_since_v2023.rs b/script/src/verify/tests/ckb_latest/features_since_v2023.rs new file mode 100644 index 0000000000..c39924e4c9 --- /dev/null +++ b/script/src/verify/tests/ckb_latest/features_since_v2023.rs @@ -0,0 +1,569 @@ +use ckb_types::{ + core::{capacity_bytes, Capacity, TransactionBuilder}, + packed::{CellInput, CellOutputBuilder, OutPoint, Script}, +}; + +use super::SCRIPT_VERSION; +use crate::verify::{tests::utils::*, *}; + +// check_vm_version: vm_version() returns 2. +// check_get_memory_limit: get_memory_limit() returns 8 in prime script. +// check_set_content: set_content() succeed in prime script but write length is 0. +// check_spawn_strcat: a smoking test for spawn(). +// check_spawn_strcat_data_hash: position child script by data hash. +// check_spawn_get_memory_limit: call get_memory_limit() in child script. +// check_spawn_set_content: set_content() with content < lenght, = length and > length. +// check_spawn_out_of_cycles: child script out-of-cycles. +// check_spawn_exec: A exec B spawn C. +// check_spawn_strcat_wrap: A spawn B spwan C. +// check_spawn_out_of_cycles_wrap: A spawn B spwan C, but C out-of-cycles. +// check_spawn_recursive: A spawn A spawn A ... ... spawn A +// check_spawn_big_memory_size: fails when memory_limit > 8. +// check_spawn_big_content_length: fails when content_length > 256K. +// check_peak_memory_4m_to_32m: spawn should success when peak memory <= 32M +// check_peak_memory_2m_to_32m: spawn should success when peak memory <= 32M + +#[test] +fn check_vm_version() { + let script_version = SCRIPT_VERSION; + + let (vm_version_cell, vm_version_data_hash) = load_cell_from_path("testdata/vm_version_2"); + + let vm_version_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(vm_version_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(vm_version_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![vm_version_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version == ScriptVersion::V2); +} + +#[test] +fn check_get_memory_limit() { + let script_version = SCRIPT_VERSION; + + let (memory_limit_cell, memory_limit_data_hash) = + load_cell_from_path("testdata/get_memory_limit"); + + let memory_limit_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(memory_limit_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(memory_limit_script) + .build(); + + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![memory_limit_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_set_content() { + let script_version = SCRIPT_VERSION; + + let (set_content_cell, set_content_data_hash) = load_cell_from_path("testdata/set_content"); + + let memory_limit_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(set_content_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(memory_limit_script) + .build(); + + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![set_content_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_spawn_strcat() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_strcat"); + let (spawn_callee_cell, _spawn_callee_data_hash) = + load_cell_from_path("testdata/spawn_callee_strcat"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_spawn_strcat_data_hash() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_strcat_data_hash"); + let (spawn_callee_cell, _spawn_callee_data_hash) = + load_cell_from_path("testdata/spawn_callee_strcat"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_spawn_get_memory_limit() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_get_memory_limit"); + let (spawn_callee_cell, _spawn_callee_data_hash) = + load_cell_from_path("testdata/spawn_callee_get_memory_limit"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_spawn_set_content() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_set_content"); + let (spawn_callee_cell, _spawn_callee_data_hash) = + load_cell_from_path("testdata/spawn_callee_set_content"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_spawn_out_of_cycles() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_out_of_cycles"); + let (spawn_callee_cell, _spawn_callee_data_hash) = + load_cell_from_path("testdata/spawn_callee_out_of_cycles"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify(script_version, &rtx, 0xffffff); + if script_version >= ScriptVersion::V2 { + assert!(result + .unwrap_err() + .to_string() + .contains("ExceededMaximumCycles")) + } else { + assert!(result.is_err()) + } +} + +#[test] +fn check_spawn_exec() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_exec"); + let (spawn_callee_caller_cell, _) = load_cell_from_path("testdata/spawn_callee_exec_caller"); + let (spawn_callee_callee_cell, _) = load_cell_from_path("testdata/spawn_callee_exec_callee"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![ + spawn_caller_cell, + spawn_callee_caller_cell, + spawn_callee_callee_cell, + ], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify(script_version, &rtx, 0xffffff); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_spawn_strcat_wrap() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_strcat_wrap"); + let (spawn_callee_caller_cell, _) = load_cell_from_path("testdata/spawn_caller_strcat"); + let (spawn_callee_callee_cell, _) = load_cell_from_path("testdata/spawn_callee_strcat"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![ + spawn_caller_cell, + spawn_callee_callee_cell, + spawn_callee_caller_cell, + ], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify(script_version, &rtx, 0xffffff); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_spawn_out_of_cycles_wrap() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_out_of_cycles_wrap"); + let (spawn_callee_caller_cell, _) = load_cell_from_path("testdata/spawn_caller_out_of_cycles"); + let (spawn_callee_callee_cell, _) = load_cell_from_path("testdata/spawn_callee_out_of_cycles"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![ + spawn_caller_cell, + spawn_callee_callee_cell, + spawn_callee_caller_cell, + ], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify(script_version, &rtx, 0xffffff); + if script_version >= ScriptVersion::V2 { + assert!(result + .unwrap_err() + .to_string() + .contains("ExceededMaximumCycles")) + } else { + assert!(result.is_err()) + } +} + +#[test] +fn check_spawn_recursive() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_recursive"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + if script_version >= ScriptVersion::V2 { + assert!(result.unwrap_err().to_string().contains("error code 7")) + } else { + assert!(result.is_err()) + } +} + +#[test] +fn check_spawn_big_memory_size() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_big_memory_size"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_spawn_big_content_length() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_big_content_length"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_peak_memory_4m_to_32m() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_peak_memory_4m_to_32m"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} + +#[test] +fn check_peak_memory_2m_to_32m() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_peak_memory_2m_to_32m"); + + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); + + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} diff --git a/script/src/verify/tests/ckb_latest/mod.rs b/script/src/verify/tests/ckb_latest/mod.rs index 52924dc1bb..ef6ddd5e75 100644 --- a/script/src/verify/tests/ckb_latest/mod.rs +++ b/script/src/verify/tests/ckb_latest/mod.rs @@ -2,3 +2,4 @@ const SCRIPT_VERSION: crate::ScriptVersion = crate::ScriptVersion::latest(); mod features_since_v2019; mod features_since_v2021; +mod features_since_v2023; diff --git a/script/src/verify/tests/mod.rs b/script/src/verify/tests/mod.rs index 62378eeba9..9729a4f943 100644 --- a/script/src/verify/tests/mod.rs +++ b/script/src/verify/tests/mod.rs @@ -5,5 +5,6 @@ pub(crate) mod utils; mod ckb_2019; -#[path = "ckb_latest/mod.rs"] mod ckb_2021; +#[path = "ckb_latest/mod.rs"] +mod ckb_2023; diff --git a/script/testdata/Makefile b/script/testdata/Makefile index e7951e3b46..3cc2566c06 100644 --- a/script/testdata/Makefile +++ b/script/testdata/Makefile @@ -37,6 +37,7 @@ ALL_BINS := jalr_zero \ current_cycles \ current_cycles_with_snapshot \ vm_version \ + vm_version_2 \ vm_version_with_snapshot \ exec_callee \ exec_caller_from_cell_data \ @@ -48,7 +49,26 @@ ALL_BINS := jalr_zero \ load_is_even_into_global \ load_is_even_with_snapshot \ load_arithmetic \ - debugger + debugger \ + get_memory_limit \ + set_content \ + spawn_big_content_length \ + spawn_big_memory_size \ + spawn_callee_exec_callee \ + spawn_callee_exec_caller \ + spawn_callee_get_memory_limit \ + spawn_callee_out_of_cycles \ + spawn_callee_set_content \ + spawn_callee_strcat \ + spawn_caller_exec \ + spawn_caller_get_memory_limit \ + spawn_caller_out_of_cycles \ + spawn_caller_out_of_cycles_wrap \ + spawn_caller_set_content \ + spawn_caller_strcat_wrap \ + spawn_caller_strcat \ + spawn_caller_strcat_data_hash \ + spawn_recursive ALL_LIBS := is_even.lib \ add1.lib sub1.lib mul2.lib div2.lib @@ -95,6 +115,7 @@ mop_adc_lock: mop_adc_lock.S current_cycles: current_cycles.c current_cycles_with_snapshot: current_cycles_with_snapshot.c vm_version: vm_version.c +vm_version_2: vm_version_2.c vm_version_with_snapshot: vm_version_with_snapshot.c exec_callee: exec_callee.c exec_caller_from_cell_data: exec_caller_from_cell_data.c @@ -111,3 +132,23 @@ sub1.lib: sub1.c mul2.lib: mul2.c div2.lib: div2.c load_arithmetic: load_arithmetic.c + +get_memory_limit: get_memory_limit.c +set_content: set_content.c +spawn_big_content_length: spawn_big_content_length.c +spawn_big_memory_size: spawn_big_memory_size.c +spawn_callee_exec_callee: spawn_callee_exec_callee.c +spawn_callee_exec_caller: spawn_callee_exec_caller.c +spawn_callee_get_memory_limit: spawn_callee_get_memory_limit.c +spawn_callee_out_of_cycles: spawn_callee_out_of_cycles.c +spawn_callee_set_content: spawn_callee_out_of_cycles.c +spawn_callee_strcat: spawn_callee_strcat.c +spawn_caller_exec: spawn_caller_exec.c +spawn_caller_get_memory_limit: spawn_caller_get_memory_limit.c +spawn_caller_out_of_cycles: spawn_caller_out_of_cycles.c +spawn_caller_out_of_cycles_wrap: spawn_caller_out_of_cycles_wrap.c +spawn_caller_set_content: spawn_caller_set_content.c +spawn_caller_strcat_wrap: spawn_caller_strcat_wrap.c +spawn_caller_strcat: spawn_caller_strcat.c +spawn_caller_strcat_data_hash: spawn_caller_strcat_data_hash.c +spawn_recursive: spawn_recursive.c diff --git a/script/testdata/get_memory_limit b/script/testdata/get_memory_limit new file mode 100755 index 0000000000000000000000000000000000000000..83529f8502219a82b762d14591393e0cd2a80a94 GIT binary patch literal 3968 zcmeHKZD>~05ukV2U6RtDl8YnONelY!`xD( zU7^ncKO4yb9f_cNPFrpZz(LX}8bv6S>x892&kjnkSk_T&)5^T73Q}E7kz^|!(WJ}U zGoW9k>XRn7x-Sd{;-#SsSSv#1@NeVc|%xgdAl0|{wVes zxmDxRsYBHb-v<2gH2_gb=+lLyDP0HiH1Dir%fQW-OYpUH>aUE;hU93-kO6-gx|+4E z2gaUx)cCZkzow{kBzQ}j(xfkBNYB!bHtbo=$8p>-^bl`2^LVny!8&UgdF%_wh=!Oy z2&)9Ay%|{nKT}jXKGbY;){R8NJg?L4%0-mPvwu*XjAUHe;17g{MR&t)=o{F1&GC({k>q&CLy6of&o3DMnq3=i0BCw zB6@;FL{Bh?=m|hX$M>F^Du~8HaHlI8Q#09;z0=i@jK+*0kI@kr^OyY@^AD7)JhwfT zIz0H~i{yug-+iRIAx+jj=}4=pJ6HFNls&7Te1Br!_($oc5iu{1EkFI;=}_JChTz%= zEN`Ej5%+Kq;;yCFt`R#Hv%w^%7X!ysCo3Nmr(Ua^>2+wFqrM%-dycawMnB$hpyvSl ziGVW_G)CZ(<9U_X9_9>JIS}p#jd|wpW1XN{AAzZJk};BD<0@nYt2$SU#bG8DHvV<{ z{`QEF3>tTvgMC~fVO<{E7h>ZN`VIIrNBT_|KTgth&8`#2?Ou7NEUlS{zE^3LhK1to z7gso*7YoIK_^;38H6kl?C4~Fe&e-z0RY_?wSQTFV<=`d$zmR&Urky~^Dm?B&gj z?dP+GD|ajYWf9KFy~tbilbZZu#9B2l-DGc(@1#T|#x$CYPmRkfsZa7rY=q80g3Xv2ingnwenq&}V@FD=1ye(dz$0sy_$>(bGfyvdr*60FAd0gOWDsxipb-&4+M_msoT ze?33dTQMMg()k-#^y7+t6D2A*e|#I}$@sY2<`~t#H76@`Ns4HQ)uZFshq9HNg5GEO aoE!;D1G%e&J6 literal 0 HcmV?d00001 diff --git a/script/testdata/get_memory_limit.c b/script/testdata/get_memory_limit.c new file mode 100644 index 0000000000..a148ad4713 --- /dev/null +++ b/script/testdata/get_memory_limit.c @@ -0,0 +1,8 @@ +#include "ckb_syscalls.h" + +int main() { + if (ckb_get_memory_limit() == 8) { + return 0; + } + return 1; +} diff --git a/script/testdata/set_content b/script/testdata/set_content new file mode 100755 index 0000000000000000000000000000000000000000..9a0ae8c2c29fca01ee86223cab53f94ec407631d GIT binary patch literal 4064 zcmeHKeP~lx6hH6fy~JW?+oi1Q)HOEJY(=xiR_jOY61#j@oWhtwh0VUc#J1D;k;G4s zNjzTLk3;TMBEsHl!#-vQcHy)Y=4LYVZbn-2>S;Q)tyE0wrH z&w@Q`$p)=Nke?OHjR16#K~X3|q3jcu8ug?SKUpm2Q9P=VdDj)Bd6pu{TAoy=D?7%( zT&C)iChFW51_JT&&=@qYwiJD0x41%W^=U27J5~T=lWdG#vPVxI4SI3F0vIp2tl@#T zN||z3_3Cc0FaduQYea@DE-nAX`lhb}{`fM0sMO!54M~&QPUerivyycTzI&+ze<*Sc zrGv6Hs2>A=1uD;4Nv*N*x1WX*mZI`xa7da|r!S0=k)`jgIC97l$NCx6kX?WJ$wW^x z>!h_WAR`)LekZIFT!>a=1^i4=`N&|a)!CSghKC$l%^in&v?5&{$(Y468PGPZGi$j! z4(XjG%^_|X7l@}umrq-rgRRl9rctZmHWMaciKmdwahqo|hnqJ!dz@@LF9iG>8!E%% z!2vdUWD5FI-#&^SR!?v2x)sY$5QoMZ*FA4fTMzOC4tcVzE~L70_!E(5p^> z9<`T8MD67eQF~R0sJ$#AYA=I`+6#!NIOmg-1<_at?w^UqcxI+$@1JQ(L}Lb!Yjg%O z{)#_i{{E7s=jvmrg9A@LOMGzfy>ZnoX`=CIXIizctE?wk@oekFj?tYXAEsN9VqP9w zdFty^p~mM;!Q~NH+%YjNZsQ=t-AFHACU!1lg9%P229Bss)I2Iqy;?JUrCIG9_H8=W zbBsMc{L!X8J$u-_0?tU#5P?h0&uhhwFsHxHf$%VB$TNKt>jKq^2uz-n43RN5u0mF@ zwyR7m4l}8+;jeoS>mx!UXxMBD_Hl)T^=W2jh>btGt;eT1blZsblLTGYnRVhi8ke4~ zNUKMq@7I{6yFzjO#U;(pi-qDq{Fi6)8j%&c7Q%gOW2|}Is)RHVtPPiaK5)r?!Xa)O z;gnD^~baNYY(daWf9Ja?Z{j315f@rVgnCMH`&{j9qRN3&Tqzj575ta ztNNJ9fWOVPckh1WQK?hjJ2w^V%6T^tPO?<~zn_0iM)P7BY5xBm>91K-eecVfm)(y? zf9CNmJ1_GyFh2wHGcZ2`^E2>bGjLToFH^KPG_2RX(Q0xD>uT4!s;kzlc~fUvWi%P9 zKn~frZqN2uY*^gW?iCLMQ->y3$a@a2scBzzplX+!Gy-Wv(j0FQOf%3TgD8U+0l?^O z^ZGnKp#_XS*HIrBJ^P)4PXME0Mw_r0Ry?uPxswbCEtNJom`=Lw9kS@ZvMD(-WyjAMgR5uG~a;+ z8I#T*EFq(zDEHO1vX^b=)_)fxBm;NtY*F%8&hDMzk}jnR>_8i9ADBbS-k0rj0yK|y V6F>Xxv=h;%)Njk_Bj()ve*g|7$kYG; literal 0 HcmV?d00001 diff --git a/script/testdata/set_content.c b/script/testdata/set_content.c new file mode 100644 index 0000000000..b6b80a211b --- /dev/null +++ b/script/testdata/set_content.c @@ -0,0 +1,12 @@ +#include "ckb_syscalls.h" + +int main() { + uint64_t length = 5; + if (ckb_set_content((uint8_t *)"hello", &length) != 0) { + return 1; + } + if (length != 0) { + return 1; + } + return 0; +} diff --git a/script/testdata/spawn_big_content_length b/script/testdata/spawn_big_content_length new file mode 100755 index 0000000000000000000000000000000000000000..b3ee51e0f58fed1c63960e16ba45bbed8e7932a5 GIT binary patch literal 3992 zcmeHKZ%k8H6hH6vy;de0u(B~Hj!GTfh&I%s$V5_LuSK$GV&*bTHv4$3z+9cQ^$#Xy z{X@Z`D5j=$S+-P~8RwS8#E=@7jS(c6EGF9rqlw9ev=fq%fLR%Cld*Go?{$S_pZv6h zlbriI=bqoW=e>JxU+?{pd&5jq6v#ruZ$P|VQlCi*+|3pZ5;MUTP++?fo#w zB#pswlh88`>c&cwnz>Q$eZ9~cVAe9eNMdr`JZBqj4t1#-)GB5>VG@>b64?y1eKB*) zT5IdG(XA}L|F*i)E}?CR4jq|=!NfQBLx+{~+q$oZvlH3lHL8T;&fj@sKF?LP#vsyNmipOCIk? zy*0UK;@xD^sF0OKm!ACUWT0WL(Z4PTt2cY|Vm z5N6JJb-^h*qCl3vqPs}Q@1hc2y1#DSs}AyUzizw1-_PU{)<@%e0(9j5fEJ(T(10H8 zhjDpb7uJdCXjpTqB&nPXy;*MZ-sJPE&lOtd^7(vU{w#;g@*KX!2E~yNxdF%5Jz}RvVwCHKC-PHumLe6dYSXlt) zMvTp~8j8#QmFzo}Mq4%el4HPs(PE&uA5Uv9-zoc-ML5TIBX7kIEcwj{bu3U(vbRe+ zl*z4($AtSHV33L``l%TonzGbN-<@wI?9KQ#5zgo;@%P^QqKKx|BFg#yca-1e8RM-l z%Aa*SnEZ*w@9eTH&%p8wEYHC53@p#Ulg+>->AWnXrLOKZ%`43YJ6~C`#cnLyy!lm) zVWZxlF9R`T*|9s_Q)9;B&Q_Oj7^o^VnOxR+cyoE{#)D;h9i-t&Bar4;6K`06CJ_V? zTnGSqSBuN-bn{K1ciWG;L2qx_yU)ox?4WNw(CXgHJDq$x==Y%`+cw_KW1a|2E*I#9 z4;&8r0Zd+aAU*GPJ6oF$x$We<@#I4ObIE@(xoZ%aSnvpn@+qFQGX)Q}izE*{k}uQb z`-yySk*+W4oTdJ1j69Q(-z%+KuSArtL+Sh#k|m=K{hW;asFWX-@@1Ypfb7d?#6afr z%lqY$lwXf`lT4BG_8i9A6!C9-*YWX0&e literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_big_content_length.c b/script/testdata/spawn_big_content_length.c new file mode 100644 index 0000000000..94c44fe379 --- /dev/null +++ b/script/testdata/spawn_big_content_length.c @@ -0,0 +1,13 @@ +#include +#include + +#include "ckb_syscalls.h" + +int main() { + uint64_t content_length = 0xffffffff; + int success = ckb_spawn(8, 1, 3, 0, 0, NULL, NULL, NULL, &content_length); + if (success != 5) { + return 1; + } + return 0; +} diff --git a/script/testdata/spawn_big_memory_size b/script/testdata/spawn_big_memory_size new file mode 100755 index 0000000000000000000000000000000000000000..d2063a959ecd6b09675fab9bb2b05c7db5a2d4c9 GIT binary patch literal 3976 zcmeHKZERCj7=G{VZOde`%}yu6Tv>6|1)G%)w(+rajN5LDfy9V$BuejY%T}=nZ2=(= z`mwHdFg{XjXN<{Q12IU92`(iVgUhn8#E{?*f(eN!Yh_DZ(h)a@3eNZJ-ZMLlzxZeN zCg(iwdEe(b=iYNpZ_hc-zh+?>2B@*{E09)`95c&_k$lM^IWyFP0_&yl6e8^7Fjgw( zW%@i==RL`xBN0?C$mM1Lj*?E%C_{AjVHqv%yjyh}1tT|<$dFHfm5m7Q6D zGR1&@YLn~iP#|6&%7S(sQ*_=M>Znh#8FrkVQ1U%IWAR%UYj-&M;afouc3A+E1Dm81k3A1t<2dpdmXK9<^8Qr6 zjkPy0(%5H_5e+fF5mpH3Q5 z!*Naitt)LIZWR}Zrzcj=^7i3&WH%EwVG@>j0@?p!j@q`^`|Yfgy#MCL%CNY9h>aea zfx+~*ccTYYvzxoG#`4qoV-4!G>-JwoqXFM#)sVSc6=wlrv3B1D(5aJWRjb%v{ah>S;|zV|tLr=n9PaD*lN1 z21`m$*T>TPhaP;Ie0%@vlZvbUsg?&_8AV-pS%0eH;kKzaCw7j%lW9wdd3kK*i7!ut zS{}6qS4Ut)=hUpYor4f}IkS3|*tL`mCONGbIHWjMeYZIMeD&-Fo60`w-Ez49FneV5 z-7S0i_pt8?I3q!Q1bS_cYQ)Ykr~8Tn;Z9JWXZ$AC4T?1pm_F^-N3v{OfvjLncbQlm zX3}B(pEvH*M}%Zh-)syHaD{~R@z~A~8^3!^hfj0hngRX$NxH6c>%?_7m!7Q1s3xLs zRGa-HLUH}Mm9|I4LUADe^FwKk$O>Hy;SRPid|sa->7NSLgv&k~>a`wg61R_YrGu9{ zX0*C1BZZ33)kdXd<8$}G)G-1&Z0WB2sEt^}f?M#3sszqmH?_}b89x6PvhUPd-KLor zUDtvatVV|a;gs&;?W%uRgmY{M@|N6GlHZKjs05~u?Cr`0{$&dh5bZ?C}2vK+ln zUN@gil&?SY`X#bQQIG9{9Q_$te@50*9_@g(DVi{m`}}mj^ve1syp`k{)zMfTI=T9k zd`?TrhnfF+eyTU4L;9riH!15UWqmCr%J}&BJjTiRxZ4&O)xWwRDsf4OXozjYf@ANS gYvfe)UTe*X5tr&{IQQLYjG$e<7u#}!=s&Li8~Q`RLjV8( literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_big_memory_size.c b/script/testdata/spawn_big_memory_size.c new file mode 100644 index 0000000000..6490316fdd --- /dev/null +++ b/script/testdata/spawn_big_memory_size.c @@ -0,0 +1,12 @@ +#include +#include + +#include "ckb_syscalls.h" + +int main() { + int success = ckb_spawn(9, 1, 3, 0, 0, NULL, NULL, NULL, NULL); + if (success != 6) { + return 1; + } + return 0; +} diff --git a/script/testdata/spawn_callee_exec_callee b/script/testdata/spawn_callee_exec_callee new file mode 100755 index 0000000000000000000000000000000000000000..477a948625b23377d4a5342ed9eddfd2abaa1d3a GIT binary patch literal 3936 zcmeHKZD>AaTA#6XyfiP;5*}@7@)~s&oy7%PX#{3U z;v%pw%4tso`2}tHEdWjAp=cDLNXZFHi@slN-(RBWD4x_Qyz44bT|==fluc;UmE9RI ztkVq2v-R#vqk(u?C-~GFIGT^_V9kupq<19cd z*6tqwqb>;vZ4!*=2_6wW!6Bk2G>GU477;zcAfhJ#5gp$_;NbNYE64D~@NiQg@g$Ugto(7c>=EzK!*QW>W;R z7iCiNN*eVU{^8>|g) z_+s>m{mgD@-!!*=zsaWGK1@!H+0e_4cc<^b}R{m6T9KT3@}FnwfiS9WXD z+c>`!_dUP})2A6^vH=XKEmyxEJt{WmePamc>T2b8+q_1>Wos3r`u{u9w^>UFl z-4AAd;qiO9WJ@!!Gy_XBurvcpGw@^aVX$mA zTg+9UG})UDJg;f6VdtJsuXG%kdJMTD-gA6QP3PvWs#Z5CL{dnkINc^%a?qxLq<|Lz z!0het`aC|d4a`2*NgtS99j%8vqT2=L&Lf?^R?*`TPl5RmCNy@6J`r^aw0XT?mOgg7 zT}M!y8<1J_`8=I%$9yhw-gt2%|GDJ9nA{nNP3JO#iXFm}cD~`kc7YXRM)Z_M?-}&| zp{@V?+M<>3+#w z+OTam-c9n2>S$dZ2Ko9S^_(`O9%lY){8VqnfIO4V-?*wDSM^&dQN_jm3s_J3$KAHT xsQ%3bwF;M15e=~>bnLq;m*f@nzG}~_BO%q%>il=7bp-3x`>-Rw663}Ce*i!guz3Ig literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_callee_exec_callee.c b/script/testdata/spawn_callee_exec_callee.c new file mode 100644 index 0000000000..76e8197013 --- /dev/null +++ b/script/testdata/spawn_callee_exec_callee.c @@ -0,0 +1 @@ +int main() { return 0; } diff --git a/script/testdata/spawn_callee_exec_caller b/script/testdata/spawn_callee_exec_caller new file mode 100755 index 0000000000000000000000000000000000000000..315d852c4bc5ee346ae1af0d6ec95d213f888d70 GIT binary patch literal 3960 zcmeHKeP~lx6hH6fy~NIH+oh~?+8G;Zw&Fr#ina5D)b1sn427YC3Y&R-iEZcNY7#%e znU^$;sa7eG#4$FyhRJXr2vQ=BQA;fqhT#4X2f`Mc%obLtvUb%?*PWa9ZkG!C%fALa zaPIHibILf~w+N!pjh>#NV4@;C30JKJLbt%!Wjo`L9kE3hkNdEbBDi04Y-cbK!=9oe^=>`S z*EM||3?xA^0YSFGf8@ue-N~uUagOVL zuEYy7g=6))jOX^>C8NQ>CGC){OPgQ;;_;Tic`)iykkqEYh??XPQIi}ZYEpxUnq(1C zlMEti5)e`Gxu>U#V(~EC>W;;ECRehzx|>q5xCxXTox!m{<)87uU|IQ@&GF3sp@*NQ z-rfK9ea#hlYU{(!tfsDOWna4T@wTaVCU%X#mu*f<1qE!?$!|}Fw?1hKt&YO-j;UE` zI|pIzQg-z!sdF(KN^u4$ct~@s=5A@`#hTgkPOWRyzvW2Z5%%cl`&;(*?PWg@aYjO> zD4cUXsg*h+obe(D;+>GG!17(Z3p8t@FnvZgMJL&W2BSi?T`Q&12$PAJ{Db;e-4e7#unrOv|J zH@t8UtgY9x#=93Nrvk^_MnD-uB zSJSq(y?VEY6e1}kQXFj-EjegbKvKYm0ATjD`utwM*bHXB`>-F(?$+IVyrRbq=C*xp z{@tS2D;@#!9;{H?CHh6=DbVcmfm!;{<8kjpa&ACo(eL-RH6QT1$$8`1h5U2LznI)5 zh>YiI1Qq!RPulr{2itj4f;GaYVf6k%?WRCN6eL1!)&EvPL>z2Drpb01Pdfgz%1^8O^)yh$r}GQwC;4%=%@fLhZJt+&B`(4tvJDk;x92K(1--{Q@_fXk WJnGJWcIqRzL%jz(^POlv&Ho3bzPkhf literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_callee_exec_caller.c b/script/testdata/spawn_callee_exec_caller.c new file mode 100644 index 0000000000..22723c1f0d --- /dev/null +++ b/script/testdata/spawn_callee_exec_caller.c @@ -0,0 +1,6 @@ +#include "ckb_syscalls.h" + +int main() { + syscall(2043, 2, 3, 0, 0, 0, NULL); + return -1; +} diff --git a/script/testdata/spawn_callee_get_memory_limit b/script/testdata/spawn_callee_get_memory_limit new file mode 100755 index 0000000000000000000000000000000000000000..715691fdc7e05ac0e0627fd14997f6b9437aaadc GIT binary patch literal 3960 zcmeHKeMnnZ6uR#exSQzcV!e*W?sc~I8o22#w zWbY-$H1>;?SN|G# z;N0Ii=l;$;@7;Uza_?vCdsdpF5D^;vj<8oH$INoaP_AU)J~P^l6wq!&F9D)<24b7! zewn@swpB|qNF|KQHGSDV2)Xc}AOumq58s7 zbh|_`C@$=EUm5ksN`rGKX$rb1R%9uwXr*kTEppBk@WL>8Xg-hH;TIw>R(Rav)F^k< zHht?CV%rglh?YT3P+Zh>Q%`d)i7bq|sR&+3qr9%)GA3DLx;Z42gDPouC!(x#^TSWC z4_gXKlYwz@QI)H3k)@L4!8kg~tnhcG_W~q}o@25eZU%U{(=Kcq_2{ z0##5tGuFyF8j_LFxK*RRV^z(Tr%mB$Gkr0ntN0+8lh;kRp>`Lbppjz38Vv!D*-{{3?OJ+0SFqW0YT#w zAZQ!`g2H<*F6Kp|L3ICOB&wt`Eq(uDQz8=8BdJEWe_AO2Gb)S}m0aE*O`RBh@@3+~ z6YtL}Zix#GPrB2J+MaEF$?|873m?oLnfWN)lH_x8=!)~-oewrFHwDVVsJLrkg+Iuk zATy9I+s=1yqyq^?%ll6$I;$oNQ?FL7^xIXADc^xJeP`&iQy(8V)_08lgo7Cg=)>rm zeYuA33NgBy4B{RJ^f|`wqdiEmGmI85i~8^!9a8`+P}8%GFAPzskp8c`5BG<;L_q(p zF)+yFW7g->M}l;0a##mXb8^@K_TvOu*UUOGUG*gw%G0XZ$e}8;IKdU}zq-}FT*wvr zW4}I=)(EfAjUen?E5+vYDiY#CpeD5KtI=z=&U*gf3{x^P;9An^h9>eAU#pEu>z-F0 zA(LwY>A=$s{j3dJ`Mmq+3sn)iI&NxR(o$^hZ+PFSwYt4aue*l>{Wc@T{&Y!q<3Z)W zEX?UV47?5Zl=!#8*C`Rzi}!X#mnyx75zMgf5gMU-6@%2GA52NgUTg-=$>(8$ zwz|5vwQsZn*_@T%F0WhWG6iw@y0eS%~BMu-n!M$$x82RN~?g&cV_M3boraPF6$iv9_!jHc1`{ UXTLj%VLT+?gYDTtu%FNW2NtfolK=n! literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_callee_get_memory_limit.c b/script/testdata/spawn_callee_get_memory_limit.c new file mode 100644 index 0000000000..574544f877 --- /dev/null +++ b/script/testdata/spawn_callee_get_memory_limit.c @@ -0,0 +1,3 @@ +#include "ckb_syscalls.h" + +int main() { return ckb_get_memory_limit(); } diff --git a/script/testdata/spawn_callee_out_of_cycles b/script/testdata/spawn_callee_out_of_cycles new file mode 100755 index 0000000000000000000000000000000000000000..46c8861b15dd0290f74c33291e1129858d2e19fc GIT binary patch literal 4800 zcmeHLe^3)w9)Fvk2JmON;t`b}@xU@QBa(_F$b~>cr7fL0#T%Vb2}}4{sFH}TiX}fb z+x)_D(n4+gb*bv);+oqFRz5`L&CI1PnZ=-yj)w*_wQul{v2 zyqWht-(R17-+ga)-@f<0<_#?eK>%Ag;Cn!6F2<%}9ZP6|@~OZ^z=drzh=K@q^PsJG zF&j7=3udd+*QQL=b@;PcU`GD}=sL&v&&AR4EbeFR46?l3r6x^suOO6W z9RZ13xED>~?AoK<=GJ6<1gI*r_9Raf4R0CR8rt6L5vc@%$&_&6sOWWZ)DnTIP+}DU z)Lq4uh^~{KeUC{@t`tR7ru=E{!ZXJ)c?uqkUk!cn;LNE=mf!IQ1XEC~U~AP>qg=^< z2MO#}8{3Q=EKsGcZmZ_hB#l(&q#mF-*Zi`mml%+BBXZ_oVVylzmYUQBPpNPa)ne9*K@t*hvcee#jvU9iX~9t zb%jaP5{~td0n$%Q=H`U%9;qja9HxQ}d;CzFHMvZJ!+RiH%fyC3(hF{o5?(*4#7k6Z zqexydu6X*=qx${>eSe)iIq_3Ce&WjL55wn&u7x^#wUZ;GyPl{Gm^`pw$<+hS-uQ2A z`jkp-`9Pg*U&s4j8U`Ao-b<^yRa#vUT!Ft(7mE#XAd;=*wgbQLdw^vIubqgf(G=@# z>s|X{hu<{`B65H8zmUj!EGO7~B7BnYTmOk*S$?Mx3Eo`$Tq(kkh(Z}-M}pUOjL7Vd zouA-2ZZ&b9(AxYC2NF>#tqu_EYJAdmNa0@Zk`Y&|{%9kDZSq^aAb9;RgG%?O2$rp| zDn)CN;NRT+15Urt4tcnC({c26gUIi6g1x8d9%uCS)sDfy@Wsl$$AzL~j16k3}y21mZ|Dco&`=q%{WKDtV0GAoOJyT{olDY!EG!GIIXrn37b zui!Tg<6a^fP)}j-RLy-a@q|>0T)^*4Mb4KjD|==v!aA`<2cA_I)hv4V@u9-TvyD6P z&YHL3JBTbz9=cJXDJ$&t5CsRt!u*4R;gnE@eNctE2Z4B7mP*XaKWNHdQG)Z5c;?pN z@M=<1cB8^W5QoG<>p?1#ib9<*nrEF887NVgwUu$I_^_u#1Hx9ajU-Wqz z1mq^i<(8OW%wVoCSbP7cr2%u(1wpsUA!y|Q(9%-T)B&VIA7~f&fE3ntK15jCc@SZ3 z=R$QznbTTZgv~?F^Onq9PF|&DrV13#YbO zR@;HZ3g4f%cmU^J2(3;+ZP6TykC%v=_i-ELeX+sia$2-|0F#})C`@)Oo#n7IWc{`EM2w^(5`}_;-4+K zTG)Agl>u!4NH!FCOZfE-8{}2%cdy%3OEo&GL8<0IsV;pQN@+l8FhBr6W~ek6>y5fn zAT#Rs8-Yw;xvRWhSE~oIs=6xUE?s@S4g<1ssIYRG&ZvVt8cGcYAVc4)t<~2-@^nHn zozYldRl3)xr~Ws7eWBJ|YAvSrjcg!;bMHq3?NpEO zX`5A8{@PhqI+ilgSprZ5W!U%bIblDa2Nle5usqgG>1^(-jl$zh{v|VwP@c>G4>~ng A8vpxy~26+;=D19|6g@7bj4 zU;gu6!Z$hRbH3m2=X<{2dro`rJ@?O+Jyx2cfCvqWXS{UGr=}cp*|DV zAcO-9vi)bRLQDf&nocrdRIl*;+yhX}$xechE$f)YqP9oz@5z(n2)Y&fdkT^`bB@Nvjf^+E7L+Y34=saM{dUE@Bl2jZJP95%s*v3oq|=UTKJ)51;{#f^c4NjR1O?Y`|M zEyJ{UA1km+%m&66j!kb|vN%TS5xW($F%z?dZp8itbJAYn=yT8wYP2T1Dogyr!C^Xh zXda@mzfJ^O*`-}w7ebk_%!HYXHIDt1GwJgTu*0SqSj9#M6DkXqK4LDZZ0brlHl^OU`S0Z_w?ms`y#u*J<9Co^Jswj@ugfr2?_hXroP3X9mX?DHesnwixs75tl6(!98 zHwEG-2ff{k^IFXp^l6R*f#S4U?mR675_bf1XC7S4rK(4+YB^8|M-$m+E6-YuDL4Ig zO}?L7q-vcIrwBS0Am6ok*ncm1{K~wf4~b zov{LLRvf(tqLl$n)cSBFUp0FpHc@vSRr2Gmq1fZ8)Y(Xo)6oUdqE7QagVOb-qR!08 zw}x;IoC{}BS6?0^bM{u^S$nOqY%b}H{Js4~oNVd(gqG&uPD!KY?a7rd$6 z*E`~>?Op5p#)}qeQqNBBpL!u)H!fsk&?VjPcT2k$_lX+=kl&tK5}ss0Vg}+HHwYbT zXfeX*1m7W5TiHZz?4GivGj`T7>8?1^cZ7a@@}-KG`(CDB;n6yX#Q`{JU)(CR`x*Ut z2KcYV;*8S2gt|cWPypuM^cDw_bXbL0;?}P9Lav{R`HOFU{&jhPkBG(9rQ#ryjajD> z`z1O&F{DS;vnKa+zwv#7)9H84-`6-Kp0SlumVdmVKR34dHVbpw zoI$r`!0%fDmvY`CXsfLJqi$1usgvKnb(_<;dCQgubfu3NN)4Mq zcG+s4xn(h1QSzpSW}y|RooL8ptD9Q4lr=nZU~_FF?s(h@xO=^hFI|Q@83Y-c5davP zUCr($H(v(^xAU+Y3{9^&csCCQr>pkGCce=LhK5%g+_ijD6MqB@FCvAEWnQxkby~_UYMQ30v%4Y#t zK|RS&@DIp_KV6V`yAp3#;t7vTKy-pTkON;ai6_51ml9v4V0t{!&1v!HmG`~#%J-7r zs-MJHp#iRimZeo4{4RHPFSGz(;{KG4(G8dcVT?Tj-jZy9cX|!A4 cdu(YA5=YEfC$$qB#xlGqNL(`9>eJ)@3qC=P2LJ#7 literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_callee_set_content.c b/script/testdata/spawn_callee_set_content.c new file mode 100644 index 0000000000..ed376ba5ce --- /dev/null +++ b/script/testdata/spawn_callee_set_content.c @@ -0,0 +1,18 @@ +#include +#include + +#include "ckb_syscalls.h" + +int main(int argc, char *argv[]) { + uint64_t size = (uint64_t)atoi(argv[0]); + uint64_t real = (uint64_t)atoi(argv[1]); + uint8_t data[20] = {}; + int success = ckb_set_content(&data[0], &size); + if (success != 0) { + return 1; + } + if (size != real) { + return 1; + } + return 0; +} diff --git a/script/testdata/spawn_callee_strcat b/script/testdata/spawn_callee_strcat new file mode 100755 index 0000000000000000000000000000000000000000..c2ac8c4342d75b516f8c6fa2923651159739da17 GIT binary patch literal 4440 zcmeHLe{56r7C*Q5N9_~cW`}4PZ{3Q_H?`U9gdwok0c~+HNQ^ULqV(>zZhO8VY=t?K zY1_NI(jo4V^4b|)GS_4XMx$v)jrsz(V2K2O{DFJ#k-UtxZ(U@hn8#Kku)g!{y%)Cr z>t7~2$@hHD`JQv`_k7R2-+O!dmi1|yhN3_v4g3#?_NFptQ49n3$^x-jpcZK4cf%hL zVGo0ISME_9^T3{`t1A&?7ugnC08E^0R1pegop=#bm13{DUyf7pZ(7;!tb%G>eUaB% zKEWj`d(vQdk{+ezHntre^M%W$G+1^#xcA$uy*G!ik6hF1C`x#F2uwXhiaJLP%Nz|- z8IuMmO{_dJ-+=yx$E23ZWbnZ2VuSQ3P&TiPvU}|vxNrenEg&B7$Z+%29-G@N9kqfZ5M({SpZ6<8WQ>-zJ9 zXJkp*fLYe1!NY2-WX1H=(%DV1`l9j)F-~Q;wZtJYWsEPJm|2~*I?pr*{eGuj+anN9;w2nJZ>A^DbJDTdIqcN5vbg_ETPpp+ z-Z4$EGXtj+|F{&~&t*6DeGyugSeB~SCfdg5iza=ZC^u&5X&Hgw$mz_6oSlB*wW9)-b!AE(6=-q``Z`}t_+IGhOotN%j3@P3@D z?CpNxfyn{a2W%O4$CB`CvtpbDI=&plZyv(^%)#Kf2uuNcPK-Z+`}_$8zoz3>-1QtB z{$7kXVhyH1caDy`up)EdjT>py(>~8}KaE$Cv=STXPtEVU;qz4XHpU_}M=C^i=|6Uv z*xH%YJWD;=I#b94K(=VxA=emU7RA?S3P%7dRAlp1dB6jujeWzV&&@C*YI6HTrz z6MFB~h%v?>_&VwCnoGrr2Wqk-4$e90-rP0ZrFmoWFPmQ-epT~V9-l_BA^-!9TkC`# zKV$rq0sf*`p{xEf)CcsV0hsOgRs_CykiRzLO@De~GDQDtAU0#Or!vDP~ zpAT|6j!XC^u~Amt5FMlD#C87C55@-U-P?p`rkPczqb(VO@$<8V^oQDN*0$mPDKNL3 z1tV(4&;Mx%*o1-$@E*4Uj>OH)83ScqcA1=ct--i4^T)Q6;)uPPvi|sv@%VVv9WUb3 z-H3j7{lJpGuvCGi3M^G%sRF;P0@-<)JPN&~ z&<>^FQPI9-%aewOo2y;?`gOG~bJg0le=<}*ZmKp_fo!sGZ@fKIZ^NY8TRVjPKy5^k zDP-ICudQi)d{5P`Ho|zq1j62E;;VDeB!eJB2Ld){9W5R1b~oPyCb#Q#H<(;4yIyJM z+gxC3-QDWm#kaTfU0`|z6;*cfZXV-gXzJ(ylki$wn`<`)=MpmUZg+cY(>}M0{0{l; zM83u38?Cg7FrCu?Q6}5s<`b~lSVTprk$7y9a-{Z`YTrqE-i4H}uS6qhnbr7O<-XM_ z2`TOD?MvLHNGevKUa%m3n-afGiC6v93#ht^W;86!UwvM7DDm60YNU*6oI1NcFMeQ^ z{EKHm>GK~}9Tm)vx8OXPQ}=&Li9e;p*D7%;Hq)$ literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_callee_strcat.c b/script/testdata/spawn_callee_strcat.c new file mode 100644 index 0000000000..f2f3f56e6c --- /dev/null +++ b/script/testdata/spawn_callee_strcat.c @@ -0,0 +1,17 @@ +#include +#include + +#include "ckb_syscalls.h" + +int main(int argc, char *argv[]) { + char content[80]; + for (int i = 0; i < argc; i++) { + strcat(content, argv[i]); + } + uint64_t content_size = (uint64_t)strlen(content); + ckb_set_content((uint8_t *)&content[0], &content_size); + if (content_size != (uint64_t)strlen(content)) { + return 1; + } + return 0; +} diff --git a/script/testdata/spawn_caller_exec b/script/testdata/spawn_caller_exec new file mode 100755 index 0000000000000000000000000000000000000000..cbbefa050490aac5238a7459d9925b9fd9876381 GIT binary patch literal 3976 zcmeHKZAe>J7(Vyr-lVRs>LPPpYnz(RY|;gz;zvIuYHzMBqlK}KS=gHEO{%U-*Cwg` zfUPXnKhlz@zckzLl7*@93z?i7q5%2n!^r3F8swx7sXbZOKnyz43wU0t5c6(zK( zl8zbFyFoJ`&uw>I9QH+v0yF5l3M%h1A84&j&?$O~o@TjjjDkXsYe$r5 z#5jYbVsMt`wjjzjGyC(Suj6%jMG60?Jg-e%oWVWI-*eD&fRDnMli&f~c=q93pPhEp zQOejCfe{W+zhhPbOn(cod=iycG&Rz~Id&()!BJkXyTxm#i&N#HNvqgBiS$i1Ry}iz zmv^qW2bfKaFPfa*yvR95TEaoyF1?Ov#7xW*&j6cY8kaLC?DdX52i=C>e@8<}P&_(J zhmS9yq2#yY;dbrfj;@=L>}2+2oi6FR_jlfePwLkWTf4MT8lgy}MY@8Fx;Tny-W|i{f4e1(^QS=1pSfYT6%X45IJ2=5)n)e)6S?#VdBLW5Qd1vhO5) zYU2I+Lw$$n4+NMIzbS-z>`$u1jv!;a&LH8w-;`zfCenp8TS935yle{1&`}Mr{8e2W z#rzvc?hnw>@j)Xz&9Ol<#1G?SU6DX0xwm7Ao z4!>1lmB)nq+Dq&0Px6I)U-Xy9${OJnx*CAJYooZVUQJw{^H&8oULNk@PdAEtrZ~SNo*~FZ?=u>S0x-?qevS6UN>|gP|(;1B0 z7dE&C{a1Jk#r<&3c=cZCzbwo-y$^V+?y&gRA~vvy>cxAzq(ht9#z172=*C|N!|92#Bv!?v^mlZF#9!&ql!gqDWR%T#j z23BTZWd>Ge;Mr!NM?D`C5OHy;S+FcYvjU<59sq>Qo>q_7?G>7l+3P&v zMP_H~frDeMCOA~A+ba73ZPS<+2cWG@k5u(c^Je?4`dd+UUysb zF|QM!H=f<_e=hzn#&-*BQ%g0Bik*X#cBa9>cA4ct4eJRleIHTpDJrBjPuJH$%bEMy8z!Xq7!I>B;i$b5dXUwTx1Biv0gjp#_O27*j| zLOrJ?)WghwJwMS~A;5i-`I}Ysv#P$D5LJA7d=Bz>eAsQvjObrqmQ}bog*DjrfWz2F hmMR$qx!3X;IUEulNoT%0$zgP;_hNfy65^-z{{Wf>!u9|F literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_caller_exec.c b/script/testdata/spawn_caller_exec.c new file mode 100644 index 0000000000..555c01e4d6 --- /dev/null +++ b/script/testdata/spawn_caller_exec.c @@ -0,0 +1,6 @@ +#include +#include + +#include "ckb_syscalls.h" + +int main() { return ckb_spawn(8, 1, 3, 0, 0, NULL, NULL, NULL, NULL); } diff --git a/script/testdata/spawn_caller_get_memory_limit b/script/testdata/spawn_caller_get_memory_limit new file mode 100755 index 0000000000000000000000000000000000000000..917118361cf1b1d429ca50b2d9f9918cecbb4530 GIT binary patch literal 4112 zcmeHKaZD3e82|2i*TTdBD+&&ng*xgQ*HB>~6G;KvGP5W%a}$#dj-vu|br!0kiCKH4 zc16*cn$~4m!e}&$TNV>TYFrja2+?dY+5RvtFeUH1-(qw=6*Al+u zyWjV{@ArG}-MiQ8y-&?=TWE>`*=YC^NcNM|W|9hxtHprSOt1wMcwGfAAi^OA+b(8E z#1ycmsB%v%`Bk3gUQHi`O63V*TY`3|1Oc~SnPJu?J z7;-17?dL{>P_cIkOxxBu7Tyml9zj3_Y)venazIVIAa8X;&9t|p8fp^s96c|L2{B<( zhzrv~LYNcg>n2%qznQYQEtIt&E%4c1Pd5&o3DcR>tLYCEW(V*rOR?s3PH?GN2k7Hz zd4&!7>5ZUI5bZOzV}Y=v`RqcGSwAUrMP@Q@&tnDl!>uWMV*u;!h!)=}lpdx74)_w$Ys|uIaXVy^nW{(1D|~FdY5ie&C35aa-T@ zU`8}!qE;2P-+hujF1W5LM@)Un5DgFvw!1EYRuzG;G6GukFpG#DW)RWC3PkiUjfftm z5YfYch>rI?Gm{wzdf`rgAjncnSNcwWQzQ`7fjGuVVZv4NchEJQTX?o67RUfJRx-ac@m_r2;uInKg^tU>-f-zQyI#oG)lu$l-E? z(1UsL8IdP+*^9po3uR6pP(<7bPo;1DS0fj!CmQ%&lT6|8)s9(>_S&s1#n&n$YuUQ? zA(VC80xf3RYrkpy7C!S1e4)&R^Eb=dXEl^L;}5d$R2psd>?`&go=a9EW&ZVy_VV4* zXDq@wu?Kl+zp&)@#n-by4UoO9?^VXOGAhloqL|P)LL-xuFh`$2vF4+GFfcbk&5!p z&4)^x?c~Cd3r{Y`TRGzrw2Hus(2W3K=dt=-*V;6Jh3Z3j`jG$8}$bar*N9(LNu_r~)Z`OhW)#Y<-# z#L1oy;w%AnVvJ)SN})YHUt3cO YvQBO$xjc8djbL1we@k*B#;N*$0W~D(9RL6T literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_caller_get_memory_limit.c b/script/testdata/spawn_caller_get_memory_limit.c new file mode 100644 index 0000000000..a07b3edf6d --- /dev/null +++ b/script/testdata/spawn_caller_get_memory_limit.c @@ -0,0 +1,40 @@ +#include +#include + +#include "ckb_syscalls.h" + +int main() { + int8_t exit_code = 255; + uint8_t content[80] = {}; + uint64_t content_length = 80; + uint64_t success = 0; + + success = + ckb_spawn(3, 1, 3, 0, 0, NULL, &exit_code, &content[0], &content_length); + if (success != 0) { + return 1; + } + if (exit_code != 3) { + return 1; + } + + success = + ckb_spawn(7, 1, 3, 0, 0, NULL, &exit_code, &content[0], &content_length); + if (success != 0) { + return 1; + } + if (exit_code != 7) { + return 1; + } + + success = + ckb_spawn(8, 1, 3, 0, 0, NULL, &exit_code, &content[0], &content_length); + if (success != 0) { + return 1; + } + if (exit_code != 8) { + return 1; + } + + return 0; +} diff --git a/script/testdata/spawn_caller_out_of_cycles b/script/testdata/spawn_caller_out_of_cycles new file mode 100755 index 0000000000000000000000000000000000000000..0c6c76352042e717bf36da05ac11f2cc88fa9634 GIT binary patch literal 3976 zcmeHKeQZ-z6hH6vwPiBdW~UQj(5<-Yg3Zdt#`sve&DV~_jKqj>Bud|2%QmqHZ2=(= z``UH2gYjWWJ7bKnMq-c{BUwr?2A5@Fi6Oy12qq+^td%WsNk`lqDmc&Gdv|si|KdNh zlbriIAHQ?&d-vYH-upiPij`#;pu)nhKs>7wvnYv?T-hKw3v2)twoBm&MA*w=tXRn_ z^m(w&Te3k%BB)-F%gz8CCY_>CgnZd2EDh=rC4Zz)uA}JH%DjsT(z^Nri7!oR(&b$l zNUl;1NK>0#r-%Hp(qIN)JyUSb7VM}?vT1glolx_=JY$utjIAdW`QVL!2fNIJ$vozH z-TJ3NE%<#A>^*#~-leX$aNh*UD53rf?vZszx#6B3_+@188eSJbILGcF&N ztzkn3d}XL=mR}2uH8c6?{ZA701*OTrHECLtKAj;wOW*U@^RO+3kok?Uif{?qk>&R>1*PM|?YyHo83}2dbXu-SGf|eV43AmF-Z9X%)>?EN z*Cf5X(jMeWIDafPv1XQc47VeDD`68RVTs3({V(RIy}{A%U^~hCZ)q$KiTj4w$iW#H zOnrMNazHb?rRPdCH0t~2eH6m)9 zLqv_M5K-eSB5IsLM2!O?D!%vhbY3JHgqyvQsG6B;*_*wsiAdB4@)+IzF<;pqQQu%u z@yWVqYTppf?VI~vom5?srkd|}r&YB*tNW8>4_c;PpV%?}R=O=I=H#&D$G$ukY<}1p zSQCa7T~o8-HV%T^rSzH-v3n^SNN{@5e^7O_>P}(m*{a#|c8z1y+i70oB?tOrMmD;S3v7AuCYRvsx?+F{zO8 z&+E7A!a^co+-eRCaQTGw(b$e48@qGWfKRjkstN6T3A(Ox>%?_!Ek0hB)=WfRtFlNV zLSfyRmG*~)LZLtQ^8Hu;{LTVe9l=_LYfNHgjSy$>a!hf61RKFz z-r7@-1;{B|%l7$5y%h&{cY4GF zz-&g7%U8P(R9AJb+gq{IMH+!LB54k{3FbLylR=chg8*Riba=dOuh0f2uk$@Gn4BFu zcew?Z6HJ|ZI=wpuw_7*_rd{Yz+aY)btdpV5;{lWSuFK`zgT-?XWD>kycW2vvualfL z9$(0RF8MDecMBrpa~?riKEzXYw&0<5ffS%e>M4!hN9a98xvtFDJnFB&%(AR{pR#T~ zg{WMA=IfUz7DXfad0F+Rl=@RjJ>}63s86vH6WPyC_e-Br--P#)Y@u~DR*Obe?32~x1d4#r1Lka)K4n)8z@o1N5|(ePR7UGwm@k8OADehmxM?Skrq@Od+(f+ f)zEvbEh|P$T1Ug#?@nU`9m>7fo*hK{(fYpu723e> literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_caller_out_of_cycles.c b/script/testdata/spawn_caller_out_of_cycles.c new file mode 100644 index 0000000000..3642385036 --- /dev/null +++ b/script/testdata/spawn_caller_out_of_cycles.c @@ -0,0 +1,12 @@ +#include +#include + +#include "ckb_syscalls.h" + +int main() { + uint64_t success = ckb_spawn(8, 1, 3, 0, 0, NULL, NULL, NULL, NULL); + if (success == 0) { + return 1; + } + return 0; +} diff --git a/script/testdata/spawn_caller_out_of_cycles_wrap b/script/testdata/spawn_caller_out_of_cycles_wrap new file mode 100755 index 0000000000000000000000000000000000000000..da53965757b0cf9179d47259a639997571a1bed0 GIT binary patch literal 3992 zcmeHKZ%k8H6hH6vy;dd@Sjm_ZN1=vpL>npuWGX4L*9uuQS*9B%n|-`iV6INus>8&r ze<-X7{z*-%F=j|JLY!Ha7*gZ1Fh+3RxL$ld*Go?{$S`pZvCP zl5>CO-19s4ym#;I>%E_FZ<=U|0$FJI6^OTA>N84#2ic-QVn)~o3T)THbBJ)1!M-h0 zT%xDJoVG+mu0)Vs7R!tP^pHVOWQ1JNCoCmuuN3di7xQFvsYKp&3FW-HJP%hAQzptf zlMpLX40}>L?B~b4;SzrmpsJ&N;hl(T7Ot9Wr~Iu!v}&j689J54^>LKRW1`H3Yl5G? z>vQ7ZIWUuRS;Yd&U5YE%S>SlDJBZZ+x9et##pdh)u2`}4a(`# zL`7iIDD+K&x~ayfW|#)g8-*4>Q_Oh7@##&AoOQef*^Puvn1m&qM)tp$6P8`p0W00c z;`{HcFY6ZC$LQdRc^Hj<^C);+xwy0ERwz53Jz1xU+wcFCH{o^PP>vaUlwlem6l!q~ zf>srUh%yRV)Ch}+8etGoBML;+2#tsup%76cfQX9kJvWyV4Ef<+UogZ{OD%n`uPGV~ z=|HT}<(+hw{t&@kv)gQPWd25G#GUC$)e2z|{MR z=9rL`MVFoa^0dEkp~<%?02?|}i^5(8{LGESredLME$xdk8o_%)ajNoBe*C4%#X*bG zI^o*YG0;JuocLhZ;eo^Shdj=RPZxlTmW67evzyU=#Q^`%r^_;Y9qIwa<^ar{_2>dg zI;=pJuezs5$nU1&-MT;TKCBJ!QJ=2C;2UOg3G3420Y4pnG@`|)IX0q4dp0Vs>(V+g zosAoNOB2fJ;Md9p*Y219!y=qh`;fQh2bTP9gnAaJezLdAI+cm-jN6F& z9$=K}R}52gUNniAr0>pm5?;voHj#L2z4&`S_p*q_4I+}*|3T!pSyyrQi^>=5kEefP z@jJUJt23}V1FJKzIs>aS@N6?MB%POKG}qU^u6eb^VB>45x7jMntEyhp7`EyS`f?CM z<~{q;J#{85?r3ug$AQ{`CX>rLj#pK-Z9Q6k&`uhjGy-W(HuHuhXcj>b!HEE%ceXlR z4j11HdYA2E7wB!R2M;-TyAAYhN7`Hmd544V0R16!WZTNSc+3-_+35tm@R8kaJA%ne z52WW^E=ODQF_(>;HJ)9_e=hkiCU*@YQ%fE}Q3mjoohf*zT_$g{1@@qgwU4f#rSG}s6#+R +#include + +#include "ckb_syscalls.h" + +int main() { + int8_t exit_code = 255; + uint64_t success = ckb_spawn(8, 2, 3, 0, 0, NULL, &exit_code, NULL, NULL); + if (success != 0) { + return 1; + } + return exit_code; +} diff --git a/script/testdata/spawn_caller_set_content b/script/testdata/spawn_caller_set_content new file mode 100755 index 0000000000000000000000000000000000000000..85c5dfd927dfea29a9f7a65b5543da6622031bf2 GIT binary patch literal 4352 zcmeHLeN0nV6hE(hZ6&f%RuqgdD|Mj6byOH1icKqP>x>`CGIgNNK1v1Vs?t`RCd7VF zSWz^lu4OSxkS=6Xvyd25<1&#DB4#n!{xB{vSqgMQA_wv6Xfbjo<%H36xgKG|)^j7noU4Wn=; zSA4@gUShk@;|XQ@Mj>j{Cre|apj(>ID>1a2^^C_g3NHEa=crqr_jVghL;@Jke^+l+ zNZ#0fufyXCtp*6VnR^PKdqUC3JWn|1HlU9(700EJSU0ZdM0S5~z{tJjAsqY=7N1FV_UU-LSyV~JLKqj25%4j;5mqWL zdKI!fuI{P>wSlIlGVPdl{IW^=EFi0e`n}p0=}W@mez+Z7XDR_-^~Tukm}pp)&VaRCT*;{3TK142x88eIguINj{2%g;NQ+1WIow-isN5FC*!vVRcAs=4E0*UU z(pg%DKv7n#Q?Tql_dDrkAG@0Mga${}OdBeD$w>ASHenK$G(KSm$B7k79%GCiX zSp>q;2&k}xC5TwUEFzY$7!gZYgoq`~AYusvA{Kl`CMJ>sK_5J52?QlfycRuZDT@Sx z*}&&$^bEPOeh<33Q!~zMgM+m_&%THpsC{ote9Jw)?O9_?T->~>J(~4m=lGtH^5G9- z6;Vq$1s{7owq~`ZajD1~VU-ro32}XXf68E5{&a^~ zS~=j{afB5$@ITFq01mWC!))yV?)$eW#@`8L=L;`M%*IPcE( zkBUNKWO)mlS6Nb;n8Bv(Kkh%$`niZV`(2Iq1}i75&xgu=qELUA3P*FiOO5TP5xTGO zePSE-XPnK7Nk; zr`1%y)v{}t&FH>fJ*iaP?30VXl4&HyP0JrcUUeU+u&28DlhSXrBt3vj(p0#3H?L|^ z$ruu!kl(0GsVbR#-PYypFliXWkLOfZ9_G%n2&aBG@|OG{A-_6HsRWod@*c=(kj6H# zE*-u-0J@nr@eO9e<0?W95lyau8+cqRyqCWeux`$~JI+|izYjYFG~=)S|0Hxaujbvq zn*W;Z@yO2-{0c3~;tDLTz~TxluE637yxa=(3HJ$#rqa@l%C%J*D_2}tWX;PhC|IY| zY*1^|xxkxDJ9p1$^hQi>uW?xFfGNQyE0@^o3i4|<9LqguBNay~3#m?3aGE$&@L=J= zfdHU(R6Cq@CszS#r}YyjsO?89IVT5dYxTiHcFtx6b!Q<{cNyZ-W z7mhd3D&fEIt-}3IF^>(fMCj9VzzV@1uS9X7_dt3-T#z0X_EqRbuC~;_Q`rAbA-|jt zJ5$sA6yHKi(j5Ogg8v=CpYmt`+NZb)4P-7fKYi}{1plpg_nRx!kLvW;nCmak;8#X2 z+{gcE{M3IdHb_jGUn%%21%G-DrTm5Ycc6h}6ppEs2Gsw}84cgyN5}gR%^ob6`xtMX gt?B;>rdd_IMg6Io^y%2Cj^IUM{MB=n*k0)W7jlF!QUCw| literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_caller_set_content.c b/script/testdata/spawn_caller_set_content.c new file mode 100644 index 0000000000..bb996739b7 --- /dev/null +++ b/script/testdata/spawn_caller_set_content.c @@ -0,0 +1,80 @@ +#include +#include + +#include "ckb_syscalls.h" + +int main_lt_content_length() { + int8_t exit_code = -1; + uint8_t content[10] = {}; + uint64_t content_length = 10; + const char *argv[] = {"8", "8"}; + uint64_t success = 0; + + success = + ckb_spawn(8, 1, 3, 0, 2, argv, &exit_code, &content[0], &content_length); + if (success != 0) { + return 1; + } + if (exit_code != 0) { + return 1; + } + if (content_length != 8) { + return 1; + } + return 0; +} + +int main_eq_content_length() { + int8_t exit_code = -1; + uint8_t content[10] = {}; + uint64_t content_length = 10; + const char *argv[] = {"10", "10"}; + uint64_t success = 0; + + success = + ckb_spawn(8, 1, 3, 0, 2, argv, &exit_code, &content[0], &content_length); + if (success != 0) { + return 1; + } + if (exit_code != 0) { + return 1; + } + if (content_length != 10) { + return 1; + } + return 0; +} + +int main_gt_content_length() { + int8_t exit_code = -1; + uint8_t content[10] = {}; + uint64_t content_length = 10; + const char *argv[] = {"12", "10"}; + uint64_t success = 0; + + success = + ckb_spawn(8, 1, 3, 0, 2, argv, &exit_code, &content[0], &content_length); + if (success != 0) { + return 1; + } + if (exit_code != 0) { + return 1; + } + if (content_length != 10) { + return 1; + } + return 0; +} + +int main() { + if (main_lt_content_length() != 0) { + return 1; + } + if (main_eq_content_length() != 0) { + return 1; + } + if (main_gt_content_length() != 0) { + return 1; + } + return 0; +} diff --git a/script/testdata/spawn_caller_strcat b/script/testdata/spawn_caller_strcat new file mode 100755 index 0000000000000000000000000000000000000000..7483b03f8bfd4a3a1a82c958dadb0e124be5caa8 GIT binary patch literal 4568 zcmeHLZ%iBK8Gr8Vv!P83#I&RhG=NjsSm!~^@@Gk0lhk$^Ev>XJZBuCr$Jw#HLKBP= zmab9HcQ~HOQkosJlTMuoNJ*1P)h3p@>eOW(N{KY3YCi<3RhkTT3tN~V8^$b!c+cy* zqlSIhhkl!Qr1$wff8T$;_uhN_s_naWnxa4@8vX@Ddt0$t6~`y{%L4IPVJm2muYr3J z;fNM(k1Bp8d*u;(A5#zw)4*w}g5*?sp2Rc}*n& zTXjO0s_U8t*r~ZfrFXQQ84{w^!D*;`Chl%;mqPkOmdUtV3WW|?rWT(Y(A)+|4~!*s z-eH-M^zBf6+cL|;4hVWI3%Yd8KZJyk5+;QyVMdr0=7j}%jQ*^8p0S;_QTDKXT|s%V z^wa0X4xCUC%oI_N2A_CfOmwuvxoI+L-#0EfxQEjacS%9UO)QD^gN=P~`N%!~n&97^ z`&fa;@gY3i=c!8qAFTqA0_Q(81gSa0$-uu0Ukli#;g9!~;Z_3fD zqU5p9V1yJ5%#o-v{Hfg-CGb>9_2f0T&AB&$d*(6dwI1D6P0AdeuyUs-z;Ixj)u7dS z0#B4T2enmNA)1`pn6){t;m+#4B$`B$DDD(S|5xOA^Dbwz3iZG4$Ryf{Nd+=<1N6Q^WDQeGC~)- zdR;3#Z}JDuYhI7m}KF|9YdK;BSm!@Ze4~(nMRrB*5+giWr{1$fZ;ie z8P#dbOvWl5O&6W{o4_|oacM~(6L>>srbx_LS5+6E%BYe?Bf1nu1Y`HIRfuQKkm8NlMKi1iuO=; zP=C>S=>yRo&A$1eXup^xax5ngXMg)A(LRb?W1GmDzugCxUmSlx;BWjzbl_prOUF7P z{Y7DqfyrcXrom{AhjKiY;}>&$ILAkk|DgSQGn)6P^xpZCDb2R-4gHClg{NkpoqA#N zhpCnXS6E2boqGFJaPQ&)abpl(8c znsv@`|E}Zx$LW{Hf3)kx{uk+17N142HVkK*7q@U-A+7N@T3|mFYYQ8GAL$0oV_``5 z1Zu<6bX0>;;+F0WTxp0(hHAgK@u?-u#>Cnu8^kNxViI+3;)Ng`9lL78*&MxULiu(~ zJyE$6qV4il{H!LWo07iYXboIvOD(>zJalCfADiKd#-~KHRHRVREF(b(M|ZJt_*sI z&F)MkWm|KLoOpeuaYyEnwyWX=M+0U1_%-9@(fTi=NX&`-7+3HSL*8oKZU(46@>Z$q z(xtX*c`Lqg0OC}i=1L$fpa|e`wYDBc>^$sib*j3mp#Cf6o_Uy--{VtxcM-bbqxG_# zFPE{tLPp~Ie;{==_nUA0x^ZpW=Tm=W@K#-=)g4&ffz=&Y-GS8|_-Z@wszPU#I!Q&x z?%m(1{F=ML#ctcO)n%^Vy!q>u4Vz32rh1TFj;Ho7S(@xP37@xvI|kGa6t%^S@7U%> z@1`U52ipi^3F8QRxrJ@WL5mEW3>^pnrVdYs-{)srz~p!R*bgS(VJGWn!Q}EBJmh2B zTwwCPE&}u3r`nP@w4Q_rOD_6B&!H94*zi zN +#include + +#include "ckb_syscalls.h" + +int main() { + const char *argv[] = {"hello", "world"}; + int8_t exit_code = 255; + uint8_t content[80] = {}; + uint64_t content_length = 80; + + int success = + ckb_spawn(8, 1, 3, 0, 2, argv, &exit_code, &content[0], &content_length); + if (success != 0) { + return 1; + } + if (exit_code != 0) { + return 1; + } + if (strlen((char *)content) != 10) { + return 1; + } + if (strcmp((char *)content, "helloworld") != 0) { + return 1; + } + return 0; +} diff --git a/script/testdata/spawn_caller_strcat_data_hash b/script/testdata/spawn_caller_strcat_data_hash new file mode 100755 index 0000000000000000000000000000000000000000..32ab33f22411c1ef2f76e8d4ad8f470446d8ae70 GIT binary patch literal 7008 zcmeHMe^3+I9e=yYZW2WS1A;}*NGw#w=7`~!KaPT$gfi;2_B>B-?qsuxfjdzMQL0zx zk_}4?=rP`Ea@IQKU=Dvxo!&4S=Q>x1V*uM5JH0=|j@P*X5&@MfI1+*grtf8Ut!Acw zUH|D!-pu=czCYjh<-70gPTu=azr}!K7!Vr{9s?xR;JmIxFjS=T4APc>A|Qb@0nCR8 zYNSy2hcv-428=PXmvZVaEsXPE&e$hqAO9LpYC(n>r0^IW}Y zpxDjILNm#~C$hQvH1L;^vpds3LV5dfj>Ia@PizFDq5oG8&R1{pG9 zP6>H>b`wi~c(p3HFyudU)=$ zt?)VhVjQ$C!u6{GW*DD{+{^#6G&ys?)rU=y!IR@?Warm;xo^_t$=H6yn>BUZOVa?cPZUMl#h7?Azb#C|mF?rHzIc8{UTwok_cO0vO z<0gWM#35@2NdQGJJ--7Z^q;pXNq{FLZHEG-y$YPIES`Q) zzh0q`nrgKL6aUb4ky$a4XpEG#A z=E$kYsteTO6~w0mJ=F`+sozlnMfe%gFZhZjuXy2ZIB^@ej0BMM5r80AB5-Wv*?M-Q z1kPK}I9}V7yV$LmsCWMR^SJ7`-$Mlslo%9a5qr!X@0nP~yq^jH8t6;-1Tcj05dOwC|CQaYzgV zaP{)lr+>V zuKB)cx!n@*_@B89?ntNXe96ULm%$e~_cxc}d<60SDBlZy)q~JeMT?RMN8n6ZUzEC|)E}kiqqHwd??C!a?e+=D7g(r#x-lqO z+qArGAZvEp&uPBW%$CpXa;@}$jE2bw{kjye($3(@6?Ef#+~t?5 zXr^9rG;c5^ke(Oms36Tl_Kk*}lwtJK$TCP^;Hw1i>(;$fhxyb07$QeXdv z%447tZ-cXB8aUObvxZfeKH(vHE6P;r4dGX+Z@4;)T1@}VN9s#=a{uFne2(sbe)7K) z==T16kBeYYI&ktuDW)D1WVajmcuBE#|fP zmiz*3!P-3SUXzK=v*ere%(;0w%3P$?(R(erLYlVFg$0GQE?38o0zjo@-@XG-s6Sxa zXNDM+ML~3mW4r?K3dAcAuRy#4@e2G;Do`Q(-~Xq8R|FIXe=C*$pDka^<8=W=`~N!% zrwCx7?$+hJMb*P&-x2V1Bi`Z_h*uz9fp`Vt75HHl_)usn;hb7T(3Z*hFMXMCzd*m_4S=8)vH-9|h=)hVe0zT1z>Dba|(rJh?fiZ7veRBIEI*C#8;sq@rC$wAwFFQ6#f2N{Ca3WzgWyKt~-?wUlvop z*zrnZ;w#hm`c(?|J;Jq+nErYFL`4~7(3oO=hY;@&;)_H_0b}!Tg?f}RH^xtl|7nb# qpB*2AOmD&tbJxVUJ-@Fq#u&tSQH^AA?xGIiq%i-=7nP8YjsG{Kw1SWT literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_caller_strcat_data_hash.c b/script/testdata/spawn_caller_strcat_data_hash.c new file mode 100644 index 0000000000..d5dd9bb484 --- /dev/null +++ b/script/testdata/spawn_caller_strcat_data_hash.c @@ -0,0 +1,33 @@ +#include +#include +#include + +#include "ckb_exec.h" +#include "ckb_syscalls.h" + +int main() { + const char *argv[] = {"hello", "world"}; + int8_t exit_code = 255; + uint8_t content[80] = {}; + uint64_t content_length = 80; + uint8_t hash[32] = {}; + uint32_t hash_len = 0; + _exec_hex2bin( + "b27be1358859d2bedced95e5616941fbbc4e5d4d043ad813cfe37ccec767c303", hash, + 32, &hash_len); + int success = ckb_spawn_cell(8, hash, 0, 0, 0, 2, argv, &exit_code, + &content[0], &content_length); + if (success != 0) { + return 1; + } + if (exit_code != 0) { + return 1; + } + if (strlen((char *)content) != 10) { + return 1; + } + if (strcmp((char *)content, "helloworld") != 0) { + return 1; + } + return 0; +} diff --git a/script/testdata/spawn_caller_strcat_wrap b/script/testdata/spawn_caller_strcat_wrap new file mode 100755 index 0000000000000000000000000000000000000000..da53965757b0cf9179d47259a639997571a1bed0 GIT binary patch literal 3992 zcmeHKZ%k8H6hH6vy;dd@Sjm_ZN1=vpL>npuWGX4L*9uuQS*9B%n|-`iV6INus>8&r ze<-X7{z*-%F=j|JLY!Ha7*gZ1Fh+3RxL$ld*Go?{$S`pZvCP zl5>CO-19s4ym#;I>%E_FZ<=U|0$FJI6^OTA>N84#2ic-QVn)~o3T)THbBJ)1!M-h0 zT%xDJoVG+mu0)Vs7R!tP^pHVOWQ1JNCoCmuuN3di7xQFvsYKp&3FW-HJP%hAQzptf zlMpLX40}>L?B~b4;SzrmpsJ&N;hl(T7Ot9Wr~Iu!v}&j689J54^>LKRW1`H3Yl5G? z>vQ7ZIWUuRS;Yd&U5YE%S>SlDJBZZ+x9et##pdh)u2`}4a(`# zL`7iIDD+K&x~ayfW|#)g8-*4>Q_Oh7@##&AoOQef*^Puvn1m&qM)tp$6P8`p0W00c z;`{HcFY6ZC$LQdRc^Hj<^C);+xwy0ERwz53Jz1xU+wcFCH{o^PP>vaUlwlem6l!q~ zf>srUh%yRV)Ch}+8etGoBML;+2#tsup%76cfQX9kJvWyV4Ef<+UogZ{OD%n`uPGV~ z=|HT}<(+hw{t&@kv)gQPWd25G#GUC$)e2z|{MR z=9rL`MVFoa^0dEkp~<%?02?|}i^5(8{LGESredLME$xdk8o_%)ajNoBe*C4%#X*bG zI^o*YG0;JuocLhZ;eo^Shdj=RPZxlTmW67evzyU=#Q^`%r^_;Y9qIwa<^ar{_2>dg zI;=pJuezs5$nU1&-MT;TKCBJ!QJ=2C;2UOg3G3420Y4pnG@`|)IX0q4dp0Vs>(V+g zosAoNOB2fJ;Md9p*Y219!y=qh`;fQh2bTP9gnAaJezLdAI+cm-jN6F& z9$=K}R}52gUNniAr0>pm5?;voHj#L2z4&`S_p*q_4I+}*|3T!pSyyrQi^>=5kEefP z@jJUJt23}V1FJKzIs>aS@N6?MB%POKG}qU^u6eb^VB>45x7jMntEyhp7`EyS`f?CM z<~{q;J#{85?r3ug$AQ{`CX>rLj#pK-Z9Q6k&`uhjGy-W(HuHuhXcj>b!HEE%ceXlR z4j11HdYA2E7wB!R2M;-TyAAYhN7`Hmd544V0R16!WZTNSc+3-_+35tm@R8kaJA%ne z52WW^E=ODQF_(>;HJ)9_e=hkiCU*@YQ%fE}Q3mjoohf*zT_$g{1@@qgwU4f#rSG}s6#+R +#include + +#include "ckb_syscalls.h" + +int main() { + int8_t exit_code = 255; + uint64_t success = ckb_spawn(8, 2, 3, 0, 0, NULL, &exit_code, NULL, NULL); + if (success != 0) { + return 1; + } + return exit_code; +} diff --git a/script/testdata/spawn_peak_memory_2m_to_32m b/script/testdata/spawn_peak_memory_2m_to_32m new file mode 100755 index 0000000000000000000000000000000000000000..c172d7fe777fdd02f9f7da340d23e4e1786913ae GIT binary patch literal 63264 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%0Aw0Ajpfg&2AN3NiA27N$wLNfqHuDjA4N#NZDw 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 UcS@3#zwC%t;IC3n55ZXfFT-{)O#lD@ literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_peak_memory_2m_to_32m.c b/script/testdata/spawn_peak_memory_2m_to_32m.c new file mode 100644 index 0000000000..88167a4fda --- /dev/null +++ b/script/testdata/spawn_peak_memory_2m_to_32m.c @@ -0,0 +1,30 @@ +#include +#include +#include + +#include "ckb_syscalls.h" + +int main(int argc, char *argv[]) { + int8_t exit_code = 255; + int8_t can_i_spawn = 0; + if (argc == 0) { + can_i_spawn = 1; + } + uint64_t depth = (uint64_t)atoi(argv[0]); + if (depth < 14) { + can_i_spawn = 1; + } + if (can_i_spawn) { + char buffer[20]; + itoa(depth + 1, buffer, 10); + const char *argv[] = {buffer}; + uint64_t success = ckb_spawn(4, 0, 3, 0, 1, argv, &exit_code, NULL, NULL); + if (success != 0) { + return success; + } + if (exit_code != 0) { + return 1; + } + } + return 0; +} diff --git a/script/testdata/spawn_peak_memory_4m_to_32m b/script/testdata/spawn_peak_memory_4m_to_32m new file mode 100755 index 0000000000000000000000000000000000000000..a0b2f3b6247e09d5fa71f1a8f3f306b0ed3fb2df GIT binary patch literal 63264 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 O>J|8#l+#1d*8dB20Wf3$ literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_peak_memory_4m_to_32m.c b/script/testdata/spawn_peak_memory_4m_to_32m.c new file mode 100644 index 0000000000..2ac0d67b0e --- /dev/null +++ b/script/testdata/spawn_peak_memory_4m_to_32m.c @@ -0,0 +1,30 @@ +#include +#include +#include + +#include "ckb_syscalls.h" + +int main(int argc, char *argv[]) { + int8_t exit_code = 255; + int8_t can_i_spawn = 0; + if (argc == 0) { + can_i_spawn = 1; + } + uint64_t depth = (uint64_t)atoi(argv[0]); + if (depth < 7) { + can_i_spawn = 1; + } + if (can_i_spawn) { + char buffer[20]; + itoa(depth + 1, buffer, 10); + const char *argv[] = {buffer}; + uint64_t success = ckb_spawn(8, 0, 3, 0, 1, argv, &exit_code, NULL, NULL); + if (success != 0) { + return success; + } + if (exit_code != 0) { + return 1; + } + } + return 0; +} diff --git a/script/testdata/spawn_recursive b/script/testdata/spawn_recursive new file mode 100755 index 0000000000000000000000000000000000000000..f7a13029a5dc30613bce176fe4e400f0638bfeed GIT binary patch literal 3992 zcmeHKZ%k8H6unqhWGX4J*CJUoF>@Oxn|-`iV6INu`UexU zzLrvpqL61=mt_mm%s96!CWh3wY>XhmWHH%37)?wzpq-G61jx#8n~a^yd$%hj`{bu3 zoaEf!Irsd|J@4In`+Dz(-0K#aq7V@p{f4l&SLrh=f%}=Vfn#R04XL1Ajh+HTM;Pea zti%<13alwhHb^Cm?2=e|1fh03Cc1W#yW-ZceDUR93B6^^JA z#cfllr$E&wCU-cy2Yr#kz!duKmDZN|x1yREbjeyd5onUYs+^>!=_JKWscdZ z?Y(xonT7Y?SyLPoS_Wz9_#7IDe={l_Q!ni7xEaojXO35C;?8@2=ZyKh*VTjO4t0b^ zC>(C|UPgLN3`Ny3qz8?%fS^$Z5HzX+1dY;wpiv4CG>QO0;k{>Pv!rkU-R+dZEVbCu zcRTB2QrLjx8tuMuZ_%G&??B%A^OfOv%iyC=V(+xA{W3n;pqw)O#Ix^a?ho?E(Zv=ZL zM%Hz4otU<|^=FF`>PhL1GP8J_&#k=zAETVew-Y#xa zC$=+QGwgeW2B;oYA2sU(lSsAl-T79*uC#9x=8UYBfA3w-%V=IFBgy~2BYB%OrFXt4 zd&c>2@+TI)vn#SP11mGIG6O3!urdQrHUn3b^D;qeP0g#iml{nDzM_1aqqJn})|Yjr zEk={E1j!-m?tQ7ADhm{MHM@mlh}r=rlg+x0Z7plwa-`&d6E{3=1l*i#;7yCrAcG)- z8vr4ryUFcwdH4oo^f*p&T_QQ);e0|P z_Y-n&QLZnkoaO#Hh^$G=?^4#SOCc)Pp;Z1V#Uf|`KPxT2N6GI|@(GU&KzxFw5J-Q1 zvR|$!`L%F2Nf(kw`YOOk&!1M#Y17JK=D(hw +#include + +#include "ckb_syscalls.h" + +int main() { + int8_t exit_code = 255; + uint64_t success = ckb_spawn(8, 0, 3, 0, 0, NULL, &exit_code, NULL, NULL); + if (success != 0) { + return success; + } + return exit_code; +} diff --git a/script/testdata/vm_version_2 b/script/testdata/vm_version_2 new file mode 100755 index 0000000000000000000000000000000000000000..13ea61a6ca09c7d935e6940fc99732c497d0272c GIT binary patch literal 11696 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 R&uHWO@ry1T@`=gE{~rqT$58+P literal 0 HcmV?d00001 diff --git a/script/testdata/vm_version_2.c b/script/testdata/vm_version_2.c new file mode 100644 index 0000000000..2b1cff6e02 --- /dev/null +++ b/script/testdata/vm_version_2.c @@ -0,0 +1,8 @@ +#include "ckb_syscalls.h" + +int main() { + if (syscall(2041, 0, 0, 0, 0, 0, 0) == 2) { + return 0; + } + return 1; +} diff --git a/spec/src/lib.rs b/spec/src/lib.rs index c04991975e..cd69fea49d 100644 --- a/spec/src/lib.rs +++ b/spec/src/lib.rs @@ -706,6 +706,15 @@ impl ChainSpec { .into()); } } + ScriptHashType::Data2 => { + if !data_hashes.contains_key(&lock_script.code_hash()) { + return Err(format!( + "Invalid lock script: code_hash={}, hash_type=data2", + lock_script.code_hash(), + ) + .into()); + } + } } } diff --git a/util/jsonrpc-types/src/blockchain.rs b/util/jsonrpc-types/src/blockchain.rs index 439a35c5ea..d7aabab741 100644 --- a/util/jsonrpc-types/src/blockchain.rs +++ b/util/jsonrpc-types/src/blockchain.rs @@ -25,6 +25,8 @@ pub enum ScriptHashType { Type = 1, /// Type "data1" matches script code via cell data hash, and run the script code in v1 CKB VM. Data1 = 2, + /// Type "data2" matches script code via cell data hash, and run the script code in v2 CKB VM. + Data2 = 3, } impl Default for ScriptHashType { @@ -39,6 +41,7 @@ impl From for core::ScriptHashType { ScriptHashType::Data => core::ScriptHashType::Data, ScriptHashType::Type => core::ScriptHashType::Type, ScriptHashType::Data1 => core::ScriptHashType::Data1, + ScriptHashType::Data2 => core::ScriptHashType::Data2, } } } @@ -49,6 +52,7 @@ impl From for ScriptHashType { core::ScriptHashType::Data => ScriptHashType::Data, core::ScriptHashType::Type => ScriptHashType::Type, core::ScriptHashType::Data1 => ScriptHashType::Data1, + core::ScriptHashType::Data2 => ScriptHashType::Data2, } } } @@ -59,6 +63,7 @@ impl fmt::Display for ScriptHashType { Self::Data => write!(f, "data"), Self::Type => write!(f, "type"), Self::Data1 => write!(f, "data1"), + Self::Data2 => write!(f, "data2"), } } } diff --git a/util/types/src/core/blockchain.rs b/util/types/src/core/blockchain.rs index 9c6e4a1e67..b28a126433 100644 --- a/util/types/src/core/blockchain.rs +++ b/util/types/src/core/blockchain.rs @@ -11,6 +11,8 @@ pub enum ScriptHashType { Type = 1, /// Type "data1" matches script code via cell data hash, and run the script code in v1 CKB VM. Data1 = 2, + /// Type "data2" matches script code via cell data hash, and run the script code in v2 CKB VM. + Data2 = 3, } impl Default for ScriptHashType { @@ -27,6 +29,7 @@ impl TryFrom for ScriptHashType { 0 => Ok(ScriptHashType::Data), 1 => Ok(ScriptHashType::Type), 2 => Ok(ScriptHashType::Data1), + 3 => Ok(ScriptHashType::Data2), _ => Err(OtherError::new(format!("Invalid script hash type {v}"))), } } @@ -43,7 +46,7 @@ impl TryFrom for ScriptHashType { impl ScriptHashType { #[inline] pub(crate) fn verify_value(v: u8) -> bool { - v <= 2 + v <= 3 } } @@ -54,6 +57,7 @@ impl Into for ScriptHashType { Self::Data => 0, Self::Type => 1, Self::Data1 => 2, + Self::Data2 => 3, } } } From 71333f017c1070a5d850a506f7f124ac5c17a177 Mon Sep 17 00:00:00 2001 From: mohanson Date: Tue, 28 Mar 2023 09:05:27 +0800 Subject: [PATCH 2/6] Re-generate rpc/README.md --- rpc/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rpc/README.md b/rpc/README.md index 2a99fb7f50..fe976772fd 100644 --- a/rpc/README.md +++ b/rpc/README.md @@ -6581,11 +6581,12 @@ Allowed kinds: “data”, “type” and “data1”. Refer to the section [Code Locating](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md#code-locating) and [Upgradable Script](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md#upgradable-script) in the RFC *CKB Transaction Structure*. -`ScriptHashType` is equivalent to `"data" | "type" | "data1"`. +`ScriptHashType` is equivalent to `"data" | "type" | "data1" | "data2"`. * Type “data” matches script code via cell data hash, and run the script code in v0 CKB VM. * Type “type” matches script code via cell type script hash. * Type “data1” matches script code via cell data hash, and run the script code in v1 CKB VM. +* Type “data2” matches script code via cell data hash, and run the script code in v2 CKB VM. ### Type `SerializedBlock` From 7d778bb043a93f42e9b0dad12d60dbd724a61df7 Mon Sep 17 00:00:00 2001 From: mohanson Date: Tue, 28 Mar 2023 10:28:54 +0800 Subject: [PATCH 3/6] Fix clippy --- script/src/syscalls/current_cycles.rs | 2 +- script/src/syscalls/spawn.rs | 10 +++++--- .../syscalls/tests/vm_latest/syscalls_2.rs | 3 ++- script/src/syscalls/vm_version.rs | 2 +- script/src/verify.rs | 25 ++++++++++++++++--- 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/script/src/syscalls/current_cycles.rs b/script/src/syscalls/current_cycles.rs index 4f80c73d3f..15528ce111 100644 --- a/script/src/syscalls/current_cycles.rs +++ b/script/src/syscalls/current_cycles.rs @@ -4,7 +4,7 @@ use ckb_vm::{ Error as VMError, Register, SupportMachine, Syscalls, }; -#[derive(Debug)] +#[derive(Debug, Default)] pub struct CurrentCycles {} impl CurrentCycles { diff --git a/script/src/syscalls/spawn.rs b/script/src/syscalls/spawn.rs index 9a01c11df8..23f9ecddc3 100644 --- a/script/src/syscalls/spawn.rs +++ b/script/src/syscalls/spawn.rs @@ -32,6 +32,7 @@ pub struct Spawn
{ } impl Spawn
{ + #[allow(clippy::too_many_arguments)] pub fn new( data_loader: DL, group_inputs: Indices, @@ -169,10 +170,11 @@ where let machine_builder = machine_builder.syscall(Box::new( self.syscalls_generator.build_get_memory_limit(memory_limit), )); - let machine_builder = machine_builder.syscall(Box::new( - self.syscalls_generator - .build_set_content(machine_content.clone(), content_length.to_u64()), - )); + let machine_builder = + machine_builder.syscall(Box::new(self.syscalls_generator.build_set_content( + Arc::>>::clone(&machine_content), + content_length.to_u64(), + ))); let machine_builder = machine_builder.syscall(Box::new(Spawn::new( self.data_loader.clone(), Arc::clone(&self.group_inputs), diff --git a/script/src/syscalls/tests/vm_latest/syscalls_2.rs b/script/src/syscalls/tests/vm_latest/syscalls_2.rs index b27418c156..2dd25c375a 100644 --- a/script/src/syscalls/tests/vm_latest/syscalls_2.rs +++ b/script/src/syscalls/tests/vm_latest/syscalls_2.rs @@ -83,7 +83,8 @@ fn test_set_content() { machine.set_register(A7, SET_CONTENT); let content_data = Arc::new(Mutex::new(vec![])); - let result = SetContent::new(content_data.clone(), 5).ecall(&mut machine); + let result = + SetContent::new(Arc::>>::clone(&content_data), 5).ecall(&mut machine); assert!(result.unwrap()); assert_eq!(machine.memory_mut().load64(&20000).unwrap(), 5); diff --git a/script/src/syscalls/vm_version.rs b/script/src/syscalls/vm_version.rs index ad2283dfcb..1884c0fa69 100644 --- a/script/src/syscalls/vm_version.rs +++ b/script/src/syscalls/vm_version.rs @@ -4,7 +4,7 @@ use ckb_vm::{ Error as VMError, Register, SupportMachine, Syscalls, }; -#[derive(Debug)] +#[derive(Debug, Default)] pub struct VMVersion {} impl VMVersion { diff --git a/script/src/verify.rs b/script/src/verify.rs index f73b8b1e1d..c0e82240b4 100644 --- a/script/src/verify.rs +++ b/script/src/verify.rs @@ -132,14 +132,17 @@ pub struct TransactionScriptsSyscallsGenerator
{ impl TransactionScriptsSyscallsGenerator
{ + /// Build syscall: current_cycles pub fn build_current_cycles(&self) -> CurrentCycles { CurrentCycles::new() } + /// Build syscall: vm_version pub fn build_vm_version(&self) -> VMVersion { VMVersion::new() } + /// Build syscall: exec pub fn build_exec(&self, group_inputs: Indices, group_outputs: Indices) -> Exec
{ Exec::new( self.data_loader.clone(), @@ -150,10 +153,12 @@ impl ) } + /// Build syscall: load_tx pub fn build_load_tx(&self) -> LoadTx { LoadTx::new(Arc::clone(&self.rtx)) } + /// Build syscall: load_cell pub fn build_load_cell(&self, group_inputs: Indices, group_outputs: Indices) -> LoadCell
{ LoadCell::new( self.data_loader.clone(), @@ -164,6 +169,7 @@ impl ) } + /// Build syscall: load_cell_data pub fn build_load_cell_data( &self, group_inputs: Indices, @@ -178,14 +184,17 @@ impl ) } + ///Build syscall: load_input pub fn build_load_input(&self, group_inputs: Indices) -> LoadInput { LoadInput::new(Arc::clone(&self.rtx), group_inputs) } + /// Build syscall: load_script_hash pub fn build_load_script_hash(&self, hash: Byte32) -> LoadScriptHash { LoadScriptHash::new(hash) } + /// Build syscall: load_header pub fn build_load_header(&self, group_inputs: Indices) -> LoadHeader
{ LoadHeader::new( self.data_loader.clone(), @@ -194,18 +203,22 @@ impl ) } + /// Build syscall: load_witness pub fn build_load_witness(&self, group_inputs: Indices, group_outputs: Indices) -> LoadWitness { LoadWitness::new(Arc::clone(&self.rtx), group_inputs, group_outputs) } + /// Build syscall: load_script pub fn build_load_script(&self, script: Script) -> LoadScript { LoadScript::new(script) } + /// Build syscall: get_memory_limit pub fn build_get_memory_limit(&self, memory_limit: u64) -> GetMemoryLimit { GetMemoryLimit::new(memory_limit) } + /// Build syscall: set_content pub fn build_set_content( &self, content: Arc>>, @@ -214,6 +227,7 @@ impl SetContent::new(content, content_length) } + /// Generate same syscalls. The result does not contain spawn syscalls. pub fn generate_same_syscalls( &self, script_version: ScriptVersion, @@ -260,6 +274,7 @@ impl syscalls } + /// Generate root syscalls. pub fn generate_root_syscalls( &self, script_version: ScriptVersion, @@ -910,11 +925,13 @@ impl ) -> Vec)>> { let generator = TransactionScriptsSyscallsGenerator { data_loader: self.data_loader.clone(), - debug_printer: self.debug_printer.clone(), - outputs: self.outputs.clone(), - rtx: self.rtx.clone(), + debug_printer: Arc:: Fn(&'a Byte32, &'b str) + Send + Sync>::clone( + &self.debug_printer, + ), + outputs: Arc::>::clone(&self.outputs), + rtx: Arc::::clone(&self.rtx), #[cfg(test)] - skip_pause: self.skip_pause.clone(), + skip_pause: Arc::::clone(&self.skip_pause), }; generator.generate_root_syscalls(script_version, script_group) } From 61694a82c9133a1e2772e7a54a5c37cd779f427c Mon Sep 17 00:00:00 2001 From: mohanson Date: Tue, 28 Mar 2023 15:51:21 +0800 Subject: [PATCH 4/6] jsonrpc-types(tests): fix test_script_serialization --- util/jsonrpc-types/src/tests/blockchain.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/util/jsonrpc-types/src/tests/blockchain.rs b/util/jsonrpc-types/src/tests/blockchain.rs index 825cf1007a..a82be1a06b 100644 --- a/util/jsonrpc-types/src/tests/blockchain.rs +++ b/util/jsonrpc-types/src/tests/blockchain.rs @@ -94,6 +94,19 @@ fn test_script_serialization() { args: JsonBytes::default(), }, ), + ( + "{\ + \"code_hash\":\"0x00000000000000000000000000000000\ + 00000000000000000000000000000001\",\ + \"hash_type\":\"data2\",\ + \"args\":\"0x\"\ + }", + Script { + code_hash: h256!("0x1"), + hash_type: ScriptHashType::Data2, + args: JsonBytes::default(), + }, + ), ] { let decoded: Script = serde_json::from_str(original).unwrap(); assert_eq!(&decoded, entity); @@ -118,12 +131,6 @@ fn test_script_serialization() { \"hash_type\":type,\ \"args\":\"0x\"\ }", - "{\ - \"code_hash\":\"0x00000000000000000000000000000000\ - 00000000000000000000000000000000\",\ - \"hash_type\":\"data2\",\ - \"args\":\"0x\"\ - }", "{\ \"code_hash\":\"0x00000000000000000000000000000000\ 00000000000000000000000000000000\",\ From 66708d69aa225fc03d712aab8d85cf920ec66fe6 Mon Sep 17 00:00:00 2001 From: mohanson Date: Tue, 28 Mar 2023 16:27:20 +0800 Subject: [PATCH 5/6] utils(tests): fix core::tests::blockchain::test_script_hash_type --- util/types/src/core/tests/blockchain.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/types/src/core/tests/blockchain.rs b/util/types/src/core/tests/blockchain.rs index c849f0becd..0fa63847de 100644 --- a/util/types/src/core/tests/blockchain.rs +++ b/util/types/src/core/tests/blockchain.rs @@ -10,7 +10,7 @@ fn test_script_hash_type() { let default_value: u8 = default.into(); assert_eq!(default_value, 0); - let max_value = 2u8; + let max_value = 3u8; for v in 0..32 { let res = ScriptHashType::try_from(v); if v <= max_value { From 0a4ee691bb9d43aa915093e63109a6e39b5e8089 Mon Sep 17 00:00:00 2001 From: mohanson Date: Tue, 28 Mar 2023 16:40:30 +0800 Subject: [PATCH 6/6] util(tests): fix extension::tests::check_data::check_data --- util/types/src/extension/tests/check_data.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/types/src/extension/tests/check_data.rs b/util/types/src/extension/tests/check_data.rs index 54bc2840ed..05489411dd 100644 --- a/util/types/src/extension/tests/check_data.rs +++ b/util/types/src/extension/tests/check_data.rs @@ -28,11 +28,11 @@ fn test_check_data_via_transaction( #[test] fn check_data() { - for ht in 0..3 { + for ht in 0..4 { for dt in 0..2 { let ht_right = ht.into(); let dt_right = dt.into(); - let ht_error = 3.into(); + let ht_error = 4.into(); let dt_error = 2.into(); let script_right = packed::Script::new_builder().hash_type(ht_right).build();