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

feat(repair): link shred collector with snapshot - root slot, leader schedule, verify shreds #169

Merged
merged 41 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6e17a8d
feat(utils): impl chacha for compat with rand_chacha
dnut May 19, 2024
25a65e2
feat(rand): WeightedRandomSampler and reorganize rand
dnut May 21, 2024
0322760
feat(core): leader schedule calculator
dnut May 23, 2024
1345e2e
Merge branch 'dnut/repair2' into dnut/repair3
dnut May 23, 2024
8289530
feat(shred-collector): pass leader schedule and root slot from snapsh…
dnut May 29, 2024
3094a27
refactor(utils): more versatile ServiceManager
dnut May 29, 2024
6f7b491
feat(utils): log message when cleaning up service manager
dnut May 29, 2024
9cf54b1
fix(utils): service manager name
dnut May 29, 2024
58e49e3
fix(utils): log unexpected returns by default
dnut May 30, 2024
c1a7e39
feat(utils): log service exit when receiving exit signal
dnut May 30, 2024
cd41978
refactor(leader_schedule): generify leader schedule and make it required
dnut May 31, 2024
4929ee2
Merge branch 'dnut/repair2' into dnut/repair3
dnut May 31, 2024
81886b8
fix(shred-collector): staked nodes & signed data
dnut Jun 3, 2024
8f1c2cd
Merge branch 'dnut/repair2' into dnut/repair3
dnut Jun 4, 2024
2dcc0df
refactor(gossip): remove RunHandles, superceded by ServiceManager
dnut Jun 4, 2024
2220f5a
Merge branch 'dnut/repair2' into dnut/repair3
dnut Jun 5, 2024
a038d5d
Merge branch 'dnut/repair2' into dnut/repair3
dnut Jun 5, 2024
560bebb
Merge branch 'dnut/repair2' into dnut/repair3
dnut Jun 5, 2024
b4e0753
fix(core, accountsdb): compute staked nodes and use for leader schedule
dnut Jun 6, 2024
7789370
feat(cmd): add leader-schedule command (and refactor for modularity)
dnut Jun 10, 2024
8e5cdad
Merge branch 'dnut/repair2' into dnut/repair3
dnut Jun 11, 2024
4eacdc6
Merge remote-tracking branch 'remotes/origin/main' into dnut/repair3
dnut Jun 11, 2024
65af230
feat: parse leader schedule
dnut Jun 12, 2024
b5b6828
Merge branch 'main' into dnut/repair3
dnut Jun 12, 2024
492247a
refactor(shred-collector): import usage
dnut Jun 12, 2024
96ac55f
fix(shred-collector): get shred signed data
dnut Jun 12, 2024
9e53401
fix(accountsdb): zig fmt
dnut Jun 12, 2024
a8eefe4
fix(cmd): re-enable most of snapshot validations
dnut Jun 12, 2024
ca303cf
Merge remote-tracking branch 'remotes/origin/main' into dnut/repair3
dnut Jun 12, 2024
0363821
feat(shred-collector): start from snapshot slot
dnut Jun 12, 2024
0eb0afa
feat(cmd): log error on bank validation failure
dnut Jun 13, 2024
e2c6906
fix(accountsdb): fix stakedNodes memoization
dnut Jun 26, 2024
10ee2a4
Merge branch 'main' into dnut/repair3
dnut Jun 28, 2024
1db74d0
Merge branch 'main' into dnut/repair3
dnut Jun 28, 2024
0c5121e
fix(cmd): errdefer deinit accountsdb items
dnut Jun 28, 2024
7514974
refactor(cmd): rename loadSnapshot to loadFromSnapshot
dnut Jun 28, 2024
bd13921
feat(cmd): log when downloading a snapshot for the leader schedule
dnut Jun 28, 2024
4abb203
refactor(config): move leader_schedule_path field out of general section
dnut Jun 28, 2024
2b3c851
test(accountsdb): assert MINIMUM_SLOTS_PER_EPOCH works properly in g…
dnut Jun 28, 2024
0f3c5c9
refactor(shred-collector): check exit bool in while condition
dnut Jun 28, 2024
a65ebf7
Merge remote-tracking branch 'remotes/origin/main' into dnut/repair3
dnut Jul 1, 2024
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
8 changes: 1 addition & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
.zig-cache/
zig-cache/
zig-out/
data/

# unpacking test snapshots
test_data/version
test_data/accounts/
test_data/snapshots/
test_data/tmp/
test_data/bench_snapshot/
test_data/accountsdb_fuzz/
index_storage/

