diff --git a/crypto3/libs/blueprint/include/nil/blueprint/bbf/enums.hpp b/crypto3/libs/blueprint/include/nil/blueprint/bbf/enums.hpp index f7e0d32548..b1c94be43c 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/bbf/enums.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/bbf/enums.hpp @@ -27,6 +27,9 @@ #ifndef CRYPTO3_BLUEPRINT_PLONK_BBF_ENUMS_HPP #define CRYPTO3_BLUEPRINT_PLONK_BBF_ENUMS_HPP +#include +#include + namespace nil { namespace blueprint { namespace bbf { @@ -35,7 +38,7 @@ namespace nil { enum column_type { witness = 0, public_input = 1, constant = 2, COLUMN_TYPES_COUNT = 3}; std::ostream &operator<<(std::ostream &os, const column_type &t) { - std::map type_map = { + static std::map type_map = { {column_type::witness, "witness"}, {column_type::public_input, "public input"}, {column_type::constant, "constant"}, diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/hardhat_input_generator.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/hardhat_input_generator.hpp index 526c6e3355..1c47b4ae3e 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/hardhat_input_generator.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/hardhat_input_generator.hpp @@ -54,7 +54,6 @@ namespace nil { std::size_t call_id = 0; std::size_t rw_counter = 0; - //_rw_operations.push_back(start_rw_operation()); for( auto &pt: pts){ boost::property_tree::ptree ptrace = pt.get_child("result.structLogs"); std::cout << "PT = " << ptrace.size() << std::endl; diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/opcode_tester_input_generator.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/opcode_tester_input_generator.hpp index cbd0331278..5d245d7f29 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/opcode_tester_input_generator.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/opcode_tester_input_generator.hpp @@ -49,7 +49,6 @@ namespace nil { const zkevm_opcode_tester &tester ): rw_counter(1), transactions_amount(0){ // It may be done for multiple transactions; - // _rw_operations.push_back(start_rw_operation()); apply_tester(tester); } diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/call.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/call.hpp new file mode 100644 index 0000000000..dbd0d18b5d --- /dev/null +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/call.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace nil { + namespace blueprint { + namespace bbf{ + + template + using zkevm_call_operation = zkevm_dummy_operation; + } // namespace bbf + } // namespace blueprint +} // namespace nil diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/dummy.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/dummy.hpp new file mode 100644 index 0000000000..01e0fd105c --- /dev/null +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/dummy.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include +#include + +namespace nil { + namespace blueprint { + namespace bbf{ + template + class opcode_abstract; + + // SHOULD NOT BE USED IN THE FINAL VERSION + template + class zkevm_dummy_operation : public opcode_abstract { + public: + virtual void fill_context( + typename generic_component::context_type &context, + const opcode_input_type ¤t_state + ) override { + } + virtual void fill_context( + typename generic_component::context_type &context, + const opcode_input_type ¤t_state + ) override { + std::cout << "DUMMY CONTSTRAINT, REPLACE ME WITH SOME ACTUAL IMPL" << std::endl; + } + virtual std::size_t rows_amount() override { + return 1; + } + }; + } // namespace bbf + } // namespace blueprint +} // namespace nil diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/gas.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/gas.hpp new file mode 100644 index 0000000000..d9d38d8fc2 --- /dev/null +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/gas.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace nil { + namespace blueprint { + namespace bbf{ + + template + using zkevm_gas_operation = zkevm_dummy_operation; + } // namespace bbf + } // namespace blueprint +} // namespace nil diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/mcopy.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/mcopy.hpp new file mode 100644 index 0000000000..ff605a35e6 --- /dev/null +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/mcopy.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace nil { + namespace blueprint { + namespace bbf{ + + template + using zkevm_mcopy_operation = zkevm_dummy_operation; + } // namespace bbf + } // namespace blueprint +} // namespace nil diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/returndatacopy.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/returndatacopy.hpp new file mode 100644 index 0000000000..710d0d905b --- /dev/null +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/returndatacopy.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace nil { + namespace blueprint { + namespace bbf{ + + template + using zkevm_returndatacopy_operation = zkevm_dummy_operation; + } // namespace bbf + } // namespace blueprint +} // namespace nil diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/returndatasize.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/returndatasize.hpp new file mode 100644 index 0000000000..6dc1a55b27 --- /dev/null +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/returndatasize.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace nil { + namespace blueprint { + namespace bbf{ + + template + using zkevm_returndatasize_operation = zkevm_dummy_operation; + } // namespace bbf + } // namespace blueprint +} // namespace nil diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/staticcall.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/staticcall.hpp new file mode 100644 index 0000000000..2277d1b124 --- /dev/null +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/staticcall.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace nil { + namespace blueprint { + namespace bbf{ + + template + using zkevm_staticcall_operation = zkevm_dummy_operation; + } // namespace bbf + } // namespace blueprint +} // namespace nil diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/zkevm_opcodes.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/zkevm_opcodes.hpp index ff274807c3..612f9f7767 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/zkevm_opcodes.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/zkevm_opcodes.hpp @@ -72,8 +72,15 @@ #include #include #include -#include #include +#include + +#include +#include +#include +#include +#include +#include namespace nil { namespace blueprint { @@ -683,6 +690,14 @@ namespace nil { opcodes[zkevm_opcode::POP] = std::make_shared>(); opcodes[zkevm_opcode::RETURN] = std::make_shared>(); + // not implemented yet opcodes + opcodes[zkevm_opcode::MCOPY] = std::make_shared>(); + opcodes[zkevm_opcode::RETURNDATASIZE] = std::make_shared>(); + opcodes[zkevm_opcode::RETURNDATACOPY] = std::make_shared>(); + opcodes[zkevm_opcode::CALL] = std::make_shared>(); + opcodes[zkevm_opcode::GAS] = std::make_shared>(); + opcodes[zkevm_opcode::STATICCALL] = std::make_shared>(); + // // DUP opcodes[zkevm_opcode::DUP1] = std::make_shared>(1); opcodes[zkevm_opcode::DUP2] = std::make_shared>(2); diff --git a/proof-producer/libs/assigner/include/nil/proof-generator/assigner/copy.hpp b/proof-producer/libs/assigner/include/nil/proof-generator/assigner/copy.hpp index 2b06da81c0..2db30c4aa1 100644 --- a/proof-producer/libs/assigner/include/nil/proof-generator/assigner/copy.hpp +++ b/proof-producer/libs/assigner/include/nil/proof-generator/assigner/copy.hpp @@ -48,20 +48,11 @@ namespace nil { } const auto rw_trace_path = get_rw_trace_path(trace_base_path); - const auto rw_operations = deserialize_rw_traces_from_file(rw_trace_path); + auto rw_operations = deserialize_rw_traces_from_file(rw_trace_path); if (!rw_operations) { return "can't read rw operations trace from file: " + rw_trace_path.string(); } - for (const auto& stack_op : rw_operations->stack_ops) { - input.rw_operations.push_back(stack_op); - } - for (const auto& memory_op : rw_operations->memory_ops) { - input.rw_operations.push_back(memory_op); - } - for (const auto& storage_op : rw_operations->storage_ops) { - input.rw_operations.push_back(storage_op); - } - + input.rw_operations = std::move(rw_operations.value()); auto start = std::chrono::high_resolution_clock::now(); ComponentType instance( diff --git a/proof-producer/libs/assigner/include/nil/proof-generator/assigner/rw.hpp b/proof-producer/libs/assigner/include/nil/proof-generator/assigner/rw.hpp index b956c88d1c..05a7c4d395 100644 --- a/proof-producer/libs/assigner/include/nil/proof-generator/assigner/rw.hpp +++ b/proof-producer/libs/assigner/include/nil/proof-generator/assigner/rw.hpp @@ -24,28 +24,14 @@ namespace nil { typename nil::blueprint::bbf::context context_object(assignment_table, limits::max_rows); - nil::blueprint::bbf::rw_operations_vector input; const auto rw_trace_path = get_rw_trace_path(trace_base_path); - const auto rw_operations = deserialize_rw_traces_from_file(rw_trace_path); - if (!rw_operations) { + auto input = deserialize_rw_traces_from_file(rw_trace_path); + if (!input) { return "can't read rw from file: " + rw_trace_path.string(); } - for (const auto& stack_op : rw_operations->stack_ops) { - input.push_back(stack_op); - } - for (const auto& memory_op : rw_operations->memory_ops) { - input.push_back(memory_op); - } - for (const auto& storage_op : rw_operations->storage_ops) { - input.push_back(storage_op); - } - BOOST_LOG_TRIVIAL(debug) << "number RW operations " << input.size() << ":\n" - << "stack " << rw_operations->stack_ops.size() << "\n" - << "memory " << rw_operations->memory_ops.size() << "\n" - << "storage " << rw_operations->storage_ops.size() << "\n"; auto start = std::chrono::high_resolution_clock::now(); - ComponentType instance(context_object, std::move(input), limits::max_rw_size, limits::max_mpt_size); + ComponentType instance(context_object, input.value(), limits::max_rw_size, limits::max_mpt_size); auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); std::cout << "FILL ASSIGNMENT TABLE: " << duration.count() << "\n"; return {}; diff --git a/proof-producer/libs/assigner/include/nil/proof-generator/assigner/trace_parser.hpp b/proof-producer/libs/assigner/include/nil/proof-generator/assigner/trace_parser.hpp index ffead47970..2e55e0defb 100644 --- a/proof-producer/libs/assigner/include/nil/proof-generator/assigner/trace_parser.hpp +++ b/proof-producer/libs/assigner/include/nil/proof-generator/assigner/trace_parser.hpp @@ -19,12 +19,7 @@ namespace nil { namespace proof_generator { - struct RWOperations { - std::vector stack_ops; - std::vector memory_ops; - std::vector storage_ops; - }; - + const char BYTECODE_EXTENSION[] = ".bc"; const char RW_EXTENSION[] = ".rw"; const char ZKEVM_EXTENSION[] = ".zkevm"; @@ -149,18 +144,18 @@ namespace nil { return contract_bytecodes; } - [[nodiscard]] std::optional deserialize_rw_traces_from_file(const boost::filesystem::path& rw_traces_path) { + [[nodiscard]] std::optional deserialize_rw_traces_from_file(const boost::filesystem::path& rw_traces_path) { const auto pb_traces = read_pb_traces_from_file(rw_traces_path); if (!pb_traces) { return std::nullopt; } - RWOperations rw_traces; + blueprint::bbf::rw_operations_vector rw_traces; + rw_traces.reserve(pb_traces->stack_ops_size() + pb_traces->memory_ops_size() + pb_traces->storage_ops_size() + 1); // +1 slot for start op // Convert stack operations - rw_traces.stack_ops.reserve(pb_traces->stack_ops_size()); for (const auto& pb_sop : pb_traces->stack_ops()) { - rw_traces.stack_ops.push_back(blueprint::bbf::stack_rw_operation( + rw_traces.push_back(blueprint::bbf::stack_rw_operation( static_cast(pb_sop.msg_id()), static_cast(pb_sop.index()), static_cast(pb_sop.rw_idx()), @@ -170,7 +165,6 @@ namespace nil { } // Convert memory operations - rw_traces.memory_ops.reserve(pb_traces->memory_ops_size()); for (const auto& pb_mop : pb_traces->memory_ops()) { auto const value = string_to_bytes(pb_mop.value()); auto const op = blueprint::bbf::memory_rw_operation( @@ -180,11 +174,10 @@ namespace nil { !pb_mop.is_read(), blueprint::zkevm_word_from_bytes(value) ); - rw_traces.memory_ops.push_back(op); + rw_traces.push_back(op); } // Convert storage operations - rw_traces.storage_ops.reserve(pb_traces->storage_ops_size()); for (const auto& pb_sop : pb_traces->storage_ops()) { const auto& op = blueprint::bbf::storage_rw_operation( static_cast(pb_sop.msg_id()), @@ -196,9 +189,20 @@ namespace nil { blueprint::zkevm_word_from_string(pb_sop.address().address_bytes()) ); //TODO root and initial_root? - rw_traces.storage_ops.push_back(std::move(op)); + rw_traces.push_back(std::move(op)); } + using nil::blueprint::bbf::rw_operation; + std::sort(rw_traces.begin(), rw_traces.end(), [](rw_operation a, rw_operation b){ + return a < b; + }); + + BOOST_LOG_TRIVIAL(debug) << "number RW operations " << rw_traces.size() << ":\n" + << "stack " << pb_traces->stack_ops_size() << "\n" + << "memory " << pb_traces->memory_ops_size() << "\n" + << "storage " << pb_traces->storage_ops_size() << "\n"; + + return rw_traces; } diff --git a/proof-producer/libs/assigner/include/nil/proof-generator/assigner/zkevm.hpp b/proof-producer/libs/assigner/include/nil/proof-generator/assigner/zkevm.hpp index 73a36213cd..f818614ed8 100644 --- a/proof-producer/libs/assigner/include/nil/proof-generator/assigner/zkevm.hpp +++ b/proof-producer/libs/assigner/include/nil/proof-generator/assigner/zkevm.hpp @@ -40,20 +40,11 @@ namespace nil { // rw const auto rw_trace_path = get_rw_trace_path(trace_base_path); - const auto rw_operations = deserialize_rw_traces_from_file(rw_trace_path); + auto rw_operations = deserialize_rw_traces_from_file(rw_trace_path); if (!rw_operations) { return "can't read rw from file: " + rw_trace_path.string(); } - for (const auto& stack_op : rw_operations->stack_ops) { - input.rw_operations.push_back(stack_op); - } - for (const auto& memory_op : rw_operations->memory_ops) { - input.rw_operations.push_back(memory_op); - } - for (const auto& storage_op : rw_operations->storage_ops) { - input.rw_operations.push_back(storage_op); - } - + input.rw_operations = std::move(rw_operations.value()); // states const auto zkevm_trace_path = get_zkevm_trace_path(trace_base_path); diff --git a/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.bc b/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.bc new file mode 100644 index 0000000000..8bf6398a63 Binary files /dev/null and b/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.bc differ diff --git a/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.copy b/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.copy new file mode 100644 index 0000000000..4559e0871b Binary files /dev/null and b/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.copy differ diff --git a/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.msg b/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.msg new file mode 100644 index 0000000000..59f144ee09 Binary files /dev/null and b/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.msg differ diff --git a/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.rw b/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.rw new file mode 100644 index 0000000000..7ae0400419 Binary files /dev/null and b/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.rw differ diff --git a/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.zkevm b/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.zkevm new file mode 100644 index 0000000000..b87a67f418 Binary files /dev/null and b/proof-producer/tests/bin/proof-producer/resources/traces/increment_simple.pb.zkevm differ diff --git a/proof-producer/tests/bin/proof-producer/test_zkevm_bbf_circuits.cpp b/proof-producer/tests/bin/proof-producer/test_zkevm_bbf_circuits.cpp index a7adb2a9d3..88aadf5374 100644 --- a/proof-producer/tests/bin/proof-producer/test_zkevm_bbf_circuits.cpp +++ b/proof-producer/tests/bin/proof-producer/test_zkevm_bbf_circuits.cpp @@ -1,11 +1,24 @@ #include -#include -#include +#include +#include #include +#include "nil/proof-generator/preset/preset.hpp" + + +namespace { + + struct Input { + std::string trace_base_name; // base name of trace set collected from the cluster + std::string circuit_name; // circuit name + bool skip_check{false}; // skip satisfiability check while running the test + }; + +} -class ProverTests: public ::testing::Test { + +class ProverTests: public ::testing::TestWithParam { protected: using CurveType = nil::crypto3::algebra::curves::pallas; @@ -19,35 +32,16 @@ class ProverTests: public ::testing::Test { static constexpr std::size_t max_quotient_chunks = 0; }; -TEST_F(ProverTests, Bytecode) { - std::string trace_base_path = std::string(TEST_DATA_DIR) + "increment_multi_tx.pb"; - nil::proof_generator::Prover prover( - lambda, - expand_factor, - max_quotient_chunks, - grind, - nil::proof_generator::circuits::BYTECODE - ); - ASSERT_TRUE(prover.setup_prover()); - - ASSERT_TRUE(prover.fill_assignment_table(trace_base_path)); - - const auto& circuit = prover.get_constraint_system(); - const auto& assignment_table = prover.get_assignment_table(); - - GTEST_SKIP() << "Skipping satisfiability_check for bytecode"; - ASSERT_TRUE(nil::blueprint::is_satisfied(circuit, assignment_table)); -} - -TEST_F(ProverTests, RW) { - std::string trace_base_path = std::string(TEST_DATA_DIR) + "increment_multi_tx.pb"; +TEST_P(ProverTests, FillAssignmentAndCheck) { + const auto input = GetParam(); + const std::string trace_base_path = std::string(TEST_DATA_DIR) + input.trace_base_name; nil::proof_generator::Prover prover( lambda, expand_factor, max_quotient_chunks, grind, - nil::proof_generator::circuits::RW + input.circuit_name ); ASSERT_TRUE(prover.setup_prover()); @@ -57,47 +51,26 @@ TEST_F(ProverTests, RW) { const auto& circuit = prover.get_constraint_system(); const auto& assignment_table = prover.get_assignment_table(); - GTEST_SKIP() << "Skipping satisfiability_check for rw"; - ASSERT_TRUE(nil::blueprint::is_satisfied(circuit, assignment_table)); -} - -TEST_F(ProverTests, Copy) { - std::string trace_base_path = std::string(TEST_DATA_DIR) + "increment_multi_tx.pb"; - nil::proof_generator::Prover prover( - lambda, - expand_factor, - max_quotient_chunks, - grind, - nil::proof_generator::circuits::COPY - ); - - ASSERT_TRUE(prover.setup_prover()); - - ASSERT_TRUE(prover.fill_assignment_table(trace_base_path)); - - const auto& circuit = prover.get_constraint_system(); - const auto& assignment_table = prover.get_assignment_table(); + if (input.skip_check) { + GTEST_SKIP() << "Skipping satisfiability_check for " << input.circuit_name << " circuit for trace " << input.trace_base_name; + } ASSERT_TRUE(nil::blueprint::is_satisfied(circuit, assignment_table)); } -TEST_F(ProverTests, Zkevm) { - std::string trace_base_path = std::string(TEST_DATA_DIR) + "increment_multi_tx.pb"; - nil::proof_generator::Prover prover( - lambda, - expand_factor, - max_quotient_chunks, - grind, - nil::proof_generator::circuits::ZKEVM - ); - ASSERT_TRUE(prover.setup_prover()); +using namespace nil::proof_generator::circuits; - ASSERT_TRUE(prover.fill_assignment_table(trace_base_path)); - - const auto& circuit = prover.get_constraint_system(); - const auto& assignment_table = prover.get_assignment_table(); +// Single call of Counter contract increment function +const std::string SimpleIncrement = "increment_simple.pb"; +INSTANTIATE_TEST_SUITE_P(SimpleRw, ProverTests, ::testing::Values(Input{SimpleIncrement, RW})); +INSTANTIATE_TEST_SUITE_P(SimpleBytecode, ProverTests, ::testing::Values(Input{SimpleIncrement, BYTECODE})); +INSTANTIATE_TEST_SUITE_P(SimpleCopy, ProverTests, ::testing::Values(Input{SimpleIncrement, COPY})); +INSTANTIATE_TEST_SUITE_P(SimpleZkevm, ProverTests, ::testing::Values(Input{SimpleIncrement, ZKEVM, true})); // TODO - GTEST_SKIP() << "Skipping satisfiability_check for zkevm"; - ASSERT_TRUE(nil::blueprint::is_satisfied(circuit, assignment_table)); -} +// Multiple calls of Counter contract increment function (several transactions) +const std::string MultiTxIncrement = "increment_multi_tx.pb"; +INSTANTIATE_TEST_SUITE_P(MultiTxRw, ProverTests, ::testing::Values(Input{MultiTxIncrement, RW, true})); // https://github.com/NilFoundation/placeholder/issues/187 +INSTANTIATE_TEST_SUITE_P(MultiTxBytecode, ProverTests, ::testing::Values(Input{MultiTxIncrement, BYTECODE, true})); // TODO +INSTANTIATE_TEST_SUITE_P(MultiTxCopy, ProverTests, ::testing::Values(Input{MultiTxIncrement, COPY})); +INSTANTIATE_TEST_SUITE_P(MultiTxZkevm, ProverTests, ::testing::Values(Input{MultiTxIncrement, ZKEVM, true})); // TODO