Skip to content

Commit

Permalink
prover_server: clean up flags and output. addresses #242
Browse files Browse the repository at this point in the history
  • Loading branch information
dtebbs committed Aug 25, 2020
1 parent c2e6eca commit 6ddddec
Showing 1 changed file with 84 additions and 90 deletions.
174 changes: 84 additions & 90 deletions prover_server/prover_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,50 +41,35 @@ using circuit_wrapper = libzeth::circuit_wrapper<
namespace proto = google::protobuf;
namespace po = boost::program_options;

static void serialize_setup_to_file(
const typename snark::keypair &keypair,
boost::filesystem::path setup_path = "")
static snark::keypair load_keypair(const boost::filesystem::path &keypair_file)
{
if (setup_path.empty()) {
setup_path = libzeth::get_path_to_setup_directory();
}

const boost::filesystem::path path_vk_json = setup_path / "vk.json";
const boost::filesystem::path path_vk_raw = setup_path / "vk.raw";
const boost::filesystem::path path_pk_raw = setup_path / "pk.raw";

const typename snark::proving_key &proving_key = keypair.pk;
const typename snark::verification_key &verification_key = keypair.vk;
std::ifstream in_s(
keypair_file.c_str(), std::ios_base::in | std::ios_base::binary);
in_s.exceptions(
std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit);
return snark::keypair_read_bytes(in_s);
}

// Write the verification key in json format
{
std::ofstream vk_json_s(path_vk_json.c_str());
snark::verification_key_write_json(verification_key, vk_json_s);
}
static void write_keypair(
const typename snark::keypair &keypair,
const boost::filesystem::path &keypair_file)
{
std::ofstream out_s(
keypair_file.c_str(), std::ios_base::out | std::ios_base::binary);
snark::keypair_write_bytes(keypair, out_s);
}

// Write the verification and proving keys in raw format
{
std::ofstream vk_bytes_s(path_vk_raw.c_str());
snark::verification_key_write_bytes(verification_key, vk_bytes_s);
}
{
std::ofstream pk_bytes_s(path_pk_raw.c_str());
snark::proving_key_write_bytes(proving_key, pk_bytes_s);
}
static void write_constraint_system(
const circuit_wrapper &prover, const boost::filesystem::path &r1cs_file)
{
std::ofstream r1cs_stream(r1cs_file.c_str());
libzeth::r1cs_write_json<pp>(prover.get_constraint_system(), r1cs_stream);
}

static void write_ext_proof_to_file(
const libzeth::extended_proof<pp, snark> &ext_proof,
boost::filesystem::path proof_path = "")
boost::filesystem::path proof_path)
{
if (proof_path.empty()) {
// Used for debugging
const boost::filesystem::path tmp_path =
libzeth::get_path_to_debug_directory();
proof_path = tmp_path / "proof_and_inputs.json";
}

std::cout << "[DEBUG] Writing extended proof to" << proof_path << std::endl;
std::ofstream os(proof_path.c_str());
ext_proof.write_json(os);
}
Expand All @@ -100,10 +85,15 @@ class prover_server final : public zeth_proto::Prover::Service
// The keypair is the result of the setup. Store a copy internally.
snark::keypair keypair;

// Optional file to write proofs into (for debugging).
boost::filesystem::path proof_output_file;

public:
explicit prover_server(
circuit_wrapper &prover, const snark::keypair &keypair)
: prover(prover), keypair(keypair)
circuit_wrapper &prover,
const snark::keypair &keypair,
const boost::filesystem::path &proof_output_file)
: prover(prover), keypair(keypair), proof_output_file(proof_output_file)
{
}

Expand Down Expand Up @@ -210,7 +200,11 @@ class prover_server final : public zeth_proto::Prover::Service
ext_proof.write_json(std::cout);

// Write a copy of the proof for debugging.
write_ext_proof_to_file(ext_proof);
if (!proof_output_file.empty()) {
std::cout << "[DEBUG] Writing extended proof to "
<< proof_output_file << "\n";
write_ext_proof_to_file(ext_proof, proof_output_file);
}

std::cout << "[DEBUG] Preparing response..." << std::endl;
api_handler::extended_proof_to_proto(ext_proof, proof);
Expand Down Expand Up @@ -264,12 +258,14 @@ void display_server_start_message()
}

