mirror of
https://github.com/logos-blockchain/logos-blockchain-circuits.git
synced 2026-07-05 16:39:29 +00:00
Fix memory leak
This commit is contained in:
parent
523091e17c
commit
969d9e2cda
@ -4,6 +4,17 @@
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <mutex>
|
||||
|
||||
Circom_Circuit* getCachedCircuit(const ConstBytes& circuit_bytes) {
|
||||
// The circuit is immutable, compiled-in data and has no destructor that
|
||||
// frees its internal buffers, so load it once and keep it for the process
|
||||
// lifetime instead of allocating (and leaking) it on every call.
|
||||
static Circom_Circuit* cached = nullptr;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&]() { cached = loadCircuit(circuit_bytes); });
|
||||
return cached;
|
||||
}
|
||||
|
||||
Circom_Circuit* loadCircuit(const ConstBytes& circuit_bytes) {
|
||||
Circom_Circuit* circuit = new Circom_Circuit;
|
||||
|
||||
@ -7,6 +7,16 @@
|
||||
|
||||
// Return value
|
||||
Circom_Circuit* loadCircuit(const ConstBytes& circuit);
|
||||
|
||||
// Returns a process-wide, lazily-loaded circuit for this library.
|
||||
//
|
||||
// `loadCircuit` allocates the circuit's internal buffers (input hash map,
|
||||
// witness->signal list, constants, IO field defs) but `Circom_Circuit` has no
|
||||
// destructor, so `delete circuit` leaks all of them. The circuit is immutable
|
||||
// data derived from the compiled-in `.dat`, so we load it exactly once and
|
||||
// reuse it for every (including concurrent) witness-generation call.
|
||||
Circom_Circuit* getCachedCircuit(const ConstBytes& circuit);
|
||||
|
||||
void loadJson(Circom_CalcWit *ctx, const char* inputs_json);
|
||||
void writeBinWitness(Circom_CalcWit *ctx, Bytes* output_witness);
|
||||
|
||||
|
||||
@ -89,26 +89,23 @@ static Status validate_witness_arguments(const WitnessInput* input, const Bytes*
|
||||
static Status generate_witness_impl(const WitnessInput* input, Bytes* output) {
|
||||
const ConstBytes& circuit_bytes = input->dat;
|
||||
|
||||
Circom_Circuit* circuit = loadCircuit(circuit_bytes);
|
||||
Circom_Circuit* circuit = getCachedCircuit(circuit_bytes);
|
||||
Circom_CalcWit* ctx = new Circom_CalcWit(circuit);
|
||||
|
||||
try {
|
||||
loadJson(ctx, input->inputs_json);
|
||||
} catch (...) {
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
throw;
|
||||
}
|
||||
if (ctx->getRemaingInputsToBeSet()!=0) {
|
||||
const std::string message = "Not all inputs have been set. Only " + std::to_string(get_main_input_signal_no()-ctx->getRemaingInputsToBeSet()) + " out of " + std::to_string(get_main_input_signal_no()) + ".";
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
return status_new(StatusCode_InvalidInput, message.c_str());
|
||||
}
|
||||
|
||||
writeBinWitness(ctx, output);
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
@ -89,26 +89,23 @@ static Status validate_witness_arguments(const WitnessInput* input, const Bytes*
|
||||
static Status generate_witness_impl(const WitnessInput* input, Bytes* output) {
|
||||
const ConstBytes& circuit_bytes = input->dat;
|
||||
|
||||
Circom_Circuit* circuit = loadCircuit(circuit_bytes);
|
||||
Circom_Circuit* circuit = getCachedCircuit(circuit_bytes);
|
||||
Circom_CalcWit* ctx = new Circom_CalcWit(circuit);
|
||||
|
||||
try {
|
||||
loadJson(ctx, input->inputs_json);
|
||||
} catch (...) {
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
throw;
|
||||
}
|
||||
if (ctx->getRemaingInputsToBeSet()!=0) {
|
||||
const std::string message = "Not all inputs have been set. Only " + std::to_string(get_main_input_signal_no()-ctx->getRemaingInputsToBeSet()) + " out of " + std::to_string(get_main_input_signal_no()) + ".";
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
return status_new(StatusCode_InvalidInput, message.c_str());
|
||||
}
|
||||
|
||||
writeBinWitness(ctx, output);
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
@ -89,26 +89,23 @@ static Status validate_witness_arguments(const WitnessInput* input, const Bytes*
|
||||
static Status generate_witness_impl(const WitnessInput* input, Bytes* output) {
|
||||
const ConstBytes& circuit_bytes = input->dat;
|
||||
|
||||
Circom_Circuit* circuit = loadCircuit(circuit_bytes);
|
||||
Circom_Circuit* circuit = getCachedCircuit(circuit_bytes);
|
||||
Circom_CalcWit* ctx = new Circom_CalcWit(circuit);
|
||||
|
||||
try {
|
||||
loadJson(ctx, input->inputs_json);
|
||||
} catch (...) {
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
throw;
|
||||
}
|
||||
if (ctx->getRemaingInputsToBeSet()!=0) {
|
||||
const std::string message = "Not all inputs have been set. Only " + std::to_string(get_main_input_signal_no()-ctx->getRemaingInputsToBeSet()) + " out of " + std::to_string(get_main_input_signal_no()) + ".";
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
return status_new(StatusCode_InvalidInput, message.c_str());
|
||||
}
|
||||
|
||||
writeBinWitness(ctx, output);
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
@ -89,26 +89,23 @@ static Status validate_witness_arguments(const WitnessInput* input, const Bytes*
|
||||
static Status generate_witness_impl(const WitnessInput* input, Bytes* output) {
|
||||
const ConstBytes& circuit_bytes = input->dat;
|
||||
|
||||
Circom_Circuit* circuit = loadCircuit(circuit_bytes);
|
||||
Circom_Circuit* circuit = getCachedCircuit(circuit_bytes);
|
||||
Circom_CalcWit* ctx = new Circom_CalcWit(circuit);
|
||||
|
||||
try {
|
||||
loadJson(ctx, input->inputs_json);
|
||||
} catch (...) {
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
throw;
|
||||
}
|
||||
if (ctx->getRemaingInputsToBeSet()!=0) {
|
||||
const std::string message = "Not all inputs have been set. Only " + std::to_string(get_main_input_signal_no()-ctx->getRemaingInputsToBeSet()) + " out of " + std::to_string(get_main_input_signal_no()) + ".";
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
return status_new(StatusCode_InvalidInput, message.c_str());
|
||||
}
|
||||
|
||||
writeBinWitness(ctx, output);
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user