From 39a3d60549596975fcb2e4c6cdeb05a39a389624 Mon Sep 17 00:00:00 2001 From: x19 <0x39015319@gmail.com> Date: Tue, 4 Jun 2024 14:26:32 -0400 Subject: [PATCH 1/5] init fix for snapshot + status cache verification --- src/accountsdb/db.zig | 24 +++++++++++++++++++++--- src/accountsdb/snapshots.zig | 13 ++++++++++--- src/common/merkle_tree.zig | 2 +- src/core/pubkey.zig | 5 ++++- src/utils/tar.zig | 2 +- 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/accountsdb/db.zig b/src/accountsdb/db.zig index ce889dc54..a468fdd8d 100644 --- a/src/accountsdb/db.zig +++ b/src/accountsdb/db.zig @@ -15,6 +15,7 @@ const AccountFileInfo = @import("../accountsdb/snapshots.zig").AccountFileInfo; const AccountFile = @import("../accountsdb/accounts_file.zig").AccountFile; const FileId = @import("../accountsdb/accounts_file.zig").FileId; const AccountInFile = @import("../accountsdb/accounts_file.zig").AccountInFile; +const Blake3 = std.crypto.hash.Blake3; const ThreadPool = @import("../sync/thread_pool.zig").ThreadPool; const Task = ThreadPool.Task; @@ -768,11 +769,28 @@ pub const AccountsDB = struct { } orelse continue; const result = try self.getAccountHashAndLamportsFromRef(max_slot_ref); - // only include non-zero lamport accounts (for full snapshots) const lamports = result.lamports; - if (config == .FullAccountHash and lamports == 0) continue; + var account_hash = result.hash; + if (lamports == 0) { + switch (config) { + // for full snapshots, only include non-zero lamport accounts + .FullAccountHash => continue, + // zero-lamport accounts for incrementals = hash(pubkey) + .IncrementalAccountHash => { + var hasher = Blake3.init(.{}); + hasher.update(&key.data); + hasher.final(&account_hash.data); + }, + } + } else { + // hashes arent always stored correctly in snapshots + if (account_hash.order(&Hash.default()) == .eq) { + const account = try self.getAccountFromRef(max_slot_ref); + account_hash = account.hash(&key); + } + } - hashes.appendAssumeCapacity(result.hash); + hashes.appendAssumeCapacity(account_hash); local_total_lamports += lamports; } diff --git a/src/accountsdb/snapshots.zig b/src/accountsdb/snapshots.zig index 4346ba5da..da99cbe99 100644 --- a/src/accountsdb/snapshots.zig +++ b/src/accountsdb/snapshots.zig @@ -705,10 +705,17 @@ pub const StatusCache = struct { return error.SlotNotFoundInHistory; } } - for (slot_history.oldest()..slot_history.newest()) |slot| { - if (!slots_seen.contains(slot)) { - return error.SlotNotFoundInStatusCache; + + var slots_checked: u32 = 0; + var slot = slot_history.newest(); + while (slot >= slot_history.oldest() and slots_checked != MAX_CACHE_ENTRIES) { + if (slot_history.check(slot) == sysvars.SlotCheckResult.Found) { + slots_checked += 1; + if (!slots_seen.contains(slot)) { + return error.SlotNotFoundInStatusCache; + } } + slot -= 1; } } }; diff --git a/src/common/merkle_tree.zig b/src/common/merkle_tree.zig index 89673d657..17983e3ae 100644 --- a/src/common/merkle_tree.zig +++ b/src/common/merkle_tree.zig @@ -36,7 +36,7 @@ pub const NestedHashTree = struct { var i: usize = 0; while (i < self.hashes.len) { const nested_len = self.hashes[i].items.len; - if ((search_index + nested_len) > index) { + if (search_index + nested_len > index) { const index_in_nested = index - search_index; return &self.hashes[i].items[index_in_nested]; } else { diff --git a/src/core/pubkey.zig b/src/core/pubkey.zig index 1df17963d..e156b1749 100644 --- a/src/core/pubkey.zig +++ b/src/core/pubkey.zig @@ -81,7 +81,10 @@ pub const Pubkey = struct { } pub fn format(self: @This(), comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { - return writer.print("{s}", .{self.string()}); + var dest: [44]u8 = undefined; + @memset(&dest, 0); + const written = encoder.encode(&self.data, &dest) catch return error.EncodingError; + return writer.print("{s}", .{dest[0..written]}); } pub fn isDefault(self: *const Self) bool { diff --git a/src/utils/tar.zig b/src/utils/tar.zig index 90526c086..5d70d5a2c 100644 --- a/src/utils/tar.zig +++ b/src/utils/tar.zig @@ -78,7 +78,7 @@ pub fn parallelUntarToFileSystem( thread_pool.deinit(); } - logger.infof("using {d} threads to unpack snapshot\n", .{n_threads}); + logger.infof("using {d} threads to unpack snapshot", .{n_threads}); const tasks = try UnTarTask.init(allocator, n_threads); defer allocator.free(tasks); From da9289bec96b4f2e2ec290f9264c5a7fe5562446 Mon Sep 17 00:00:00 2001 From: x19 <0x39015319@gmail.com> Date: Wed, 5 Jun 2024 16:10:06 -0400 Subject: [PATCH 2/5] fix enum fmt --- src/accountsdb/snapshots.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/accountsdb/snapshots.zig b/src/accountsdb/snapshots.zig index b75589b39..85e92fe20 100644 --- a/src/accountsdb/snapshots.zig +++ b/src/accountsdb/snapshots.zig @@ -701,7 +701,7 @@ pub const StatusCache = struct { return error.SlotHistoryMismatch; } for (slots_seen.keys()) |slot| { - if (slot_history.check(slot) != sysvars.SlotCheckResult.Found) { + if (slot_history.check(slot) != .Found) { return error.SlotNotFoundInHistory; } } @@ -709,7 +709,7 @@ pub const StatusCache = struct { var slots_checked: u32 = 0; var slot = slot_history.newest(); while (slot >= slot_history.oldest() and slots_checked != MAX_CACHE_ENTRIES) { - if (slot_history.check(slot) == sysvars.SlotCheckResult.Found) { + if (slot_history.check(slot) == .Found) { slots_checked += 1; if (!slots_seen.contains(slot)) { return error.SlotNotFoundInStatusCache; From 73e9ea66adf89b572883a95f4e75ae19826706c6 Mon Sep 17 00:00:00 2001 From: x19 <0x39015319@gmail.com> Date: Tue, 11 Jun 2024 18:34:50 -0400 Subject: [PATCH 3/5] fix blake3 hash impl --- src/accountsdb/db.zig | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/accountsdb/db.zig b/src/accountsdb/db.zig index 2de2b6aae..0241f19c3 100644 --- a/src/accountsdb/db.zig +++ b/src/accountsdb/db.zig @@ -776,11 +776,7 @@ pub const AccountsDB = struct { // for full snapshots, only include non-zero lamport accounts .FullAccountHash => continue, // zero-lamport accounts for incrementals = hash(pubkey) - .IncrementalAccountHash => { - var hasher = Blake3.init(.{}); - hasher.update(&key.data); - hasher.final(&account_hash.data); - }, + .IncrementalAccountHash => Blake3.hash(&key.data, &account_hash.data, .{}), } } else { // hashes arent always stored correctly in snapshots From 3564b9172849a74958f340140c77cdcfd8855e98 Mon Sep 17 00:00:00 2001 From: x19 <0x39015319@gmail.com> Date: Tue, 11 Jun 2024 18:36:09 -0400 Subject: [PATCH 4/5] add permalink to status cache validation --- src/accountsdb/snapshots.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/accountsdb/snapshots.zig b/src/accountsdb/snapshots.zig index 0d66b1da9..7be9d02e6 100644 --- a/src/accountsdb/snapshots.zig +++ b/src/accountsdb/snapshots.zig @@ -676,6 +676,7 @@ pub const StatusCache = struct { bincode.free(self.bank_slot_deltas.allocator, self.*); } + /// [verify_slot_deltas](https://github.com/anza-xyz/agave/blob/ed500b5afc77bc78d9890d96455ea7a7f28edbf9/runtime/src/snapshot_bank_utils.rs#L709) pub fn validate( self: *const StatusCache, allocator: std.mem.Allocator, @@ -715,6 +716,7 @@ pub const StatusCache = struct { } } + var slots_checked: u32 = 0; var slot = slot_history.newest(); while (slot >= slot_history.oldest() and slots_checked != MAX_CACHE_ENTRIES) { From 6c2f94d215c67a4f9a8b60854a4bcde8e6f548dd Mon Sep 17 00:00:00 2001 From: x19 <0x39015319@gmail.com> Date: Tue, 11 Jun 2024 18:41:29 -0400 Subject: [PATCH 5/5] fix lint --- src/accountsdb/snapshots.zig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/accountsdb/snapshots.zig b/src/accountsdb/snapshots.zig index 7be9d02e6..ba9015361 100644 --- a/src/accountsdb/snapshots.zig +++ b/src/accountsdb/snapshots.zig @@ -716,7 +716,6 @@ pub const StatusCache = struct { } } - var slots_checked: u32 = 0; var slot = slot_history.newest(); while (slot >= slot_history.oldest() and slots_checked != MAX_CACHE_ENTRIES) {