diff --git a/src/main.zig b/src/main.zig index 0447837..1206302 100644 --- a/src/main.zig +++ b/src/main.zig @@ -67,6 +67,9 @@ pub fn main(init: std.process.Init) !void { zds.core.log.info("bootstrap invite code: {s}\n", .{code}); } } + zds.storage.store.sequenceUnannouncedAccounts(allocator) catch |err| { + zds.core.log.err("startup sequence_unannounced_accounts failed err={s}\n", .{@errorName(err)}); + }; zds.atproto.sync.notifyCrawlers(true); try zds.http.server.listen(io, .{ .host = options.host, .port = options.port }); } diff --git a/src/storage/store.zig b/src/storage/store.zig index 1302743..4a8a9a4 100644 --- a/src/storage/store.zig +++ b/src/storage/store.zig @@ -1225,6 +1225,40 @@ pub fn sequenceNewAccount(allocator: std.mem.Allocator, account: auth.Account) ! try sequenceSyncEvent(allocator, account.did); } +/// Startup repair for accounts created before ZDS sequenced creation events: +/// any active account with no commits gets its genesis announcement now, so +/// relays stop reporting RepoNotFound for it. +pub fn sequenceUnannouncedAccounts(allocator: std.mem.Allocator) !void { + const unannounced = blk: { + db_mutex.lockUncancelable(store_io); + defer db_mutex.unlock(store_io); + try requireInitialized(); + var rows = try conn.rows( + \\SELECT did, handle FROM accounts + \\WHERE activated_at IS NOT NULL AND account_status = 'active' + \\ AND did NOT IN (SELECT did FROM commits) + , .{}); + defer rows.deinit(); + var found: std.ArrayList(auth.Account) = .empty; + while (rows.next()) |row| { + try found.append(allocator, .{ + .did = try allocator.dupe(u8, row.text(0)), + .handle = try allocator.dupe(u8, row.text(1)), + .email = "", + .password = "", + }); + } + break :blk try found.toOwnedSlice(allocator); + }; + for (unannounced) |account| { + sequenceNewAccount(allocator, account) catch |err| { + log.err("store announce failed did={s} handle={s} err={s}\n", .{ account.did, account.handle, @errorName(err) }); + continue; + }; + log.info("store announced pre-existing account did={s} handle={s}\n", .{ account.did, account.handle }); + } +} + pub fn sequenceSyncEvent(allocator: std.mem.Allocator, did: []const u8) !void { db_mutex.lockUncancelable(store_io); defer db_mutex.unlock(store_io);