Skip to content

Commit dd8265b

Browse files
committed
refactor: Syscall generator is now the only interfact to customize verifier
Debug printer is now part of customizing syscall generator
1 parent 314a124 commit dd8265b

File tree

8 files changed

+156
-172
lines changed

8 files changed

+156
-172
lines changed

script/src/scheduler.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ use crate::syscalls::{
55
};
66

77
use crate::types::{
8-
CoreMachineType, DataLocation, DataPieceId, DebugContext, FIRST_FD_SLOT, FIRST_VM_ID, Fd,
9-
FdArgs, FullSuspendedState, Machine, Message, ReadState, RunMode, SgData, SyscallGenerator,
10-
VmArgs, VmContext, VmId, VmState, WriteState,
8+
CoreMachineType, DataLocation, DataPieceId, FIRST_FD_SLOT, FIRST_VM_ID, Fd, FdArgs,
9+
FullSuspendedState, Machine, Message, ReadState, RunMode, SgData, SyscallGenerator, VmArgs,
10+
VmContext, VmId, VmState, WriteState,
1111
};
1212
use ckb_traits::{CellDataProvider, ExtensionProvider, HeaderProvider};
1313
use ckb_types::core::Cycle;
@@ -43,18 +43,17 @@ pub const MAX_FDS: u64 = 64;
4343
/// A scheduler holds & manipulates a core, the scheduler also holds
4444
/// all CKB-VM machines, each CKB-VM machine also gets a mutable reference
4545
/// of the core for IO operations.
46-
pub struct Scheduler<DL>
46+
pub struct Scheduler<DL, V>
4747
where
4848
DL: CellDataProvider,
4949
{
5050
/// Immutable context data for current running transaction & script.
5151
pub sg_data: SgData<DL>,
5252

53-
/// Mutable context data used by current scheduler
54-
pub debug_context: DebugContext,
55-
5653
/// Syscall generator
57-
pub syscall_generator: SyscallGenerator<DL>,
54+
pub syscall_generator: SyscallGenerator<DL, V>,
55+
/// Syscall generator context
56+
pub syscall_context: V,
5857

5958
/// Total cycles. When a scheduler executes, there are 3 variables
6059
/// that might all contain charged cycles: +total_cycles+,
@@ -109,20 +108,21 @@ where
109108
pub message_box: Arc<Mutex<Vec<Message>>>,
110109
}
111110

