Skip to content

Commit

Permalink
feat: add traces reader to proof producer
Browse files Browse the repository at this point in the history
  • Loading branch information
x-mass committed Oct 30, 2024
1 parent 6572b08 commit 6c6d726
Show file tree
Hide file tree
Showing 13 changed files with 439 additions and 27 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -637,3 +637,7 @@ callgrind.*

.ycm_extra_config.py
.color_coded

# Ignore generated protobufs
*.pb.h
*.pb.cc
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_compile_options (-fcolor-diagnostics)
endif ()

if(DEFINED CMAKE_BUILD_TYPE AND ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
if(DEFINED CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -ggdb")
set(BOOST_FORCEINLINE "OFF") # improves debugging traces
endif()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@
namespace nil {
namespace blueprint {

constexpr static const
inline constexpr const
boost::multiprecision::number<
boost::multiprecision::backends::cpp_int_modular_backend<257>> zkevm_modulus =
0x10000000000000000000000000000000000000000000000000000000000000000_cppui_modular257;

constexpr static const boost::multiprecision::backends::modular_params<
inline constexpr const boost::multiprecision::backends::modular_params<
boost::multiprecision::backends::cpp_int_modular_backend<257>>
zkevm_modular_params = zkevm_modulus.backend();

Expand Down
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions proof-producer.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
boost,
gdb,
lldb,
protobuf,
cmake_modules,
enableDebugging,
enableDebug ? false,
Expand All @@ -19,14 +20,14 @@ in stdenv.mkDerivation {
src = lib.sourceByRegex ./. ["^proof-producer(/.*)?$" "^crypto3(/.*)?$" "^parallel-crypto3(/.*)?$" "CMakeLists.txt"];
hardeningDisable = [ "fortify" ];

nativeBuildInputs = [ cmake ninja pkg-config ] ++
nativeBuildInputs = [ cmake ninja pkg-config protobuf ] ++
(lib.optional (!stdenv.isDarwin) gdb) ++
(lib.optional (stdenv.isDarwin) lldb);

# enableDebugging will keep debug symbols in boost
propagatedBuildInputs = [ (if enableDebug then (enableDebugging boost) else boost) ];

buildInputs = [cmake_modules ];
buildInputs = [ cmake_modules ];

cmakeFlags =
[
Expand Down
4 changes: 2 additions & 2 deletions proof-producer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

cmake_minimum_required(VERSION 3.22 FATAL_ERROR)

if(DEFINED CMAKE_BUILD_TYPE AND ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
if(DEFINED CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL "Debug")
set(ZK_PLACEHOLDER_DEBUG_ENABLED TRUE)
endif()

Expand All @@ -26,7 +26,7 @@ cm_project(proof-producer WORKSPACE_NAME ${CMAKE_WORKSPACE_NAME} LANGUAGES CXX)
# If Nix is used, LSP could not guess the locations of implicit include
# directories, so we need to include them explicitly.
if(CMAKE_EXPORT_COMPILE_COMMANDS)
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
endif()

Expand Down
32 changes: 31 additions & 1 deletion proof-producer/bin/proof-producer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
include(CMDeploy)
include(CMSetupVersion)

find_package(Protobuf REQUIRED)
find_package(absl REQUIRED)

if (CPACK_PACKAGE_VERSION)
add_compile_definitions(PROOF_GENERATOR_VERSION=${CPACK_PACKAGE_VERSION})
endif()
Expand All @@ -38,6 +41,7 @@ function(setup_proof_generator_target)
add_executable(${ARG_TARGET_NAME}
src/arg_parser.cpp
src/main.cpp
${PROTO_SRC}
)

add_library(${ARG_TARGET_NAME}-lib INTERFACE)
Expand All @@ -58,10 +62,12 @@ function(setup_proof_generator_target)
target_include_directories(${ARG_TARGET_NAME}-lib INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
${PROTOBUF_INCLUDE_DIR}
)

target_link_libraries(${ARG_TARGET_NAME}-lib INTERFACE ${INTERFACE_LIBS})
target_link_libraries(${ARG_TARGET_NAME} PRIVATE ${ARG_TARGET_NAME}-lib Boost::program_options)
# absl is required for protobuf
target_link_libraries(${ARG_TARGET_NAME} PRIVATE ${ARG_TARGET_NAME}-lib Boost::program_options absl::log_internal_check_op crypto3::blueprint ${PROTOBUF_LIBRARY})

target_include_directories(${ARG_TARGET_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
Expand All @@ -81,6 +87,30 @@ function(setup_proof_generator_target)

endfunction()

file(GLOB PROTO_FILES "proto/*.proto")

foreach(PROTO_FILE ${PROTO_FILES})
get_filename_component(PROTO_NAME_WE ${PROTO_FILE} NAME_WE)
get_filename_component(PROTO_DIR ${PROTO_FILE} DIRECTORY)

set(OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/nil/proof-generator")
set(PROTO_HDR "${OUTPUT_DIR}/${PROTO_NAME_WE}.pb.h")
set(PROTO_SRC "${OUTPUT_DIR}/${PROTO_NAME_WE}.pb.cc")

add_custom_command(
OUTPUT ${PROTO_HDR} ${PROTO_SRC}
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out=${OUTPUT_DIR} --proto_path ${PROTO_DIR} ${PROTO_FILE}
DEPENDS ${PROTO_FILE}
COMMENT "Generating ${PROTO_SRC} and ${PROTO_HDR} from ${PROTO_FILE}"
VERBATIM

)

list(APPEND GENERATED_SOURCES ${PROTO_SRC})
list(APPEND GENERATED_HEADERS ${PROTO_HDR})
endforeach()

set(SINGLE_THREADED_TARGET "${CURRENT_PROJECT_NAME}-single-threaded")
setup_proof_generator_target(TARGET_NAME ${SINGLE_THREADED_TARGET} ADDITIONAL_DEPENDENCIES crypto3::all)
set(MULTI_THREADED_TARGET "${CURRENT_PROJECT_NAME}-multi-threaded")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
namespace nil {
namespace proof_generator {
inline bool is_valid_path(const std::string& path) {
if (path.empty()) {
BOOST_LOG_TRIVIAL(error) << "Provided file path is empty.";
return false;
}

if (path.length() >= PATH_MAX) {
BOOST_LOG_TRIVIAL(error) << path << ": file path is too long. Maximum allowed length is " << PATH_MAX
<< " characters.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@

#include <nil/blueprint/transpiler/recursive_verifier_generator.hpp>


#include <nil/proof-generator/arithmetization_params.hpp>
#include <nil/proof-generator/file_operations.hpp>

#include <nil/proof-generator/traces_reader.hpp>

namespace nil {
namespace proof_generator {
namespace detail {
Expand Down Expand Up @@ -102,18 +103,20 @@ namespace nil {
}

enum class ProverStage {
ALL = 0,
PREPROCESS = 1,
PROVE = 2,
VERIFY = 3,
GENERATE_AGGREGATED_CHALLENGE = 4,
GENERATE_PARTIAL_PROOF = 5,
COMPUTE_COMBINED_Q = 6,
GENERATE_AGGREGATED_FRI_PROOF = 7,
GENERATE_CONSISTENCY_CHECKS_PROOF = 8,
MERGE_PROOFS = 9
ALL,
PREPROCESS,
PROVE,
VERIFY,
GENERATE_AGGREGATED_CHALLENGE,
GENERATE_PARTIAL_PROOF,
COMPUTE_COMBINED_Q,
GENERATE_AGGREGATED_FRI_PROOF,
GENERATE_CONSISTENCY_CHECKS_PROOF,
MERGE_PROOFS,
READ_TRACES
};

// TODO: make it another macro in parser for two-way conversion
ProverStage prover_stage_from_string(const std::string& stage) {
static std::unordered_map<std::string, ProverStage> stage_map = {
{"all", ProverStage::ALL},
Expand All @@ -125,7 +128,8 @@ namespace nil {
{"compute-combined-Q", ProverStage::COMPUTE_COMBINED_Q},
{"merge-proofs", ProverStage::MERGE_PROOFS},
{"aggregated-FRI", ProverStage::GENERATE_AGGREGATED_FRI_PROOF},
{"consistency-checks", ProverStage::GENERATE_CONSISTENCY_CHECKS_PROOF}
{"consistency-checks", ProverStage::GENERATE_CONSISTENCY_CHECKS_PROOF},
{"read-traces", ProverStage::READ_TRACES}
};
auto it = stage_map.find(stage);
if (it == stage_map.end()) {
Expand Down Expand Up @@ -462,6 +466,18 @@ namespace nil {
return true;
}

bool read_execution_traces_from_file(boost::filesystem::path execution_traces_file_path) {
BOOST_LOG_TRIVIAL(info) << "Read execution traces from " << execution_traces_file_path;

auto traces = deserialize_traces_from_file(execution_traces_file_path);
if (!traces) {
return false;
}
execution_traces_.emplace(*traces);

return true;
}

bool verify(const Proof& proof) const {
BOOST_LOG_TRIVIAL(info) << "Verifying proof...";
bool verification_result =
Expand Down Expand Up @@ -972,6 +988,7 @@ namespace nil {
std::optional<TableDescription> table_description_;
std::optional<ConstraintSystem> constraint_system_;
std::optional<AssignmentTable> assignment_table_;
std::optional<ExecutionTraces> execution_traces_;
std::optional<LpcScheme> lpc_scheme_;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include <fstream>
#include <vector>
#include <string>
#include <cstdint>
#include <unordered_map>

#include <nil/blueprint/zkevm/zkevm_word.hpp>

#include <nil/proof-generator/meta_utils.hpp>
#include <nil/proof-generator/traces.pb.h>


namespace nil {
namespace proof_generator {

struct StackOp {
bool is_read;
int idx;
blueprint::zkevm_word_type value;
std::byte op_code;
};

struct MemoryOp {
bool is_read;
int idx;
std::byte value;
std::byte op_code;
};

struct ExecutionTraces {
std::vector<StackOp> stack_ops;
std::vector<MemoryOp> memory_ops;
std::unordered_map<std::string, std::vector<std::vector<std::byte>>> storage_proofs;
std::vector<std::byte> executed_op_codes;
};

// Convert protobuf Uint256 to zkevm_word_type
[[nodiscard]] blueprint::zkevm_word_type proto_uint256_to_zkevm_word(const pb::Uint256& pb_uint) {
blueprint::zkevm_word_type result = 0;
for (size_t i = 0; i < pb_uint.word_parts_size() && i < 4; i++) {
result |= (static_cast<blueprint::zkevm_word_type>(pb_uint.word_parts(i)) << (i * 64));
}
return result;
}

// Convert protobuf Proof to vector of bytes
[[nodiscard]] std::vector<std::byte> proto_proof_to_cpp(const pb::Proof& pb_proof) {
const auto& data = pb_proof.proof_data();
return std::vector<std::byte>(
reinterpret_cast<const std::byte*>(data.data()),
reinterpret_cast<const std::byte*>(data.data() + data.size())
);
}

[[nodiscard]] std::optional<pb::ExecutionTraces> read_pb_traces_from_file(const boost::filesystem::path& filename) {
if (!is_valid_path(filename.c_str()) || !can_read_from_file(filename.c_str())) {
return std::nullopt;
}

auto file = open_file<std::ifstream>(filename.c_str(), std::ios::in | std::ios::binary);
if (!file) {
return std::nullopt;
}

pb::ExecutionTraces pb_traces;
if (!pb_traces.ParseFromIstream(&*file)) {
return std::nullopt;
}

return pb_traces;
}

[[nodiscard]] std::optional<ExecutionTraces> deserialize_traces_from_file(const boost::filesystem::path& filename) {
const auto pb_traces = read_pb_traces_from_file(filename);
if (!pb_traces) {
return std::nullopt;
}

ExecutionTraces traces;

// Convert stack operations
traces.stack_ops.reserve(pb_traces->stack_ops_size());
for (const auto& pb_sop : pb_traces->stack_ops()) {
traces.stack_ops.push_back(StackOp{
/*is_read=*/ pb_sop.is_read(),
/*idx=*/ static_cast<int>(pb_sop.index()),
/*value=*/ proto_uint256_to_zkevm_word(pb_sop.value()),
/*op_code=*/ static_cast<std::byte>(pb_sop.op_code())
});
}

// Convert memory operations
traces.memory_ops.reserve(pb_traces->memory_ops_size());
for (const auto& pb_mop : pb_traces->memory_ops()) {
traces.memory_ops.push_back(MemoryOp{
/*is_read=*/ pb_mop.is_read(),
/*idx=*/ static_cast<int>(pb_mop.index()),
/*value=*/ static_cast<std::byte>(pb_mop.value()[0]),
/*op_code=*/ static_cast<std::byte>(pb_mop.op_code())
});
}

// Convert storage proofs
for (const auto& [addr_hex, pb_traces_addr] : pb_traces->storage_proofs_by_address()) {
auto& proofs = traces.storage_proofs[addr_hex];
proofs.reserve(pb_traces_addr.proof_list_size());

for (const auto& pb_proof : pb_traces_addr.proof_list()) {
proofs.push_back(proto_proof_to_cpp(pb_proof));
}
}

// Read executed op codes
traces.executed_op_codes.reserve(pb_traces->executed_op_codes_size());
const auto& executed_op_codes = pb_traces->executed_op_codes();
std::transform(executed_op_codes.begin(), executed_op_codes.end(), traces.executed_op_codes.begin(), [](auto elem) {
return static_cast<std::byte>(elem);
});

return traces;
}

} // namespace proof_generator
} // namespace nil
Loading

0 comments on commit 6c6d726

Please sign in to comment.