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 f73a9efae8..fac884e630 100644 --- a/script/src/verify/tests/ckb_latest/features_since_v2023.rs +++ b/script/src/verify/tests/ckb_latest/features_since_v2023.rs @@ -1185,3 +1185,39 @@ fn check_spawn_length_out_of_bound() { let result = simple_spawn_test("testdata/spawn_cases", &[16]); assert_eq!(result.is_ok(), SCRIPT_VERSION == ScriptVersion::V2); } + +#[test] +fn check_spawn_huge_swap() { + let script_version = SCRIPT_VERSION; + + let (spawn_caller_cell, spawn_caller_data_hash) = + load_cell_from_path("testdata/spawn_huge_swap"); + + 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(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()) + } +} diff --git a/script/testdata/Makefile b/script/testdata/Makefile index 1d49c6e297..81dacc5b45 100644 --- a/script/testdata/Makefile +++ b/script/testdata/Makefile @@ -71,7 +71,8 @@ ALL_BINS := jalr_zero \ spawn_configurable_caller \ spawn_configurable_callee \ spawn_dag \ - spawn_fuzzing + spawn_fuzzing \ + spawn_huge_swap ALL_LIBS := is_even.lib \ add1.lib sub1.lib mul2.lib div2.lib @@ -156,3 +157,4 @@ spawn_configurable_caller: spawn_configurable_caller.c spawn_utils.h spawn_configurable_callee: spawn_configurable_callee.c spawn_utils.h spawn_dag: spawn_dag.c spawn_dag.h spawn_dag_escape_encoding.h spawn_fuzzing: spawn_fuzzing.c spawn_utils.h +spawn_huge_swap: spawn_huge_swap.c spawn_utils.h \ No newline at end of file diff --git a/script/testdata/add1.lib b/script/testdata/add1.lib index 69a36247da..e6cd7e9c06 100755 Binary files a/script/testdata/add1.lib and b/script/testdata/add1.lib differ diff --git a/script/testdata/div2.lib b/script/testdata/div2.lib index 5b11cc2fc4..d631c7773a 100755 Binary files a/script/testdata/div2.lib and b/script/testdata/div2.lib differ diff --git a/script/testdata/mul2.lib b/script/testdata/mul2.lib index 5529fbb34c..889d6cf06d 100755 Binary files a/script/testdata/mul2.lib and b/script/testdata/mul2.lib differ diff --git a/script/testdata/spawn_cases b/script/testdata/spawn_cases index 89f913c0a2..e26caac38c 100755 Binary files a/script/testdata/spawn_cases and b/script/testdata/spawn_cases differ diff --git a/script/testdata/spawn_huge_swap b/script/testdata/spawn_huge_swap new file mode 100755 index 0000000000..3d7ab1ca7a Binary files /dev/null and b/script/testdata/spawn_huge_swap differ diff --git a/script/testdata/spawn_huge_swap.c b/script/testdata/spawn_huge_swap.c new file mode 100644 index 0000000000..2666857631 --- /dev/null +++ b/script/testdata/spawn_huge_swap.c @@ -0,0 +1,65 @@ +#include "spawn_utils.h" + +// 2.4 M bytes +static uint64_t g_data[300 * 1024]; + +int main() { + int err = 0; + uint64_t fds[2] = {0}; + uint64_t pid = 0; + uint64_t current_pid = ckb_process_id(); + size_t argc = 1; + const char* argv[2] = {"", 0}; + int8_t exit_code = 0; + + printf("current pid = %d", current_pid); + for (size_t i = 0; i < sizeof(g_data) / sizeof(uint64_t); i++) { + g_data[i] = current_pid; + } + + if (current_pid == 7) { + // wait forever + ckb_wait(0, &exit_code); + } else { + err = full_spawn(0, argc, argv, fds, &pid); + CHECK(err); + if (current_pid == 0) { + uint8_t buf[1] = {0}; + while (true) { + size_t len = 1; + ckb_read(fds[CKB_STDIN], buf, &len); + } + } else if (current_pid == 1) { + uint64_t inherited_fds[3]; + size_t fds_len = 3; + err = ckb_inherited_file_descriptors(inherited_fds, &fds_len); + CHECK(err); + uint8_t buf[1] = {0}; + while (true) { + size_t len = 1; + ckb_write(inherited_fds[CKB_STDOUT], buf, &len); + ckb_read(fds[CKB_STDIN], buf, &len); + } + } else if (current_pid == 2) { + uint64_t inherited_fds[3]; + size_t fds_len = 3; + err = ckb_inherited_file_descriptors(inherited_fds, &fds_len); + CHECK(err); + uint8_t buf[1] = {0}; + while (true) { + size_t len = 1; + ckb_write(inherited_fds[CKB_STDOUT], buf, &len); + } + } else { + // wait forever + ckb_wait(0, &exit_code); + } + } + // avoid g_data to be optimized + for (size_t i = 0; i < sizeof(g_data) / sizeof(uint64_t); i++) { + err += (int8_t)g_data[i]; + } + +exit: + return err; +} \ No newline at end of file diff --git a/script/testdata/sub1.lib b/script/testdata/sub1.lib index c3fb211c9b..b1a89a227b 100755 Binary files a/script/testdata/sub1.lib and b/script/testdata/sub1.lib differ