112-
impl<DL> Scheduler<DL>
111+
impl<DL, V> Scheduler<DL, V>
113112
where
114113
DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + Clone + 'static,
114+
V: Send + Clone,
115115
{
116116
/// Create a new scheduler from empty state
117117
pub fn new(
118118
sg_data: SgData<DL>,
119-
debug_context: DebugContext,
120-
syscall_generator: SyscallGenerator<DL>,
119+
syscall_generator: SyscallGenerator<DL, V>,
120+
syscall_context: V,
121121
) -> Self {
122122
Self {
123123
sg_data,
124-
debug_context,
125124
syscall_generator,
125+
syscall_context,
126126
total_cycles: Arc::new(AtomicU64::new(0)),
127127
iteration_cycles: 0,
128128
next_vm_id: FIRST_VM_ID,
@@ -157,14 +157,14 @@ where
157157
/// Resume a previously suspended scheduler state
158158
pub fn resume(
159159
sg_data: SgData<DL>,
160-
debug_context: DebugContext,
161-
syscall_generator: SyscallGenerator<DL>,
160+
syscall_generator: SyscallGenerator<DL, V>,
161+
syscall_context: V,
162162
full: FullSuspendedState,
163163
) -> Self {
164164
let mut scheduler = Self {
165165
sg_data,
166-
debug_context,
167166
syscall_generator,
167+
syscall_context,
168168
total_cycles: Arc::new(AtomicU64::new(full.total_cycles)),
169169
iteration_cycles: 0,
170170
next_vm_id: full.next_vm_id,
@@ -908,7 +908,7 @@ where
908908
let machine_builder = DefaultMachineBuilder::new(core_machine)
909909
.instruction_cycle_func(Box::new(estimate_cycles));
910910
let machine_builder =
911-
(self.syscall_generator)(id, &self.sg_data, &vm_context, &self.debug_context)
911+
(self.syscall_generator)(id, &self.sg_data, &vm_context, &self.syscall_context)
912912
.into_iter()
913913
.fold(machine_builder, |builder, syscall| builder.syscall(syscall));
914914
let default_machine = machine_builder.build();

script/src/syscalls/debugger.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::types::{
2-
DebugContext, DebugPrinter, {SgData, SgInfo},
2+
DebugPrinter, {SgData, SgInfo},
33
};
44
use crate::{cost_model::transferred_byte_cycles, syscalls::DEBUG_PRINT_SYSCALL_NUMBER};
55
use ckb_vm::{
@@ -14,10 +14,10 @@ pub struct Debugger {
1414
}
1515

1616
impl Debugger {
17-
pub fn new<DL>(sg_data: &SgData<DL>, debug_context: &DebugContext) -> Debugger {
17+
pub fn new<DL>(sg_data: &SgData<DL>, debug_printer: &DebugPrinter) -> Debugger {
1818
Debugger {
1919
sg_info: Arc::clone(&sg_data.sg_info),
20-
printer: Arc::clone(&debug_context.debug_printer),
20+
printer: Arc::clone(debug_printer),
2121
}
2222
}
2323
}

script/src/syscalls/generator.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
LoadCellData, LoadHeader, LoadInput, LoadScript, LoadScriptHash, LoadTx, LoadWitness, Pipe,
55
ProcessID, Read, Spawn, VMVersion, Wait, Write,
66
},
7-
types::{CoreMachine, DebugContext, ScriptVersion, SgData, VmContext, VmId},
7+
types::{CoreMachine, DebugPrinter, ScriptVersion, SgData, VmContext, VmId},
88
};
99
use ckb_traits::{CellDataProvider, ExtensionProvider, HeaderProvider};
1010
use ckb_vm::Syscalls;
@@ -14,7 +14,7 @@ pub fn generate_ckb_syscalls<DL>(
1414
vm_id: &VmId,
1515
sg_data: &SgData<DL>,
1616
vm_context: &VmContext<DL>,
17-
debug_context: &DebugContext,
17+
debug_printer: &DebugPrinter,
1818
) -> Vec<Box<(dyn Syscalls<CoreMachine>)>>
1919
where
2020
DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + Clone + 'static,
@@ -28,7 +28,7 @@ where
2828
Box::new(LoadWitness::new(sg_data)),
2929
Box::new(LoadScript::new(sg_data)),
3030
Box::new(LoadCellData::new(vm_context)),
31-
Box::new(Debugger::new(sg_data, debug_context)),
31+
Box::new(Debugger::new(sg_data, debug_printer)),
3232
];
3333
let script_version = &sg_data.sg_info.script_version;
3434
if script_version >= &ScriptVersion::V1 {
@@ -54,9 +54,5 @@ where
5454
Box::new(Close::new(vm_id, vm_context)),
5555
]);
5656
}
57-
#[cfg(test)]
58-
syscalls.push(Box::new(crate::syscalls::Pause::new(
59-
std::sync::Arc::clone(&debug_context.skip_pause),
60-
)));
6157
syscalls
6258
}

script/src/types.rs

+2-19
Original file line numberDiff line numberDiff line change
@@ -72,25 +72,8 @@ pub type Machine = TraceMachine<CoreMachine>;
7272
/// Debug printer function type
7373
pub type DebugPrinter = Arc<dyn Fn(&Byte32, &str) + Send + Sync>;
7474
/// Syscall generator function type
75-
pub type SyscallGenerator<DL> = Arc<
76-
dyn Fn(
77-
&VmId,
78-
&SgData<DL>,
79-
&VmContext<DL>,
80-
&DebugContext,
81-
) -> Vec<Box<(dyn Syscalls<CoreMachine>)>>
82-
+ Send
83-
+ Sync,
84-
>;
85-
86-
/// VM context used for debugging purposes
87-
pub struct DebugContext {
88-
/// Debug printer in use.
89-
pub debug_printer: DebugPrinter,
90-
/// A flag to control pausing, only used in tests.
91-
#[cfg(test)]
92-
pub skip_pause: Arc<std::sync::atomic::AtomicBool>,
93-
}
75+
pub type SyscallGenerator<DL, V> =
76+
fn(&VmId, &SgData<DL>, &VmContext<DL>, &V) -> Vec<Box<(dyn Syscalls<CoreMachine>)>>;
9477

9578
/// The version of CKB Script Verifier.
9679
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]

script/src/verify.rs

