Skip to content
Merged
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
6 changes: 6 additions & 0 deletions common/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,12 @@ func NewBlockCache(dbPath string, chainName string, startHeight int, syncFromHei
c.nextBlock++
}
Log.Info("Done reading ", c.nextBlock-c.firstBlock, " blocks from disk cache")

// Initialize latestHash from the last block on disk so that the first
// block ingested after a restart is checked against the cache tip.
// Otherwise, a reorg that occurred while the server was down would go
// undetected, permanently leaving orphan blocks in the cache.
c.setLatestHash()
return c
}

Expand Down
15 changes: 15 additions & 0 deletions common/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ func TestCache(t *testing.T) {
if cache.nextBlock != 289466 {
t.Fatal("unexpected nextBlock height")
}
// The hash of the top block must be restored from disk so that a reorg
// that occurred while the server was down can be detected (the first
// block ingested after a restart must connect to the cache tip).
if cache.latestHash == hash32.Nil {
t.Fatal("latestHash not initialized after restart")
}
if cache.latestHash != hash32.FromSlice(compacts[5].Hash) {
t.Fatal("unexpected latestHash after restart")
}
if cache.HashMatch(hash32.FromSlice(compacts[4].Hash)) {
t.Fatal("HashMatch should reject a non-connecting block after restart")
}
if !cache.HashMatch(hash32.FromSlice(compacts[5].Hash)) {
t.Fatal("HashMatch should accept a block connecting to the cache tip")
}
reorgCache(t)

// Reorg to before the first block moves back to only the first block
Expand Down