Skip to content

Commit

Permalink
http router handlers (#12)
Browse files Browse the repository at this point in the history
* getKeys handler + methods for this
* build zig check step improve
* get keys route + mint init method
* minimal server with keys method
* interrupt handler on posix
* some mint tests + missing methods
* keysets, keys and check state methods
  • Loading branch information
StringNick authored Sep 8, 2024
1 parent 1074273 commit 2fba954
Show file tree
Hide file tree
Showing 13 changed files with 924 additions and 40 deletions.
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

0 comments on commit 2fba954

Please sign in to comment.