Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RW circuit constraint for muti-tx trace #189

Merged
merged 6 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ namespace nil {
_bytecodes.new_buffer(bytecode);
}

std::size_t call_id = 0;
std::size_t rw_counter = 0;
std::size_t call_id = 0;
for( auto &pt: pts){
boost::property_tree::ptree ptrace = pt.get_child("result.structLogs");
std::cout << "PT = " << ptrace.size() << std::endl;
Expand Down Expand Up @@ -83,7 +83,7 @@ namespace nil {
state.gas = atoi(it->second.get_child("gas").data().c_str());
state.pc = atoi(it->second.get_child("pc").data().c_str());
state.rw_counter = rw_counter;
state.bytecode_hash = _bytecodes.get_data()[0].second; // TODO: fix it if possible
state.bytecode_hash = _bytecodes.get_data()[call_id].second; // TODO: fix it if possible
state.additional_input = opcode.substr(0,4) == "PUSH"? stack_next[stack_next.size() - 1]: 0;
state.tx_finish = (std::distance(it, ptrace.end()) != 1);
state.stack_size = stack.size();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ namespace nil {
special_constraints[STACK_OP].push_back(context_object.relativize(stack_selector * is_first[1] * (1 - is_write[1]), -1)); // 4. First stack operation is obviously write
//if(i!=0) {
non_first_row_constraints.push_back(context_object.relativize(stack_selector * (address[1] - address[0]) * (is_write[1] - 1), -1)); // 5. First operation is always write
non_first_row_constraints.push_back(context_object.relativize(stack_selector * (address[1] - address[0]) * (address[1] - address[0] - 1), -1)); // 6. Stack pointer always grows and only by one
non_first_row_constraints.push_back(context_object.relativize(stack_selector * (1 - is_first[1]) * (address[1] - address[0]) * (address[1] - address[0] - 1), -1)); // 6. Stack pointer always grows and only by one
non_first_row_constraints.push_back(context_object.relativize(stack_selector * (1 - is_first[1]) * (state_root_hi[1] - state_root_before_hi[0]), -1));
non_first_row_constraints.push_back(context_object.relativize(stack_selector * (1 - is_first[1]) * (state_root_lo[1] - state_root_before_lo[0]), -1));
//}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ namespace nil {
//std::cout << "RW assign size = " << rw_trace.size() << std::endl;
BOOST_ASSERT(rw_trace.size() < max_rw_size);
for( std::size_t i = 0; i < rw_trace.size(); i++ ){
//if( rw_trace[i].op != nil::blueprint::PADDING_OP ) std::cout << "\t" << i << "." << rw_trace[i] << std::endl;
//if( rw_trace[i].op != rw_operation_type::padding )
oclaw marked this conversation as resolved.
Show resolved Hide resolved
// std::cout << "\t" << i << "." << rw_trace[i] << std::endl;
op[i] = rw_op_to_num(rw_trace[i].op);
id[i] = rw_trace[i].call_id;
address[i] = integral_type(rw_trace[i].address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,30 @@ namespace nil {
}
};

// For testing purposes
std::ostream& operator<<(std::ostream& os, const rw_operation& obj){
if(obj.op == rw_operation_type::start ) os << "START : ";
if(obj.op == rw_operation_type::stack ) os << "STACK : ";
if(obj.op == rw_operation_type::memory ) os << "MEMORY : ";
if(obj.op == rw_operation_type::storage ) os << "STORAGE : ";
if(obj.op == rw_operation_type::transient_storage ) os << "TRANSIENT_STORAGE : ";
if(obj.op == rw_operation_type::call_context ) os << "CALL_CONTEXT_OP : ";
if(obj.op == rw_operation_type::account ) os << "ACCOUNT_OP : ";
if(obj.op == rw_operation_type::tx_refund_op ) os << "TX_REFUND_OP : ";
if(obj.op == rw_operation_type::tx_access_list_account ) os << "TX_ACCESS_LIST_ACCOUNT_OP : ";
if(obj.op == rw_operation_type::tx_access_list_account_storage ) os << "TX_ACCESS_LIST_ACCOUNT_STORAGE_OP : ";
if(obj.op == rw_operation_type::tx_log ) os << "TX_LOG_OP : ";
if(obj.op == rw_operation_type::tx_receipt ) os << "TX_RECEIPT_OP : ";
if(obj.op == rw_operation_type::padding ) os << "PADDING_OP : ";
os << obj.rw_counter << " call_id = " << obj.call_id << ", addr =" << std::hex << obj.address << std::dec;
if(obj.op == rw_operation_type::storage || obj.op == rw_operation_type::transient_storage)
os << " storage_key = " << obj.storage_key;
if(obj.is_write) os << " W "; else os << " R ";
os << "[" << std::hex << obj.initial_value << std::dec <<"] => ";
os << "[" << std::hex << obj.value << std::dec <<"]";
return os;
}

rw_operation start_rw_operation(){
return rw_operation({rw_operation_type::start, 0, 0, 0, 0, 0, 0, 0});
}
Expand Down
23 changes: 16 additions & 7 deletions crypto3/libs/blueprint/test/zkevm_bbf/rw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,15 @@ class zkEVMRWTestFixture: public BBFTestFixture {

template <typename field_type>
void test_zkevm_rw(
std::string path,
std::vector<std::string> paths,
std::size_t max_rw_size
){
auto [bytecodes, traces] = load_hardhat_input(path);
auto [bytecodes, traces] = load_hardhat_input(paths[0]);
for( std::size_t i = 1; i < paths.size(); i++ ){
auto [bytecodes_next, traces_next] = load_hardhat_input(paths[i]);
bytecodes.insert(bytecodes.end(), bytecodes_next.begin(), bytecodes_next.end());
traces.insert(traces.end(), traces_next.begin(), traces_next.end());
}

nil::blueprint::bbf::zkevm_hardhat_input_generator circuit_inputs(bytecodes, traces);

Expand All @@ -83,22 +88,26 @@ BOOST_FIXTURE_TEST_SUITE(blueprint_bbf_rw, zkEVMRWTestFixture)
using integral_type = typename field_type::integral_type;
using value_type = typename field_type::value_type;
BOOST_AUTO_TEST_CASE(minimal_math){
test_zkevm_rw<field_type>("minimal_math/", 500);
test_zkevm_rw<field_type>({"minimal_math/"}, 500);
}

BOOST_AUTO_TEST_CASE(small_storage){
test_zkevm_rw<field_type>("small_stack_storage/", 500);
test_zkevm_rw<field_type>({"small_stack_storage/"}, 500);
}

BOOST_AUTO_TEST_CASE(mstore8){
test_zkevm_rw<field_type>("mstore8/", 5000);
test_zkevm_rw<field_type>({"mstore8/"}, 5000);
}

BOOST_AUTO_TEST_CASE(meminit){
test_zkevm_rw<field_type>("mem_init/", 10000);
test_zkevm_rw<field_type>({"mem_init/"}, 10000);
}

BOOST_AUTO_TEST_CASE(calldatacopy){
test_zkevm_rw<field_type>("calldatacopy/", 10000);
test_zkevm_rw<field_type>({"calldatacopy/"}, 10000);
}

BOOST_AUTO_TEST_CASE(multiple_traces){
test_zkevm_rw<field_type>({"minimal_math/", "keccak/", "exp/"} , 3000);
}
BOOST_AUTO_TEST_SUITE_END()
Original file line number Diff line number Diff line change
Expand Up @@ -166,20 +166,20 @@ namespace nil {

// Convert memory operations
for (const auto& pb_mop : pb_traces->memory_ops()) {
auto const value = string_to_bytes(pb_mop.value());
auto value = string_to_bytes(pb_mop.value());
auto const op = blueprint::bbf::memory_rw_operation(
static_cast<uint64_t>(pb_mop.msg_id()),
blueprint::zkevm_word_type(static_cast<int>(pb_mop.index())),
static_cast<uint64_t>(pb_mop.rw_idx()),
!pb_mop.is_read(),
blueprint::zkevm_word_from_bytes(value)
);
rw_traces.push_back(op);
rw_traces.push_back(std::move(op));
}

// Convert storage operations
for (const auto& pb_sop : pb_traces->storage_ops()) {
const auto& op = blueprint::bbf::storage_rw_operation(
auto op = blueprint::bbf::storage_rw_operation(
static_cast<uint64_t>(pb_sop.msg_id()),
blueprint::zkevm_word_from_string(static_cast<std::string>(pb_sop.key())),
static_cast<uint64_t>(pb_sop.rw_idx()),
Expand All @@ -192,17 +192,13 @@ namespace nil {
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;
});
std::sort(rw_traces.begin(), rw_traces.end(), std::less());

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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include <nil/blueprint/utils/satisfiability_check.hpp>
#include <nil/proof-generator/prover.hpp>
#include "nil/proof-generator/preset/preset.hpp"
#include <nil/proof-generator/preset/preset.hpp>


namespace {
Expand All @@ -15,7 +15,7 @@ namespace {
bool skip_check{false}; // skip satisfiability check while running the test
};

}
} // namespace


class ProverTests: public ::testing::TestWithParam<Input> {
Expand Down Expand Up @@ -70,7 +70,7 @@ INSTANTIATE_TEST_SUITE_P(SimpleZkevm, ProverTests, ::testing::Values(Input{Simpl

// 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(MultiTxRw, ProverTests, ::testing::Values(Input{MultiTxIncrement, RW}));
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
Loading