Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New spawn mohanson #16

Merged
merged 1 commit into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading