diff --git a/script/src/syscalls/mod.rs b/script/src/syscalls/mod.rs index 15e23e1462..3d4952e99d 100644 --- a/script/src/syscalls/mod.rs +++ b/script/src/syscalls/mod.rs @@ -63,6 +63,10 @@ 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 WAIT_FAILURE: u8 = 5; +pub const INVALID_PIPE: u8 = 6; +pub const OTHER_END_CLOSED: u8 = 7; +pub const MAX_VMS_SPAWNED: u8 = 8; pub const VM_VERSION: u64 = 2041; pub const CURRENT_CYCLES: u64 = 2042; @@ -93,12 +97,7 @@ 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 pub const SPAWN_EXTRA_CYCLES_BASE: u64 = 100_000; -pub const SPAWN_EXTRA_CYCLES_PER_MEMORY_PAGE: u64 = 8192; #[derive(Debug, PartialEq, Clone, Copy, Eq)] enum CellField { diff --git a/script/src/syscalls/read.rs b/script/src/syscalls/read.rs index 90ce16e793..9d14021425 100644 --- a/script/src/syscalls/read.rs +++ b/script/src/syscalls/read.rs @@ -1,6 +1,5 @@ use crate::cost_model::transferred_byte_cycles; -use crate::syscalls::READ; -use crate::v2_syscalls::INVALID_PIPE; +use crate::syscalls::{INVALID_PIPE, READ}; use crate::v2_types::{Message, PipeId, PipeIoArgs, VmId}; use ckb_vm::{ registers::{A0, A1, A2, A7}, diff --git a/script/src/syscalls/utils.rs b/script/src/syscalls/utils.rs index cacfdfa0fb..a62d0900b3 100644 --- a/script/src/syscalls/utils.rs +++ b/script/src/syscalls/utils.rs @@ -47,21 +47,3 @@ pub fn load_c_string(machine: &mut Mac, addr: u64) -> Resul 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/syscalls/write.rs b/script/src/syscalls/write.rs index 19ec918469..bda3a92afd 100644 --- a/script/src/syscalls/write.rs +++ b/script/src/syscalls/write.rs @@ -1,6 +1,5 @@ use crate::cost_model::transferred_byte_cycles; -use crate::syscalls::WRITE; -use crate::v2_syscalls::INVALID_PIPE; +use crate::syscalls::{INVALID_PIPE, WRITE}; use crate::v2_types::{Message, PipeId, PipeIoArgs, VmId}; use ckb_vm::{ registers::{A0, A1, A2, A7}, diff --git a/script/src/v2_scheduler.rs b/script/src/v2_scheduler.rs index 2638c8ac6b..3d66a9ee6c 100644 --- a/script/src/v2_scheduler.rs +++ b/script/src/v2_scheduler.rs @@ -1,12 +1,10 @@ -use crate::v2_syscalls::{INDEX_OUT_OF_BOUND, MAX_VMS_SPAWNED}; +use crate::cost_model::transferred_byte_cycles; +use crate::syscalls::{INDEX_OUT_OF_BOUND, INVALID_PIPE, OTHER_END_CLOSED, SUCCESS, WAIT_FAILURE}; use crate::v2_types::PipeIoArgs; use crate::verify::TransactionScriptsSyscallsGenerator; use crate::ScriptVersion; use crate::{ - v2_syscalls::{ - transferred_byte_cycles, MachineContext, INVALID_PIPE, OTHER_END_CLOSED, SUCCESS, - WAIT_FAILURE, - }, + v2_syscalls::MachineContext, v2_types::{ DataPieceId, FullSuspendedState, Message, PipeId, RunMode, TxData, VmId, VmState, FIRST_PIPE_SLOT, FIRST_VM_ID, @@ -800,12 +798,7 @@ where machine_context.snapshot2_context = syscalls_generator.snapshot2_context.clone(); let machine_builder = DefaultMachineBuilder::new(core_machine) - .instruction_cycle_func(Box::new(estimate_cycles)) - // ckb-vm iterates syscalls in insertion order, by putting - // MachineContext at the first place, we can override other - // syscalls with implementations from MachineContext. For example, - // we can override load_cell_data syscall with a new implementation. - .syscall(Box::new(machine_context.clone())); + .instruction_cycle_func(Box::new(estimate_cycles)); let machine_builder = syscalls_generator .generate_same_syscalls(version, &self.tx_data.script_group) .into_iter() diff --git a/script/src/v2_syscalls.rs b/script/src/v2_syscalls.rs index 74efd69b9c..5e17bd9c54 100644 --- a/script/src/v2_syscalls.rs +++ b/script/src/v2_syscalls.rs @@ -1,18 +1,9 @@ -use crate::syscalls::SPAWN_EXTRA_CYCLES_BASE; use crate::{ - v2_types::{DataPieceId, Message, PipeId, SpawnArgs, TxData, VmId}, + v2_types::{DataPieceId, Message, TxData, VmId}, ScriptVersion, }; use ckb_traits::{CellDataProvider, ExtensionProvider, HeaderProvider}; -use ckb_vm::{ - bytes::Bytes, - machine::SupportMachine, - memory::{Memory, FLAG_EXECUTABLE, FLAG_FREEZED}, - registers::{A0, A1, A2, A3, A4, A5, A7}, - snapshot2::{DataSource, Snapshot2Context}, - syscalls::Syscalls, - Error, Register, -}; +use ckb_vm::snapshot2::Snapshot2Context; use std::sync::{Arc, Mutex}; #[derive(Clone)] @@ -52,68 +43,4 @@ where pub fn set_base_cycles(&mut self, base_cycles: u64) { *self.base_cycles.lock().expect("lock") = base_cycles; } - - // Reimplementing debug syscall for printing debug messages - fn debug(&mut self, machine: &mut Mac) -> Result<(), Error> { - let mut addr = machine.registers()[A0].to_u64(); - let mut buffer = Vec::new(); - - loop { - let byte = machine - .memory_mut() - .load8(&Mac::REG::from_u64(addr))? - .to_u8(); - if byte == 0 { - break; - } - buffer.push(byte); - addr += 1; - } - - machine.add_cycles_no_checking(transferred_byte_cycles(buffer.len() as u64))?; - let s = String::from_utf8(buffer) - .map_err(|e| Error::External(format!("String from buffer {e:?}")))?; - println!("VM {}: {}", self.id, s); - - Ok(()) - } -} - -impl Syscalls for MachineContext
-where - DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + Clone + 'static, -{ - fn initialize(&mut self, _machine: &mut Mac) -> Result<(), Error> { - Ok(()) - } - - fn ecall(&mut self, machine: &mut Mac) -> Result { - let code = machine.registers()[A7].to_u64(); - match code { - 2177 => self.debug(machine), - _ => return Ok(false), - }?; - Ok(true) - } } - -// Below are all simple utilities copied over from ckb-script package to -// ease the implementation. - -/// How many bytes can transfer when VM costs one cycle. -// 0.25 cycles per byte -const BYTES_PER_CYCLE: u64 = 4; - -/// Calculates how many cycles spent to load the specified number of bytes. -pub(crate) fn transferred_byte_cycles(bytes: u64) -> u64 { - // Compiler will optimize the divisin here to shifts. - (bytes + BYTES_PER_CYCLE - 1) / BYTES_PER_CYCLE -} - -pub(crate) const SUCCESS: u8 = 0; -pub(crate) const INDEX_OUT_OF_BOUND: u8 = 1; -pub(crate) const SLICE_OUT_OF_BOUND: u8 = 3; -pub(crate) const WAIT_FAILURE: u8 = 5; -pub(crate) const INVALID_PIPE: u8 = 6; -pub(crate) const OTHER_END_CLOSED: u8 = 7; -pub(crate) const MAX_VMS_SPAWNED: u8 = 8; diff --git a/script/src/verify/tests/utils.rs b/script/src/verify/tests/utils.rs index d9ab364b5f..70f61a84b5 100644 --- a/script/src/verify/tests/utils.rs +++ b/script/src/verify/tests/utils.rs @@ -311,12 +311,18 @@ impl TransactionScriptsVerifierWithEnv { .epoch(epoch.pack()) .build(); let tx_env = Arc::new(TxVerifyEnv::new_commit(&header)); - let verifier = TransactionScriptsVerifier::new( + let mut verifier = TransactionScriptsVerifier::new( Arc::new(rtx.clone()), data_loader, Arc::clone(&self.consensus), tx_env, ); + verifier.set_debug_printer(Box::new(move |_hash: &Byte32, message: &str| { + print!("{}", message); + if !message.ends_with('\n') { + println!(""); + } + })); verify_func(verifier) } }