mirror of
https://github.com/logos-blockchain/logos-blockchain-circuits.git
synced 2026-05-18 23:39:47 +00:00
Remove incompatible C ABI things.
This commit is contained in:
parent
505048bc3b
commit
5946705b1c
83
src/ffi.cpp
83
src/ffi.cpp
@ -2,6 +2,8 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@ -19,21 +21,86 @@ json::value_t check_type(std::string prefix, json in);
|
||||
void qualify_input(std::string prefix, json& in, json& in1);
|
||||
void qualify_input_list(std::string prefix, json& in, json& in1);
|
||||
|
||||
// -------------------------------------------------------------
|
||||
|
||||
// ---- File-based entry point (wraps circom-generated main) ----
|
||||
|
||||
extern "C" int generate_witness_from_files(const char* dat, const char* inputs, const char* output) {
|
||||
static status::Status validate_generate_witness_from_files_input(const char* dat, const char* inputs, const char* output) {
|
||||
if (dat == nullptr) {
|
||||
return status::Status{status::StatusCode::InvalidInput, "dat is null"};
|
||||
}
|
||||
if (inputs == nullptr) {
|
||||
return status::Status{status::StatusCode::InvalidInput, "inputs is null"};
|
||||
}
|
||||
if (output == nullptr) {
|
||||
return status::Status{status::StatusCode::InvalidInput, "output is null"};
|
||||
}
|
||||
return status::ok();
|
||||
}
|
||||
|
||||
extern "C" status::Status generate_witness_from_files(const char* dat, const char* inputs, const char* output) {
|
||||
const status::Status status = validate_generate_witness_from_files_input(dat, inputs, output);
|
||||
if (is_error(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
char* argv[] = {
|
||||
(char*)dat,
|
||||
(char*)inputs,
|
||||
(char*)output,
|
||||
const_cast<char*>(dat),
|
||||
const_cast<char*>(inputs),
|
||||
const_cast<char*>(output),
|
||||
nullptr
|
||||
};
|
||||
return main(3, argv);
|
||||
const int code = main(3, argv);
|
||||
|
||||
if (code == 0) {
|
||||
return status::ok();
|
||||
}
|
||||
return status::from_code(status::StatusCode::DynError);
|
||||
}
|
||||
|
||||
// ---- Memory-based entry point ----
|
||||
|
||||
extern "C" int generate_witness(const WitnessInput input, Bytes* output) {
|
||||
// TODO
|
||||
return 0;
|
||||
static status::Status validate_witness_input(const WitnessInput* input, const Bytes* output) {
|
||||
if (output == nullptr) {
|
||||
return status::Status{status::StatusCode::InvalidInput, "output is null"};
|
||||
}
|
||||
if (output->data != nullptr) {
|
||||
return status::Status{status::StatusCode::InvalidInput, "output.data is not null"};
|
||||
}
|
||||
|
||||
if (input == nullptr) {
|
||||
return status::Status{status::StatusCode::InvalidInput, "input is null"};
|
||||
}
|
||||
if (input->dat.data == nullptr) {
|
||||
return status::Status{status::StatusCode::InvalidInput, "input.dat.data is null"};
|
||||
}
|
||||
if (input->dat.size == 0) {
|
||||
return status::Status{status::StatusCode::InvalidInput, "input.dat.size is zero"};
|
||||
}
|
||||
if (input->inputs_json == nullptr) {
|
||||
return status::Status{status::StatusCode::InvalidInput, "input.inputs_json is null"};
|
||||
}
|
||||
return status::ok();
|
||||
}
|
||||
|
||||
extern "C" status::Status generate_witness(const WitnessInput* input, Bytes* output) {
|
||||
const status::Status status = validate_witness_input(input, output);
|
||||
if (is_error(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// TODO: Implement the actual witness generation logic using the provided input data.
|
||||
const uint8_t dummy_witness[] = {0, 1, 2, 3}; // Placeholder for actual witness data
|
||||
|
||||
const size_t witness_size = sizeof(dummy_witness);
|
||||
uint8_t* witness_data = static_cast<uint8_t*>(malloc(witness_size));
|
||||
if (witness_data == nullptr) {
|
||||
return status::Status{status::StatusCode::OutOfMemory, "Failed to allocate witness memory"};
|
||||
}
|
||||
std::copy(dummy_witness, dummy_witness + witness_size, witness_data);
|
||||
|
||||
output->data = witness_data;
|
||||
output->size = witness_size;
|
||||
|
||||
return status::ok();
|
||||
}
|
||||
|
||||
22
src/ffi.hpp
22
src/ffi.hpp
@ -21,20 +21,30 @@ extern "C" {
|
||||
///
|
||||
/// - `dat`: Path to the .dat file. Must be extensionless.
|
||||
/// - `inputs`: Path to the inputs file for the circuit. Must be a JSON file.
|
||||
/// - `output`: Path where the output witness file will be written.
|
||||
int generate_witness_from_files(const char* dat, const char* inputs, const char* output);
|
||||
/// - `output`: Path to the output file where the witness will be written.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// On success, returns a `Status` with `StatusCode::Ok` and writes the witness to the specified output file.
|
||||
/// On failure, returns a `Status` with an appropriate error code.
|
||||
status::Status generate_witness_from_files(const char* dat, const char* inputs, const char* output);
|
||||
|
||||
/// Generates a witness from in-memory buffers.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `input`: The `WitnessInput` struct containing the circuit information.
|
||||
/// - `output`: On success, this will be populated with the generated witness bytes.
|
||||
/// The caller is responsible for freeing this buffer.
|
||||
int generate_witness(const WitnessInput input, Bytes* output);
|
||||
/// - `output`: Pointer to a `Bytes` struct that will be populated with the generated witness bytes.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// On success, returns a `Status` with `StatusCode::Ok` and populates `output` with the generated witness bytes. The
|
||||
/// caller is responsible for freeing the memory allocated for `output.data`.
|
||||
/// On failure, returns a `Status` with an appropriate error code, and `output` will not be modified.
|
||||
status::Status generate_witness(const WitnessInput* input, Bytes* output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FFI_HPP
|
||||
#endif
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
#ifndef TYPES_HPP
|
||||
#define TYPES_HPP
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
/// A pointer to a contiguous sequence of elements with a known length.
|
||||
///
|
||||
@ -24,71 +23,35 @@ using Bytes = Slice<uint8_t>;
|
||||
/// Immutable byte buffer.
|
||||
using ConstBytes = Slice<const uint8_t>;
|
||||
|
||||
namespace result {
|
||||
namespace status_code {
|
||||
/// Represents the outcome of an operation.
|
||||
enum StatusCode {
|
||||
Ok = 0,
|
||||
InvalidInput = 1,
|
||||
};
|
||||
namespace status {
|
||||
/// Represents the outcome of an operation.
|
||||
enum StatusCode {
|
||||
Ok = 0,
|
||||
DynError = 1,
|
||||
InvalidInput = 2,
|
||||
OutOfMemory = 3,
|
||||
};
|
||||
|
||||
inline bool is_ok(const StatusCode code) {
|
||||
return code == Ok;
|
||||
}
|
||||
|
||||
inline bool is_error(const StatusCode code) {
|
||||
return code != Ok;
|
||||
}
|
||||
inline bool is_ok(const StatusCode code) {
|
||||
return code == Ok;
|
||||
}
|
||||
|
||||
using StatusCode = status_code::StatusCode;
|
||||
inline bool is_error(const StatusCode code) {
|
||||
return !is_ok(code);
|
||||
}
|
||||
|
||||
/// A status code with an optional human-readable description.
|
||||
struct Status {
|
||||
StatusCode code;
|
||||
const char* message = nullptr;
|
||||
|
||||
Status() : code(StatusCode::Ok) {}
|
||||
explicit Status(const StatusCode code) : code(code) {}
|
||||
Status(const StatusCode code, const char* message) : code(code), message(message) {}
|
||||
|
||||
bool is_ok() const { return status_code::is_ok(code); }
|
||||
bool is_error() const { return status_code::is_error(code); }
|
||||
const char* message;
|
||||
};
|
||||
|
||||
/// A result type that encapsulates either a successful value of type `T` or an error status.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// There's no distinction between the `Ok` and `Error` variants at the type level.
|
||||
/// Instead, the `status` field indicates whether the result is successful or an error.
|
||||
/// Consumers are responsible for checking the status before accessing the value.
|
||||
template<typename T>
|
||||
struct Result {
|
||||
/// The result value. Undefined behavior if `is_error()`.
|
||||
T value;
|
||||
Status status;
|
||||
inline Status from_code(const StatusCode code) { return Status { code, nullptr }; }
|
||||
inline Status ok() { return from_code(Ok); }
|
||||
|
||||
static Result ok(T value) { return Result{value, Status{}}; }
|
||||
/// Constructs an error result with a fallback value for non-default-constructible `T`.
|
||||
static Result error(const T fallback, const Status status) {
|
||||
assert(status.is_error() && "Result::error() called with Ok status.");
|
||||
return Result{fallback, status};
|
||||
}
|
||||
/// Constructs an error result. Requires `T` to be default-constructible.
|
||||
static Result error(const Status status) {
|
||||
return Result::error(T{}, status);
|
||||
}
|
||||
/// Constructs an error result from a status code. Requires `T` to be default-constructible.
|
||||
static Result error(const StatusCode status_code) {
|
||||
const Status status{status_code};
|
||||
return Result::error(status);
|
||||
}
|
||||
Result(T value, const Status status) : value(value), status(status) {}
|
||||
inline bool is_ok(const Status status) { return is_ok(status.code); }
|
||||
inline bool is_error(const Status status) { return is_error(status.code); }
|
||||
|
||||
bool is_ok() const { return status.is_ok(); }
|
||||
bool is_error() const { return status.is_error(); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TYPES_HPP
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user