Skip to content

Commit

Permalink
Use scheduler to run tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mohanson committed Mar 4, 2024
1 parent 8d8ce55 commit b7c91c6
Show file tree
Hide file tree
Showing 4 changed files with 1,001 additions and 986 deletions.
4 changes: 2 additions & 2 deletions script/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ mod error;
mod syscalls;
mod type_id;
mod types;
mod verify;
mod verify_env;
mod v2_scheduler;
mod v2_syscalls;
mod v2_types;
mod verify;
mod verify_env;

pub use crate::error::{ScriptError, TransactionScriptError};
pub use crate::syscalls::spawn::update_caller_machine;
Expand Down
41 changes: 20 additions & 21 deletions script/src/v2_scheduler.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::types::CoreMachine as ICoreMachine;
use crate::v2_syscalls::INDEX_OUT_OF_BOUND;
use crate::v2_types::PipeIoArgs;
use crate::verify::TransactionScriptsSyscallsGenerator;
use crate::{
v2_syscalls::{
transferred_byte_cycles, MachineContext, INVALID_PIPE, JOIN_FAILURE, OTHER_END_CLOSED,
Expand All @@ -24,7 +26,7 @@ use ckb_vm::{
memory::Memory,
registers::A0,
snapshot2::{DataSource, Snapshot2},
Error, Register,
Error, Register, Syscalls,
};
use std::sync::{Arc, Mutex};
use std::{
Expand All @@ -49,7 +51,8 @@ pub struct Scheduler<
// TransactionScriptsVerifier, nonetheless much of current syscall
// implementation is strictly tied to TransactionScriptsVerifier, we
// are using it here to save some extra code.
verifier: TransactionScriptsVerifier<DL>,
script_version: ScriptVersion,
syscalls: TransactionScriptsSyscallsGenerator<DL>,

total_cycles: Cycle,
next_vm_id: VmId,
Expand All @@ -70,10 +73,15 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
Scheduler<DL>
{
/// Create a new scheduler from empty state
pub fn new(tx_data: TxData<DL>, verifier: TransactionScriptsVerifier<DL>) -> Self {
pub fn new(
tx_data: TxData<DL>,
script_version: ScriptVersion,
syscalls: TransactionScriptsSyscallsGenerator<DL>,
) -> Self {
Self {
tx_data,
verifier,
script_version,
syscalls,
total_cycles: 0,
next_vm_id: FIRST_VM_ID,
next_pipe_slot: FIRST_PIPE_SLOT,
Expand All @@ -94,12 +102,14 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
/// Resume a previously suspended scheduler state
pub fn resume(
tx_data: TxData<DL>,
verifier: TransactionScriptsVerifier<DL>,
script_version: ScriptVersion,
syscalls: TransactionScriptsSyscallsGenerator<DL>,
full: FullSuspendedState,
) -> Self {
Self {
tx_data,
verifier,
script_version,
syscalls,
total_cycles: full.total_cycles,
next_vm_id: full.next_vm_id,
next_pipe_slot: full.next_pipe_slot,
Expand Down Expand Up @@ -739,10 +749,7 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
// The code here looks slightly weird, since I don't want to copy over all syscall
// impls here again. Ideally, this scheduler package should be merged with ckb-script,
// or simply replace ckb-script. That way, the quirks here will be eliminated.
let version = self
.verifier
.select_version(&self.tx_data.script_group.script)
.map_err(|e| Error::Unexpected(format!("Select version error: {:?}", e)))?;
let version = self.script_version;
// log::debug!("Creating VM {} using version {:?}", id, version);
let core_machine = AsmCoreMachine::new(
version.vm_isa(),
Expand All @@ -759,17 +766,9 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
// syscalls with implementations from MachineContext. For example,
// we can override load_cell_data syscall with a new implementation.
.syscall(Box::new(machine_context.clone()));
let syscalls = self.verifier.generate_syscalls(
// Skip current spawn implementation
if version == ScriptVersion::V2 {
ScriptVersion::V1
} else {
version
},
&self.tx_data.script_group,
Default::default(),
);
let machine_builder = syscalls
let machine_builder = self
.syscalls
.generate_root_syscalls(version, &self.tx_data.script_group, Default::default())
.into_iter()
.fold(machine_builder, |builder, syscall| builder.syscall(syscall));
let default_machine = machine_builder.build();
Expand Down
44 changes: 30 additions & 14 deletions script/src/verify.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#[cfg(test)]
use crate::syscalls::Pause;
use crate::v2_scheduler::Scheduler;
use crate::v2_types::{RunMode, TxData};
use crate::{
cost_model::transferred_byte_cycles,
error::{ScriptError, TransactionScriptError},
Expand Down Expand Up @@ -1092,33 +1094,47 @@ impl<DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + C
&self,
script_group: &ScriptGroup,
max_cycles: Cycle,
) -> Result<(i8, Machine), ScriptError> {
) -> Result<(i8, Cycle), ScriptError> {
let program = self.extract_script(&script_group.script)?;
let context = Default::default();
let mut machine = self.build_machine(script_group, max_cycles, context)?;

let tx_data = TxData {
rtx: self.rtx.clone(),
data_loader: self.data_loader.clone(),
program,
script_group: Arc::new(script_group.clone()),
};
let version = self.select_version(&script_group.script)?;
let mut scheduler = Scheduler::new(tx_data.clone(), version, self.generator.clone());

let map_vm_internal_error = |error: VMInternalError| match error {
VMInternalError::CyclesExceeded => ScriptError::ExceededMaximumCycles(max_cycles),
_ => ScriptError::VMInternalError(error),
};

let bytes = machine
.load_program(&program, &[])
.map_err(map_vm_internal_error)?;
machine
.machine
.add_cycles_no_checking(transferred_byte_cycles(bytes))
.map_err(map_vm_internal_error)?;
let code = machine.run().map_err(map_vm_internal_error)?;
scheduler
.run(RunMode::LimitCycles(max_cycles))
.map_err(map_vm_internal_error)

// let context = Default::default();
// let mut machine = self.build_machine(script_group, max_cycles, context)?;

// let bytes = machine
// .load_program(&program, &[])
// .map_err(map_vm_internal_error)?;
// machine
// .machine
// .add_cycles_no_checking(transferred_byte_cycles(bytes))
// .map_err(map_vm_internal_error)?;
// let code = machine.run().map_err(map_vm_internal_error)?;

Ok((code, machine))
// Ok((code, machine))
}

fn run(&self, script_group: &ScriptGroup, max_cycles: Cycle) -> Result<Cycle, ScriptError> {
let (code, machine) = self.detailed_run(script_group, max_cycles)?;
let (code, cycles) = self.detailed_run(script_group, max_cycles)?;

if code == 0 {
Ok(machine.machine.cycles())
Ok(cycles)
} else {
Err(ScriptError::validation_failure(&script_group.script, code))
}
Expand Down
Loading

0 comments on commit b7c91c6

Please sign in to comment.