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

Keys router handler #12

Merged
merged 7 commits into from
Sep 8, 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
87 changes: 68 additions & 19 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -107,26 +107,74 @@ pub fn build(b: *std.Build) !void {
// **************************************************************
// for lsp build on save step
{
const exe = b.addExecutable(.{
.name = "coconut-mint",
.root_source_file = b.path("src/mint.zig"),
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("httpz", httpz_module);
exe.root_module.addImport("pg", pg.module("pg"));
exe.root_module.addImport("zul", zul);

// Add dependency modules to the executable.
for (deps) |mod| exe.root_module.addImport(
mod.name,
mod.module,
);

// These two lines you might want to copy
// (make sure to rename 'exe_check')
const check = b.step("check", "Check if foo compiles");
check.dependOn(&exe.step);
// mint binary
{
const exe = b.addExecutable(.{
.name = "mint",
.root_source_file = b.path("src/mint.zig"),
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("zul", zul);
exe.root_module.addImport("secp256k1", secp256k1.module("secp256k1"));
exe.root_module.linkLibrary(secp256k1.artifact("libsecp"));
exe.root_module.addImport("httpz", httpz_module);
exe.root_module.addImport("bitcoin", bitcoin_zig.module("bitcoin"));
exe.root_module.addImport("base58", base58_module);

exe.root_module.addImport("channels", channel_m);

// Add dependency modules to the executable.
for (deps) |mod| exe.root_module.addImport(
mod.name,
mod.module,
);

check.dependOn(&exe.step);
}
// main
{
const exe = b.addExecutable(.{
.name = "main",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("httpz", httpz_module);
exe.root_module.addImport("pg", pg.module("pg"));
exe.root_module.addImport("zul", zul);

// Add dependency modules to the executable.
for (deps) |mod| exe.root_module.addImport(
mod.name,
mod.module,
);

check.dependOn(&exe.step);
}

// tests
{
const lib_unit_tests = b.addTest(.{
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
.single_threaded = false,
});
lib_unit_tests.root_module.addImport("zul", zul);
lib_unit_tests.root_module.addImport("secp256k1", secp256k1.module("secp256k1"));
lib_unit_tests.root_module.linkLibrary(secp256k1.artifact("libsecp"));
lib_unit_tests.root_module.addImport("httpz", httpz_module);
lib_unit_tests.root_module.addImport("bitcoin", bitcoin_zig.module("bitcoin"));
lib_unit_tests.root_module.addImport("base58", base58_module);

lib_unit_tests.root_module.addImport("channels", channel_m);

const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);

check.dependOn(&run_lib_unit_tests.step);
}
}

// **************************************************************
Expand All @@ -144,6 +192,7 @@ pub fn build(b: *std.Build) !void {
exe.root_module.addImport("secp256k1", secp256k1.module("secp256k1"));
exe.root_module.linkLibrary(secp256k1.artifact("libsecp"));
exe.root_module.addImport("pg", pg.module("pg"));
exe.root_module.addImport("bitcoin", bitcoin_zig.module("bitcoin"));

// Add dependency modules to the executable.
for (deps) |mod| exe.root_module.addImport(
Expand Down
4 changes: 2 additions & 2 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
.hash = "12204099afd10139d640e1c5b5338c7434bf5d7bb8336728007f575b8b3a05821e96",
},
.httpz = .{
.url = "git+https://github.com/karlseguin/http.zig#7080d974aeee6438038ae7744509367317fdf5a0",
.hash = "1220f5faa5dd0ed08950e24ed1923e3a4ad1e431196c69e745098e4364de91ffcbc4",
.url = "git+https://github.com/karlseguin/http.zig#ece900d21a7ad3703f11ebd6ad5e340475c0f22b",
.hash = "122021aca176ac2393ac02448521f5ab5c942a68bce675d8b646a2361333bec5b328",
},
.pg = .{
.url = "https://github.com/karlseguin/pg.zig/archive/1491270ac43c7eba91992bb06b3758254c36e39a.zip",
Expand Down
86 changes: 78 additions & 8 deletions src/core/database/mint_memory.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,74 @@ pub const MintMemoryDatabase = struct {
mint_quotes: std.AutoHashMap([16]u8, MintQuote),
melt_quotes: std.AutoHashMap([16]u8, MeltQuote),
proofs: std.AutoHashMap([33]u8, nuts.Proof),
proof_state: std.AutoHashMap([33]u8, nuts.nut07.State),
proof_states: std.AutoHashMap([33]u8, nuts.nut07.State),
blinded_signatures: std.AutoHashMap([33]u8, nuts.BlindSignature),

allocator: std.mem.Allocator,

pub fn init(
/// initFrom - take own on all data there, except slices (only own data in slices)
pub fn initFrom(
allocator: std.mem.Allocator,
active_keysets: std.AutoHashMap(nuts.CurrencyUnit, nuts.Id),
keysets: []const MintKeySetInfo,
mint_quotes: []const MintQuote,
melt_quotes: []const MeltQuote,
pending_proofs: []const nuts.Proof,
spent_proofs: []const nuts.Proof,
blinded_signatures: std.AutoHashMap([33]u8, nuts.BlindSignature),
) !MintMemoryDatabase {
var proofs = std.AutoHashMap([33]u8, nuts.Proof).init(allocator);
errdefer proofs.deinit();

var proof_states = std.AutoHashMap([33]u8, nuts.nut07.State).init(allocator);
errdefer proof_states.deinit();

for (pending_proofs) |proof| {
const y = (try dhke.hashToCurve(proof.secret.toBytes())).serialize();
try proofs.put(y, proof);
try proof_states.put(y, .pending);
}

for (spent_proofs) |proof| {
const y = (try dhke.hashToCurve(proof.secret.toBytes())).serialize();
try proofs.put(y, proof);
try proof_states.put(y, .pending);
}

var _keysets = std.AutoHashMap(nuts.Id, MintKeySetInfo).init(allocator);
errdefer _keysets.deinit();

for (keysets) |ks| {
try _keysets.put(ks.id, ks);
}

var _mint_quotes = std.AutoHashMap([16]u8, MintQuote).init(allocator);
errdefer _mint_quotes.deinit();

for (mint_quotes) |q| {
try _mint_quotes.put(q.id, q);
}
var _melt_quotes = std.AutoHashMap([16]u8, MeltQuote).init(allocator);
errdefer _melt_quotes.deinit();

for (melt_quotes) |q| {
try _melt_quotes.put(q.id, q);
}

return .{
.allocator = allocator,
.lock = .{},
.active_keysets = active_keysets,
.keysets = _keysets,
.mint_quotes = _mint_quotes,
.melt_quotes = _melt_quotes,
.proofs = proofs,
.proof_states = proof_states,
.blinded_signatures = blinded_signatures,
};
}

pub fn initManaged(
allocator: std.mem.Allocator,
) !zul.Managed(Self) {
var arena = try allocator.create(std.heap.ArenaAllocator);
Expand Down Expand Up @@ -57,7 +119,7 @@ pub const MintMemoryDatabase = struct {
.mint_quotes = mint_quotes,
.melt_quotes = melt_quotes,
.proofs = proofs,
.proof_state = proof_state,
.proof_states = proof_state,
.blinded_signatures = blinded_signatures,
.allocator = arena.allocator(),
},
Expand All @@ -79,6 +141,14 @@ pub const MintMemoryDatabase = struct {
return self.active_keysets.get(unit);
}

/// caller own result data, so responsible to deallocate
pub fn getActiveKeysets(self: *Self, allocator: std.mem.Allocator) !std.AutoHashMap(nuts.CurrencyUnit, nuts.Id) {
self.lock.lockShared();
defer self.lock.unlockShared();
// key and value doesnt have heap data, so we can clone all map
return try self.active_keysets.cloneWithAllocator(allocator);
}

/// keyset inside is cloned, so caller own keyset
pub fn addKeysetInfo(self: *Self, keyset: MintKeySetInfo) !void {
self.lock.lock();
Expand Down Expand Up @@ -359,23 +429,23 @@ pub const MintMemoryDatabase = struct {
errdefer states.deinit();

for (ys) |y| {
const kv = try self.proof_state.fetchPut(y.serialize(), proof_state);
const kv = try self.proof_states.fetchPut(y.serialize(), proof_state);
states.appendAssumeCapacity(if (kv) |_kv| _kv.value else null);
}

return states;
}

// caller must free result
pub fn getProofsStates(self: *Self, allocator: std.mem.Allocator, ys: []secp256k1.PublicKey) !std.ArrayList(?nuts.nut07.State) {
pub fn getProofsStates(self: *Self, allocator: std.mem.Allocator, ys: []const secp256k1.PublicKey) !std.ArrayList(?nuts.nut07.State) {
self.lock.lockShared();
defer self.lock.unlockShared();

var states = try std.ArrayList(?nuts.nut07.State).initCapacity(allocator, ys.len);
errdefer states.deinit();

for (ys) |y| {
states.appendAssumeCapacity(self.proof_state.get(y.serialize()));
states.appendAssumeCapacity(self.proof_states.get(y.serialize()));
}

return states;
Expand Down Expand Up @@ -508,7 +578,7 @@ pub fn worker(m: *MintMemoryDatabase, unit: nuts.CurrencyUnit) !void {
}

test MintMemoryDatabase {
var db_arened = try MintMemoryDatabase.init(std.testing.allocator);
var db_arened = try MintMemoryDatabase.initManaged(std.testing.allocator);
defer db_arened.deinit();
var db = &db_arened.value;
var rnd = std.Random.DefaultPrng.init(std.testing.random_seed);
Expand Down Expand Up @@ -563,7 +633,7 @@ test MintMemoryDatabase {
}

test "multithread" {
var shared_data = try MintMemoryDatabase.init(std.testing.allocator);
var shared_data = try MintMemoryDatabase.initManaged(std.testing.allocator);
defer shared_data.deinit();

const thread1 = try std.Thread.spawn(.{
Expand Down
Loading
Loading