+60-76
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ use crate::{
66
syscalls::generator::generate_ckb_syscalls,
77
type_id::TypeIdSystemScript,
88
types::{
9-
CoreMachine, DebugContext, DebugPrinter, FullSuspendedState, RunMode, ScriptGroup,
10-
ScriptGroupType, ScriptVersion, SgData, SyscallGenerator, TransactionState, TxData,
11-
VerifyResult, VmContext, VmId,
9+
DebugPrinter, FullSuspendedState, RunMode, ScriptGroup, ScriptGroupType, ScriptVersion,
10+
SgData, SyscallGenerator, TransactionState, TxData, VerifyResult,
1211
},
1312
verify_env::TxVerifyEnv,
1413
};
@@ -23,19 +22,16 @@ use ckb_types::{
2322
packed::{Byte32, Script},
2423
prelude::*,
2524
};
25+
use ckb_vm::Error as VMInternalError;
2626
#[cfg(not(target_family = "wasm"))]
2727
use ckb_vm::machine::Pause as VMPause;
28-
use ckb_vm::{Error as VMInternalError, Syscalls};
2928
use std::sync::Arc;
3029
#[cfg(not(target_family = "wasm"))]
3130
use tokio::sync::{
3231
oneshot,
3332
watch::{self, Receiver},
3433
};
3534

36-
#[cfg(test)]
37-
use core::sync::atomic::{AtomicBool, Ordering};
38-
3935
#[cfg(test)]
4036
mod tests;
4137

@@ -56,33 +52,23 @@ impl ChunkState {
5652
}
5753

