From 7906a08637880a081d5a6f4047f20e0a4f48725f Mon Sep 17 00:00:00 2001 From: Pierre Hong Date: Thu, 30 Nov 2023 10:03:52 +0800 Subject: [PATCH] ADD: contract ret fetch --- assembler/src/test_data_generator.rs | 49 +- .../test_data/asm/sccall/sccall_callee.json | 86 ++- circuits/benches/fibo_loop.rs | 6 +- circuits/benches/sqrt_prophet.rs | 7 +- .../src/builtins/bitwise/bitwise_stark.rs | 6 +- .../builtins/rangecheck/rangecheck_stark.rs | 6 +- .../generation/ctl_test/debug_trace_print.rs | 6 +- circuits/src/program/program_stark.rs | 6 +- circuits/src/stark/ola_stark.rs | 6 +- circuits/src/test_utils.rs | 6 +- client/src/main.rs | 7 +- core/src/crypto/poseidon_trace.rs | 3 - core/src/merkle_tree/patch.rs | 17 +- core/src/merkle_tree/tree.rs | 17 +- core/src/program/mod.rs | 1 + core/src/state/mod.rs | 5 + core/src/trace/trace.rs | 10 +- core/src/types/merkle_tree/mod.rs | 2 +- core/src/vm/vm_state.rs | 1 - executor/src/lib.rs | 574 ++++++++++-------- executor/src/tests.rs | 36 +- zk-vm/src/lib.rs | 12 +- 22 files changed, 480 insertions(+), 389 deletions(-) diff --git a/assembler/src/test_data_generator.rs b/assembler/src/test_data_generator.rs index ade438be..a1a5a590 100644 --- a/assembler/src/test_data_generator.rs +++ b/assembler/src/test_data_generator.rs @@ -126,29 +126,29 @@ mod tests { generate_from_file("sc_input.json".to_string(), "sc_input.json".to_string()); } - // #[test] - // fn generate_sccall() { - // generate_from_file( - // "sccall/sccall_caller.json".to_string(), - // "sccall/sccall_caller.json".to_string(), - // ); - // generate_from_file( - // "sccall/sccall_callee.json".to_string(), - // "sccall/sccall_callee.json".to_string(), - // ); - // } + #[test] + fn generate_sccall() { + generate_from_file( + "sccall/sccall_caller.json".to_string(), + "sccall/sccall_caller.json".to_string(), + ); + generate_from_file( + "sccall/sccall_callee.json".to_string(), + "sccall/sccall_callee.json".to_string(), + ); + } - // #[test] - // fn generate_sccall_test() { - // generate_from_file( - // "sccall/caller.json".to_string(), - // "sccall/caller.json".to_string(), - // ); - // generate_from_file( - // "sccall/callee.json".to_string(), - // "sccall/callee.json".to_string(), - // ); - // } + #[test] + fn generate_sccall_test() { + generate_from_file( + "sccall/caller.json".to_string(), + "sccall/caller.json".to_string(), + ); + generate_from_file( + "sccall/callee.json".to_string(), + "sccall/callee.json".to_string(), + ); + } #[test] fn generate_store_u32() { @@ -194,6 +194,11 @@ mod tests { "sqrt_prophet_asm.json".to_string(), ); } + + #[test] + fn generate_ptr_call() { + generate_from_file("ptr_call.json".to_string(), "ptr_call.json".to_string()); + } fn generate_from_file(input_file_name: String, output_file_name: String) { let _ = fs::create_dir_all("test_data/bin"); let input_path = format!("test_data/asm/{}", input_file_name); diff --git a/assembler/test_data/asm/sccall/sccall_callee.json b/assembler/test_data/asm/sccall/sccall_callee.json index 75ca660c..0d45b84d 100644 --- a/assembler/test_data/asm/sccall/sccall_callee.json +++ b/assembler/test_data/asm/sccall/sccall_callee.json @@ -1,8 +1,60 @@ { - "program": "memcpy:\n.LBL15_0:\n add r9 r9 4\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mstore [r9,-3] r2\n mload r2 [r9,-3]\n mstore [r9,-2] r3\n mload r3 [r9,-2]\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL15_1\n.LBL15_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL15_2\n jmp .LBL15_3\n.LBL15_2:\n mload r6 [r1,r4]\n mstore [r2,r4] r6\n add r5 r4 1\n mstore [r9,-1] r5\n jmp .LBL15_1\n.LBL15_3:\n add r9 r9 -4\n ret\nmemcmp:\n.LBL16_0:\n add r9 r9 5\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mstore [r9,-3] r2\n mload r2 [r9,-3]\n mstore [r9,-2] r3\n mload r3 [r9,-2]\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL16_1\n.LBL16_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL16_2\n jmp .LBL16_3\n.LBL16_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n mstore [r9,-5] r7\n mload r7 [r9,-5]\n eq r6 r6 r7\n cjmp r6 .LBL16_2\n jmp .LBL16_4\n add r5 r4 1\n mstore [r9,-1] r5\n jmp .LBL16_1\n.LBL16_3:\n add r9 r9 -5\n ret\n.LBL16_4:\n mov r0 0\n add r9 r9 -5\n ret\nsetVars:\n.LBL17_0:\n add r9 r9 1\n mstore [r9,-1] r1\n mload r4 [r9,-1]\n mov r1 4\n.PROPHET17_0:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n not r7 4\n add r7 r7 1\n add r2 r1 r7\n mov r1 0\n mstore [r2] r1\n mov r1 0\n mstore [r2,+1] r1\n mov r1 0\n mstore [r2,+2] r1\n mov r1 0\n mstore [r2,+3] r1\n mov r1 4\n.PROPHET17_1:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n not r7 4\n add r7 r7 1\n add r3 r1 r7\n mov r1 r3\n mstore [r1] r4\n mov r3 0\n mstore [r1,+1] r3\n mov r3 0\n mstore [r1,+2] r3\n mov r3 0\n mstore [r1,+3] r3\n sstore r2 r1\n add r9 r9 -1\n ret\nadd:\n.LBL18_0:\n add r9 r9 2\n mstore [r9,-2] r1\n mstore [r9,-1] r2\n mload r1 [r9,-2]\n mload r2 [r9,-1]\n add r0 r1 r2\n range r0\n add r9 r9 -2\n ret\nfunction_dispatch:\n.LBL19_0:\n add r9 r9 4\n mstore [r9,-2] r9\n mov r4 r1\n mov r1 r2\n mov r1 r3\n mstore [r9,-3] r1\n mload r1 [r9,-3]\n eq r1 r4 2371037854\n cjmp r1 .LBL19_2\n eq r1 r4 2062500454\n cjmp r1 .LBL19_3\n jmp .LBL19_1\n.LBL19_1:\n ret\n.LBL19_2:\n mload r1 [r1]\n call setVars\n add r9 r9 -4\n ret\n.LBL19_3:\n mov r3 r1\n mload r3 [r3]\n add r2 r1 1\n mov r1 r2\n mload r2 [r1]\n mov r1 r3\n call add\n mov r2 r0\n mov r1 2\n.PROPHET19_0:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n not r7 2\n add r7 r7 1\n add r1 r1 r7\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mstore [r1] r2\n mov r2 1\n mstore [r1,+1] r2\n mload r1 [r9,-4]\n tstore r1 2\n add r9 r9 -4\n ret\nmain:\n.LBL20_0:\n add r9 r9 2\n mstore [r9,-2] r9\n mov r1 13\n.PROPHET20_0:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n mov r6 1\n not r7 13\n add r7 r7 1\n add r2 r1 r7\n tload r2 r6 13\n mov r1 r2\n mload r6 [r1]\n mov r1 14\n.PROPHET20_1:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n mov r2 1\n not r7 14\n add r7 r7 1\n add r3 r1 r7\n tload r3 r2 14\n mov r1 r3\n mload r2 [r1]\n add r4 r2 14\n mov r1 r4\n.PROPHET20_2:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n mov r3 1\n not r7 r4\n add r7 r7 1\n add r5 r1 r7\n tload r5 r3 r4\n mov r3 r5\n mov r1 r6\n call function_dispatch\n add r9 r9 -2\n end\n", + "program": "memcpy:\n.LBL15_0:\n add r9 r9 4\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mstore [r9,-3] r2\n mload r2 [r9,-3]\n mstore [r9,-2] r3\n mload r3 [r9,-2]\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL15_1\n.LBL15_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL15_2\n jmp .LBL15_3\n.LBL15_2:\n mload r6 [r1,r4]\n mstore [r2,r4] r6\n add r5 r4 1\n mstore [r9,-1] r5\n jmp .LBL15_1\n.LBL15_3:\n add r9 r9 -4\n ret\nmemcmp_eq:\n.LBL16_0:\n add r9 r9 5\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mstore [r9,-3] r2\n mload r2 [r9,-3]\n mstore [r9,-2] r3\n mload r3 [r9,-2]\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL16_1\n.LBL16_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL16_2\n mov r0 1\n jmp .LBL16_3\n.LBL16_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n mstore [r9,-5] r7\n add r5 r4 1\n mstore [r9,-1] r5\n mload r4 [r9,-5]\n eq r4 r6 r4\n cjmp r4 .LBL16_1\n mov r0 0\n jmp .LBL16_3\n.LBL16_3:\n add r9 r9 -5\n ret\nmemcmp_ugt:\n.LBL17_0:\n add r9 r9 5\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mstore [r9,-3] r2\n mload r2 [r9,-3]\n mstore [r9,-2] r3\n mload r3 [r9,-2]\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL17_1\n.LBL17_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL17_2\n mov r0 1\n jmp .LBL17_3\n.LBL17_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n mstore [r9,-5] r7\n add r5 r4 1\n mstore [r9,-1] r5\n mload r4 [r9,-5]\n gte r4 r6 r4\n mload r5 [r9,-5]\n neq r5 r6 r5\n and r4 r4 r5\n cjmp r4 .LBL17_1\n mov r0 0\n jmp .LBL17_3\n.LBL17_3:\n add r9 r9 -5\n ret\nmemcmp_uge:\n.LBL18_0:\n add r9 r9 5\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mstore [r9,-3] r2\n mload r2 [r9,-3]\n mstore [r9,-2] r3\n mload r3 [r9,-2]\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL18_1\n.LBL18_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL18_2\n mov r0 1\n jmp .LBL18_3\n.LBL18_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n mstore [r9,-5] r7\n add r5 r4 1\n mstore [r9,-1] r5\n mload r4 [r9,-5]\n gte r4 r6 r4\n cjmp r4 .LBL18_1\n mov r0 0\n jmp .LBL18_3\n.LBL18_3:\n add r9 r9 -5\n ret\nu32_div_mod:\n.LBL19_0:\n add r9 r9 9\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mstore [r9,-7] r1\n mstore [r9,-3] r2\n mload r1 [r9,-3]\n mstore [r9,-8] r1\n mstore [r9,-2] r3\n mload r3 [r9,-2]\n mstore [r9,-1] r4\n mload r4 [r9,-1]\n mload r1 [r9,-8]\n mov r2 r1\n mload r1 [r9,-7]\n.PROPHET19_0:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n mstore [r9,-9] r1\n mload r1 [r9,-9]\n range r1\n mload r1 [r9,-9]\n add r5 r1 1\n not r7 r5\n add r7 r7 1\n mload r1 [r9,-8]\n add r6 r1 r7\n range r6\n mload r1 [r9,-8]\n mov r2 r1\n mload r1 [r9,-7]\n.PROPHET19_1:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n range r3\n mload r2 [r9,-8]\n mul r2 r1 r2\n mstore [r9,-5] r2\n mload r2 [r9,-5]\n mload r5 [r9,-9]\n add r2 r2 r5\n mstore [r9,-6] r2\n mload r2 [r9,-6]\n mload r5 [r9,-7]\n eq r2 r2 r5\n assert r2\n mstore [r3] r1\n mload r1 [r9,-9]\n mstore [r4] r1\n add r9 r9 -9\n ret\nu32_power:\n.LBL20_0:\n add r9 r9 2\n mstore [r9,-2] r1\n mload r1 [r9,-2]\n mstore [r9,-1] r2\n mload r2 [r9,-1]\n mov r0 1\n mov r3 0\n jmp .LBL20_1\n.LBL20_1:\n add r5 r3 1\n mul r4 r0 r1\n gte r3 r2 r5\n cjmp r3 .LBL20_1\n mov r0 r4\n mov r3 r5\n jmp .LBL20_2\n.LBL20_2:\n range r0\n add r9 r9 -2\n ret\nsetVars:\n.LBL21_0:\n add r9 r9 1\n mstore [r9,-1] r1\n mload r4 [r9,-1]\n mov r1 4\n.PROPHET21_0:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n not r7 4\n add r7 r7 1\n add r2 r1 r7\n mov r1 0\n mstore [r2] r1\n mov r1 0\n mstore [r2,+1] r1\n mov r1 0\n mstore [r2,+2] r1\n mov r1 0\n mstore [r2,+3] r1\n mov r1 4\n.PROPHET21_1:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n not r7 4\n add r7 r7 1\n add r3 r1 r7\n mov r1 r3\n mstore [r1] r4\n mov r3 0\n mstore [r1,+1] r3\n mov r3 0\n mstore [r1,+2] r3\n mov r3 0\n mstore [r1,+3] r3\n sstore r2 r1\n add r9 r9 -1\n ret\nadd:\n.LBL22_0:\n add r9 r9 2\n mstore [r9,-2] r1\n mstore [r9,-1] r2\n mload r1 [r9,-2]\n mload r2 [r9,-1]\n add r0 r1 r2\n range r0\n add r9 r9 -2\n ret\nfunction_dispatch:\n.LBL23_0:\n add r9 r9 5\n mstore [r9,-2] r9\n mov r2 r3\n mstore [r9,-3] r2\n mload r2 [r9,-3]\n eq r8 r1 2371037854\n cjmp r8 .LBL23_2\n eq r8 r1 2062500454\n cjmp r8 .LBL23_3\n jmp .LBL23_1\n.LBL23_1:\n ret\n.LBL23_2:\n mov r1 r2\n mload r1 [r1]\n call setVars\n mov r1 1\n.PROPHET23_0:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n not r7 1\n add r7 r7 1\n add r1 r1 r7\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mov r2 0\n mstore [r1] r2\n mload r1 [r9,-4]\n tstore r1 1\n add r9 r9 -5\n ret\n.LBL23_3:\n mov r3 r2\n mload r3 [r3]\n add r1 r2 1\n mload r2 [r1]\n mov r1 r3\n call add\n mov r2 r0\n mov r1 2\n.PROPHET23_1:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n not r7 2\n add r7 r7 1\n add r1 r1 r7\n mstore [r9,-5] r1\n mload r1 [r9,-5]\n mstore [r1] r2\n mov r2 1\n mstore [r1,+1] r2\n mload r1 [r9,-5]\n tstore r1 2\n add r9 r9 -5\n ret\nmain:\n.LBL24_0:\n add r9 r9 2\n mstore [r9,-2] r9\n mov r1 13\n.PROPHET24_0:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n mov r6 1\n not r7 13\n add r7 r7 1\n add r2 r1 r7\n tload r2 r6 13\n mov r1 r2\n mload r6 [r1]\n mov r1 14\n.PROPHET24_1:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n mov r2 1\n not r7 14\n add r7 r7 1\n add r3 r1 r7\n tload r3 r2 14\n mov r1 r3\n mload r2 [r1]\n add r4 r2 14\n mov r1 r4\n.PROPHET24_2:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n mov r3 1\n not r7 r4\n add r7 r7 1\n add r5 r1 r7\n tload r5 r3 r4\n mov r3 r5\n mov r1 r6\n call function_dispatch\n add r9 r9 -2\n end\n", "prophets": [ { - "label": ".PROPHET17_0", + "label": ".PROPHET19_0", + "code": "%{\n function mod(felt x, felt y) -> felt {\n return x % y;\n }\n entry() {\n cid.r = mod(cid.x, cid.y);\n }\n%}", + "inputs": [ + { + "name": "cid.x", + "length": 1, + "is_ref": false, + "is_input_output": false + }, + { + "name": "cid.y", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.r", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + }, + { + "label": ".PROPHET19_1", + "code": "%{\n function div(felt x, felt y) -> felt {\n return x / y;\n }\n entry() {\n cid.q = div(cid.x, cid.y);\n }\n%}", + "inputs": [ + { + "name": "cid.x", + "length": 1, + "is_ref": false, + "is_input_output": false + }, + { + "name": "cid.y", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.q", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + }, + { + "label": ".PROPHET21_0", "code": "%{\n entry() {\n cid.addr = malloc(cid.len);\n }\n%}", "inputs": [ { @@ -22,7 +74,7 @@ ] }, { - "label": ".PROPHET17_1", + "label": ".PROPHET21_1", "code": "%{\n entry() {\n cid.addr = malloc(cid.len);\n }\n%}", "inputs": [ { @@ -42,7 +94,27 @@ ] }, { - "label": ".PROPHET19_0", + "label": ".PROPHET23_0", + "code": "%{\n entry() {\n cid.addr = malloc(cid.len);\n }\n%}", + "inputs": [ + { + "name": "cid.len", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.addr", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + }, + { + "label": ".PROPHET23_1", "code": "%{\n entry() {\n cid.addr = malloc(cid.len);\n }\n%}", "inputs": [ { @@ -62,7 +134,7 @@ ] }, { - "label": ".PROPHET20_0", + "label": ".PROPHET24_0", "code": "%{\n entry() {\n cid.addr = malloc(cid.len);\n }\n%}", "inputs": [ { @@ -82,7 +154,7 @@ ] }, { - "label": ".PROPHET20_1", + "label": ".PROPHET24_1", "code": "%{\n entry() {\n cid.addr = malloc(cid.len);\n }\n%}", "inputs": [ { @@ -102,7 +174,7 @@ ] }, { - "label": ".PROPHET20_2", + "label": ".PROPHET24_2", "code": "%{\n entry() {\n cid.addr = malloc(cid.len);\n }\n%}", "inputs": [ { diff --git a/circuits/benches/fibo_loop.rs b/circuits/benches/fibo_loop.rs index ae56a034..29624c77 100644 --- a/circuits/benches/fibo_loop.rs +++ b/circuits/benches/fibo_loop.rs @@ -34,11 +34,7 @@ pub fn test_by_asm_json(path: String) { prophets.insert(item.host as u64, item); } - let mut program: Program = Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: program.debug_info, - }; + let mut program: Program = Program::default(); for inst in instructions { program.instructions.push(inst.to_string()); diff --git a/circuits/benches/sqrt_prophet.rs b/circuits/benches/sqrt_prophet.rs index 709c66ed..eb451653 100644 --- a/circuits/benches/sqrt_prophet.rs +++ b/circuits/benches/sqrt_prophet.rs @@ -34,12 +34,7 @@ pub fn test_by_asm_json(path: String) { prophets.insert(item.host as u64, item); } - let mut program: Program = Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: program.debug_info, - }; - + let mut program: Program = Program::default(); for inst in instructions { program.instructions.push(inst.to_string()); } diff --git a/circuits/src/builtins/bitwise/bitwise_stark.rs b/circuits/src/builtins/bitwise/bitwise_stark.rs index 6e879fe8..405ae175 100644 --- a/circuits/src/builtins/bitwise/bitwise_stark.rs +++ b/circuits/src/builtins/bitwise/bitwise_stark.rs @@ -444,11 +444,7 @@ mod tests { prophets.insert(item.host as u64, item); } - let mut program: Program = Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: Default::default(), - }; + let mut program: Program = Program::default(); for inst in instructions { program.instructions.push(inst.to_string()); diff --git a/circuits/src/builtins/rangecheck/rangecheck_stark.rs b/circuits/src/builtins/rangecheck/rangecheck_stark.rs index b4e5270c..892671b9 100644 --- a/circuits/src/builtins/rangecheck/rangecheck_stark.rs +++ b/circuits/src/builtins/rangecheck/rangecheck_stark.rs @@ -184,11 +184,7 @@ mod tests { prophets.insert(item.host as u64, item); } - let mut program: Program = Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: Default::default(), - }; + let mut program: Program = Program::default(); for inst in instructions { program.instructions.push(inst.to_string()); diff --git a/circuits/src/generation/ctl_test/debug_trace_print.rs b/circuits/src/generation/ctl_test/debug_trace_print.rs index ed4cea50..c7f422b8 100644 --- a/circuits/src/generation/ctl_test/debug_trace_print.rs +++ b/circuits/src/generation/ctl_test/debug_trace_print.rs @@ -167,11 +167,7 @@ pub fn get_exec_trace( prophets.insert(item.host as u64, item); } - let mut program: Program = Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: program.debug_info, - }; + let mut program: Program = Program::default(); for inst in instructions { program.instructions.push(inst.to_string()); diff --git a/circuits/src/program/program_stark.rs b/circuits/src/program/program_stark.rs index 769dc0cc..8a501d57 100644 --- a/circuits/src/program/program_stark.rs +++ b/circuits/src/program/program_stark.rs @@ -144,11 +144,7 @@ mod tests { prophets.insert(item.host as u64, item); } - let mut program: Program = Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: program.debug_info, - }; + let mut program: Program = Program::default(); for inst in instructions { program.instructions.push(inst.to_string()); diff --git a/circuits/src/stark/ola_stark.rs b/circuits/src/stark/ola_stark.rs index cd75a7d2..c6e3f417 100644 --- a/circuits/src/stark/ola_stark.rs +++ b/circuits/src/stark/ola_stark.rs @@ -757,11 +757,7 @@ mod tests { prophets.insert(item.host as u64, item); } - let mut program: Program = Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: program.debug_info, - }; + let mut program: Program = Program::default(); for inst in instructions { program.instructions.push(inst.to_string()); diff --git a/circuits/src/test_utils.rs b/circuits/src/test_utils.rs index e318d324..507a05e1 100644 --- a/circuits/src/test_utils.rs +++ b/circuits/src/test_utils.rs @@ -43,11 +43,7 @@ pub fn test_stark_with_asm_path( prophets.insert(item.host as u64, item); } - let mut program: Program = Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: program.debug_info, - }; + let mut program: Program = Program::default(); for inst in instructions { program.instructions.push(inst.to_string()); diff --git a/client/src/main.rs b/client/src/main.rs index db4b4765..3f60993d 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -107,11 +107,7 @@ fn main() { prophets.insert(item.host as u64, item); } - let mut program: Program = Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: BTreeMap::new(), - }; + let mut program: Program = Program::default(); for inst in instructions { program.instructions.push(inst.to_string()); @@ -188,6 +184,7 @@ fn main() { instructions: trace.raw_binary_instructions.clone(), trace, debug_info: BTreeMap::new(), + pre_exe_flag: false, }; let inputs = GenerationInputs::default(); diff --git a/core/src/crypto/poseidon_trace.rs b/core/src/crypto/poseidon_trace.rs index 616279f6..83d49e67 100644 --- a/core/src/crypto/poseidon_trace.rs +++ b/core/src/crypto/poseidon_trace.rs @@ -185,9 +185,6 @@ pub fn calculate_arbitrary_poseidon_and_generate_intermediate_trace( } #[cfg(test)] mod test { - - - #[test] fn test_poseidon() { diff --git a/core/src/merkle_tree/patch.rs b/core/src/merkle_tree/patch.rs index dc4ca7f7..9413ca1e 100644 --- a/core/src/merkle_tree/patch.rs +++ b/core/src/merkle_tree/patch.rs @@ -2,7 +2,7 @@ use super::iter_ext::IteratorExt; use super::TreeError; use crate::crypto::hash::Hasher; -use crate::trace::trace::{PoseidonRow, HashTrace}; +use crate::trace::trace::{HashTrace, PoseidonRow}; use crate::types::merkle_tree::constant::ROOT_TREE_DEPTH; use crate::types::merkle_tree::{ tree_key_to_u256, u256_to_tree_key, NodeEntry, TreeKey, TreeKeyU256, TreeValue, @@ -110,20 +110,7 @@ impl UpdatesBatch { pub fn calculate( self, hasher: H, - ) -> Result< - ( - TreePatch, - Arc< - Mutex< - Vec<( - usize, - HashTrace, - )>, - >, - >, - ), - TreeError, - > + ) -> Result<(TreePatch, Arc>>), TreeError> where H: Hasher + Send + Sync, { diff --git a/core/src/merkle_tree/tree.rs b/core/src/merkle_tree/tree.rs index f5b7b326..00966b99 100644 --- a/core/src/merkle_tree/tree.rs +++ b/core/src/merkle_tree/tree.rs @@ -4,6 +4,7 @@ use crate::merkle_tree::storage::Storage; use crate::merkle_tree::tree_config::TreeConfig; use crate::merkle_tree::utils::idx_to_merkle_path; use crate::merkle_tree::TreeError; +use crate::trace::trace::HashTrace; use crate::trace::trace::PoseidonRow; use crate::types::merkle_tree::constant::ROOT_TREE_DEPTH; use crate::types::merkle_tree::{ @@ -11,7 +12,6 @@ use crate::types::merkle_tree::{ LevelIndex, NodeEntry, TreeKey, TreeMetadata, TreeOperation, TreeValue, ZkHash, }; use crate::types::proof::StorageLogMetadata; -use crate::trace::trace::HashTrace; use itertools::Itertools; use log::{debug, info}; use std::borrow::{Borrow, BorrowMut}; @@ -100,10 +100,7 @@ impl AccountTree { /// be sealed. Returns tree metadata for the corresponding blocks. /// /// - `storage_logs` - an iterator of storage logs for a given block - pub fn process_block( - &mut self, - storage_logs: I, - ) -> (Vec, Option) + pub fn process_block(&mut self, storage_logs: I) -> (Vec, Option) where I: IntoIterator, I::Item: Borrow, @@ -112,10 +109,7 @@ impl AccountTree { (hash_traces, tree_metadata.last().cloned()) } - pub fn process_blocks( - &mut self, - blocks: I, - ) -> (Vec, Vec) + pub fn process_blocks(&mut self, blocks: I) -> (Vec, Vec) where I: IntoIterator, I::Item: IntoIterator, @@ -165,10 +159,7 @@ impl AccountTree { fn apply_updates_batch( &mut self, updates_batch: Vec>, - ) -> Result< - (Vec, Vec), - TreeError, - > { + ) -> Result<(Vec, Vec), TreeError> { let total_blocks = updates_batch.len(); let storage_logs_with_blocks: Vec<_> = updates_batch diff --git a/core/src/program/mod.rs b/core/src/program/mod.rs index 09afdc05..0ccd00f7 100644 --- a/core/src/program/mod.rs +++ b/core/src/program/mod.rs @@ -19,6 +19,7 @@ pub struct Program { pub instructions: Vec, pub trace: Trace, pub debug_info: BTreeMap, + pub pre_exe_flag: bool, } impl Program {} diff --git a/core/src/state/mod.rs b/core/src/state/mod.rs index e423be56..90fe2e41 100644 --- a/core/src/state/mod.rs +++ b/core/src/state/mod.rs @@ -120,6 +120,11 @@ where Vec::new(), )); + trace.ret.extend(std::mem::replace( + &mut self.txs_trace.get_mut(&0).unwrap().ret, + Vec::new(), + )); + loop { let data = self.txs_trace.pop_first(); match data { diff --git a/core/src/trace/trace.rs b/core/src/trace/trace.rs index 20b30d92..1d4449fb 100644 --- a/core/src/trace/trace.rs +++ b/core/src/trace/trace.rs @@ -259,7 +259,14 @@ impl Display for PoseidonRow { } #[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)] -pub struct HashTrace(pub PoseidonRow, pub TreeValue, pub TreeValue, pub TreeValue, pub TreeValue, pub PoseidonRow); +pub struct HashTrace( + pub PoseidonRow, + pub TreeValue, + pub TreeValue, + pub TreeValue, + pub TreeValue, + pub PoseidonRow, +); #[derive(Debug, Copy, Clone, Serialize, Deserialize)] pub struct StorageRow { @@ -337,6 +344,7 @@ pub struct Trace { pub builtin_program_hash: Vec, pub tape: Vec, pub sc_call: Vec, + pub ret: Vec, } impl Trace { diff --git a/core/src/types/merkle_tree/mod.rs b/core/src/types/merkle_tree/mod.rs index 680ba943..4aa0e703 100644 --- a/core/src/types/merkle_tree/mod.rs +++ b/core/src/types/merkle_tree/mod.rs @@ -7,7 +7,7 @@ use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::types::Field; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use web3::types::{U256, H256}; +use web3::types::{H256, U256}; pub const TREE_VALUE_LEN: usize = 4; pub type TreeKey = [GoldilocksField; TREE_VALUE_LEN]; diff --git a/core/src/vm/vm_state.rs b/core/src/vm/vm_state.rs index 3bc2b0e0..4161c411 100644 --- a/core/src/vm/vm_state.rs +++ b/core/src/vm/vm_state.rs @@ -1,4 +1,3 @@ - use crate::trace::trace::Step; pub use crate::types::account::Address; pub use plonky2::field::goldilocks_field::GoldilocksField; diff --git a/executor/src/lib.rs b/executor/src/lib.rs index 3a3f0077..9f0bb934 100644 --- a/executor/src/lib.rs +++ b/executor/src/lib.rs @@ -976,22 +976,24 @@ impl Process { if self.registers[op1_index].to_canonical_u64() > u32::MAX as u64 { return Err(ProcessorError::U32RangeCheckFail); } - self.opcode = GoldilocksField::from_canonical_u64(1 << Opcode::RC as u8); - self.register_selector.op1 = self.registers[op1_index]; - self.register_selector.op1_reg_sel[op1_index] = - GoldilocksField::from_canonical_u64(1); - program.trace.insert_rangecheck( - self.registers[op1_index], - ( - GoldilocksField::ZERO, - GoldilocksField::ONE, - GoldilocksField::ZERO, - GoldilocksField::ZERO, - GoldilocksField::ZERO, - ), - ); + if !program.pre_exe_flag { + self.opcode = GoldilocksField::from_canonical_u64(1 << Opcode::RC as u8); + self.register_selector.op1 = self.registers[op1_index]; + self.register_selector.op1_reg_sel[op1_index] = + GoldilocksField::from_canonical_u64(1); + program.trace.insert_rangecheck( + self.registers[op1_index], + ( + GoldilocksField::ZERO, + GoldilocksField::ONE, + GoldilocksField::ZERO, + GoldilocksField::ZERO, + GoldilocksField::ZERO, + ), + ); + } self.pc += step; } "and" | "or" | "xor" => { @@ -1039,16 +1041,18 @@ impl Process { _ => panic!("not match opcode:{}", opcode), }; - self.register_selector.dst = self.registers[dst_index]; - self.register_selector.dst_reg_sel[dst_index] = - GoldilocksField::from_canonical_u64(1); + if !program.pre_exe_flag { + self.register_selector.dst = self.registers[dst_index]; + self.register_selector.dst_reg_sel[dst_index] = + GoldilocksField::from_canonical_u64(1); - program.trace.insert_bitwise_combined( - opcode, - self.register_selector.op0, - op1_value.0, - self.registers[dst_index], - ); + program.trace.insert_bitwise_combined( + opcode, + self.register_selector.op0, + op1_value.0, + self.registers[dst_index], + ); + } self.pc += step; } "gte" => { @@ -1086,87 +1090,112 @@ impl Process { _ => panic!("not match opcode:{}", opcode), }; - self.register_selector.dst = self.registers[dst_index]; - self.register_selector.dst_reg_sel[dst_index] = - GoldilocksField::from_canonical_u64(1); + if !program.pre_exe_flag { + self.register_selector.dst = self.registers[dst_index]; + self.register_selector.dst_reg_sel[dst_index] = + GoldilocksField::from_canonical_u64(1); - let abs_diff; - if self.register_selector.dst.is_one() { - abs_diff = self.register_selector.op0 - self.register_selector.op1; - } else { - abs_diff = self.register_selector.op1 - self.register_selector.op0; - } + let abs_diff; + if self.register_selector.dst.is_one() { + abs_diff = self.register_selector.op0 - self.register_selector.op1; + } else { + abs_diff = self.register_selector.op1 - self.register_selector.op0; + } - if abs_diff.to_canonical_u64() > u32::MAX as u64 { - return Err(ProcessorError::U32RangeCheckFail); - } - program.trace.insert_rangecheck( - abs_diff, - ( - GoldilocksField::ZERO, - GoldilocksField::ZERO, - GoldilocksField::ONE, - GoldilocksField::ZERO, - GoldilocksField::ZERO, - ), - ); + if abs_diff.to_canonical_u64() > u32::MAX as u64 { + return Err(ProcessorError::U32RangeCheckFail); + } + program.trace.insert_rangecheck( + abs_diff, + ( + GoldilocksField::ZERO, + GoldilocksField::ZERO, + GoldilocksField::ONE, + GoldilocksField::ZERO, + GoldilocksField::ZERO, + ), + ); - program.trace.insert_cmp( - self.register_selector.op0, - value.0, - self.register_selector.dst, - abs_diff, - GoldilocksField::ONE, - ); + program.trace.insert_cmp( + self.register_selector.op0, + value.0, + self.register_selector.dst, + abs_diff, + GoldilocksField::ONE, + ); + } self.pc += step; } "end" => { self.opcode = GoldilocksField::from_canonical_u64(1 << Opcode::END as u8); - program.trace.insert_step( + + let len = self.tape.read( + self.tx_idx, + self.tp.to_canonical_u64() - 1, self.clk, - pc_status, - self.tp, - self.instruction, - self.immediate_data, - self.op1_imm, - self.opcode, - ctx_regs_status, - registers_status, - self.register_selector.clone(), - GoldilocksField::ZERO, + GoldilocksField::from_canonical_u64(1 << Opcode::END as u64), GoldilocksField::ZERO, - GoldilocksField::ZERO, - ctx_code_regs_status, - self.tx_idx, - self.env_idx, - self.call_sc_cnt, - self.storage_access_idx, - ); - if self.env_idx.ne(&GoldilocksField::ZERO) { - self.register_selector.aux0 = self.env_idx; - self.register_selector.aux1 = - GoldilocksField::from_canonical_u64(self.clk as u64); - let register_selector = self.register_selector.clone(); - end_step = Some(Step { - tx_idx: self.tx_idx, - env_idx: GoldilocksField::default(), - call_sc_cnt: self.call_sc_cnt, - tp: self.tp, - addr_storage: Address::default(), - addr_code: Address::default(), - instruction: self.instruction, - immediate_data: self.immediate_data, - opcode: self.opcode, - op1_imm: self.op1_imm, - clk: 0, - pc: pc_status, - register_selector, - is_ext_line: GoldilocksField::ONE, - ext_cnt: GoldilocksField::ONE, - regs: self.registers, - filter_tape_looking: GoldilocksField::ZERO, - storage_access_idx: self.storage_access_idx, - }); + )?; + + if len != GoldilocksField::ZERO { + let len = len.to_canonical_u64(); + for i in 0..len { + program.trace.ret.push(self.tape.read( + self.tx_idx, + self.tp.to_canonical_u64() - len - 1 + i, + self.clk, + GoldilocksField::from_canonical_u64(1 << Opcode::END as u64), + GoldilocksField::ZERO, + )?); + } + } + if !program.pre_exe_flag { + program.trace.insert_step( + self.clk, + pc_status, + self.tp, + self.instruction, + self.immediate_data, + self.op1_imm, + self.opcode, + ctx_regs_status, + registers_status, + self.register_selector.clone(), + GoldilocksField::ZERO, + GoldilocksField::ZERO, + GoldilocksField::ZERO, + ctx_code_regs_status, + self.tx_idx, + self.env_idx, + self.call_sc_cnt, + self.storage_access_idx, + ); + if self.env_idx.ne(&GoldilocksField::ZERO) { + self.register_selector.aux0 = self.env_idx; + self.register_selector.aux1 = + GoldilocksField::from_canonical_u64(self.clk as u64); + let register_selector = self.register_selector.clone(); + end_step = Some(Step { + tx_idx: self.tx_idx, + env_idx: GoldilocksField::default(), + call_sc_cnt: self.call_sc_cnt, + tp: self.tp, + addr_storage: Address::default(), + addr_code: Address::default(), + instruction: self.instruction, + immediate_data: self.immediate_data, + opcode: self.opcode, + op1_imm: self.op1_imm, + clk: 0, + pc: pc_status, + register_selector, + is_ext_line: GoldilocksField::ONE, + ext_cnt: GoldilocksField::ONE, + regs: self.registers, + filter_tape_looking: GoldilocksField::ZERO, + storage_access_idx: self.storage_access_idx, + }); + } } break; } @@ -1214,10 +1243,6 @@ impl Process { let (tree_key, hash_row) = storage_key.hashed_key(); register_selector_regs.dst_reg_sel[0..TREE_VALUE_LEN] .clone_from_slice(&tree_key); - self.storage_log.push(WitnessStorageLog { - storage_log: StorageLog::new_write_log(tree_key, store_value), - previous_value: tree_key_default(), - }); self.storage.write( self.clk, @@ -1228,22 +1253,29 @@ impl Process { self.tx_idx, self.env_idx, ); + self.storage_access_idx += GoldilocksField::ONE; - program.trace.builtin_poseidon.push(hash_row); + if !program.pre_exe_flag { + self.storage_log.push(WitnessStorageLog { + storage_log: StorageLog::new_write_log(tree_key, store_value), + previous_value: tree_key_default(), + }); - self.storage_access_idx += GoldilocksField::ONE; - let ext_cnt = GoldilocksField::ONE; - let filter_tape_looking = GoldilocksField::ZERO; - aux_insert!( - self, - aux_steps, - ctx_regs_status, - ctx_code_regs_status, - registers_status, - register_selector_regs, - ext_cnt, - filter_tape_looking - ); + program.trace.builtin_poseidon.push(hash_row); + let ext_cnt = GoldilocksField::ONE; + let filter_tape_looking = GoldilocksField::ZERO; + + aux_insert!( + self, + aux_steps, + ctx_regs_status, + ctx_code_regs_status, + registers_status, + register_selector_regs, + ext_cnt, + filter_tape_looking + ); + } self.pc += step; if print_vm_state { println!("******************** sstore ********************"); @@ -1334,11 +1366,6 @@ impl Process { read_value[index]; } - self.storage_log.push(WitnessStorageLog { - storage_log: StorageLog::new_read_log(tree_key, read_value), - previous_value: tree_key_default(), - }); - self.storage.read( self.clk, GoldilocksField::from_canonical_u64(1 << Opcode::SLOAD as u64), @@ -1348,21 +1375,30 @@ impl Process { self.tx_idx, self.env_idx, ); - program.trace.builtin_poseidon.push(hash_row); self.storage_access_idx += GoldilocksField::ONE; - let ext_cnt = GoldilocksField::ONE; - let filter_tape_looking = GoldilocksField::ZERO; - aux_insert!( - self, - aux_steps, - ctx_regs_status, - ctx_code_regs_status, - registers_status, - register_selector_regs, - ext_cnt, - filter_tape_looking - ); + + if !program.pre_exe_flag { + self.storage_log.push(WitnessStorageLog { + storage_log: StorageLog::new_read_log(tree_key, read_value), + previous_value: tree_key_default(), + }); + + program.trace.builtin_poseidon.push(hash_row); + + let ext_cnt = GoldilocksField::ONE; + let filter_tape_looking = GoldilocksField::ZERO; + aux_insert!( + self, + aux_steps, + ctx_regs_status, + ctx_code_regs_status, + registers_status, + register_selector_regs, + ext_cnt, + filter_tape_looking + ); + } self.pc += step; if print_vm_state { @@ -1419,22 +1455,22 @@ impl Process { let mut hash_pre = [GoldilocksField::ZERO; POSEIDON_INPUT_NUM]; let mut hash_cap = [GoldilocksField::ZERO; POSEIDON_OUTPUT_VALUE_LEN]; let mut hash_input_value = [GoldilocksField::ZERO; POSEIDON_INPUT_VALUE_LEN]; - - program.trace.insert_poseidon_chunk( - self.tx_idx, - self.env_idx, - self.clk, - self.opcode, - self.register_selector.dst, - self.register_selector.op0, - self.register_selector.op1, - GoldilocksField::ZERO, - hash_input_value, - hash_cap, - hash_pre, - GoldilocksField::ZERO, - ); - + if !program.pre_exe_flag { + program.trace.insert_poseidon_chunk( + self.tx_idx, + self.env_idx, + self.clk, + self.opcode, + self.register_selector.dst, + self.register_selector.op0, + self.register_selector.op1, + GoldilocksField::ZERO, + hash_input_value, + hash_cap, + hash_pre, + GoldilocksField::ZERO, + ); + } let tail_len: usize; loop { if read_ptr + 8 > input_len { @@ -1451,24 +1487,26 @@ impl Process { row.filter_looked_normal = true; output.clone_from_slice(&row.output[0..POSEIDON_OUTPUT_VALUE_LEN]); read_ptr += 8; - hash_input_value.clone_from_slice(&input[0..POSEIDON_INPUT_VALUE_LEN]); - hash_cap.clone_from_slice(&hash_pre[POSEIDON_INPUT_VALUE_LEN..]); - program.trace.insert_poseidon_chunk( - self.tx_idx, - self.env_idx, - self.clk, - self.opcode, - self.register_selector.dst, - GoldilocksField::from_canonical_u64(src_mem_addr + read_ptr - 8), - GoldilocksField::from_canonical_u64(input_len), - GoldilocksField::from_canonical_u64(read_ptr), - hash_input_value, - hash_cap, - row.output, - GoldilocksField::ONE, - ); - hash_pre.clone_from_slice(&row.output); - program.trace.builtin_poseidon.push(row); + if !program.pre_exe_flag { + hash_input_value.clone_from_slice(&input[0..POSEIDON_INPUT_VALUE_LEN]); + hash_cap.clone_from_slice(&hash_pre[POSEIDON_INPUT_VALUE_LEN..]); + program.trace.insert_poseidon_chunk( + self.tx_idx, + self.env_idx, + self.clk, + self.opcode, + self.register_selector.dst, + GoldilocksField::from_canonical_u64(src_mem_addr + read_ptr - 8), + GoldilocksField::from_canonical_u64(input_len), + GoldilocksField::from_canonical_u64(read_ptr), + hash_input_value, + hash_cap, + row.output, + GoldilocksField::ONE, + ); + hash_pre.clone_from_slice(&row.output); + program.trace.builtin_poseidon.push(row); + } if read_ptr + 8 > input_len { tail_len = (input_len - read_ptr) as usize; @@ -1491,24 +1529,25 @@ impl Process { let mut row = calculate_poseidon_and_generate_intermediate_trace(input); row.filter_looked_normal = true; output.clone_from_slice(&row.output[0..POSEIDON_OUTPUT_VALUE_LEN]); - - hash_input_value.clone_from_slice(&input[0..POSEIDON_INPUT_VALUE_LEN]); - hash_cap.clone_from_slice(&hash_pre[POSEIDON_INPUT_VALUE_LEN..]); - program.trace.insert_poseidon_chunk( - self.tx_idx, - self.env_idx, - self.clk, - self.opcode, - self.register_selector.dst, - GoldilocksField::from_canonical_u64(src_mem_addr + read_ptr), - GoldilocksField::from_canonical_u64(input_len), - GoldilocksField::from_canonical_u64(read_ptr + tail_len as u64), - hash_input_value, - hash_cap, - row.output, - GoldilocksField::ONE, - ); - program.trace.builtin_poseidon.push(row); + if !program.pre_exe_flag { + hash_input_value.clone_from_slice(&input[0..POSEIDON_INPUT_VALUE_LEN]); + hash_cap.clone_from_slice(&hash_pre[POSEIDON_INPUT_VALUE_LEN..]); + program.trace.insert_poseidon_chunk( + self.tx_idx, + self.env_idx, + self.clk, + self.opcode, + self.register_selector.dst, + GoldilocksField::from_canonical_u64(src_mem_addr + read_ptr), + GoldilocksField::from_canonical_u64(input_len), + GoldilocksField::from_canonical_u64(read_ptr + tail_len as u64), + hash_input_value, + hash_cap, + row.output, + GoldilocksField::ONE, + ); + program.trace.builtin_poseidon.push(row); + } } for index in 0..POSEIDON_OUTPUT_VALUE_LEN { @@ -1689,19 +1728,6 @@ impl Process { ); } - program.trace.insert_sccall( - self.tx_idx, - self.env_idx, - self.addr_storage, - self.addr_code, - self.register_selector.op1, - GoldilocksField::from_canonical_u64(self.clk as u64), - GoldilocksField::from_canonical_u64((self.clk + 1) as u64), - registers_status, - self.register_selector.aux0, - GoldilocksField::ZERO, - ); - let len; if op1_value.0 == GoldilocksField::ONE { len = load_ctx_addr_info( @@ -1723,53 +1749,69 @@ impl Process { panic!("not support") } - program.trace.insert_step( - self.clk, - pc_status, - self.tp, - self.instruction, - self.immediate_data, - self.op1_imm, - self.opcode, - ctx_regs_status, - registers_status, - self.register_selector.clone(), - GoldilocksField::ZERO, - GoldilocksField::ZERO, - GoldilocksField::ZERO, - ctx_code_regs_status, - self.tx_idx, - self.env_idx, - self.call_sc_cnt, - self.storage_access_idx, - ); + if !program.pre_exe_flag { + program.trace.insert_sccall( + self.tx_idx, + self.env_idx, + self.addr_storage, + self.addr_code, + self.register_selector.op1, + GoldilocksField::from_canonical_u64(self.clk as u64), + GoldilocksField::from_canonical_u64((self.clk + 1) as u64), + registers_status, + self.register_selector.aux0, + GoldilocksField::ZERO, + ); + + program.trace.insert_step( + self.clk, + pc_status, + self.tp, + self.instruction, + self.immediate_data, + self.op1_imm, + self.opcode, + ctx_regs_status, + registers_status, + self.register_selector.clone(), + GoldilocksField::ZERO, + GoldilocksField::ZERO, + GoldilocksField::ZERO, + ctx_code_regs_status, + self.tx_idx, + self.env_idx, + self.call_sc_cnt, + self.storage_access_idx, + ); + + //aux + let mut register_selector_regs: RegisterSelector = Default::default(); + register_selector_regs.op0_reg_sel[0..TREE_VALUE_LEN] + .clone_from_slice(&ctx_regs_status); + register_selector_regs.op0_reg_sel[TREE_VALUE_LEN..TREE_VALUE_LEN * 2] + .clone_from_slice(&ctx_code_regs_status); + program.trace.insert_step( + self.clk, + pc_status, + self.tp, + self.instruction, + self.immediate_data, + self.op1_imm, + self.opcode, + self.addr_storage, + registers_status, + register_selector_regs, + GoldilocksField::ONE, + GoldilocksField::ONE, + GoldilocksField::ZERO, + self.addr_code, + self.tx_idx, + self.env_idx, + self.call_sc_cnt, + self.storage_access_idx, + ); + } - //aux - let mut register_selector_regs: RegisterSelector = Default::default(); - register_selector_regs.op0_reg_sel[0..TREE_VALUE_LEN] - .clone_from_slice(&ctx_regs_status); - register_selector_regs.op0_reg_sel[TREE_VALUE_LEN..TREE_VALUE_LEN * 2] - .clone_from_slice(&ctx_code_regs_status); - program.trace.insert_step( - self.clk, - pc_status, - self.tp, - self.instruction, - self.immediate_data, - self.op1_imm, - self.opcode, - self.addr_storage, - registers_status, - register_selector_regs, - GoldilocksField::ONE, - GoldilocksField::ONE, - GoldilocksField::ZERO, - self.addr_code, - self.tx_idx, - self.env_idx, - self.call_sc_cnt, - self.storage_access_idx, - ); self.pc += step; self.clk += 1; if op1_value.0 == GoldilocksField::ONE { @@ -1796,31 +1838,33 @@ impl Process { "pc:{}, tp:{}, call_sc_cnt:{}", pc_status, tp_status, self.call_sc_cnt ); - program.trace.insert_step( - self.clk, - pc_status, - tp_status, - self.instruction, - self.immediate_data, - self.op1_imm, - self.opcode, - ctx_regs_status, - registers_status, - self.register_selector.clone(), - GoldilocksField::ZERO, - GoldilocksField::ZERO, - GoldilocksField::ZERO, - ctx_code_regs_status, - self.tx_idx, - self.env_idx, - self.call_sc_cnt, - storage_acc_id_status, - ); - if !aux_steps.is_empty() { - program.trace.exec.extend(aux_steps); - } + if !program.pre_exe_flag { + program.trace.insert_step( + self.clk, + pc_status, + tp_status, + self.instruction, + self.immediate_data, + self.op1_imm, + self.opcode, + ctx_regs_status, + registers_status, + self.register_selector.clone(), + GoldilocksField::ZERO, + GoldilocksField::ZERO, + GoldilocksField::ZERO, + ctx_code_regs_status, + self.tx_idx, + self.env_idx, + self.call_sc_cnt, + storage_acc_id_status, + ); + if !aux_steps.is_empty() { + program.trace.exec.extend(aux_steps); + } + } if self.pc >= instrs_len { break; } diff --git a/executor/src/tests.rs b/executor/src/tests.rs index 90b3577e..2a609464 100644 --- a/executor/src/tests.rs +++ b/executor/src/tests.rs @@ -53,6 +53,7 @@ fn executor_run_test_program( instructions: Vec::new(), trace: Default::default(), debug_info: program.debug_info, + pre_exe_flag: false, }; for inst in instructions { @@ -196,6 +197,20 @@ fn fibo_use_loop_decode() { ); } +#[test] +fn ptr_call() { + let calldata = vec![ + GoldilocksField::from_canonical_u64(0), + GoldilocksField::from_canonical_u64(2657046596), + ]; + executor_run_test_program( + "../assembler/test_data/bin/ptr_call.json", + "ptr_call_trace.txt", + true, + Some(calldata), + ); +} + #[test] fn fibo_recursive() { executor_run_test_program( @@ -390,14 +405,25 @@ fn printf_test() { Some(calldata), ); } +#[test] +fn callee_ret_test() { + let call_data = [5, 11, 2, 2062500454]; + + let calldata = call_data + .iter() + .map(|e| GoldilocksField::from_canonical_u64(*e)) + .collect(); + executor_run_test_program( + "../assembler/test_data/bin/sccall/sccall_callee.json", + "sccall_callee_trace.txt", + false, + Some(calldata), + ); +} #[test] fn gen_storage_table_test() { - let mut program: Program = Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: Default::default(), - }; + let mut program: Program = Program::default(); let mut hash = Vec::new(); let mut process = Process::new(); diff --git a/zk-vm/src/lib.rs b/zk-vm/src/lib.rs index 968899ef..bad71e6a 100644 --- a/zk-vm/src/lib.rs +++ b/zk-vm/src/lib.rs @@ -240,11 +240,7 @@ impl OlaVM { caller_addr, &self.ctx_info, ); - let mut program = Arc::new(Mutex::new(Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: Default::default(), - })); + let mut program = Arc::new(Mutex::new(Program::default())); let mut caller_addr = caller_addr; let mut code_exe_addr = code_exe_addr; @@ -283,11 +279,7 @@ impl OlaVM { mutex_data!(process).env_idx = GoldilocksField::from_canonical_u64(sc_cnt); mutex_data!(process).call_sc_cnt = GoldilocksField::from_canonical_u64(sc_cnt); - program = Arc::new(Mutex::new(Program { - instructions: Vec::new(), - trace: Default::default(), - debug_info: Default::default(), - })); + program = Arc::new(Mutex::new(Program::default())); match ret { SCCallType::Call(addr) => {