Skip to content

Commit

Permalink
Staged
Browse files Browse the repository at this point in the history
  • Loading branch information
mohanson committed Mar 12, 2024
1 parent 0481dec commit 2f24133
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 114 deletions.
9 changes: 4 additions & 5 deletions script/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 1 addition & 2 deletions script/src/syscalls/read.rs
Original file line number Diff line number Diff line change
@@ -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},
Expand Down
18 changes: 0 additions & 18 deletions script/src/syscalls/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,3 @@ pub fn load_c_string<Mac: SupportMachine>(machine: &mut Mac, addr: u64) -> Resul

Ok(Bytes::from(buffer))
}

pub fn load_bytes<Mac: SupportMachine>(
machine: &mut Mac,
addr: u64,
size: u64,
) -> Result<Bytes, VMError> {
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))
}
3 changes: 1 addition & 2 deletions script/src/syscalls/write.rs
Original file line number Diff line number Diff line change
@@ -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},
Expand Down
15 changes: 4 additions & 11 deletions script/src/v2_scheduler.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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()
Expand Down
77 changes: 2 additions & 75 deletions script/src/v2_syscalls.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -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<Mac: SupportMachine>(&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<Mac: SupportMachine, DL> Syscalls<Mac> for MachineContext<DL>
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<bool, Error> {
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;
8 changes: 7 additions & 1 deletion script/src/verify/tests/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down

0 comments on commit 2f24133

Please sign in to comment.