/gossip-dumps
Expand Down
23 changes: 13 additions & 10 deletions src/accountsdb/genesis_config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ pub const EpochSchedule = extern struct {
first_normal_slot: Slot,

pub fn getEpoch(self: *const EpochSchedule, slot: Slot) Epoch {
return self.getEpochAndSlotIndex(slot).epoch;
return self.getEpochAndSlotIndex(slot)[0];
}

pub fn getEpochAndSlotIndex(self: *const EpochSchedule, slot: Slot) struct { epoch: Epoch, slot_index: Slot } {
pub fn getEpochAndSlotIndex(self: *const EpochSchedule, slot: Slot) struct { Epoch, Slot } {
if (slot < self.first_normal_slot) {
var epoch = slot +| MINIMUM_SLOTS_PER_EPOCH +| 1;
epoch = @ctz(std.math.ceilPowerOfTwo(u64, epoch) catch {
Expand All @@ -123,23 +123,26 @@ pub const EpochSchedule = extern struct {

const slot_index = slot -| (epoch_len -| MINIMUM_SLOTS_PER_EPOCH);

return .{
.epoch = epoch,
.slot_index = slot_index,
};
return .{ epoch, slot_index };
} else {
const normal_slot_index = slot -| self.first_normal_slot;
const normal_epoch_index = std.math.divTrunc(u64, normal_slot_index, self.slots_per_epoch) catch 0;

const epoch = self.first_normal_epoch +| normal_epoch_index;
const slot_index = std.math.rem(u64, normal_slot_index, self.slots_per_epoch) catch 0;

return .{
.epoch = epoch,
.slot_index = slot_index,
};
return .{ epoch, slot_index };
}
}

/// get the length of the given epoch (in slots)
pub fn getSlotsInEpoch(self: *const EpochSchedule, epoch: Epoch) Slot {
comptime std.debug.assert(std.math.isPowerOfTwo(MINIMUM_SLOTS_PER_EPOCH));
return if (epoch < self.first_normal_epoch)
@as(Slot, 1) <<| epoch +| @ctz(MINIMUM_SLOTS_PER_EPOCH)
0xNineteen marked this conversation as resolved.
Show resolved Hide resolved
else
self.slots_per_epoch;
}
};

pub const ClusterType = enum(u8) {
Expand Down
1 change: 1 addition & 0 deletions src/accountsdb/lib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub const AccountsDB = db.AccountsDB;
pub const AllSnapshotFields = snapshots.AllSnapshotFields;
pub const Bank = bank.Bank;
pub const GenesisConfig = genesis_config.GenesisConfig;
pub const SnapshotFields = snapshots.SnapshotFields;
pub const SnapshotFieldsAndPaths = snapshots.SnapshotFieldsAndPaths;
pub const SnapshotFiles = snapshots.SnapshotFiles;
pub const StatusCache = snapshots.StatusCache;
Expand Down
55 changes: 54 additions & 1 deletion src/accountsdb/snapshots.zig
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,69 @@ pub const Stakes = struct {
};

pub const VoteAccounts = struct {
vote_accounts: HashMap(Pubkey, struct { u64, Account }),
vote_accounts: HashMap(Pubkey, struct { u64, VoteAccount }),

staked_nodes: ?HashMap(
Pubkey, // VoteAccount.vote_state.node_pubkey.
u64, // Total stake across all vote-accounts.
) = null,

pub const @"!bincode-config:staked_nodes" = bincode.FieldConfig(?HashMap(Pubkey, u64)){ .skip = true };

const Self = @This();

pub fn stakedNodes(self: *Self, allocator: std.mem.Allocator) !*const HashMap(Pubkey, u64) {
if (self.staked_nodes) |*staked_nodes| {
return staked_nodes;
}
const vote_accounts = self.vote_accounts;
var staked_nodes = HashMap(Pubkey, u64).init(allocator);
var iter = vote_accounts.iterator();
while (iter.next()) |vote_entry| {
const vote_state = try vote_entry.value_ptr[1].voteState();
const node_entry = try staked_nodes.getOrPut(vote_state.node_pubkey);
if (!node_entry.found_existing) {
node_entry.value_ptr.* = 0;
}
node_entry.value_ptr.* += vote_entry.value_ptr[0];
}
self.staked_nodes = staked_nodes;
return &self.staked_nodes.?;
}
};

pub const VoteAccount = struct {
account: Account,
vote_state: ?anyerror!VoteState = null,

pub const @"!bincode-config:vote_state" = bincode.FieldConfig(?anyerror!VoteState){ .skip = true };

pub fn voteState(self: *@This()) !VoteState {
if (self.vote_state) |vs| {
return vs;
}
self.vote_state = bincode.readFromSlice(undefined, VoteState, self.account.data, .{});
return self.vote_state.?;
}
};

pub const VoteState = struct {
/// The variant of the rust enum
tag: u32, // TODO: consider varint bincode serialization (in rust this is enum)
/// the node that votes in this account
node_pubkey: Pubkey,
};

test "deserialize VoteState.node_pubkey" {
const bytes = .{
2, 0, 0, 0, 60, 155, 13, 144, 187, 252, 153, 72, 190, 35, 87, 94, 7, 178,
90, 174, 158, 6, 199, 179, 134, 194, 112, 248, 166, 232, 144, 253, 128, 249, 67, 118,
} ++ .{0} ** 1586 ++ .{ 31, 0, 0, 0, 0, 0, 0, 0, 1 } ++ .{0} ** 24;
const vote_state = try bincode.readFromSlice(undefined, VoteState, &bytes, .{});
const expected_pubkey = try Pubkey.fromString("55abJrqFnjm7ZRB1noVdh7BzBe3bBSMFT3pt16mw6Vad");
try std.testing.expect(expected_pubkey.equals(&vote_state.node_pubkey));
}

pub const Delegation = struct {
/// to whom the stake is delegated
voter_pubkey: Pubkey,
Expand Down
Loading
Loading