Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 3 additions & 4 deletions conformance/src/txn_execute.zig
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,7 @@ fn executeTxnContext(
var parent_hash: Hash = Hash.ZEROES;
var epoch_schedule: EpochSchedule = undefined;

var ancestors: Ancestors = .{};
defer ancestors.deinit(allocator);
var ancestors: Ancestors = .EMPTY;

var compute_budget = ComputeBudget.DEFAULT;
compute_budget.compute_unit_limit = compute_budget.compute_unit_limit;
Expand All @@ -214,7 +213,7 @@ fn executeTxnContext(
// Bank::new_with_paths(...)
// https://github.com/firedancer-io/agave/blob/10fe1eb29aac9c236fd72d08ae60a3ef61ee8353/runtime/src/bank.rs#L1162
{
try ancestors.addSlot(allocator, 0);
try ancestors.addSlot(0);
// bank.compute_budget = runtime_config.compute_budget;
// bank.transaction_account_lock_limit = null;
// bank.transaction_debug_keys = null;
Expand Down Expand Up @@ -506,7 +505,7 @@ fn executeTxnContext(
// var new = Bank{...}

// Create ancestors with new slot and all parent slots
try ancestors.addSlot(allocator, slot);
try ancestors.addSlot(slot);

// Update epoch
if (parent_slots_epoch < epoch) {
Expand Down
12 changes: 5 additions & 7 deletions src/accountsdb/account_store.zig
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ pub const ThreadSafeAccountMap = struct {
const list = map.get(address) orelse return null;
for (list.items) |slot_account| {
const slot, const account = slot_account;
if (ancestors.ancestors.contains(slot)) {
if (ancestors.containsSlot(slot)) {
return if (account.lamports == 0) null else try toAccount(self.allocator, account);
}
}
Expand Down Expand Up @@ -434,9 +434,8 @@ test "AccountStore does not return 0-lamport accounts from accountsdb" {
try std.testing.expectEqual(null, try reader.getLatest(zero_lamport_address));
try std.testing.expectEqual(1, (try reader.getLatest(one_lamport_address)).?.lamports);

var ancestors = Ancestors{};
defer ancestors.deinit(std.testing.allocator);
try ancestors.ancestors.put(std.testing.allocator, 0, {});
var ancestors = Ancestors.EMPTY;
try ancestors.addSlot(0);
const slot_reader = db.accountReader().forSlot(&ancestors);

try std.testing.expectEqual(null, try slot_reader.get(zero_lamport_address));
Expand All @@ -455,11 +454,10 @@ test ThreadSafeAccountMap {
const account_store = tsm.accountStore();
const account_reader = tsm.accountReader();

var ancestors1: Ancestors = .{};
defer ancestors1.deinit(allocator);
var ancestors1: Ancestors = .EMPTY;
const slot1: Slot = 1;
const addr1: Pubkey = .initRandom(random);
try ancestors1.ancestors.put(allocator, slot1, {});
try ancestors1.addSlot(slot1);

var expected_data: [128]u8 = undefined;
random.bytes(&expected_data);
Expand Down
56 changes: 23 additions & 33 deletions src/accountsdb/db.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3623,25 +3623,24 @@ test "write and read an account (write single + read with ancestors)" {
// assume we've progessed past the need for ancestors
{
accounts_db.largest_flushed_slot.store(10_000, .monotonic);
var account = (try accounts_db.getAccountWithAncestors(&pubkey, &.{})).?;
var account = (try accounts_db.getAccountWithAncestors(&pubkey, &.EMPTY)).?;
accounts_db.largest_flushed_slot.store(0, .monotonic);
defer account.deinit(allocator);
try std.testing.expect(test_account.equals(&account));
}

// slot is in ancestors
{
var ancestors = sig.core.Ancestors{};
defer ancestors.deinit(allocator);
try ancestors.ancestors.put(allocator, 5083, {});
var ancestors = sig.core.Ancestors.EMPTY;
try ancestors.addSlot(5083);

var account = (try accounts_db.getAccountWithAncestors(&pubkey, &ancestors)).?;
defer account.deinit(allocator);
try std.testing.expect(test_account.equals(&account));
}

// slot is not in ancestors
try std.testing.expectEqual(null, accounts_db.getAccountWithAncestors(&pubkey, &.{}));
try std.testing.expectEqual(null, accounts_db.getAccountWithAncestors(&pubkey, &.EMPTY));

// write account to the same pubkey in the next slot (!)
{
Expand All @@ -3667,9 +3666,8 @@ test "write and read an account (write single + read with ancestors)" {

// prev slot, get prev account
{
var ancestors = sig.core.Ancestors{};
defer ancestors.deinit(allocator);
try ancestors.ancestors.put(allocator, 5083, {});
var ancestors = sig.core.Ancestors.EMPTY;
try ancestors.addSlot(5083);

var account = (try accounts_db.getAccountWithAncestors(&pubkey, &ancestors)).?;
defer account.deinit(allocator);
Expand All @@ -3678,9 +3676,8 @@ test "write and read an account (write single + read with ancestors)" {

// new slot, get new account
{
var ancestors = sig.core.Ancestors{};
defer ancestors.deinit(allocator);
try ancestors.ancestors.put(allocator, 5084, {});
var ancestors = sig.core.Ancestors.EMPTY;
try ancestors.addSlot(5084);

var account = (try accounts_db.getAccountWithAncestors(&pubkey, &ancestors)).?;
defer account.deinit(allocator);
Expand Down Expand Up @@ -4583,9 +4580,8 @@ test "insert multiple accounts on same slot" {
const slot: Slot = 10;

// Create ancestors with initial slot
var ancestors = Ancestors{};
defer ancestors.deinit(allocator);
try ancestors.ancestors.put(allocator, slot, {});
var ancestors = Ancestors.EMPTY;
try ancestors.addSlot(slot);

// Insert 50 random accounts on current slot and reload them immediately
for (0..50) |i| {
Expand Down Expand Up @@ -4664,14 +4660,13 @@ test "insert multiple accounts on multiple slots" {
for (0..50) |i| {
const slot = slots[random.uintLessThan(u64, slots.len)];

var ancestors = Ancestors{};
defer ancestors.deinit(allocator);
try ancestors.ancestors.put(allocator, slot, {});
var ancestors = Ancestors.EMPTY;
try ancestors.addSlot(slot);

const pubkey = Pubkey.initRandom(random);
errdefer std.log.err(
"Failed to insert and load account: i={}, slot={}, ancestors={any} pubkey={}\n",
.{ i, slot, ancestors.ancestors.keys(), pubkey },
"Failed to insert and load account: i={}, slot={}, ancestors={} pubkey={}\n",
.{ i, slot, ancestors, pubkey },
);

const expected = try createRandomAccount(allocator, random);
Expand Down Expand Up @@ -4707,19 +4702,18 @@ test "insert account on multiple slots" {
for (0..num_slots_to_insert) |j| {
const slot = slots[random.uintLessThan(u64, slots.len)];

var ancestors = Ancestors{};
defer ancestors.deinit(allocator);
try ancestors.ancestors.put(allocator, slot, {});
var ancestors = Ancestors.EMPTY;
try ancestors.addSlot(slot);

errdefer std.log.err(
\\Failed to insert and load account: i={}
\\ j: {}/{}
\\ slot: {}
\\ ancestors: {any}
\\ ancestors: {}
\\ pubkey: {}
\\
,
.{ i, j, num_slots_to_insert, slot, ancestors.ancestors.keys(), pubkey },
.{ i, j, num_slots_to_insert, slot, ancestors, pubkey },
);

const expected = try createRandomAccount(allocator, random);
Expand Down Expand Up @@ -4754,9 +4748,7 @@ test "missing ancestor returns null" {
defer allocator.free(account.data);
try accounts_db.putAccount(slot, pubkey, account);

var ancestors = Ancestors{};
defer ancestors.deinit(allocator);

var ancestors = Ancestors.EMPTY;
try std.testing.expectEqual(null, try accounts_db.getAccountWithAncestors(&pubkey, &ancestors));
}

Expand All @@ -4772,9 +4764,8 @@ test "overwrite account in same slot" {
const slot: Slot = 15;
const pubkey = Pubkey.initRandom(random);

var ancestors = Ancestors{};
defer ancestors.deinit(allocator);
try ancestors.ancestors.put(allocator, slot, {});
var ancestors = Ancestors.EMPTY;
try ancestors.addSlot(slot);

const first = try createRandomAccount(allocator, random);
defer allocator.free(first.data);
Expand Down Expand Up @@ -4842,9 +4833,8 @@ test "insert many duplicate individual accounts, get latest with ancestors" {
for (pubkeys, expected_latest) |pubkey, maybe_expected| {
const expected = maybe_expected orelse return error.ExpectedMissing;

var ancestors = Ancestors{};
defer ancestors.deinit(allocator);
try ancestors.ancestors.put(allocator, expected.slot, {});
var ancestors = Ancestors.EMPTY;
try ancestors.addSlot(expected.slot);

const maybe_actual = try accounts_db.getAccountWithAncestors(&pubkey, &ancestors);
defer if (maybe_actual) |actual| actual.deinit(allocator);
Expand Down
24 changes: 11 additions & 13 deletions src/accountsdb/fuzz.zig
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ pub fn run(seed: u64, args: *std.process.ArgIterator) !void {
var top_slot: Slot = 0;

var ancestors: sig.core.Ancestors = .EMPTY;
defer ancestors.deinit(allocator);

// get/put a bunch of accounts
while (true) {
Expand All @@ -251,10 +250,15 @@ pub fn run(seed: u64, args: *std.process.ArgIterator) !void {
defer if (will_inc_slot) {
top_slot += random.intRangeAtMost(Slot, 1, 2);
};
try ancestors.addSlot(allocator, top_slot);
try ancestors.addSlot(top_slot);

const current_slot = if (!non_sequential_slots) top_slot else slot: {
const ancestor_slots: []const Slot = ancestors.ancestors.keys();
var ancestor_slots = try allocator.alloc(Slot, ancestors.count());
var iter = ancestors.iterator();
var i: usize = 0;
while (iter.next()) |slot| : (i += 1) ancestor_slots[i] = slot;
std.mem.sort(Slot, ancestor_slots, {}, std.sort.asc(Slot));

std.debug.assert(ancestor_slots[ancestor_slots.len - 1] == top_slot);
const ancestor_index = random.intRangeLessThan(
usize,
Expand Down Expand Up @@ -318,18 +322,12 @@ pub fn run(seed: u64, args: *std.process.ArgIterator) !void {
break :blk .{ key, tracked_accounts.get(key).? };
};

var ancestors_sub = try ancestors.clone(allocator);
defer ancestors_sub.deinit(allocator);
for (ancestors_sub.ancestors.keys()) |other_slot| {
var ancestors_sub = ancestors;
var iter = ancestors_sub.iterator();
while (iter.next()) |other_slot| {
if (other_slot <= tracked_account.slot) continue;
_ = ancestors_sub.ancestors.swapRemove(other_slot);
_ = ancestors_sub.removeSlot(other_slot);
}
ancestors_sub.ancestors.sort(struct {
ancestors_sub: []Slot,
pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
return ctx.ancestors_sub[a] < ctx.ancestors_sub[b];
}
}{ .ancestors_sub = ancestors_sub.ancestors.keys() });

const account =
try accounts_db.getAccountWithAncestors(&pubkey, &ancestors_sub) orelse {
Expand Down
3 changes: 2 additions & 1 deletion src/cmd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1223,9 +1223,10 @@ fn validator(
epoch_stakes,
);
errdefer current_epoch_constants.deinit(allocator);
const ancestors = try sig.core.Ancestors.fromMap(&bank_fields.ancestors);
const feature_set = try sig.replay.service.getActiveFeatures(
allocator,
loaded_snapshot.accounts_db.accountReader().forSlot(&bank_fields.ancestors),
loaded_snapshot.accounts_db.accountReader().forSlot(&ancestors),
bank_fields.slot,
);
const root_slot_constants = try sig.core.SlotConstants.fromBankFields(
Expand Down
23 changes: 9 additions & 14 deletions src/consensus/optimistic_vote_verifier.zig
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,7 @@ test "OptimisticConfirmationVerifier.verifyForUnrootedOptimisticSlots: same slot
latest.deinit();
try std.testing.expectEqual(2, latest.items.len);

var root_ancestors: sig.core.Ancestors = .{ .ancestors = .empty };
defer root_ancestors.deinit(allocator);
var root_ancestors: sig.core.Ancestors = .EMPTY;

const unrooted = try verifier.verifyForUnrootedOptimisticSlots(
allocator,
Expand Down Expand Up @@ -327,10 +326,9 @@ test "OptimisticConfirmationVerifier.verifyForUnrootedOptimisticSlots: unrooted
try std.testing.expectEqual(3, latest.items.len);

// Root on same fork at slot 5: ancestors include 1 and 3
var anc5: sig.core.Ancestors = .{ .ancestors = .{} };
defer anc5.deinit(allocator);
try anc5.addSlot(allocator, 1);
try anc5.addSlot(allocator, 3);
var anc5: sig.core.Ancestors = .EMPTY;
try anc5.addSlot(1);
try anc5.addSlot(3);
{
const unrooted = try verifier.verifyForUnrootedOptimisticSlots(
allocator,
Expand All @@ -344,9 +342,8 @@ test "OptimisticConfirmationVerifier.verifyForUnrootedOptimisticSlots: unrooted

// Re-add optimistic slots and check root at 3 (same fork)
try verifier.addNewOptimisticConfirmedSlots(allocator, optimistic, &ledger_writer);
var anc3: sig.core.Ancestors = .{ .ancestors = .{} };
defer anc3.deinit(allocator);
try anc3.addSlot(allocator, 1);
var anc3: sig.core.Ancestors = .EMPTY;
try anc3.addSlot(1);
{
const unrooted = try verifier.verifyForUnrootedOptimisticSlots(
allocator,
Expand All @@ -361,10 +358,9 @@ test "OptimisticConfirmationVerifier.verifyForUnrootedOptimisticSlots: unrooted

// Re-add optimistic slots and set a different fork root at slot 4
try verifier.addNewOptimisticConfirmedSlots(allocator, optimistic, &ledger_writer);
var anc4: sig.core.Ancestors = .{ .ancestors = .{} };
defer anc4.deinit(allocator);
var anc4: sig.core.Ancestors = .EMPTY;
// ancestors for 4 include 1 (but not 3)
try anc4.addSlot(allocator, 1);
try anc4.addSlot(1);
{
const unrooted = try verifier.verifyForUnrootedOptimisticSlots(
allocator,
Expand All @@ -383,9 +379,8 @@ test "OptimisticConfirmationVerifier.verifyForUnrootedOptimisticSlots: unrooted

// Simulate missing ancestors by using root at 7 with no ancestors info
var anc7: sig.core.Ancestors = .{ .ancestors = .empty };
defer anc7.deinit(allocator);
// First run should return 1 and 3 (not in ancestors and not rooted). Mark 5 as ancestor.
try anc7.addSlot(allocator, 5);
try anc7.addSlot(5);
try verifier.addNewOptimisticConfirmedSlots(
allocator,
optimistic,
Expand Down
Loading