From 65fe67f561b47e1c84825556d8e86211f23ad485 Mon Sep 17 00:00:00 2001 From: xjd Date: Wed, 6 Mar 2024 11:29:44 +0800 Subject: [PATCH 1/2] Add more test cases --- script/src/v2_syscalls.rs | 4 +- .../tests/ckb_latest/features_since_v2023.rs | 633 ++++-------------- script/testdata/Makefile | 21 +- script/testdata/spawn_callee_exec_callee | Bin 0 -> 1184 bytes script/testdata/spawn_callee_exec_callee.c | 3 + script/testdata/spawn_callee_exec_caller | Bin 0 -> 1208 bytes script/testdata/spawn_callee_exec_caller.c | 8 + script/testdata/spawn_callee_out_of_cycles | Bin 0 -> 1928 bytes script/testdata/spawn_callee_out_of_cycles.c | 10 + script/testdata/spawn_caller_exec | Bin 0 -> 4648 bytes script/testdata/spawn_caller_exec.c | 4 + script/testdata/spawn_caller_out_of_cycles | Bin 0 -> 4656 bytes script/testdata/spawn_caller_out_of_cycles.c | 6 + script/testdata/spawn_caller_strcat | Bin 5328 -> 5224 bytes script/testdata/spawn_caller_strcat.c | 3 - script/testdata/spawn_caller_strcat_wrap | Bin 0 -> 4656 bytes script/testdata/spawn_caller_strcat_wrap.c | 6 + script/testdata/spawn_recursive | Bin 0 -> 4648 bytes script/testdata/spawn_recursive.c | 4 + script/testdata/utils.h | 21 + 20 files changed, 211 insertions(+), 512 deletions(-) create mode 100755 script/testdata/spawn_callee_exec_callee create mode 100644 script/testdata/spawn_callee_exec_callee.c create mode 100755 script/testdata/spawn_callee_exec_caller create mode 100644 script/testdata/spawn_callee_exec_caller.c create mode 100755 script/testdata/spawn_callee_out_of_cycles create mode 100644 script/testdata/spawn_callee_out_of_cycles.c create mode 100755 script/testdata/spawn_caller_exec create mode 100644 script/testdata/spawn_caller_exec.c create mode 100755 script/testdata/spawn_caller_out_of_cycles create mode 100644 script/testdata/spawn_caller_out_of_cycles.c create mode 100755 script/testdata/spawn_caller_strcat_wrap create mode 100644 script/testdata/spawn_caller_strcat_wrap.c create mode 100755 script/testdata/spawn_recursive create mode 100644 script/testdata/spawn_recursive.c diff --git a/script/src/v2_syscalls.rs b/script/src/v2_syscalls.rs index f30e736dc3..4bc2b1c9a6 100644 --- a/script/src/v2_syscalls.rs +++ b/script/src/v2_syscalls.rs @@ -313,8 +313,8 @@ impl length. -// check_spawn_out_of_cycles: child script out-of-cycles. -// check_spawn_exec: A exec B spawn C. -// check_spawn_strcat_wrap: A spawn B spwan C. -// check_spawn_out_of_cycles_wrap: A spawn B spwan C, but C out-of-cycles. -// check_spawn_recursive: A spawn A spawn A ... ... spawn A -// check_spawn_big_memory_size: fails when memory_limit > 8. -// check_spawn_big_content_length: fails when content_length > 256K. -// check_peak_memory_4m_to_32m: spawn should success when peak memory <= 32M -// check_peak_memory_2m_to_32m: spawn should success when peak memory <= 32M -// check_peak_memory_512k_to_32m: spawn should success when peak memory <= 32M -// check_spawn_snapshot: A spawn B, then B gets suspended to snapshot and resume again. -// check_spawn_state: Like check_spawn_snapshot but invoking verifier.resume_from_state instead. -// check_spawn_current_memory: Use current_memory() to terminate infinite recursion. -// check_spawn_current_cycles: callee's current_cycles should inherit caller's current_cycles. -// check_spawn_times_bug_1: BUG: execution results may be inconsistent -// check_spawn_times_bug_2: BUG: execution results may be inconsistent - #[test] fn check_vm_version() { let script_version = SCRIPT_VERSION; @@ -61,71 +37,6 @@ fn check_vm_version() { assert_eq!(result.is_ok(), script_version == ScriptVersion::V2); } -// #[test] -// fn check_get_memory_limit() { -// let script_version = SCRIPT_VERSION; - -// let (memory_limit_cell, memory_limit_data_hash) = -// load_cell_from_path("testdata/get_memory_limit"); - -// let memory_limit_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(memory_limit_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(memory_limit_script) -// .build(); - -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![memory_limit_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; - -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } - -// #[test] -// fn check_set_content() { -// let script_version = SCRIPT_VERSION; - -// let (set_content_cell, set_content_data_hash) = load_cell_from_path("testdata/set_content"); - -// let memory_limit_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(set_content_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(memory_limit_script) -// .build(); - -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![set_content_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; - -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } - #[test] fn check_spawn_strcat() { let script_version = SCRIPT_VERSION; @@ -160,218 +71,119 @@ fn check_spawn_strcat() { assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); } -// #[test] -// fn check_spawn_strcat_data_hash() { -// let script_version = SCRIPT_VERSION; - -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_caller_strcat_data_hash"); -// let (spawn_callee_cell, _spawn_callee_data_hash) = -// load_cell_from_path("testdata/spawn_callee_strcat"); - -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } - -// #[test] -// fn check_spawn_get_memory_limit() { -// let script_version = SCRIPT_VERSION; - -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_caller_get_memory_limit"); -// let (spawn_callee_cell, _spawn_callee_data_hash) = -// load_cell_from_path("testdata/spawn_callee_get_memory_limit"); - -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } - -// #[test] -// fn check_spawn_set_content() { -// let script_version = SCRIPT_VERSION; - -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_caller_set_content"); -// let (spawn_callee_cell, _spawn_callee_data_hash) = -// load_cell_from_path("testdata/spawn_callee_set_content"); - -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } - -// #[test] -// fn check_spawn_out_of_cycles() { -// let script_version = SCRIPT_VERSION; +#[test] +fn check_spawn_out_of_cycles() { + let script_version = SCRIPT_VERSION; -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_caller_out_of_cycles"); -// let (spawn_callee_cell, _spawn_callee_data_hash) = -// load_cell_from_path("testdata/spawn_callee_out_of_cycles"); + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_out_of_cycles"); + let (spawn_callee_cell, _spawn_callee_data_hash) = + load_cell_from_path("testdata/spawn_callee_out_of_cycles"); -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify(script_version, &rtx, 0xffffff); -// if script_version >= ScriptVersion::V2 { -// assert!(result -// .unwrap_err() -// .to_string() -// .contains("ExceededMaximumCycles")) -// } else { -// assert!(result.is_err()) -// } -// } + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify(script_version, &rtx, 0xffffff); + if script_version >= ScriptVersion::V2 { + assert!(result + .unwrap_err() + .to_string() + .contains("ExceededMaximumCycles")) + } else { + assert!(result.is_err()) + } +} -// #[test] -// fn check_spawn_exec() { -// let script_version = SCRIPT_VERSION; +#[test] +fn check_spawn_exec() { + let script_version = SCRIPT_VERSION; -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_caller_exec"); -// let (spawn_callee_caller_cell, _) = load_cell_from_path("testdata/spawn_callee_exec_caller"); -// let (spawn_callee_callee_cell, _) = load_cell_from_path("testdata/spawn_callee_exec_callee"); + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_exec"); + let (spawn_callee_caller_cell, _) = load_cell_from_path("testdata/spawn_callee_exec_caller"); + let (spawn_callee_callee_cell, _) = load_cell_from_path("testdata/spawn_callee_exec_callee"); -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![ -// spawn_caller_cell, -// spawn_callee_caller_cell, -// spawn_callee_callee_cell, -// ], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify(script_version, &rtx, 0xffffff); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![ + spawn_caller_cell, + spawn_callee_caller_cell, + spawn_callee_callee_cell, + ], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify(script_version, &rtx, 0xffffff); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} -// #[test] -// fn check_spawn_strcat_wrap() { -// let script_version = SCRIPT_VERSION; +#[test] +fn check_spawn_strcat_wrap() { + let script_version = SCRIPT_VERSION; -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_caller_strcat_wrap"); -// let (spawn_callee_caller_cell, _) = load_cell_from_path("testdata/spawn_caller_strcat"); -// let (spawn_callee_callee_cell, _) = load_cell_from_path("testdata/spawn_callee_strcat"); + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_strcat_wrap"); + let (spawn_callee_caller_cell, _) = load_cell_from_path("testdata/spawn_caller_strcat"); + let (spawn_callee_callee_cell, _) = load_cell_from_path("testdata/spawn_callee_strcat"); -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![ -// spawn_caller_cell, -// spawn_callee_callee_cell, -// spawn_callee_caller_cell, -// ], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify(script_version, &rtx, 0xffffff); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![ + spawn_caller_cell, + spawn_callee_callee_cell, + spawn_callee_caller_cell, + ], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify(script_version, &rtx, 0xffffff); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} // #[test] // fn check_spawn_out_of_cycles_wrap() { @@ -417,195 +229,41 @@ fn check_spawn_strcat() { // } // } -// #[test] -// fn check_spawn_recursive() { -// let script_version = SCRIPT_VERSION; - -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_recursive"); - -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// if script_version >= ScriptVersion::V2 { -// assert!(result.unwrap_err().to_string().contains("error code 7")) -// } else { -// assert!(result.is_err()) -// } -// } - -// #[test] -// fn check_spawn_big_memory_size() { -// let script_version = SCRIPT_VERSION; - -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_big_memory_size"); - -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } - -// #[test] -// fn check_spawn_big_content_length() { -// let script_version = SCRIPT_VERSION; - -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_big_content_length"); - -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } - -// #[test] -// fn check_peak_memory_4m_to_32m() { -// let script_version = SCRIPT_VERSION; - -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_peak_memory_4m_to_32m"); - -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } - -// #[test] -// fn check_peak_memory_2m_to_32m() { -// let script_version = SCRIPT_VERSION; - -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_peak_memory_2m_to_32m"); - -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } - -// #[test] -// fn check_peak_memory_512k_to_32m() { -// let script_version = SCRIPT_VERSION; +#[test] +fn check_spawn_recursive() { + let script_version = SCRIPT_VERSION; -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_peak_memory_512k_to_32m"); + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_recursive"); -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + 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")) + } else { + assert!(result.is_err()) + } +} // #[test] // fn check_spawn_snapshot() { @@ -853,37 +511,6 @@ fn check_spawn_strcat() { // assert!(chunks_count > 1); // } -// #[test] -// fn check_spawn_current_memory() { -// let script_version = SCRIPT_VERSION; - -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_current_memory"); - -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); - -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); - -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } - // #[test] // fn check_spawn_current_cycles() { // let script_version = SCRIPT_VERSION; diff --git a/script/testdata/Makefile b/script/testdata/Makefile index e4db1600f5..76e2ecdc25 100644 --- a/script/testdata/Makefile +++ b/script/testdata/Makefile @@ -57,9 +57,16 @@ ALL_BINS := jalr_zero \ load_arithmetic \ debugger \ spawn_caller_strcat \ - spawn_callee_strcat - - + spawn_callee_strcat \ + spawn_caller_exec \ + spawn_callee_exec_caller \ + spawn_callee_exec_callee \ + spawn_caller_strcat_wrap \ + spawn_recursive \ + spawn_callee_out_of_cycles \ + spawn_caller_out_of_cycles + + ALL_LIBS := is_even.lib \ add1.lib sub1.lib mul2.lib div2.lib @@ -126,4 +133,10 @@ load_arithmetic: load_arithmetic.c spawn_caller_strcat: spawn_caller_strcat.c utils.h spawn_callee_strcat: spawn_callee_strcat.c utils.h - +spawn_caller_exec: spawn_caller_exec.c +spawn_callee_exec_caller: spawn_callee_exec_caller.c +spawn_callee_exec_callee: spawn_callee_exec_callee.c +spawn_caller_strcat_wrap: spawn_caller_strcat_wrap.c utils.h +spawn_recursive: spawn_recursive.c utils.h +spawn_caller_out_of_cycles: spawn_caller_out_of_cycles.c +spawn_callee_out_of_cycles: spawn_callee_out_of_cycles.c diff --git a/script/testdata/spawn_callee_exec_callee b/script/testdata/spawn_callee_exec_callee new file mode 100755 index 0000000000000000000000000000000000000000..e7e344be7a0ba450494a290bfa21e3384559e21a GIT binary patch literal 1184 zcmb_bO>5gg5FPm=A2&6pkc47G4sIGm96~7}6g#$TT8dL}+e;72T3HeWOLnBK>p&oJ z|AN8osgPTKPLDnIAGD?Sy0g+ONw%0?vO@c2-+MFKl|~ot%SOhsK#vUk2DLg*W`GI_ z-!o~TvrexpAl{tvMl0BiQ6}KVE(+0*psjql~)=R^!Ld>7Vh!*L;kI zX05hcC^cJe9u>-Er|fJ&bpz?hkG%m{1q^d`J{mmP@wfY1EKn0ylZO+E{~1}_+mQBm z+nNPBdf{CHe+9;$5#eOQE{xKE^5*QD1D1is|<|r1e8W4Q2-wQBe72Tk8K|NhcEO z?$D^(9=oq^*x;Io$A+NuG_BU=o|N{D46i6b{ln^BAby!}5%J&d2Pjd|0r@nT&wnr@ N{|n{s=|n;^|1ZY+Zyo>u literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_callee_exec_callee.c b/script/testdata/spawn_callee_exec_callee.c new file mode 100644 index 0000000000..a53d0f5123 --- /dev/null +++ b/script/testdata/spawn_callee_exec_callee.c @@ -0,0 +1,3 @@ +#include + +int main() { return 0; } diff --git a/script/testdata/spawn_callee_exec_caller b/script/testdata/spawn_callee_exec_caller new file mode 100755 index 0000000000000000000000000000000000000000..671dd0acd25979155e36edcde192da496095fae5 GIT binary patch literal 1208 zcmb_cO>fgc5FIB?Nl!IBRlp&YIPfK_L8w9qp`@*2flxpS<-%dLaaZ6fc7na6>7h!) zol}rF^9Q1yIP(+uCj@cff?&p;744#k3uAfT?3*{UyY|>)|8cA2IAE*<-+^ZD^AVuI zfgh#9p;!a%VzdDlU^!P+So23gUQu(#F@xY1#ESpUcUqH{6HJ0>^>myey$bWyx>F z9hkZ2`6tM);a<#pxWow$Sbu8iA1$c!oa>l#(LTst;O%04d);rh&QLJSbQKtpIGM-i=4PMxfW0jzj_l766PNVJ{t*DFshh4@Z z^v0ICn0dYf?zk!PmS!cjr|KfuDPn>_>Br@9hzX7^_cZUD~ literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_callee_exec_caller.c b/script/testdata/spawn_callee_exec_caller.c new file mode 100644 index 0000000000..289a95b699 --- /dev/null +++ b/script/testdata/spawn_callee_exec_caller.c @@ -0,0 +1,8 @@ +#include +#include "ckb_syscalls.h" + +int main() { + // syscall exec + syscall(2043, 2, 3, 0, 0, 0, NULL); + return -1; +} diff --git a/script/testdata/spawn_callee_out_of_cycles b/script/testdata/spawn_callee_out_of_cycles new file mode 100755 index 0000000000000000000000000000000000000000..3b2f6684d2d1739312fad545a995e77c09f9dbc1 GIT binary patch literal 1928 zcmbtVeM}o=7=N#&EfA*&kqs{UkStTDR$$10YF8Mn5m}dkGBdN?+M|?0DbOC=j%*ne zt`%6fKdLP8%t#vDls}fZm=V&5N*ubx5aY++V=XYKd~{tI9D?V2*Slq7!+(5}dwtV!;TA^uCr2?O zh6k0=>V@OslhdZ)^m>?GSjt}+nUu{8MlQQ(J<}xv_{C@@ z;_b%_uvM}yZj_C@*?0nuE6C*RSNdF4zl>@xv{tJxj zK8IfXos-4F7x1p=cBXHf^O1|3#{0L9>0aPE57)cV?gW6lV$Y%87{~Pd!F5)I-FVM~ z3{>^Guv41kWgVJ0$)Q_*6T0;Vn?`Mir`Ll}Z);R9 zA#4Fvz`hwuA6({7Z+L*p3!I1Ce6}$3%f)C~3OXw3a?6=6sF$di@ zJYcd2k#j+k-LGBqLymSbbQ7B%B~6wqkP+y*3q~O);30u_W|U{GT!A@`1>KGZ`WvTE zPmp7ofNEJ+Vo9%w5&_p;P)S{&MO{ZIgYI}W%*3W-S>%WG0 zbja1AKX|Zc*UNgt`>*WE$x-L1vqAA*Sa=Sr6K?~^E+{6XC>(A1dDh(KY^;%=jQoVd z2|E9C$YB?r7W?&4q8!K`RUgW7AU5Sg3lO3cz&-8}lOXPZa|*QAp;BMR8T_JBU{qb& zK{gD}`3-`#=_!XPv`9RDgeHS6-Ik5@fwuznZ?x(%?G_>>UREl?>N!luB zvyrr8xY1@ao3W-=0&A+pa0<7XooXCln8ns)GTN}_Caaw=J9a}$RcY~i#aKz1{v88` zLA|7^3M(^|3bM)R#GHiDL4Zc1)efDHbImnI!U!<4y#~};O#rB!R3l+DK_nb;tdk_d ze3}4iys5F#Y=?qSH)1pW7LcC&9+|Kfg)*c`^PiDNw|X@&5u^)a~;C literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_callee_out_of_cycles.c b/script/testdata/spawn_callee_out_of_cycles.c new file mode 100644 index 0000000000..1dbfe86b0a --- /dev/null +++ b/script/testdata/spawn_callee_out_of_cycles.c @@ -0,0 +1,10 @@ +#include + +int fib(int n) { + if (n < 2) { + return n; + } + return fib(n - 1) + fib(n - 2); +} + +int main() { return fib(100); } diff --git a/script/testdata/spawn_caller_exec b/script/testdata/spawn_caller_exec new file mode 100755 index 0000000000000000000000000000000000000000..dffd1dd7150ca2bcb9ba651b575b1e547f019ea6 GIT binary patch literal 4648 zcmbVQ4^UG_8sGO`-rEoYi9F?Bz#>AgYLC&{qj$Dt2uPx~GQIP>-ZOvl4cv?UFXhx1IosUAK`X1 zMIt2Hxf{4weA6S`T?D9Hac|^pdk&Q=yr!f#x`n%Qfqf@>K&3)8=V-i68c`yx^6(sB z1nhCbJ`~{tEVC5ih-uCQMC-YL*c>^`$Es**C#v}%q@(g+S%$0-%@KihA5y%jly!~< z#Dot5_NT;M^z|nXl3DS5_M&J$4qFhAx>$`Pts08Pkya0>LLLB-PIL<#q_@4sGjSjk z{f5B+;fY#tC=~7HXgc4^D**jm4{DB7e0FV#M}JMMIX5Orjf%Cockry+=t-WzdTz~x z`DDJ=+(mTcJc(tEU*~(BJ;HcC*yw&$6vnrMFT^NMVq@Kx`QE?vh?~w`4cUtqZ(#qg z_MDV+|IQD&pVbwT;KVVNC$WuXesgg1vi&D{_Q~)U26Oc`$V{ew)BMOBy>#|*%@{Gl>nJ<*%tlD%E|}7TlG!;*H=gTM>v1# zt>1lhVe<0C;PCaK8w0rd8jpCEc{`g>1Dnb8Mgse4#ITvCi>Klq)5UPKy_Yo{aj?wQf%mC1%F#;X>ppQtig9a$)bi5?GUnYn&<5FnFg~t9gJWPD{Jdp% zuEUM7DT3`cApcmR0Qb?%IZrU(66u?NpA9;H%GoaI8WW#e5?m0uBE~m z62r$M zN3vO1bDWG3*ZUy0p`_A!eaw?;AV4q3n%H890+~*11|PXmbrRL@)_EZiYSTd0B=W*k)WpT2CiPrLyl_cL`@H|a zF-7)|X%cN-5epoxK6qGvy@lz;-m2KSsV-6YI561UUyF9bn4J1Aj*Lu!6@K5xAGRZa31NPYLbk9Z*|`c>;Wy z3yq;)E5K|HF}SZ)q@=phE|`KTEoy_QLM>FF7MQ}j&gERhI={CwiQmv*%K?q14lf(I~F((k&KWGHAM>l91jYYCUSif z6F5ht=9>=jElP6QZ{w0S$60%vMl@BNEL9q=JG-znaum$k$13FA2*-Ot{1atQ0#OZ}_JlZafQ*!NS{GH83-l-Ee zyhWk24xb%rpZh&2zcv1JQbFo_d)0ZOy*Z&LB9yb$I74DG9C)jz4JHA!xg?6L;c>59 zPbZP@266_a?j~_CjNFTaqt&sgy;+QH43hn-Q|s`a6<_Br<}!ET_8cB8O0erq-U zkko(?P5%oyg*nc2e2TWr0zk0qKc({?#*#Nj$}bDbPgx@OT;caHXsWPQSjfsqL*|l_6!c<22*l$W zo3*4mV?D4`Rh3tzm~AQP)yvWgA5IC6QF);yCA|vYyC7xBl8hx8i-CS2 zR<5#Eqm6({!K6aVR&C6D)cQ!pVpA!3naK;`7iRuUWAGj09qFDiT@-(+fm4yvePSAe z0Sx%j{Q~nDAYU@335W3eZ#INWtSZ2*AfczXIe0*0?h(l!>DmM4N%;E`PD@IQB>Y1O zZ@{jRmWdx?XC`it@Z~tyq&+WPo_>pIYWljQrL4ku4Cb^;_qcUL3AbnQqb2^w-ya`q z2*=*dxPNWKII$z&2NUs_v^xA~$-J}gx8s!Y8FpU5II$z=OTPQP7Lxz*y!(H`&f79R zW8OoO{a7jQ9e5mS)fML2G85UpmMW8FlLciUU@EV%nF?x(iY!%Ox~!(81enTf>AgvU8+ z)|m40mxt(r>S|n4<|-Q~HCxLt^L|-Nq1k2zCQDf%sJ50?l;HX!ZUc}}T~}%|7vSDj z74Fx|l+Ciq1~RJ3L#i2g0+4~qOG|MfW0VwFhS_GTvKG|Xekfu&CjUpT!#X6>a^B=T zz9ZREN8WE#-sdtp4--UR#^w4vCF#8(3rf9m#&`i96HF?Td;3)SUtnel&(zPrx@7*D z$BO*FL=5IlZ$y?fxql4Pct o6CvCp@bkmkLrD157ai_TOv4B{bAJ3&_doUDkp9 +#include "utils.h" + +int main() { return simple_spawn(1); } diff --git a/script/testdata/spawn_caller_out_of_cycles b/script/testdata/spawn_caller_out_of_cycles new file mode 100755 index 0000000000000000000000000000000000000000..a702a7757742198f6b4d1bc14dbdd48e9702812f GIT binary patch literal 4656 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 literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_caller_out_of_cycles.c b/script/testdata/spawn_caller_out_of_cycles.c new file mode 100644 index 0000000000..f7696b2f12 --- /dev/null +++ b/script/testdata/spawn_caller_out_of_cycles.c @@ -0,0 +1,6 @@ +#include "utils.h" + +int main() { + return simple_spawn(1); +} + diff --git a/script/testdata/spawn_caller_strcat b/script/testdata/spawn_caller_strcat index 98358ec114504fca3a0940bb7cc72a152512d044..57a356128f540dcdd36522ba9716ebb95f3c9e43 100755 GIT binary patch delta 622 zcmcbh`9foYgy0DtMg|aY0Fw+18WT0mIm`GUyt0Xz?jA?eg&7&QPi|*_YWL=7`sDWZ zr#ccE0?HY7(}Sib?->jnLLYXz?|WgxvG0uyLu<;u z4>l6}zDyQl)MEOeKG}&;h0F9o?@^Fh>`x{aFv>GZOrF3frE2MRG}SeAax3dIVOG{h z?->GgZ|+~zR_gY4`=Yj3x2r%h*X`%#i;TCJ8E1HNZ z9R^0X_aD~poy>88wHWAy*g~%#TAi+`!mO?L+McNW@%yr_CFsMV2d-J~KiGd4X6W3~@#4L$E78)W3bWpMl{P8zaLpRtUa;#D1xObcB$nsJCnx6Qq!z^&mlP!@mgprMfy$5Q-Tp%q3G~vYLg97f1^Coi&$}=);))YL>$oq~5ss=<&78DVlEFdf(w15}l zgay11*=r1wjfBe>%OL)oCw zL)m7c+k1uyHb>JZx3j;rd*hl4Vzs{ns(EGif$0g;7p5Off0`aNJ$cVyV5K9WA@H8z zgG21oPWOE;Y&iA-)!Q)a`v6q^)<$CAm)4Z`3>VBN{?K9)(3q^ksFJPtruQh==w~w| z_Dz*skleSOf%zCaL$ez@Ln}Kg`(uu4|EyWAIV8(nV`>IEN2!(Bgwdnfq|qJdP|v0Y zt(H}7j&4U&T~jBww!Q{h19V1#?#=y++A7`NZeP@v>2?)J3bQdVecZf}@fI`Voy|S0 z&diLmn=f!21X7bH@z|PfWOCJEV03%`Vg2sO92Z!NfdLX*==DRZ6Brz5HB$78TNKGeT`xSxUH7aJqP zGgb)xfW(H0q0mtIJ4os-O@7Fm&sJQLSX81gSx`_|TR~4x59q>-)SR4rAYGncl#>Fa zlZ#RlOH$*DOH$$sG7D0RLCPlc3Q7qwFhDdH7bKSFfkjLCVkckWlVLnC`6FMsSdzg4D*IsaMt*U|gvlrQ^%?sn|KxX_l(HXjr?&d9{aJGo0pPv`(t#{pi576r!1r-aHF nA53->wrBh_xl!1jNr8XzAz?eliph*3_MFZ_5OtoDJB8%|Jptmy diff --git a/script/testdata/spawn_caller_strcat.c b/script/testdata/spawn_caller_strcat.c index 6bb675e2b3..b1cd8f26a2 100644 --- a/script/testdata/spawn_caller_strcat.c +++ b/script/testdata/spawn_caller_strcat.c @@ -5,13 +5,11 @@ #include "utils.h" int main() { - printf("start spawn_caller_strcat ..."); int err = 0; const char *argv[] = {"hello", "world"}; uint64_t pid = 0; uint64_t fds[2] = {0}; uint64_t inherited_fds[3] = {0}; - printf("create_std_pipes ..."); err = create_std_pipes(fds, inherited_fds); CHECK(err); @@ -21,7 +19,6 @@ int main() { .process_id = &pid, .inherited_fds = inherited_fds, }; - printf("start spawn ..."); err = ckb_spawn(1, CKB_SOURCE_CELL_DEP, 0, 0, &spgs); CHECK(err); uint8_t buffer[1024] = {0}; diff --git a/script/testdata/spawn_caller_strcat_wrap b/script/testdata/spawn_caller_strcat_wrap new file mode 100755 index 0000000000000000000000000000000000000000..7f49a82ec041a6343f9f3f438e89ac221e28bd01 GIT binary patch literal 4656 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 +#include +#include +#include "utils.h" + +int main() { return simple_spawn(2); } \ No newline at end of file diff --git a/script/testdata/spawn_recursive b/script/testdata/spawn_recursive new file mode 100755 index 0000000000000000000000000000000000000000..4e5934da7594d08159b227cd1e9a5a6fc17ba08b GIT binary patch literal 4648 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 +#include "ckb_consts.h" +#include "ckb_syscalls.h" enum CkbSpawnError { ErrorCommon = 31, @@ -62,3 +65,21 @@ int create_std_pipes(uint64_t* fds, uint64_t* inherited_fds) { exit: return err; } + +// spawn script at `index` in cell_deps without any argc, argv +int simple_spawn(size_t index) { + int err = 0; + int8_t spawn_exit_code = 255; + const char* argv[1] = {0}; + uint64_t pid = 0; + uint64_t fds[1] = {0}; + spawn_args_t spgs = {.argc = 0, .argv = argv, .process_id = &pid, .inherited_fds = fds}; + err = ckb_spawn(index, CKB_SOURCE_CELL_DEP, 0, 0, &spgs); + CHECK(err); + err = ckb_wait(pid, &spawn_exit_code); + CHECK(err); + CHECK(spawn_exit_code); + +exit: + return err; +} \ No newline at end of file From f08e520c56e1318a74658bed407aea046dadb17f Mon Sep 17 00:00:00 2001 From: xjd Date: Wed, 6 Mar 2024 14:11:45 +0800 Subject: [PATCH 2/2] Add more test cases --- script/src/v2_syscalls.rs | 2 +- .../tests/ckb_latest/features_since_v2023.rs | 212 +++++++++--------- script/testdata/Makefile | 12 +- script/testdata/spawn_callee_current_cycles | Bin 0 -> 1416 bytes script/testdata/spawn_callee_current_cycles.c | 28 +++ script/testdata/spawn_callee_out_of_cycles.c | 8 +- script/testdata/spawn_caller_current_cycles | Bin 0 -> 5552 bytes script/testdata/spawn_caller_current_cycles.c | 25 +++ script/testdata/spawn_caller_out_of_cycles.c | 5 +- .../testdata/spawn_caller_out_of_cycles_wrap | Bin 0 -> 4664 bytes .../spawn_caller_out_of_cycles_wrap.c | 2 + script/testdata/spawn_times | Bin 0 -> 4672 bytes script/testdata/spawn_times.c | 13 ++ script/testdata/utils.h | 18 +- 14 files changed, 209 insertions(+), 116 deletions(-) create mode 100755 script/testdata/spawn_callee_current_cycles create mode 100644 script/testdata/spawn_callee_current_cycles.c create mode 100755 script/testdata/spawn_caller_current_cycles create mode 100644 script/testdata/spawn_caller_current_cycles.c create mode 100755 script/testdata/spawn_caller_out_of_cycles_wrap create mode 100644 script/testdata/spawn_caller_out_of_cycles_wrap.c create mode 100755 script/testdata/spawn_times create mode 100644 script/testdata/spawn_times.c diff --git a/script/src/v2_syscalls.rs b/script/src/v2_syscalls.rs index 4bc2b1c9a6..0d8b404636 100644 --- a/script/src/v2_syscalls.rs +++ b/script/src/v2_syscalls.rs @@ -314,7 +314,7 @@ impl= ScriptVersion::V2); } -// #[test] -// fn check_spawn_out_of_cycles_wrap() { -// let script_version = SCRIPT_VERSION; +#[test] +fn check_spawn_out_of_cycles_wrap() { + let script_version = SCRIPT_VERSION; -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_caller_out_of_cycles_wrap"); -// let (spawn_callee_caller_cell, _) = load_cell_from_path("testdata/spawn_caller_out_of_cycles"); -// let (spawn_callee_callee_cell, _) = load_cell_from_path("testdata/spawn_callee_out_of_cycles"); + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_out_of_cycles_wrap"); + let (spawn_callee_caller_cell, _) = load_cell_from_path("testdata/spawn_caller_out_of_cycles"); + let (spawn_callee_callee_cell, _) = load_cell_from_path("testdata/spawn_callee_out_of_cycles"); -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![ -// spawn_caller_cell, -// spawn_callee_callee_cell, -// spawn_callee_caller_cell, -// ], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify(script_version, &rtx, 0xffffff); -// if script_version >= ScriptVersion::V2 { -// assert!(result -// .unwrap_err() -// .to_string() -// .contains("ExceededMaximumCycles")) -// } else { -// assert!(result.is_err()) -// } -// } + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![ + spawn_caller_cell, + spawn_callee_callee_cell, + spawn_callee_caller_cell, + ], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify(script_version, &rtx, 0xffffff); + if script_version >= ScriptVersion::V2 { + assert!(result + .unwrap_err() + .to_string() + .contains("ExceededMaximumCycles")) + } else { + assert!(result.is_err()) + } +} #[test] fn check_spawn_recursive() { @@ -265,46 +265,47 @@ fn check_spawn_recursive() { } } -// #[test] -// fn check_spawn_snapshot() { -// let script_version = SCRIPT_VERSION; -// if script_version <= ScriptVersion::V1 { -// return; -// } - -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_caller_exec"); -// let (snapshot_cell, _) = load_cell_from_path("testdata/current_cycles_with_snapshot"); +#[test] +fn check_spawn_snapshot() { + let script_version = SCRIPT_VERSION; + if script_version <= ScriptVersion::V1 { + return; + } -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_exec"); + let (snapshot_cell, _) = load_cell_from_path("testdata/current_cycles_with_snapshot"); -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell, snapshot_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_pause(script_version, &rtx, Cycle::MAX); -// let cycles_once = result.unwrap(); + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); -// let (cycles, chunks_count) = verifier -// .verify_until_completed(script_version, &rtx) -// .unwrap(); -// assert_eq!(cycles, cycles_once); -// assert!(chunks_count > 1); -// } + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell, snapshot_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_pause(script_version, &rtx, Cycle::MAX); + let cycles_once = result.unwrap(); + + // TODO + // let (cycles, chunks_count) = verifier + // .verify_until_completed(script_version, &rtx) + // .unwrap(); + // assert_eq!(cycles, cycles_once); + // assert!(chunks_count > 1); +} // #[tokio::test(flavor = "multi_thread", worker_threads = 4)] // async fn check_spawn_async() { @@ -511,39 +512,40 @@ fn check_spawn_recursive() { // assert!(chunks_count > 1); // } -// #[test] -// fn check_spawn_current_cycles() { -// let script_version = SCRIPT_VERSION; +#[test] +fn check_spawn_current_cycles() { + let script_version = SCRIPT_VERSION; -// let (spawn_caller_cell, spawn_caller_data_hash) = -// load_cell_from_path("testdata/spawn_caller_current_cycles"); -// let (spawn_callee_cell, _spawn_callee_data_hash) = -// load_cell_from_path("testdata/spawn_callee_current_cycles"); + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_caller_current_cycles"); + let (spawn_callee_cell, _spawn_callee_data_hash) = + load_cell_from_path("testdata/spawn_callee_current_cycles"); -// let spawn_caller_script = Script::new_builder() -// .hash_type(script_version.data_hash_type().into()) -// .code_hash(spawn_caller_data_hash) -// .build(); -// let output = CellOutputBuilder::default() -// .capacity(capacity_bytes!(100).pack()) -// .lock(spawn_caller_script) -// .build(); -// let input = CellInput::new(OutPoint::null(), 0); + let spawn_caller_script = Script::new_builder() + .hash_type(script_version.data_hash_type().into()) + .code_hash(spawn_caller_data_hash) + .build(); + let output = CellOutputBuilder::default() + .capacity(capacity_bytes!(100).pack()) + .lock(spawn_caller_script) + .build(); + let input = CellInput::new(OutPoint::null(), 0); -// let transaction = TransactionBuilder::default().input(input).build(); -// let dummy_cell = create_dummy_cell(output); + let transaction = TransactionBuilder::default().input(input).build(); + let dummy_cell = create_dummy_cell(output); -// let rtx = ResolvedTransaction { -// transaction, -// resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], -// resolved_inputs: vec![dummy_cell], -// resolved_dep_groups: vec![], -// }; -// let verifier = TransactionScriptsVerifierWithEnv::new(); -// let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); -// } + let rtx = ResolvedTransaction { + transaction, + resolved_cell_deps: vec![spawn_caller_cell, spawn_callee_cell], + resolved_inputs: vec![dummy_cell], + resolved_dep_groups: vec![], + }; + let verifier = TransactionScriptsVerifierWithEnv::new(); + let result = verifier.verify_without_limit(script_version, &rtx); + assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +} +// TODO: will reach memory limit // #[test] // fn check_spawn_times_bug_1() { // let script_version = SCRIPT_VERSION; @@ -571,7 +573,9 @@ fn check_spawn_recursive() { // }; // let verifier = TransactionScriptsVerifierWithEnv::new(); // let result = verifier.verify_without_limit(script_version, &rtx); -// assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); +// let err = result.unwrap_err(); +// println!("{:?}", err); +// // assert_eq!(result.is_ok(), script_version >= ScriptVersion::V2); // } // #[test] diff --git a/script/testdata/Makefile b/script/testdata/Makefile index 76e2ecdc25..90d7a50941 100644 --- a/script/testdata/Makefile +++ b/script/testdata/Makefile @@ -64,8 +64,11 @@ ALL_BINS := jalr_zero \ spawn_caller_strcat_wrap \ spawn_recursive \ spawn_callee_out_of_cycles \ - spawn_caller_out_of_cycles - + spawn_caller_out_of_cycles \ + spawn_caller_out_of_cycles_wrap \ + spawn_caller_current_cycles \ + spawn_callee_current_cycles \ + spawn_times ALL_LIBS := is_even.lib \ add1.lib sub1.lib mul2.lib div2.lib @@ -140,3 +143,8 @@ spawn_caller_strcat_wrap: spawn_caller_strcat_wrap.c utils.h spawn_recursive: spawn_recursive.c utils.h spawn_caller_out_of_cycles: spawn_caller_out_of_cycles.c spawn_callee_out_of_cycles: spawn_callee_out_of_cycles.c +spawn_caller_out_of_cycles_wrap: spawn_caller_out_of_cycles_wrap.c +spawn_caller_current_cycles: spawn_caller_current_cycles.c +spawn_callee_current_cycles: spawn_callee_current_cycles.c +spawn_times: spawn_times.c + diff --git a/script/testdata/spawn_callee_current_cycles b/script/testdata/spawn_callee_current_cycles new file mode 100755 index 0000000000000000000000000000000000000000..a49bc961bb0c2967f2e1f45d8fde51e4a95a2251 GIT binary patch literal 1416 zcmb_c%}*0S6o1ogx8+2EASwqTkwnpKs2XF$#4WI0Oq7G@!HetevVl$dmE8g1A{4_% zJel;sfrDt$7(ID3@!(1ENc;~>H5xBqOu+bozS+)TS;dnt+4u2#zxQT3^QP0<#Y}_{ z5E6mUz@n#t22gq8l~i+BPK7g=RUr;?z>0CsZwB*fJuTi^SV-1bi)Ok>e!C88tb4Jf z5shR@8KRf;a$;rLM@l1XG`<;KUf6OU+<3MSC#36SCrYY|)8l-uL-kCut8#)|%UzBFimSd9{`qDe3J z!E##{Ji52M)CTQ|IP}iFR|R)Yu5P^8wr?k3cBVJ>MV+0IGObY2%W^9SPHC|Eef2BR z{+6r0Tiu=;G@tAJ{bxIl=tEbJcBE2DO6h@gH*V8&eR~2(2fEQ@%$qoU$~{r+F>*|q zOxdU~`45rsj3@ay*V813)Q3C11pE?rklHOp;nUALC~yyb2U)N`$I>adCbAJUFZ*p14(nK=JR9)ILknDB&kVuIC&M^?Q1W>Ls3<1!JJ zJqeu7VgS}D$_dBnFy@Ln0kb%~Cze~`#4&E!e---@EQzweW}pG>pRWUX9K6MO!i3jv Q+M|A+*Pj!G+=lCa0iVCR3IG5A literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_callee_current_cycles.c b/script/testdata/spawn_callee_current_cycles.c new file mode 100644 index 0000000000..1e7e7f11d4 --- /dev/null +++ b/script/testdata/spawn_callee_current_cycles.c @@ -0,0 +1,28 @@ +#include +#include +#include + +#include "ckb_syscalls.h" + +int atoi(const char *s) { + int n = 0, neg = 0; + switch (*s) { + case '-': + neg = 1; + case '+': + s++; + } + /* Compute n as a negative number to avoid overflow on INT_MIN */ + while (_is_digit(*s)) n = 10 * n - (*s++ - '0'); + return neg ? n : -n; +} + +int main(int argc, const char *argv[]) { + int caller_cycles = atoi(argv[0]); + // Callee's current cycles must > caller's current cycles. + int callee_cycles = ckb_current_cycles(); + if (callee_cycles < caller_cycles + 100000) { + return 1; + } + return 0; +} diff --git a/script/testdata/spawn_callee_out_of_cycles.c b/script/testdata/spawn_callee_out_of_cycles.c index 1dbfe86b0a..caad7a35f3 100644 --- a/script/testdata/spawn_callee_out_of_cycles.c +++ b/script/testdata/spawn_callee_out_of_cycles.c @@ -1,10 +1,10 @@ #include int fib(int n) { - if (n < 2) { - return n; - } - return fib(n - 1) + fib(n - 2); + if (n < 2) { + return n; + } + return fib(n - 1) + fib(n - 2); } int main() { return fib(100); } diff --git a/script/testdata/spawn_caller_current_cycles b/script/testdata/spawn_caller_current_cycles new file mode 100755 index 0000000000000000000000000000000000000000..d22c5283b0d07fb543e34530f29d229abed1b5b2 GIT binary patch literal 5552 zcmbtYeOOahnm_j@_udc!M6Ts4qKMcTZHM)%*upduK#1DPbnUd=b+%2zAw(1rLV!kb zN&-oQ1exu%Qa4&1I-=#->DJ=M3WJW$qFW!wXIj^f`aErsi-;5jRyMLP4> zoaedsyyy3RocFx%dC&cLH|ynWk|2Q4Nbo(tquZeYOci7lvjGC5D)2lY(LDr6{IXO~ z=CK5(0{X6q04nrA{#c3*kb%2AAPo%-6ueZKb_G>8HK`CmzK5qQJPf-&K(n7o{^O{8K5Rj*tR(*VcS0o``EI4w=`$Bu& z8-yv9Z!DOq)pPcn%~Td__yIH*)5hMs?1JV3dQ10?jGaw8by`c6Rek;(k!8*zvd!6q z+N|azhuM5j(cQ-HHty;3XLMfRY%666wV7L_IKBL{}SD@)2w!?GLTv-cNO z9RZdqOI2)1OHT9XW%t#AFZ*uv*e07MZg;&knLCj`DqY`FlU(~*?WsD>7p{WQOyrn@ zo1UJA2O}c6v2fCy!BKJ=a&#n-DRnH)`sz700+0(2Ln$vxvA32pB6fN#LP3X%()M%` z>~E$cVBU4W{$?zK61CD>!AA`jeXXxEBK{p_ihGz0;O@|H*g(d>{Si?xUNkpd4XM7R zA!yV^EgIC)-|%sUrAQXf<;yLrnzY)fbWIJvGb%P`)@K5R@TI> zlsQ#72XY*nY&UFF=w&NQ0n)OUk9GLEov~M>j>H44j01=|$9*elr|O1n*WAn2Zl`7M zwozCeN|JG{wLed1H%Uo2xsJ%USwn8v0yeBNWTkJNueUhc*leUty#?7@nzztfyLV<( z=3AR8Lr{)ze7KQt0!N59(}SoN-|yfaJ_CqM{!r+MIfKaL_DRTcJNIxtFuw;ENTsms z8j03PLV_oy4weQY4tX4V7>2Y0O0<$e5sSDq%@f>NV= zMWz?cT1QT@BBW=Jn9!cfacWOu9U)JAQO(^Pr?rC{&jIE3_jzu75BQ1?bHvq{zRhv| zu7iK)+BbfCG5jF%|C^3;Lhe6(l>0d+{Sq`kCUwNQDA5bYcBLLU$1>mh_z33q`E1DC zl1Lr3*{Lo*`ql``B+!e%cVOW;c08PnzvtJL@FM|TmZ@Se_d$m+5Arp*$4c7$vLx?j z(f*S*aȼ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 literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_caller_current_cycles.c b/script/testdata/spawn_caller_current_cycles.c new file mode 100644 index 0000000000..af6149bed5 --- /dev/null +++ b/script/testdata/spawn_caller_current_cycles.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include "utils.h" +#include "ckb_syscalls.h" + +int fib(int n) { + if (n < 2) { + return n; + } + return fib(n - 1) + fib(n - 2); +} + +int main() { + // Use invalid calculations to make the current cycles a larger value. + if (fib(20) != 6765) { + return 1; + } + + int cycles = ckb_current_cycles(); + char buffer[16] = {0}; + sprintf_(buffer, "%d", cycles); + const char *argv[] = {&buffer[0], 0}; + return simple_spawn_args(1, 1, argv); +} diff --git a/script/testdata/spawn_caller_out_of_cycles.c b/script/testdata/spawn_caller_out_of_cycles.c index f7696b2f12..e64f5f398a 100644 --- a/script/testdata/spawn_caller_out_of_cycles.c +++ b/script/testdata/spawn_caller_out_of_cycles.c @@ -1,6 +1,3 @@ #include "utils.h" -int main() { - return simple_spawn(1); -} - +int main() { return simple_spawn(1); } diff --git a/script/testdata/spawn_caller_out_of_cycles_wrap b/script/testdata/spawn_caller_out_of_cycles_wrap new file mode 100755 index 0000000000000000000000000000000000000000..376bcc8adacd3c9f86b48dfdd086c6bd6da18779 GIT binary patch literal 4664 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 literal 0 HcmV?d00001 diff --git a/script/testdata/spawn_caller_out_of_cycles_wrap.c b/script/testdata/spawn_caller_out_of_cycles_wrap.c new file mode 100644 index 0000000000..6d182a140f --- /dev/null +++ b/script/testdata/spawn_caller_out_of_cycles_wrap.c @@ -0,0 +1,2 @@ +#include "utils.h" +int main() { return simple_spawn(2); } diff --git a/script/testdata/spawn_times b/script/testdata/spawn_times new file mode 100755 index 0000000000000000000000000000000000000000..4a5e1eeddf149902916a8b010a555e03b40c1267 GIT binary patch literal 4672 zcmbVQ4Ny}@9^dy~-rEoYi9E|U77=6s;bPs9f(x8_^Ssob8}j$KKR>e$*K)Z7$*!@au6ngUw}D8qYoSy#GE-R2et&-Ew-yZtn8SDd*6hGr3Lre3hKp9Yc7llost zvg=K)rj#68jjRLMA9M~S-aRJc+DZ7l$5(fu%1hwGw`bMt1GXAlO-xx^cI)ujp??j2 zF>tBRG2SwEwddvW+_Ai2)$?t&sr4V$AKfDO!_!d|j2LkVKA#Wm(nJU&;j}eFV6_|) zxCkm!2)}i-3P)M8h&3?p3gN z+iAb&caRY`zzN|&DnNCi;bb#2T7wL3j~XSQpN6aXvrk}O|>t5m4+0*&`cBTA%IE}jF7fL9!|2ZeY5 z%PfG{W12HQvEYJFYzQ6XBULoD9aVl3&{4UtEJJpP9uq;q9;Dc-ly#2z#F$Tf))nFo z`qq*IWL7+%H7}fx!WIOi&R1hks|Lccr_}?hzzTp!$2tWL(p%o)nJ5tOeoeoR@IMcH)0OScX(u{z zoW$bV8`*Aqr!blg);r%8h0(3xOEJt9Tf6bAZ1%+Z6oHyz2Z@#`Xes!#W z@YcZXK3sjZM_r5DZS|;zUC4BY0_#e|unSM+PeeT%7Xh-?r40)(&L*f{q79WF_J<3whC>Q(5|-sqoc9k*cO2kN z3N4k4IZ$v#0`c4ZBLbYqpbFUZIpWWAlf5L|jjIg`8oxCYIKwWF+O-lpR zU5qIx!u=FewE^twcDzR@0`EPtvksSdXa7JP?7nX|cp7hl-2D67&@OT&&4bt<5ds8I zoZ;gOiOs7v7sN`ZtT2E4+Zkg3UVv}vZGxXJgnd-KN zQP6lMmP!_5y}f+ZGk&2;k*-@7r+@(MhS9`(x@D_ds1^J4%~5l~31>dl+!zH8?q;$e zh;zY-4woEH7K;9n@n96i$GyE$l+si5vP6f2N=DTq(Inxf&JBT3l?>9xksBtVdM*;xt7q7vg)2(hjUpa)`n?Uw=by71{|SGOE8kPV(tgflz-i#=26R#-62?iUYf@ znmr`qqQ=`Vz#(oXsROX&T`GC@G9E`n;NIdooJe~yF_6#OpmrnX3Ggj0Fos^O0Mj|d z;J!+cnB+t|U?Qfps2L^+RZxK%VIp4zm57GP4EAPA)uwH9RIwweZ%vQYKnYY^ilMpj zNgUrO%FamKCqzWqQWOaEwUJ*B|B^ zmE^SF!o_cjD(JKu&_sTMRB5>GtipoOVK8kEtB|u1&@BzNCNbLN4_4_K>`Ngm4*N3C zz5H--tyo$3T{C>(KjC!hY*AK$-yg<)h5i``Bg9Z&8J8{xY+a3vCX*R$!ht_qnRH4 zC|J`oAuMqAr_1Z!_6=G0UyqQJL5}jpW8~CLbI$H!3~CV4{!=!l9hjjJuvL1CNzWz_C*ki&I4vorNcc_(ufaAe;}al8XKUfmS` z)MA|2k>8WCl03;qEtz-vqjuhu@hNs(k{vl-*Cjh|1>}D`@9v+l(<2AutwON^*>aCB^xZNNK#jqPP?nge4DPwbc2*Xv{Ax$;~M=mX=`D zT%L@PRZDfh)fqFg49l~PMm)|~waS>4y);1QR#f03$|<*iqMU+a%zRYVY|63Z0He9s z1VC!V#v)5jF77Sm!G5hwScyeRD`P)qoit5b1atfg4{~W!%CGL z`G0mKKS>1Tx4aymLz2C;&_@l+`75I{F+ucYT&}wzN$+p6pwug;jA!F9!KC#6A^)_J zpp?(D+Eo2i%pmiVx|!VM|5rpz1~E-!Nt63$F^%Ug4S$ zNZ%vrKPfRG#=`JVUVk(Z!Yu^<9_~GW1V2i0py2kGVE6Dlb$m+NHG{-d G{r>