Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
iskyd authored Sep 16, 2024
2 parents c143dae + 0937791 commit 5a9de3f
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 49 deletions.
47 changes: 42 additions & 5 deletions src/bip44.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ pub fn KeyPath(comptime depth: u8) type {

const Self = @This();

pub fn getStrCap(self: Self) usize {
pub fn getStrCap(self: Self, comptime maxDepth: ?u8) usize {
comptime {
if (maxDepth != null) {
assert(depth >= maxDepth.?);
}
}
var cap: usize = self.path.len - 1; // number of /
for (self.path, 0..) |d, i| {
cap += if (d != 0) std.math.log10(d) + 1 else 1;
Expand All @@ -27,13 +32,23 @@ pub fn KeyPath(comptime depth: u8) type {
if (i <= 2) {
cap += 1;
}
if (comptime maxDepth != null) {
if (maxDepth.? <= i + 2) {
break;
}
}
}

return cap;
}

pub fn toStr(self: Self, allocator: std.mem.Allocator) ![]u8 {
var buffer = try allocator.alloc(u8, self.getStrCap());
pub fn toStr(self: Self, allocator: std.mem.Allocator, comptime maxDepth: ?u8) ![]u8 {
comptime {
if (maxDepth != null) {
assert(depth >= maxDepth.?);
}
}
var buffer = try allocator.alloc(u8, self.getStrCap(maxDepth));
var current: usize = 0;
for (self.path, 0..) |d, i| {
const currentcap = if (d != 0) std.math.log10(d) + 1 else 1;
Expand All @@ -43,6 +58,13 @@ pub fn KeyPath(comptime depth: u8) type {
buffer[current] = '\'';
current += 1;
}

if (comptime maxDepth != null) {
if (maxDepth.? <= i + 1) {
break;
}
}

if (i < self.path.len - 1) {
buffer[current] = '/';
}
Expand Down Expand Up @@ -103,6 +125,7 @@ pub fn KeyPath(comptime depth: u8) type {
pub const Descriptor = struct {
extended_key: [111]u8,
keypath: KeyPath(3),
private: bool,
};

// Purpose, cointype, and account use hardened derivation
Expand Down Expand Up @@ -175,7 +198,7 @@ test "keypathtest" {
try std.testing.expectEqual(k1.path[3], 0);
try std.testing.expectEqual(k1.path[4], 1);

const k1str = try k1.toStr(allocator);
const k1str = try k1.toStr(allocator, null);
defer allocator.free(k1str);
const e1 = "84'/0'/0'/0/1".*;
try std.testing.expectEqualStrings(&e1, k1str);
Expand All @@ -186,7 +209,21 @@ test "keypathtest" {
try std.testing.expectEqual(k2.path[2], 0);

const e2 = "84'/0'/0'".*;
const k2str = try k2.toStr(allocator);
const k2str = try k2.toStr(allocator, null);
defer allocator.free(k2str);
try std.testing.expectEqualStrings(&e2, k2str);
}

test "keypathToStrCapMaxDepth" {
const k1 = try KeyPath(5).fromStr("84'/0'/0'/0/1");
const res = k1.getStrCap(3);
try std.testing.expectEqual(9, res);
}

test "keypathToStrMaxDepth" {
const allocator = std.testing.allocator;
const k1 = try KeyPath(5).fromStr("84'/0'/0'/0/1");
const res = try k1.toStr(allocator, 3);
try std.testing.expectEqualStrings("84'/0'/0'", res);
defer allocator.free(res);
}
36 changes: 31 additions & 5 deletions src/db/db.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const assert = std.debug.assert;

pub fn openDB() !sqlite.Db {
const db = try sqlite.Db.init(.{
.mode = sqlite.Db.Mode{ .File = "/home/mattia/dev/walle/test.db" },
.mode = sqlite.Db.Mode{ .File = "./test.db" },
.open_flags = .{
.write = true,
.create = true,
Expand Down Expand Up @@ -40,7 +40,7 @@ pub fn initDB(db: *sqlite.Db) !void {
var stmtInputs = try db.prepare(sqlInputs);
defer stmtInputs.deinit();

const sqlDescriptors = "CREATE TABLE IF NOT EXISTS descriptors(extended_key VARCHAR(111) PRIMARY KEY, path TEXT NOT NULL)";
const sqlDescriptors = "CREATE TABLE IF NOT EXISTS descriptors(extended_key VARCHAR(111) PRIMARY KEY, path TEXT NOT NULL, private INTEGER NOT NULL)";
var stmtDescriptors = try db.prepare(sqlDescriptors);
defer stmtDescriptors.deinit();

Expand Down Expand Up @@ -141,6 +141,19 @@ pub fn getOutput(db: *sqlite.Db, txid: [64]u8, n: u32) !?Output {
return null;
}

pub fn getOutputDescriptorPath(allocator: std.mem.Allocator, db: *sqlite.Db, txid: [64]u8, n: u32) !KeyPath(5) {
const sqlOutput = "SELECT path AS c FROM outputs WHERE txid = ? AND n = ?";
var stmt = try db.prepare(sqlOutput);
defer stmt.deinit();
const row = try stmt.one(struct { path: []u8 }, .{}, .{ .txid = txid, .n = n }, allocator);
if (row != null) {
defer allocator.free(row.path);
return KeyPath(5).fromStr(row.path);
}

return null;
}

pub fn saveTransaction(db: *sqlite.Db, block_heigth: usize, transactions: std.AutoHashMap([64]u8, bool), rawtransactionsmap: std.AutoHashMap([64]u8, []u8)) !void {
const sqlBegin = "BEGIN TRANSACTION;";
var stmtBegin = try db.prepare(sqlBegin);
Expand Down Expand Up @@ -188,10 +201,10 @@ pub fn getBalance(db: *sqlite.Db, current_block: usize) !u64 {

// Memory ownership to the caller
pub fn getDescriptors(allocator: std.mem.Allocator, db: *sqlite.Db) ![]Descriptor {
const sql = "SELECT extended_key, path FROM descriptors;";
const sql = "SELECT extended_key, path, private FROM descriptors;";
var stmt = try db.prepare(sql);
defer stmt.deinit();
const rows = try stmt.all(struct { extended_key: [111]u8, path: []const u8 }, allocator, .{}, .{});
const rows = try stmt.all(struct { extended_key: [111]u8, path: []const u8, private: bool }, allocator, .{}, .{});
defer {
for (rows) |row| {
allocator.free(row.path);
Expand All @@ -201,12 +214,25 @@ pub fn getDescriptors(allocator: std.mem.Allocator, db: *sqlite.Db) ![]Descripto

var descriptors = try allocator.alloc(Descriptor, rows.len);
for (rows, 0..) |row, i| {
descriptors[i] = Descriptor{ .extended_key = row.extended_key, .keypath = try KeyPath(3).fromStr(row.path) };
descriptors[i] = Descriptor{ .extended_key = row.extended_key, .keypath = try KeyPath(3).fromStr(row.path), .private = row.private };
}

return descriptors;
}

pub fn getDescriptor(allocator: std.mem.Allocator, db: *sqlite.Db, path: []u8) !?Descriptor {
const sql = "SELECT extended_key, path, private FROM descriptor WHERE path=? LIMIT 1;";
var stmt = try db.prepare(sql);
defer stmt.deinit();
const row = try stmt.one(struct { extended_key: [111]u8, path: []const u8, private: bool }, allocator, .{}, .{ .path = path });
if (row != null) {
defer allocator.free(row.path);
return Descriptor{ .extended_key = row.extended_key, .keypath = try KeyPath(3).fromStr(row.path), .private = row.private };
}

return null;
}

pub fn getUsedKeyPaths(allocator: std.mem.Allocator, db: *sqlite.Db) ![]KeyPath(5) {
const sql = "SELECT DISTINCT(path) AS path FROM outputs;";
var stmt = try db.prepare(sql);
Expand Down
1 change: 0 additions & 1 deletion src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const io = std.io;
const bip39 = @import("bip39.zig");
const bip32 = @import("bip32.zig");
const utils = @import("utils.zig");
const clap = @import("clap");
const script = @import("script.zig");
const tx = @import("tx.zig");
const deriveP2WPKHAddress = @import("address.zig").deriveP2WPKHAddress;
Expand Down
Loading

0 comments on commit 5a9de3f

Please sign in to comment.