5854
/// This struct leverages CKB VM to verify transaction inputs.
59-
pub struct TransactionScriptsVerifier<DL: CellDataProvider> {
55+
pub struct TransactionScriptsVerifier<DL: CellDataProvider, V> {
6056
tx_data: Arc<TxData<DL>>,
61-
62-
debug_printer: DebugPrinter,
63-
syscall_generator: SyscallGenerator<DL>,
64-
#[cfg(test)]
65-
skip_pause: Arc<AtomicBool>,
57+
syscall_generator: SyscallGenerator<DL, V>,
58+
syscall_context: V,
6659
}
6760

68-
impl<DL> TransactionScriptsVerifier<DL>
61+
impl<DL> TransactionScriptsVerifier<DL, DebugPrinter>
6962
where
7063
DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + Clone + 'static,
7164
{
72-
/// Creates a script verifier for the transaction.
73-
///
74-
/// ## Params
75-
///
76-
/// * `rtx` - transaction which cell out points have been resolved.
77-
/// * `data_loader` - used to load cell data.
65+
/// Create a script verifier using default CKB syscalls and a default debug printer
7866
pub fn new(
7967
rtx: Arc<ResolvedTransaction>,
8068
data_loader: DL,
8169
consensus: Arc<Consensus>,
8270
tx_env: Arc<TxVerifyEnv>,
83-
) -> TransactionScriptsVerifier<DL> {
84-
let tx_data = Arc::new(TxData::new(rtx, data_loader, consensus, tx_env));
85-
71+
) -> Self {
8672
let debug_printer: DebugPrinter = Arc::new(
8773
#[allow(unused_variables)]
8874
|hash: &Byte32, message: &str| {
@@ -91,50 +77,58 @@ where
9177
},
9278
);
9379

94-
#[cfg(test)]
95-
let skip_pause = Arc::new(AtomicBool::new(false));
80+
Self::new_with_debug_printer(rtx, data_loader, consensus, tx_env, debug_printer)
81+
}
9682

97-
TransactionScriptsVerifier {
98-
tx_data,
83+
/// Create a script verifier using default CKB syscalls and a custom debug printer
84+
pub fn new_with_debug_printer(
85+
rtx: Arc<ResolvedTransaction>,
86+
data_loader: DL,
87+
consensus: Arc<Consensus>,
88+
tx_env: Arc<TxVerifyEnv>,
89+
debug_printer: DebugPrinter,
90+
) -> Self {
91+
Self::new_with_generator(
92+
rtx,
93+
data_loader,
94+
consensus,
95+
tx_env,
96+
generate_ckb_syscalls,
9997
debug_printer,
100-
syscall_generator: Arc::new(generate_ckb_syscalls),
101-
#[cfg(test)]
102-
skip_pause,
103-
}
98+
)
10499
}
100+
}
105101

106-
/// Sets a callback to handle the debug syscall.
107-
///
108-
///
109-
/// Script can print a message using the [debug syscall](github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#debug).
102+
impl<DL, V> TransactionScriptsVerifier<DL, V>
103+
where
104+
DL: CellDataProvider + HeaderProvider + ExtensionProvider + Send + Sync + Clone + 'static,
105+
V: Send + Clone + 'static,
106+
{
107+
/// Creates a script verifier for the transaction.
110108
///
111-
/// The callback receives two parameters:
109+
/// ## Params
112110
///
113-
/// * `hash: &Byte32`: this is the script hash of currently running script group.
114-
/// * `message: &str`: message passed to the debug syscall.
115-
pub fn set_debug_printer<F: Fn(&Byte32, &str) + Sync + Send + 'static>(&mut self, func: F) {
116-
self.debug_printer = Arc::new(func);
117-
}
118-
119-
/// Sets a new syscall generator for special usages
120-
pub fn set_syscall_generator<F>(&mut self, func: F)
121-
where
122-
F: Fn(
123-
&VmId,
124-
&SgData<DL>,
125-
&VmContext<DL>,
126-
&DebugContext,
127-
) -> Vec<Box<(dyn Syscalls<CoreMachine>)>>
128-
+ Sync
129-
+ Send
130-
+ 'static,
131-
{
132-
self.syscall_generator = Arc::new(func);
133-
}
111+
/// * `rtx` - transaction which cell out points have been resolved.
112+
/// * `data_loader` - used to load cell data.
113+
/// * `consensus` - consensus parameters.
114+
/// * `tx_env` - enviroment for verifying transaction, such as committed block, etc.
115+
/// * `syscall_generator` - a syscall generator for current verifier
116+
/// * `syscall_context` - context for syscall generator
117+
pub fn new_with_generator(
118+
rtx: Arc<ResolvedTransaction>,
119+
data_loader: DL,
120+
consensus: Arc<Consensus>,
121+
tx_env: Arc<TxVerifyEnv>,
122+
syscall_generator: SyscallGenerator<DL, V>,
123+
syscall_context: V,
124+
) -> TransactionScriptsVerifier<DL, V> {
125+
let tx_data = Arc::new(TxData::new(rtx, data_loader, consensus, tx_env));
134126

135-
#[cfg(test)]
136-
pub(crate) fn set_skip_pause(&self, skip_pause: bool) {
137-
self.skip_pause.store(skip_pause, Ordering::SeqCst);
127+
TransactionScriptsVerifier {
128+
tx_data,
129+
syscall_generator,
130+
syscall_context,
131+
}
138132
}
139133

140134
//////////////////////////////////////////////////////////////////
@@ -570,17 +564,12 @@ where
570564
pub fn create_scheduler(
571565
&self,
572566
script_group: &ScriptGroup,
573-
) -> Result<Scheduler<DL>, ScriptError> {
567+
) -> Result<Scheduler<DL, V>, ScriptError> {
574568
let sg_data = SgData::new(&self.tx_data, script_group)?;
575-
let debug_context = DebugContext {
576-
debug_printer: Arc::clone(&self.debug_printer),
577-
#[cfg(test)]
578-
skip_pause: Arc::clone(&self.skip_pause),
579-
};
580569
Ok(Scheduler::new(
581570
sg_data,
582-
debug_context,
583-
Arc::clone(&self.syscall_generator),
571+
self.syscall_generator,
572+
self.syscall_context.clone(),
584573
))
585574
}
586575

@@ -589,17 +578,12 @@ where
589578
&self,
590579
script_group: &ScriptGroup,
591580
state: &FullSuspendedState,
592-
) -> Result<Scheduler<DL>, ScriptError> {
581+
) -> Result<Scheduler<DL, V>, ScriptError> {
593582
let sg_data = SgData::new(&self.tx_data, script_group)?;
594-
let debug_context = DebugContext {
595-
debug_printer: Arc::clone(&self.debug_printer),
596-
#[cfg(test)]
597-
skip_pause: Arc::clone(&self.skip_pause),
598-
};
599583
Ok(Scheduler::resume(
600584
sg_data,
601-
debug_context,
602-
Arc::clone(&self.syscall_generator),
585+
self.syscall_generator,
586+
self.syscall_context.clone(),
603587
state.clone(),
604588
))
605589
}

0 commit comments

Comments
 (0)