Fix cross-network block detection and remove false orphan artifacts

- Change OrphanedAt from time.Time to *time.Time so JSON omitempty
  correctly omits zero values (Go serializes zero time.Time as
  "0001-01-01T00:00:00Z" which JS treats as truthy)
- Rewrite reconcileOnce with 4-pass architecture: enrichment, reorg
  detection via GetBlock verification, false-positive un-orphaning,
  and legacy block stamping
- Use inferOtherChain() to stamp cross-network blocks with the correct
  chain identifier (testnet4 reports as "testnet4", not "test")
- Move tailer startup after aggregator's first refresh so blocks are
  always stamped with the current chain
- Add StampChain store method, debug-blocks admin endpoint, and
  comprehensive reconcile tests for cross-network scenarios
This commit is contained in:
satoshi
2026-05-10 17:22:56 +03:00
parent 92fcb70d93
commit 0787f092ff
5 changed files with 391 additions and 62 deletions
+8 -10
View File
@@ -112,16 +112,10 @@ func main() {
}
}
}
go tailer.Run(ctx)
go agg.IngestBlockEvents(ctx, tailer.Events)
go agg.IngestAttemptEvents(ctx, tailer.Attempts)
// Wait briefly for the aggregator's first refresh to complete so
// the very first /api/snapshot or /api/health hit doesn't see an
// all-zeros snapshot and report bitcoin_ok=false during its own
// initialization. Cap the wait so a permanently-down bitcoind
// can't block startup forever — /healthz is honest about the
// degraded state.
// Wait for the aggregator's first refresh before starting the log
// tailer. This guarantees currentChain is set before any block
// events are processed, so blocks are always stamped with the
// correct chain — preventing false orphans on network switches.
select {
case <-agg.Ready():
log.Info("first snapshot ready")
@@ -131,6 +125,10 @@ func main() {
return
}
go tailer.Run(ctx)
go agg.IngestBlockEvents(ctx, tailer.Events)
go agg.IngestAttemptEvents(ctx, tailer.Attempts)
srv := &http.Server{
Addr: cfg.ListenAddr,
Handler: api.Handler(),