Skip to content

Commit 915a4b5

Browse files
wcatzclaude
andcommitted
fix(pr71): address CodeRabbit performance and context issues
1. Fix canceled context in /nextblock command: - Move cancelShort() after scheduleNonceMatches() call - Prevents passing canceled context to function 2. Add in-memory verified nonce cache: - Add verifiedNonces map[int][]byte to NonceTracker - Check cache before recomputing from genesis (10min operation) - Prevents blocking adder pipeline on hot paths - Cache guards with existing mutex Resolves CodeRabbit findings from PR #71. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f697f7c commit 915a4b5

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

commands.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -921,10 +921,10 @@ func (i *Indexer) cmdNextBlock(m *telebot.Message) {
921921
// Try DB first with short timeout
922922
ctxShort, cancelShort := context.WithTimeout(context.Background(), 10*time.Second)
923923
schedule, err := i.store.GetLeaderSchedule(ctxShort, currentEpoch)
924-
cancelShort()
925924
if err == nil && schedule != nil && !i.scheduleNonceMatches(ctxShort, schedule) {
926925
schedule = nil
927926
}
927+
cancelShort()
928928

929929
// If no schedule, auto-compute it
930930
if err != nil || schedule == nil {

nonce.go

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,21 @@ type NonceTracker struct {
3535
blockCount int
3636
candidateFroze bool // whether candidate nonce was frozen this epoch
3737
networkMagic int
38-
fullMode bool // true = genesis-seeded rolling nonce, false = lite (zero-seeded)
38+
fullMode bool // true = genesis-seeded rolling nonce, false = lite (zero-seeded)
39+
verifiedNonces map[int][]byte // in-memory cache of verified epoch nonces (full mode only)
3940
}
4041

4142
// NewNonceTracker creates a NonceTracker and attempts to restore state from DB.
4243
// In full mode, the initial nonce is seeded with the Shelley genesis hash.
4344
// In lite mode, the initial nonce is zero (current behavior).
4445
func NewNonceTracker(store Store, koiosClient *koios.Client, epoch, networkMagic int, fullMode bool) *NonceTracker {
4546
nt := &NonceTracker{
46-
store: store,
47-
koiosClient: koiosClient,
48-
currentEpoch: epoch,
49-
networkMagic: networkMagic,
50-
fullMode: fullMode,
47+
store: store,
48+
koiosClient: koiosClient,
49+
currentEpoch: epoch,
50+
networkMagic: networkMagic,
51+
fullMode: fullMode,
52+
verifiedNonces: make(map[int][]byte),
5153
}
5254

5355
// Try to restore evolving nonce from DB for current epoch
@@ -319,24 +321,39 @@ func (nt *NonceTracker) GetNonceForEpoch(epoch int) ([]byte, error) {
319321
// GetVerifiedNonceForEpoch returns a nonce that is verified against canonical
320322
// data for that epoch, repairing stale DB cache entries if needed.
321323
//
322-
// Full mode: always recompute from local chain data and upsert DB cache.
324+
// Full mode: check in-memory cache first, then recompute from local chain data
325+
// if not cached. Repairs stale DB entries on mismatch.
323326
// Lite mode: use existing lookup priority (DB -> Koios).
324327
func (nt *NonceTracker) GetVerifiedNonceForEpoch(epoch int) ([]byte, error) {
325328
if !nt.fullMode {
326329
return nt.GetNonceForEpoch(epoch)
327330
}
328331

332+
// Check in-memory cache first (prevents repeated genesis recomputation)
333+
nt.mu.Lock()
334+
if cached, ok := nt.verifiedNonces[epoch]; ok {
335+
nt.mu.Unlock()
336+
return cached, nil
337+
}
338+
nt.mu.Unlock()
339+
340+
// Not in cache — recompute from local chain data
329341
computeCtx, computeCancel := context.WithTimeout(context.Background(), 10*time.Minute)
330342
defer computeCancel()
331343
computed, err := nt.ComputeEpochNonce(computeCtx, epoch)
332344
if err != nil {
333345
return nil, fmt.Errorf("failed to verify nonce for epoch %d: %w", epoch, err)
334346
}
335347

348+
// Check if DB cache needs repair
336349
checkCtx, checkCancel := context.WithTimeout(context.Background(), 5*time.Second)
337350
defer checkCancel()
338351
cached, cacheErr := nt.store.GetFinalNonce(checkCtx, epoch)
339352
if cacheErr == nil && cached != nil && bytes.Equal(cached, computed) {
353+
// DB matches — store in memory cache and return
354+
nt.mu.Lock()
355+
nt.verifiedNonces[epoch] = computed
356+
nt.mu.Unlock()
340357
return cached, nil
341358
}
342359

@@ -352,6 +369,11 @@ func (nt *NonceTracker) GetVerifiedNonceForEpoch(epoch int) ([]byte, error) {
352369
log.Printf("Failed to persist verified nonce for epoch %d: %v", epoch, err)
353370
}
354371

372+
// Store in memory cache
373+
nt.mu.Lock()
374+
nt.verifiedNonces[epoch] = computed
375+
nt.mu.Unlock()
376+
355377
return computed, nil
356378
}
357379

0 commit comments

Comments
 (0)