From db050dd855d7e581f16801212e9654b512701d51 Mon Sep 17 00:00:00 2001 From: xjd Date: Fri, 8 Mar 2024 15:22:54 +0800 Subject: [PATCH] Add max_vms_count --- script/src/v2_scheduler.rs | 21 +++++++++++++----- script/src/v2_syscalls.rs | 1 + script/src/v2_types.rs | 1 + .../tests/ckb_latest/features_since_v2023.rs | 8 ++++++- script/testdata/spawn_cases | Bin 12048 -> 12384 bytes script/testdata/spawn_cases.c | 19 ++++++++++++++++ 6 files changed, 44 insertions(+), 6 deletions(-) diff --git a/script/src/v2_scheduler.rs b/script/src/v2_scheduler.rs index ae899959c4..3796e35db7 100644 --- a/script/src/v2_scheduler.rs +++ b/script/src/v2_scheduler.rs @@ -1,7 +1,7 @@ -use crate::types::CoreMachine as ICoreMachine; -use crate::v2_syscalls::INDEX_OUT_OF_BOUND; +use crate::v2_syscalls::{INDEX_OUT_OF_BOUND, MAX_VMS_SPAWNED}; 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, @@ -12,7 +12,6 @@ use crate::{ FIRST_PIPE_SLOT, FIRST_VM_ID, }, }; -use crate::{ScriptVersion, TransactionScriptsVerifier}; use ckb_traits::{CellDataProvider, ExtensionProvider, HeaderProvider}; use ckb_types::core::Cycle; use ckb_vm::snapshot2::Snapshot2Context; @@ -27,7 +26,7 @@ use ckb_vm::{ memory::Memory, registers::A0, snapshot2::{DataSource, Snapshot2}, - Error, Register, Syscalls, + Error, Register, }; use std::sync::{Arc, Mutex}; use std::{ @@ -36,6 +35,7 @@ use std::{ }; const ROOT_VM_ID: VmId = FIRST_VM_ID; +const MAX_VMS_COUNT: u64 = 16; const MAX_INSTANTIATED_VMS: usize = 4; /// A single Scheduler instance is used to verify a single script @@ -56,6 +56,7 @@ where script_version: ScriptVersion, syscalls_generator: TransactionScriptsSyscallsGenerator
, + max_vms_count: u64, total_cycles: Cycle, next_vm_id: VmId, next_pipe_slot: u64, @@ -86,6 +87,7 @@ where tx_data, script_version, syscalls_generator, + max_vms_count: MAX_VMS_COUNT, total_cycles: 0, next_vm_id: FIRST_VM_ID, next_pipe_slot: FIRST_PIPE_SLOT, @@ -115,6 +117,7 @@ where tx_data, script_version, syscalls_generator, + max_vms_count: full.max_vm_count, total_cycles: full.total_cycles, next_vm_id: full.next_vm_id, next_pipe_slot: full.next_pipe_slot, @@ -138,6 +141,7 @@ where /// Suspend current scheduler into a serializable full state pub fn suspend(mut self) -> Result { + assert!(self.message_box.lock().expect("lock").is_empty()); let mut vms = Vec::with_capacity(self.states.len()); let instantiated_ids: Vec<_> = self.instantiated.keys().cloned().collect(); for id in instantiated_ids { @@ -148,6 +152,7 @@ where vms.push((id, state, snapshot)); } Ok(FullSuspendedState { + max_vm_count: self.max_vms_count, total_cycles: self.total_cycles, next_vm_id: self.next_vm_id, next_pipe_slot: self.next_pipe_slot, @@ -316,7 +321,13 @@ where if !pipes_valid { continue; } - // TODO: spawn limits + if self.suspended.len() + self.instantiated.len() > self.max_vms_count as usize + { + self.ensure_vms_instantiated(&[vm_id])?; + let (_, machine) = self.instantiated.get_mut(&vm_id).unwrap(); + machine.machine.set_register(A0, MAX_VMS_SPAWNED as u64); + continue; + } let spawned_vm_id = self.boot_vm(&args.data_piece_id, args.offset, args.length, &args.argv)?; // Move passed pipes from spawner to spawnee diff --git a/script/src/v2_syscalls.rs b/script/src/v2_syscalls.rs index 087ac72e50..cafbe516bd 100644 --- a/script/src/v2_syscalls.rs +++ b/script/src/v2_syscalls.rs @@ -239,3 +239,4 @@ 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/v2_types.rs b/script/src/v2_types.rs index 599dbe6abb..4326529adf 100644 --- a/script/src/v2_types.rs +++ b/script/src/v2_types.rs @@ -141,6 +141,7 @@ impl TryFrom<(u64, u64, u64)> for DataPieceId { /// fully recover the running environment with the full transaction environment. #[derive(Clone, Debug)] pub struct FullSuspendedState { + pub max_vm_count: u64, pub total_cycles: Cycle, pub next_vm_id: VmId, pub next_pipe_slot: u64, diff --git a/script/src/verify/tests/ckb_latest/features_since_v2023.rs b/script/src/verify/tests/ckb_latest/features_since_v2023.rs index 73c4f263a8..77df460c08 100644 --- a/script/src/verify/tests/ckb_latest/features_since_v2023.rs +++ b/script/src/verify/tests/ckb_latest/features_since_v2023.rs @@ -95,6 +95,12 @@ fn check_spawn_read_then_close() { assert_eq!(result.is_ok(), SCRIPT_VERSION == ScriptVersion::V2); } +#[test] +fn check_spawn_max_vms_count() { + let result = simple_spawn_test("testdata/spawn_cases", &[10]); + assert_eq!(result.is_ok(), SCRIPT_VERSION == ScriptVersion::V2); +} + #[test] fn check_vm_version() { let script_version = SCRIPT_VERSION; @@ -348,7 +354,7 @@ fn check_spawn_recursive() { let result = verifier.verify(script_version, &rtx, 70_000_000); if script_version >= ScriptVersion::V2 { let msg = result.unwrap_err().to_string(); - assert!(msg.contains("ExceededMaximumCycles")) + assert!(msg.contains("error code 8")) } else { assert!(result.is_err()) } diff --git a/script/testdata/spawn_cases b/script/testdata/spawn_cases index 06ee2e2349c72bde12dff96ab309fd7e69657e99..b80d3cd078d2145c4c1bb94149d3cc6071742c94 100755 GIT binary patch delta 3194 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 Aw*UYD diff --git a/script/testdata/spawn_cases.c b/script/testdata/spawn_cases.c index 712cace0d0..f43a4505b2 100644 --- a/script/testdata/spawn_cases.c +++ b/script/testdata/spawn_cases.c @@ -320,6 +320,20 @@ int child_read_then_close() { return err; } +int parent_max_vms_count() { + const char* argv[2] = {"", 0}; + return simple_spawn_args(0, 1, argv); +} + +int child_max_vms_count() { + const char* argv[2] = {"", 0}; + int err = simple_spawn_args(0, 1, argv); + CHECK2(err == 0 || err == CKB_MAX_VMS_SPAWNED, -2); + err = 0; +exit: + return err; +} + int parent_entry(int case_id) { int err = 0; uint64_t pid = 0; @@ -341,6 +355,9 @@ int parent_entry(int case_id) { err = parent_inherited_fds_without_owner(&pid); } else if (case_id == 9) { err = parent_read_then_close(&pid); + } else if (case_id == 10) { + err = parent_max_vms_count(&pid); + return err; } else { CHECK2(false, -2); } @@ -373,6 +390,8 @@ int child_entry(int case_id) { return 0; } else if (case_id == 9) { return child_read_then_close(); + } else if (case_id == 10) { + return child_max_vms_count(); } else { return -1; }