From ef4f1eb5a9cf05a0d5789ea38c7bc32beb1827d7 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Tue, 4 Jun 2024 12:29:05 +0200 Subject: [PATCH 1/7] Cleanup --- src/tests/simple_tests/log.rs | 173 +++++------------- .../log/l1_message_out_of_gas/entry.asm | 22 +++ .../precompile_out_of_gas}/entry.asm | 0 .../rollback_to_same_value_no_reads/entry.asm | 18 ++ .../entry.asm | 20 ++ .../testdata/log/write_same_value/entry.asm | 19 ++ 6 files changed, 129 insertions(+), 123 deletions(-) create mode 100644 src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm rename src/tests/simple_tests/testdata/{log_precompile => log/precompile_out_of_gas}/entry.asm (100%) create mode 100644 src/tests/simple_tests/testdata/log/rollback_to_same_value_no_reads/entry.asm create mode 100644 src/tests/simple_tests/testdata/log/rollback_to_same_value_with_reads/entry.asm create mode 100644 src/tests/simple_tests/testdata/log/write_same_value/entry.asm diff --git a/src/tests/simple_tests/log.rs b/src/tests/simple_tests/log.rs index 4d656b86..b7a80155 100644 --- a/src/tests/simple_tests/log.rs +++ b/src/tests/simple_tests/log.rs @@ -1,58 +1,35 @@ -use super::*; - -#[test_log::test] -fn test_out_of_ergs_l1_message() { - let asm = r#" - .text - .file "Test_26" - .rodata.cst32 - .p2align 5 - .text - .globl __entry - __entry: - .main: - add 10000, r0, r1 - add 1000, r0, r10 - sstore r1, r10 - event r1, r10 - to_l1 r1, r10 - context.set_ergs_per_pubdata r10 - near_call r1, @inner, @handler - context.ergs_left r15 - ret.ok r0 - inner: - to_l1 r0, r1 - ret.ok r0 - handler: - ret.ok r0 - "#; - - run_and_try_create_witness_inner(asm, 50); -} - #[cfg(test)] mod tests { - use crate::tests::simple_tests::asm_tests::run_asm_based_test; - use crate::tests::simple_tests::run_manually::Options; + use crate::tests::simple_tests::{asm_tests::run_asm_based_test, Options}; - #[test_log::test] - /// Tests the case where we run out of gas during the precompile execution. - fn test_precompile_out_of_gas() { + fn test_common(dir: &str) { run_asm_based_test( - "src/tests/simple_tests/testdata/log_precompile", - &[], + &format!("src/tests/simple_tests/testdata/{}", dir), + &[800000], Options { - // Do only 1 cycle per VM snapshot to really test all the boundary conditions. cycles_per_vm_snapshot: 1, ..Default::default() }, ) } - fn test_common(dir: &str) { + + #[test_log::test] + fn test_log_l1_message_out_of_gas() { run_asm_based_test( - &format!("src/tests/simple_tests/testdata/{}", dir), - &[800000], + "src/tests/simple_tests/testdata/log/l1_message_out_of_gas", + &[], + Default::default(), + ) + } + + #[test_log::test] + /// Tests the case where we run out of gas during the precompile execution. + fn test_precompile_out_of_gas() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/precompile_out_of_gas", + &[], Options { + // Do only 1 cycle per VM snapshot to really test all the boundary conditions. cycles_per_vm_snapshot: 1, ..Default::default() }, @@ -60,94 +37,44 @@ mod tests { } #[test_log::test] - fn test_decommit_invalid() { + fn test_log_decommit_invalid() { test_common("decommit_invalid") } #[test_log::test] - fn test_decommit_ok() { + fn test_log_decommit_ok() { test_common("decommit_ok"); - test_common("decommit_ok_with_panic"); } -} - -#[test_log::test] -fn test_write_same_value() { - let asm = r#" - .text - .file "Test_26" - .rodata.cst32 - .p2align 5 - .text - .globl __entry - __entry: - .main: - near_call r0, @inner, @handler - context.ergs_left r15 - ret.ok r0 - inner: - add 10000, r0, r1 - add 1000, r0, r10 - sstore r1, r10 - sstore r1, r0 - ret.ok r0 - handler: - ret.ok r0 - "#; - run_and_try_create_witness_inner(asm, 50); -} - -#[test_log::test] -fn test_rollback_to_same_value_no_reads() { - let asm = r#" - .text - .file "Test_26" - .rodata.cst32 - .p2align 5 - .text - .globl __entry - __entry: - .main: - near_call r0, @inner, @handler - context.ergs_left r15 - ret.ok r0 - inner: - add 10000, r0, r1 - add 1000, r0, r10 - sstore r1, r10 - ret.panic r0 - handler: - ret.ok r0 - "#; + #[test_log::test] + fn test_log_decommit_ok_with_panic() { + test_common("decommit_ok_with_panic"); + } - run_and_try_create_witness_inner(asm, 50); -} + #[test_log::test] + fn test_log_write_same_value() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/write_same_value", + &[], + Default::default(), + ) + } -#[test_log::test] -fn test_rollback_to_same_value_with_reads() { - let asm = r#" - .text - .file "Test_26" - .rodata.cst32 - .p2align 5 - .text - .globl __entry - __entry: - .main: - near_call r1, @inner, @handler - context.ergs_left r15 - ret.ok r0 - inner: - add 10000, r0, r1 - add 1000, r0, r10 - sstore r1, r10 - ret.panic r0 - handler: - add 10000, r0, r1 - sload r1, r2 - ret.ok r0 - "#; + #[test_log::test] + fn test_log_rollback_to_same_value_no_reads() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/rollback_to_same_value_no_reads", + &[], + Default::default(), + ) + } - run_and_try_create_witness_inner(asm, 50); + #[test_log::test] + fn test_log_rollback_to_same_value_with_reads() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/rollback_to_same_value_with_reads", + &[], + Default::default(), + ) + } } diff --git a/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm b/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm new file mode 100644 index 00000000..6b391b91 --- /dev/null +++ b/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm @@ -0,0 +1,22 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + add 10000, r0, r1 + add 1000, r0, r10 + sstore r1, r10 + event r1, r10 + to_l1 r1, r10 + context.set_ergs_per_pubdata r10 + near_call r1, @inner, @handler + context.ergs_left r15 + ret.ok r0 +inner: + to_l1 r0, r1 + ret.ok r0 +handler: + ret.ok r0 \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log_precompile/entry.asm b/src/tests/simple_tests/testdata/log/precompile_out_of_gas/entry.asm similarity index 100% rename from src/tests/simple_tests/testdata/log_precompile/entry.asm rename to src/tests/simple_tests/testdata/log/precompile_out_of_gas/entry.asm diff --git a/src/tests/simple_tests/testdata/log/rollback_to_same_value_no_reads/entry.asm b/src/tests/simple_tests/testdata/log/rollback_to_same_value_no_reads/entry.asm new file mode 100644 index 00000000..b6ce5f54 --- /dev/null +++ b/src/tests/simple_tests/testdata/log/rollback_to_same_value_no_reads/entry.asm @@ -0,0 +1,18 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + near_call r0, @inner, @handler + context.ergs_left r15 + ret.ok r0 +inner: + add 10000, r0, r1 + add 1000, r0, r10 + sstore r1, r10 + ret.panic r0 +handler: + ret.ok r0 \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log/rollback_to_same_value_with_reads/entry.asm b/src/tests/simple_tests/testdata/log/rollback_to_same_value_with_reads/entry.asm new file mode 100644 index 00000000..b457450b --- /dev/null +++ b/src/tests/simple_tests/testdata/log/rollback_to_same_value_with_reads/entry.asm @@ -0,0 +1,20 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + near_call r1, @inner, @handler + context.ergs_left r15 + ret.ok r0 +inner: + add 10000, r0, r1 + add 1000, r0, r10 + sstore r1, r10 + ret.panic r0 +handler: +add 10000, r0, r1 + sload r1, r2 + ret.ok r0 \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log/write_same_value/entry.asm b/src/tests/simple_tests/testdata/log/write_same_value/entry.asm new file mode 100644 index 00000000..b591e67d --- /dev/null +++ b/src/tests/simple_tests/testdata/log/write_same_value/entry.asm @@ -0,0 +1,19 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + near_call r0, @inner, @handler + context.ergs_left r15 + ret.ok r0 +inner: + add 10000, r0, r1 + add 1000, r0, r10 + sstore r1, r10 + sstore r1, r0 + ret.ok r0 +handler: + ret.ok r0 \ No newline at end of file From fe952a8f39891894ea9f52d349e224124e9068e8 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 5 Jun 2024 12:07:34 +0200 Subject: [PATCH 2/7] Cleanup in log tests --- src/tests/simple_tests/log.rs | 59 ++++++++++++------ src/tests/simple_tests/storage.rs | 4 +- .../{ => log}/decommit_invalid/800000.asm | 0 .../{ => log}/decommit_invalid/entry.asm | 0 .../testdata/{ => log}/decommit_ok/800000.asm | 0 .../testdata/{ => log}/decommit_ok/entry.asm | 10 ++- .../decommit_ok_with_panic/800000.asm | 0 .../decommit_ok_with_panic/entry.asm | 9 +-- .../entry.asm | 45 ++++++++++++++ .../log/l1_message_out_of_gas/entry.asm | 51 +++++++++++---- .../log/precompile_invalid_address/65399.asm | 62 +++++++++++++++++++ .../log/precompile_invalid_address/entry.asm | 32 ++++++++++ .../log/precompile_out_of_gas/entry.asm | 22 ++++--- .../entry.asm | 20 ------ .../storage_clear_slot}/entry.asm | 8 ++- .../{ => log/storage}/storage_reads/entry.asm | 0 .../entry.asm | 14 +++-- .../storage_write_rollback_reads/entry.asm | 35 +++++++++++ .../storage}/storage_writes/entry.asm | 0 19 files changed, 293 insertions(+), 78 deletions(-) rename src/tests/simple_tests/testdata/{ => log}/decommit_invalid/800000.asm (100%) rename src/tests/simple_tests/testdata/{ => log}/decommit_invalid/entry.asm (100%) rename src/tests/simple_tests/testdata/{ => log}/decommit_ok/800000.asm (100%) rename src/tests/simple_tests/testdata/{ => log}/decommit_ok/entry.asm (88%) rename src/tests/simple_tests/testdata/{ => log}/decommit_ok_with_panic/800000.asm (100%) rename src/tests/simple_tests/testdata/{ => log}/decommit_ok_with_panic/entry.asm (82%) create mode 100644 src/tests/simple_tests/testdata/log/l1_message_has_zero_pubdata_cost/entry.asm create mode 100644 src/tests/simple_tests/testdata/log/precompile_invalid_address/65399.asm create mode 100644 src/tests/simple_tests/testdata/log/precompile_invalid_address/entry.asm delete mode 100644 src/tests/simple_tests/testdata/log/rollback_to_same_value_with_reads/entry.asm rename src/tests/simple_tests/testdata/log/{write_same_value => storage/storage_clear_slot}/entry.asm (77%) rename src/tests/simple_tests/testdata/{ => log/storage}/storage_reads/entry.asm (100%) rename src/tests/simple_tests/testdata/log/{rollback_to_same_value_no_reads => storage/storage_write_rollback_no_reads}/entry.asm (62%) create mode 100644 src/tests/simple_tests/testdata/log/storage/storage_write_rollback_reads/entry.asm rename src/tests/simple_tests/testdata/{ => log/storage}/storage_writes/entry.asm (100%) diff --git a/src/tests/simple_tests/log.rs b/src/tests/simple_tests/log.rs index b7a80155..8b3d6fff 100644 --- a/src/tests/simple_tests/log.rs +++ b/src/tests/simple_tests/log.rs @@ -2,21 +2,20 @@ mod tests { use crate::tests::simple_tests::{asm_tests::run_asm_based_test, Options}; - fn test_common(dir: &str) { + #[test_log::test] + /// Tests the case where we do not have enough gas to send a message to l1 + fn test_log_l1_message_out_of_gas() { run_asm_based_test( - &format!("src/tests/simple_tests/testdata/{}", dir), - &[800000], - Options { - cycles_per_vm_snapshot: 1, - ..Default::default() - }, + "src/tests/simple_tests/testdata/log/l1_message_out_of_gas", + &[], + Default::default(), ) } #[test_log::test] - fn test_log_l1_message_out_of_gas() { + fn test_log_l1_message_has_zero_pubdata_cost() { run_asm_based_test( - "src/tests/simple_tests/testdata/log/l1_message_out_of_gas", + "src/tests/simple_tests/testdata/log/l1_message_has_zero_pubdata_cost", &[], Default::default(), ) @@ -36,43 +35,67 @@ mod tests { ) } + #[test_log::test] + fn test_precompile_invalid_address() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/precompile_invalid_address", + &[65399], + Options { + // Do only 1 cycle per VM snapshot to really test all the boundary conditions. + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ) + } + + fn test_decommit(dir: &str) { + run_asm_based_test( + &format!("src/tests/simple_tests/testdata/log/{}", dir), + &[800000], + Options { + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ) + } + #[test_log::test] fn test_log_decommit_invalid() { - test_common("decommit_invalid") + test_decommit("decommit_invalid") } #[test_log::test] fn test_log_decommit_ok() { - test_common("decommit_ok"); + test_decommit("decommit_ok"); } #[test_log::test] fn test_log_decommit_ok_with_panic() { - test_common("decommit_ok_with_panic"); + test_decommit("decommit_ok_with_panic"); } #[test_log::test] - fn test_log_write_same_value() { + fn test_log_storage_clear_slot() { run_asm_based_test( - "src/tests/simple_tests/testdata/log/write_same_value", + "src/tests/simple_tests/testdata/log/storage/storage_clear_slot", &[], Default::default(), ) } #[test_log::test] - fn test_log_rollback_to_same_value_no_reads() { + fn test_log_storage_write_rollback_no_reads() { run_asm_based_test( - "src/tests/simple_tests/testdata/log/rollback_to_same_value_no_reads", + "src/tests/simple_tests/testdata/log/storage/storage_write_rollback_no_reads", &[], Default::default(), ) } #[test_log::test] - fn test_log_rollback_to_same_value_with_reads() { + fn test_log_storage_write_rollback_reads() { run_asm_based_test( - "src/tests/simple_tests/testdata/log/rollback_to_same_value_with_reads", + "src/tests/simple_tests/testdata/log/storage/storage_write_rollback_reads", &[], Default::default(), ) diff --git a/src/tests/simple_tests/storage.rs b/src/tests/simple_tests/storage.rs index d2447ebd..dcbfcc72 100644 --- a/src/tests/simple_tests/storage.rs +++ b/src/tests/simple_tests/storage.rs @@ -5,7 +5,7 @@ mod tests { #[test_log::test] fn test_pubdata_and_storage_writes() { run_asm_based_test( - "src/tests/simple_tests/testdata/storage_writes", + "src/tests/simple_tests/testdata/log/storage/storage_writes", &[], Options { cycles_per_vm_snapshot: 1, @@ -17,7 +17,7 @@ mod tests { #[test_log::test] fn test_storage_reads() { run_asm_based_test( - "src/tests/simple_tests/testdata/storage_reads", + "src/tests/simple_tests/testdata/log/storage/storage_reads", &[], Options { // Do only 1 cycle per VM snapshot to really test all the boundary conditions. diff --git a/src/tests/simple_tests/testdata/decommit_invalid/800000.asm b/src/tests/simple_tests/testdata/log/decommit_invalid/800000.asm similarity index 100% rename from src/tests/simple_tests/testdata/decommit_invalid/800000.asm rename to src/tests/simple_tests/testdata/log/decommit_invalid/800000.asm diff --git a/src/tests/simple_tests/testdata/decommit_invalid/entry.asm b/src/tests/simple_tests/testdata/log/decommit_invalid/entry.asm similarity index 100% rename from src/tests/simple_tests/testdata/decommit_invalid/entry.asm rename to src/tests/simple_tests/testdata/log/decommit_invalid/entry.asm diff --git a/src/tests/simple_tests/testdata/decommit_ok/800000.asm b/src/tests/simple_tests/testdata/log/decommit_ok/800000.asm similarity index 100% rename from src/tests/simple_tests/testdata/decommit_ok/800000.asm rename to src/tests/simple_tests/testdata/log/decommit_ok/800000.asm diff --git a/src/tests/simple_tests/testdata/decommit_ok/entry.asm b/src/tests/simple_tests/testdata/log/decommit_ok/entry.asm similarity index 88% rename from src/tests/simple_tests/testdata/decommit_ok/entry.asm rename to src/tests/simple_tests/testdata/log/decommit_ok/entry.asm index 5c5defd4..0f6c5772 100644 --- a/src/tests/simple_tests/testdata/decommit_ok/entry.asm +++ b/src/tests/simple_tests/testdata/log/decommit_ok/entry.asm @@ -9,10 +9,9 @@ .globl __entry __entry: .main: - add 10000, r0, r4 - near_call r4, @inner, @handler + ret.ok r0 inner: @@ -27,14 +26,13 @@ sub.s 2000, r9, r11 ; assert(r9-2000 >= r10) - make sure that we really burned 2k gas sub! r11, r10, r0 - jump.lt @.panic - + jump.lt @invalid_gas_burn ret.ok r0 handler: ret.panic r0 - .panic: - ret.panic r0 + invalid_gas_burn: + revert("Invalid gas burn in decommit") \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/decommit_ok_with_panic/800000.asm b/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/800000.asm similarity index 100% rename from src/tests/simple_tests/testdata/decommit_ok_with_panic/800000.asm rename to src/tests/simple_tests/testdata/log/decommit_ok_with_panic/800000.asm diff --git a/src/tests/simple_tests/testdata/decommit_ok_with_panic/entry.asm b/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm similarity index 82% rename from src/tests/simple_tests/testdata/decommit_ok_with_panic/entry.asm rename to src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm index 88f40dbe..a8bd9ffa 100644 --- a/src/tests/simple_tests/testdata/decommit_ok_with_panic/entry.asm +++ b/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm @@ -9,12 +9,10 @@ .globl __entry __entry: .main: - add 10000, r0, r4 - near_call r4, @inner, @handler - ; We should never get here - as the near_call should panic due to out of gas. - ret.panic r0 + + revert("Near call not reverted") inner: add @CPI0_0[0], r0, r1 @@ -28,7 +26,4 @@ handler: ; we expect the near_call to panic ret.ok r0 - - .panic: - ret.panic r0 \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log/l1_message_has_zero_pubdata_cost/entry.asm b/src/tests/simple_tests/testdata/log/l1_message_has_zero_pubdata_cost/entry.asm new file mode 100644 index 00000000..95511d33 --- /dev/null +++ b/src/tests/simple_tests/testdata/log/l1_message_has_zero_pubdata_cost/entry.asm @@ -0,0 +1,45 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + add 1000, r0, r1 + + ; pass 1000 gas + near_call r1, @inner, @failed_to_l1 + + near_call r0, @get_pubdata_counter, @panic + + ; check that pubdata counter is 0 + sub! stack[0], r0, r0 + jump.ne @panic_pubdata_counter_changed + + ret.ok r0 + +inner: + to_l1 r0, r1 + ret.ok r0 + +failed_to_l1: + revert("Can not send a message") + +get_pubdata_counter: + ; prepare a 32-bit mask (0xffff..) + add 1, r0, r10 + shl.s 32, r10, r10 + sub.s 1, r10, r10 + + ; get the pubdata counter + context.meta r7 + and r10, r7, stack[0] + + ret.ok r0 + +panic: + ret.panic r0 + +panic_pubdata_counter_changed: + revert("Pubdata counter changed") \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm b/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm index 6b391b91..2c02c586 100644 --- a/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm +++ b/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm @@ -6,17 +6,46 @@ .globl __entry __entry: .main: - add 10000, r0, r1 - add 1000, r0, r10 - sstore r1, r10 - event r1, r10 - to_l1 r1, r10 - context.set_ergs_per_pubdata r10 - near_call r1, @inner, @handler - context.ergs_left r15 - ret.ok r0 + add 100, r0, r1 + + ; pass 100 gas + ; should revert inside + near_call r1, @inner, @expected_panic + + revert("Near call not panicked") + inner: + ; trying to send message to l1 + ; but do not have enough gas + ; to_l1 does not have any pubdata cost to_l1 r0, r1 ret.ok r0 -handler: - ret.ok r0 \ No newline at end of file + +expected_panic: + near_call r0, @get_pubdata_counter, @panic + + ; check that pubdata counter is 0 + sub! stack[0], r0, r0 + jump.ne @panic_pubdata_counter_changed + + context.ergs_left r15 + + ret.ok r0 + +get_pubdata_counter: + ; prepare a 32-bit mask (0xffff..) + add 1, r0, r10 + shl.s 32, r10, r10 + sub.s 1, r10, r10 + + ; get the pubdata counter + context.meta r7 + and r10, r7, stack[0] + + ret.ok r0 + +panic: + ret.panic r0 + +panic_pubdata_counter_changed: + revert("Pubdata counter changed") \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log/precompile_invalid_address/65399.asm b/src/tests/simple_tests/testdata/log/precompile_invalid_address/65399.asm new file mode 100644 index 00000000..b2917927 --- /dev/null +++ b/src/tests/simple_tests/testdata/log/precompile_invalid_address/65399.asm @@ -0,0 +1,62 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + ; 2 lower bytes of this contract address are used as precompile address + ; we are in 65399 that should have address ending with 0xFF77 + ; precompile call - address 0xFF77, ABI is empty, AuxData (additional costs - 0 for now) + ; we are calling invalid precompile address, nothing should happen + log.precompile r0, r3, r4 + + ; Add extra ~16k cost + ; extra pubdata cost 2^32 - 1 + add 1, r0, r3 + shl.s 32, r3, r3 + ; extra gas cost 2^14 (~16k) + add 1, r3, r3 + shl.s 14, r3, r3 + + ; precompile call - address 0xFF77 (invalid), ABI is empty, AuxData (additional costs ~16k) + ; should burn gas + context.ergs_left r9 + log.precompile r0, r3, r4 + context.ergs_left r10 + + ; so after the precompile call, we should have burned at least 16k gas. + sub.s 16000, r9, r11 + ; assert(r9-16000 >= r10) - make sure that we really burned 16k gas + sub! r11, r10, r0 + jump.lt @not_burned_gas + + add 10000, r0, r1 + ; pass 10k gas + near_call r1, @out_of_gas_inner, @expected_panic + + revert("Near call not reverted") + +out_of_gas_inner: + to_l1 r0, r1 + + ; Add extra ~16k cost (more than this near call has) + ; extra pubdata cost 2^32 - 1 + add 1, r0, r3 + shl.s 32, r3, r3 + ; extra gas cost 2^14 (~16k) + add 1, r3, r3 + shl.s 14, r3, r3 + + ; precompile call - address 0xFF77 (invalid), ABI is empty, AuxData (additional costs ~16k) + log.precompile r0, r3, r4 + ret.ok r0 + +expected_panic: + ; we expect the near_call to panic + ret.ok r0 + +not_burned_gas: + revert("Precompile call not burned gas") + \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log/precompile_invalid_address/entry.asm b/src/tests/simple_tests/testdata/log/precompile_invalid_address/entry.asm new file mode 100644 index 00000000..53a3654c --- /dev/null +++ b/src/tests/simple_tests/testdata/log/precompile_invalid_address/entry.asm @@ -0,0 +1,32 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 65399 + .text + .globl __entry +__entry: +.main: + ; We will try to call invalid precompile address inside 65399 contract + + ; create ABI for far_call + ; use 0 for forwarding mode + add 0, r0, r1 + shl.s 32, r1, r1 + ; give 100k gas + add 100000, r1, r1 + shl.s 96, r1, r1 + add 36, r1, r1 + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + + add @CPI0_0[0], r0, r2 + + far_call r1, r2, @catch_all + + ret.ok r0 + +catch_all: + ret.panic r0 \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log/precompile_out_of_gas/entry.asm b/src/tests/simple_tests/testdata/log/precompile_out_of_gas/entry.asm index 715161a9..9b00bafd 100644 --- a/src/tests/simple_tests/testdata/log/precompile_out_of_gas/entry.asm +++ b/src/tests/simple_tests/testdata/log/precompile_out_of_gas/entry.asm @@ -6,25 +6,29 @@ .globl __entry __entry: .main: - add 10000, r0, r1 - add 1000, r0, r10 - ; precompile call - address 0x1, AuxData (additional costs - 0 for now) - log.precompile r2, r3, r4 + ; 2 lower bytes of this contract address are used as precompile address + ; we are in bootloader that should have address ending with 0x8001 + ; precompile call - address 0x1, ABI is empty, AuxData (additional costs - 0 for now) + log.precompile r0, r3, r4 + add 10000, r0, r1 + ; pass 10k gas near_call r1, @inner, @handler - ; We should never get here - as the near_call should panic due to out of gas. - ret.panic r0 + + revert("Near call not reverted") inner: to_l1 r0, r1 - ; Add extra 16k cost (more than this near call has) + ; Add extra ~16k cost (more than this near call has) + ; extra pubdata cost 2^32 - 1 add 1, r0, r3 shl.s 32, r3, r3 + ; extra gas cost 2^14 (~16k) add 1, r3, r3 shl.s 14, r3, r3 - ; precompile call - address 0x1, AuxData (additional costs - 16k for now) - log.precompile r2, r3, r4 + ; precompile call - address 0x1, ABI is empty, AuxData (additional costs ~16k) + log.precompile r0, r3, r4 ret.ok r0 handler: ; we expect the near_call to panic diff --git a/src/tests/simple_tests/testdata/log/rollback_to_same_value_with_reads/entry.asm b/src/tests/simple_tests/testdata/log/rollback_to_same_value_with_reads/entry.asm deleted file mode 100644 index b457450b..00000000 --- a/src/tests/simple_tests/testdata/log/rollback_to_same_value_with_reads/entry.asm +++ /dev/null @@ -1,20 +0,0 @@ - .text - .file "Test_26" - .rodata.cst32 - .p2align 5 - .text - .globl __entry -__entry: -.main: - near_call r1, @inner, @handler - context.ergs_left r15 - ret.ok r0 -inner: - add 10000, r0, r1 - add 1000, r0, r10 - sstore r1, r10 - ret.panic r0 -handler: -add 10000, r0, r1 - sload r1, r2 - ret.ok r0 \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log/write_same_value/entry.asm b/src/tests/simple_tests/testdata/log/storage/storage_clear_slot/entry.asm similarity index 77% rename from src/tests/simple_tests/testdata/log/write_same_value/entry.asm rename to src/tests/simple_tests/testdata/log/storage/storage_clear_slot/entry.asm index b591e67d..474c1c9c 100644 --- a/src/tests/simple_tests/testdata/log/write_same_value/entry.asm +++ b/src/tests/simple_tests/testdata/log/storage/storage_clear_slot/entry.asm @@ -8,12 +8,18 @@ __entry: .main: near_call r0, @inner, @handler context.ergs_left r15 + ret.ok r0 + inner: add 10000, r0, r1 add 1000, r0, r10 + ; write 1000 to slot 10000 sstore r1, r10 + ; write 0 to slot 10000 sstore r1, r0 + ret.ok r0 + handler: - ret.ok r0 \ No newline at end of file + ret.panic r0 \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/storage_reads/entry.asm b/src/tests/simple_tests/testdata/log/storage/storage_reads/entry.asm similarity index 100% rename from src/tests/simple_tests/testdata/storage_reads/entry.asm rename to src/tests/simple_tests/testdata/log/storage/storage_reads/entry.asm diff --git a/src/tests/simple_tests/testdata/log/rollback_to_same_value_no_reads/entry.asm b/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_no_reads/entry.asm similarity index 62% rename from src/tests/simple_tests/testdata/log/rollback_to_same_value_no_reads/entry.asm rename to src/tests/simple_tests/testdata/log/storage/storage_write_rollback_no_reads/entry.asm index b6ce5f54..a11ab6b8 100644 --- a/src/tests/simple_tests/testdata/log/rollback_to_same_value_no_reads/entry.asm +++ b/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_no_reads/entry.asm @@ -6,13 +6,19 @@ .globl __entry __entry: .main: - near_call r0, @inner, @handler - context.ergs_left r15 - ret.ok r0 + near_call r0, @inner, @expected_panic + + revert("Near call not panicked") + inner: add 10000, r0, r1 add 1000, r0, r10 + + ; write 1000 to storage slot 10000 sstore r1, r10 + ret.panic r0 -handler: + +expected_panic: + context.ergs_left r15 ret.ok r0 \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_reads/entry.asm b/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_reads/entry.asm new file mode 100644 index 00000000..e5e8528d --- /dev/null +++ b/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_reads/entry.asm @@ -0,0 +1,35 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + near_call r1, @inner, @expected_panic + + revert("Near call not panicked") + +inner: + add 10000, r0, r1 + add 1000, r0, r10 + ; write 1000 to storage slot 10000 + sstore r1, r10 + + ret.panic r0 + +expected_panic: + context.ergs_left r15 + + ; read value from storage slot 10000 + add 10000, r0, r1 + sload r1, r2 + + ; check that value is 0 + sub! r0, r2, r0 + jump.ne @invalid_storage_value + + ret.ok r0 + +invalid_storage_value: + revert("Invalid value in storage") \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/storage_writes/entry.asm b/src/tests/simple_tests/testdata/log/storage/storage_writes/entry.asm similarity index 100% rename from src/tests/simple_tests/testdata/storage_writes/entry.asm rename to src/tests/simple_tests/testdata/log/storage/storage_writes/entry.asm From cdea077bd98976758e3daa0eba4b1cb86f9d35c8 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 5 Jun 2024 12:09:03 +0200 Subject: [PATCH 3/7] Update tests names --- src/tests/simple_tests/log.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/simple_tests/log.rs b/src/tests/simple_tests/log.rs index 8b3d6fff..eee35b66 100644 --- a/src/tests/simple_tests/log.rs +++ b/src/tests/simple_tests/log.rs @@ -23,7 +23,7 @@ mod tests { #[test_log::test] /// Tests the case where we run out of gas during the precompile execution. - fn test_precompile_out_of_gas() { + fn test_log_precompile_out_of_gas() { run_asm_based_test( "src/tests/simple_tests/testdata/log/precompile_out_of_gas", &[], @@ -36,7 +36,7 @@ mod tests { } #[test_log::test] - fn test_precompile_invalid_address() { + fn test_log_precompile_invalid_address() { run_asm_based_test( "src/tests/simple_tests/testdata/log/precompile_invalid_address", &[65399], From aeebd517a067a6c77f07a1a864d95cd86733de42 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 5 Jun 2024 12:42:53 +0200 Subject: [PATCH 4/7] Cleanup --- src/tests/simple_tests/log.rs | 49 +++++++------------ .../testdata/log/decommit_ok/entry.asm | 2 +- .../log/decommit_ok_with_panic/entry.asm | 2 +- 3 files changed, 19 insertions(+), 34 deletions(-) diff --git a/src/tests/simple_tests/log.rs b/src/tests/simple_tests/log.rs index eee35b66..a48cca27 100644 --- a/src/tests/simple_tests/log.rs +++ b/src/tests/simple_tests/log.rs @@ -2,6 +2,18 @@ mod tests { use crate::tests::simple_tests::{asm_tests::run_asm_based_test, Options}; + fn test_snapshot_every_cycle(dir: &str, additional_contracts: &[i32]) { + run_asm_based_test( + &format!("src/tests/simple_tests/testdata/log/{}", dir), + additional_contracts, + Options { + // Do only 1 cycle per VM snapshot to really test all the boundary conditions. + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ) + } + #[test_log::test] /// Tests the case where we do not have enough gas to send a message to l1 fn test_log_l1_message_out_of_gas() { @@ -24,54 +36,27 @@ mod tests { #[test_log::test] /// Tests the case where we run out of gas during the precompile execution. fn test_log_precompile_out_of_gas() { - run_asm_based_test( - "src/tests/simple_tests/testdata/log/precompile_out_of_gas", - &[], - Options { - // Do only 1 cycle per VM snapshot to really test all the boundary conditions. - cycles_per_vm_snapshot: 1, - ..Default::default() - }, - ) + test_snapshot_every_cycle("precompile_out_of_gas", &[]); } #[test_log::test] fn test_log_precompile_invalid_address() { - run_asm_based_test( - "src/tests/simple_tests/testdata/log/precompile_invalid_address", - &[65399], - Options { - // Do only 1 cycle per VM snapshot to really test all the boundary conditions. - cycles_per_vm_snapshot: 1, - ..Default::default() - }, - ) - } - - fn test_decommit(dir: &str) { - run_asm_based_test( - &format!("src/tests/simple_tests/testdata/log/{}", dir), - &[800000], - Options { - cycles_per_vm_snapshot: 1, - ..Default::default() - }, - ) + test_snapshot_every_cycle("precompile_invalid_address", &[65399]); } #[test_log::test] fn test_log_decommit_invalid() { - test_decommit("decommit_invalid") + test_snapshot_every_cycle("decommit_invalid", &[800000]) } #[test_log::test] fn test_log_decommit_ok() { - test_decommit("decommit_ok"); + test_snapshot_every_cycle("decommit_ok", &[800000]); } #[test_log::test] fn test_log_decommit_ok_with_panic() { - test_decommit("decommit_ok_with_panic"); + test_snapshot_every_cycle("decommit_ok_with_panic", &[800000]); } #[test_log::test] diff --git a/src/tests/simple_tests/testdata/log/decommit_ok/entry.asm b/src/tests/simple_tests/testdata/log/decommit_ok/entry.asm index 0f6c5772..55f96ca9 100644 --- a/src/tests/simple_tests/testdata/log/decommit_ok/entry.asm +++ b/src/tests/simple_tests/testdata/log/decommit_ok/entry.asm @@ -3,7 +3,7 @@ .rodata.cst32 .p2align 5 CPI0_0: - ; this is the hash of the contract in 80000.asm + ; this is the hash of the contract in 800000.asm .cell 452312938437537823148903869859771978505772238111866864847149311043017845250 .text .globl __entry diff --git a/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm b/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm index a8bd9ffa..7833b4f5 100644 --- a/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm +++ b/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm @@ -3,7 +3,7 @@ .rodata.cst32 .p2align 5 CPI0_0: - ; this is the hash of the contract in 80000.asm + ; this is the hash of the contract in 800000.asm .cell 452312938437537823148903869859771978505772238111866864847149311043017845250 .text .globl __entry From bcbbffa16f8c2b416b9a00afea80affd0e0f47c1 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 5 Jun 2024 12:49:43 +0200 Subject: [PATCH 5/7] Move storage pubdata refunds to storage dir --- src/tests/simple_tests/storage.rs | 5 +++-- .../storage/storage_pubdata_refunds}/entry.asm | 0 2 files changed, 3 insertions(+), 2 deletions(-) rename src/tests/simple_tests/testdata/{pubdata_refunds => log/storage/storage_pubdata_refunds}/entry.asm (100%) diff --git a/src/tests/simple_tests/storage.rs b/src/tests/simple_tests/storage.rs index f094fc04..42f3075d 100644 --- a/src/tests/simple_tests/storage.rs +++ b/src/tests/simple_tests/storage.rs @@ -28,11 +28,12 @@ mod tests { } #[test_log::test] - fn test_pubdata_refunds() { + fn test_storage_pubdata_refunds() { run_asm_based_test( - "src/tests/simple_tests/testdata/pubdata_refunds", + "src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds", &[], Options { + // Do only 1 cycle per VM snapshot to really test all the boundary conditions. cycles_per_vm_snapshot: 1, ..Default::default() }, diff --git a/src/tests/simple_tests/testdata/pubdata_refunds/entry.asm b/src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds/entry.asm similarity index 100% rename from src/tests/simple_tests/testdata/pubdata_refunds/entry.asm rename to src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds/entry.asm From 806c9a4d02e32422131ca6b40f9bf1f58c694192 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 5 Jun 2024 14:59:46 +0200 Subject: [PATCH 6/7] Add decommit twice test --- src/tests/simple_tests/log.rs | 5 ++ .../testdata/log/decommit_ok_twice/800000.asm | 10 ++++ .../testdata/log/decommit_ok_twice/entry.asm | 59 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 src/tests/simple_tests/testdata/log/decommit_ok_twice/800000.asm create mode 100644 src/tests/simple_tests/testdata/log/decommit_ok_twice/entry.asm diff --git a/src/tests/simple_tests/log.rs b/src/tests/simple_tests/log.rs index a48cca27..e7be2ab6 100644 --- a/src/tests/simple_tests/log.rs +++ b/src/tests/simple_tests/log.rs @@ -54,6 +54,11 @@ mod tests { test_snapshot_every_cycle("decommit_ok", &[800000]); } + #[test_log::test] + fn test_log_decommit_ok_twice() { + test_snapshot_every_cycle("decommit_ok_twice", &[800000]); + } + #[test_log::test] fn test_log_decommit_ok_with_panic() { test_snapshot_every_cycle("decommit_ok_with_panic", &[800000]); diff --git a/src/tests/simple_tests/testdata/log/decommit_ok_twice/800000.asm b/src/tests/simple_tests/testdata/log/decommit_ok_twice/800000.asm new file mode 100644 index 00000000..24334c47 --- /dev/null +++ b/src/tests/simple_tests/testdata/log/decommit_ok_twice/800000.asm @@ -0,0 +1,10 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; empty contract + ret.ok r0 \ No newline at end of file diff --git a/src/tests/simple_tests/testdata/log/decommit_ok_twice/entry.asm b/src/tests/simple_tests/testdata/log/decommit_ok_twice/entry.asm new file mode 100644 index 00000000..8132c2e8 --- /dev/null +++ b/src/tests/simple_tests/testdata/log/decommit_ok_twice/entry.asm @@ -0,0 +1,59 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + HASHES: + ; this is the hash of the contract in 800000.asm + .cell <800000.asm> + ADDRESSES: + .cell 800000 + .text + .globl __entry + __entry: + .main: + ; create ABI fo far call + ; use 0 for forwarding mode + add 0, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 10000, r1, r1 + shl.s 96, r1, r1 + add 36, r1, r1 + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + + add @ADDRESSES[0], r0, r2 + + ; far call should also decommit 800000 + far_call r1, r2, @panic + + ; now we are trying to decommit it again + add 15000, r0, r4 + near_call r4, @inner, @panic + + ret.ok r0 + + inner: + add @HASHES[0], r0, r1 + ; add extra cost, we expect it to be refunded + ; since we are decommiting already decomitted contract + add 2000, r0, r2 + context.ergs_left r9 + log.decommit r1, r2, r3 + context.ergs_left r10 + + ; so after the call, we should have burned some gas and received 2k refund. + sub.s 2000, r9, r11 + ; assert(r9-2000 <= r10) - make sure that we did not burn 2k gas + sub! r11, r10, r0 + jump.gt @invalid_gas_burn + + ret.ok r0 + + panic: + ret.panic r0 + + invalid_gas_burn: + revert("Invalid gas burn in decommit") + \ No newline at end of file From 3a00eff87c0ca1ca1174ca06e25e109d8ac8ef73 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 5 Jun 2024 17:18:27 +0200 Subject: [PATCH 7/7] Fix gas refund test --- .../storage/storage_pubdata_refunds/entry.asm | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds/entry.asm b/src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds/entry.asm index 0aec807b..06e6d444 100644 --- a/src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds/entry.asm +++ b/src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds/entry.asm @@ -13,21 +13,35 @@ __entry: ; perform write via near call near_call r4, @inner_storage_handler, @.panic - add 5000, r0, r4 - near_call r4, @inner_storage_too_large_refund, @.expected_error_handler + ret.ok r0 - revert("Not panicked but should") inner_storage_handler: ; we'll be writing 13 at slot 25 with a warm refund of 5400 set_storage_warm(5400) add 25, r0, r1 add 13, r0, r2 + context.ergs_left r7 + add r7, r0, stack[0] log.swrite r1, r2, r0 + context.ergs_left r7 + + ; check that we spent less than 5k gas (we have refund) + sub stack[0], r7, r7 + sub!.s 5000, r7, r0 + jump.gt @not_refunded_gas ; we'll be writing 19 at slot 25 with a cold storage refund set_storage_cold() add 19, r0, r2 + context.ergs_left r7 + add r7, r0, stack[0] log.swrite r1, r2, r0 + context.ergs_left r7 + + ; check that we spent more than 5k gas (we do not have refund) + sub stack[0], r7, r7 + sub!.s 5000, r7, r0 + jump.lt @not_enough_gas_spent_cold ; read slot 25 with a warm refund of 1900 set_storage_warm(1900) @@ -39,17 +53,12 @@ inner_storage_handler: log.sread r1, r0, r6 ret.ok r0 -inner_storage_too_large_refund: - ; we'll be writing 13 at slot 25 with a warm refund of 5400 - ; this should cause it to fail because we refund more gas than we have - ; available - set_storage_warm(5400) - add 25, r0, r1 - add 13, r0, r2 - log.swrite r1, r2, r0 - ret.ok r0 +not_refunded_gas: + revert("Gas for write not refunded") + +not_enough_gas_spent_cold: + revert("Cold write gas spent too low") + .panic: - ret.panic r0 -.expected_error_handler: - ret.ok r0 \ No newline at end of file + ret.panic r0 \ No newline at end of file