//! RFC-0020: OPQ Manifests & Summaries //! //! Provides bandwidth-efficient triage of queued packets. const std = @import("std"); const merkle = @import("merkle.zig"); const quota = @import("quota.zig"); pub const Priority = enum(u8) { low = 0, normal = 1, high = 2, critical = 3, }; pub const PacketSummary = struct { queue_id: [16]u8, sender_hint: [24]u8, // DID hint size: u32, priority: Priority, created_at: i64, // WALL time (for expiry) timestamp: u64, // L0 nanoseconds (for ordering) sequence: u32, // L0 sequence (for ordering/replay) expires_at: i64, entropy_cost: u16, category: quota.TrustCategory, }; pub const QueueManifest = struct { allocator: std.mem.Allocator, recipient_hint: [24]u8, total_count: usize, total_size: u64, items: std.ArrayListUnmanaged(PacketSummary), merkle_root: [32]u8, pub fn init(allocator: std.mem.Allocator, recipient: [24]u8) QueueManifest { return .{ .allocator = allocator, .recipient_hint = recipient, .total_count = 0, .total_size = 0, .items = .{}, .merkle_root = [_]u8{0} ** 32, }; } pub fn deinit(self: *QueueManifest) void { self.items.deinit(self.allocator); } pub fn calculateMerkleRoot(self: *QueueManifest) !void { var tree = merkle.MerkleTree.init(self.allocator); defer tree.deinit(); for (self.items.items) |item| { // Hash the summary to form a leaf var hasher = std.crypto.hash.Blake3.init(.{}); hasher.update(&item.queue_id); hasher.update(&item.sender_hint); hasher.update(std.mem.asBytes(&item.size)); hasher.update(std.mem.asBytes(&item.created_at)); var leaf: [32]u8 = undefined; hasher.final(&leaf); try tree.insert(leaf); } self.merkle_root = tree.getRoot(); } };