static void RunServer(
circuit_wrapper &prover, const typename snark::keypair &keypair)
circuit_wrapper &prover,
const typename snark::keypair &keypair,
const boost::filesystem::path &proof_output_file)
{
// Listen for incoming connections on 0.0.0.0:50051
std::string server_address("0.0.0.0:50051");

prover_server service(prover, keypair);
prover_server service(prover, keypair, proof_output_file);

grpc::ServerBuilder builder;

Expand All @@ -282,36 +278,31 @@ static void RunServer(

// Finally assemble the server.
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
std::cout << "[DEBUG] Server listening on " << server_address << std::endl;
std::cout << "[INFO] Server listening on " << server_address << "\n";

// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
display_server_start_message();
server->Wait();
}

#ifdef ZETH_SNARK_GROTH16
static snark::keypair load_keypair(const std::string &keypair_file)
{
std::ifstream in(keypair_file, std::ios_base::in | std::ios_base::binary);
in.exceptions(
std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit);
return snark::keypair_read_bytes(in);
}
#endif

int main(int argc, char **argv)
{
// Options
po::options_description options("");
options.add_options()(
"keypair,k", po::value<std::string>(), "file to load keypair from");
#ifdef DEBUG
"keypair,k",
po::value<std::string>(),
"file to load keypair from. If it doesn't exist, a new keypair will be "
"generated and written to this file. (defaults to [");
options.add_options()(
"jr1cs,j",
"r1cs,r",
po::value<boost::filesystem::path>(),
"file in which to export the r1cs in json format");
#endif
"file in which to export the r1cs (in json format)");
options.add_options()(
"proof-output,p",
po::value<boost::filesystem::path>(),
"(DEBUG) file to write generated proofs into");

auto usage = [&]() {
std::cout << "Usage:"
Expand All @@ -322,10 +313,9 @@ int main(int argc, char **argv)
std::cout << std::endl;
};

std::string keypair_file;
#ifdef DEBUG
boost::filesystem::path jr1cs_file;
#endif
boost::filesystem::path keypair_file;
boost::filesystem::path r1cs_file;
boost::filesystem::path proof_output_file;
try {
po::variables_map vm;
po::store(
Expand All @@ -335,56 +325,60 @@ int main(int argc, char **argv)
return 0;
}
if (vm.count("keypair")) {
keypair_file = vm["keypair"].as<std::string>();
keypair_file = vm["keypair"].as<boost::filesystem::path>();
}
if (vm.count("r1cs")) {
r1cs_file = vm["r1cs"].as<boost::filesystem::path>();
}
#ifdef DEBUG
if (vm.count("jr1cs")) {
jr1cs_file = vm["jr1cs"].as<boost::filesystem::path>();
if (vm.count("proof-output")) {
proof_output_file =
vm["proof-output"].as<boost::filesystem::path>();
}
#endif
} catch (po::error &error) {
std::cerr << " ERROR: " << error.what() << std::endl;
usage();
return 1;
}

// We inititalize the curve parameters here
// Default keypair_file if none given
if (keypair_file.empty()) {
boost::filesystem::path setup_dir =
libzeth::get_path_to_setup_directory();
if (!setup_dir.empty()) {
boost::filesystem::create_directories(setup_dir);
}
keypair_file = setup_dir / "keypair.bin";
}

// Inititalize the curve parameters
std::cout << "[INFO] Init params" << std::endl;
pp::init_public_params();

// If the keypair file exists, load and use it, otherwise generate a new
// keypair and write it to the file.
circuit_wrapper prover;
snark::keypair keypair = [&keypair_file, &prover]() {
if (!keypair_file.empty()) {
#ifdef ZETH_SNARK_GROTH16
std::cout << "[INFO] Loading keypair: " << keypair_file
<< std::endl;
if (boost::filesystem::exists(keypair_file)) {
std::cout << "[INFO] Loading keypair: " << keypair_file << "\n";
return load_keypair(keypair_file);
#else
std::cout << "Keypair loading not supported in this config"
<< std::endl;
exit(1);
#endif
}

std::cout << "[INFO] Generate new keypair" << std::endl;
snark::keypair keypair = prover.generate_trusted_setup();

// Write the keypair to a file
serialize_setup_to_file(keypair);
std::cout << "[INFO] No keypair file " << keypair_file
<< ". Generating.\n";
const snark::keypair keypair = prover.generate_trusted_setup();
std::cout << "[INFO] Writing new keypair to " << keypair_file << "\n";
write_keypair(keypair, keypair_file);
return keypair;
}();

#ifdef DEBUG
// Run only if the flag is set
if (jr1cs_file.empty()) {
std::cout << "[DEBUG] Dump R1CS to json file" << std::endl;
std::ofstream jr1cs_stream(jr1cs_file.c_str());
libzeth::r1cs_write_json<pp>(
prover.get_constraint_system(), jr1cs_stream);
// If a file is given, export the JSON representation of the constraint
// system.
if (!r1cs_file.empty()) {
std::cout << "[INFO] Writing R1CS to " << r1cs_file << "\n";
write_constraint_system(prover, r1cs_file);
}
#endif

std::cout << "[INFO] Setup successful, starting the server..." << std::endl;
RunServer(prover, keypair);
RunServer(prover, keypair, proof_output_file);
return 0;
}

0 comments on commit 6ddddec

Please sign in to comment.