mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 19:30:44 +00:00
eth/protocols/snap: check the pivot is canonical in isPivotCommitted
This commit is contained in:
parent
44315b711b
commit
62bbe63cb7
2 changed files with 20 additions and 7 deletions
|
|
@ -817,6 +817,11 @@ func catchUpExceedsRetention(prev, curr *types.Header) bool {
|
||||||
// pivot. That only happens when a completed sync committed the pivot block
|
// pivot. That only happens when a completed sync committed the pivot block
|
||||||
// as the new chain head.
|
// as the new chain head.
|
||||||
func isPivotCommitted(db ethdb.Database, pivot *types.Header) bool {
|
func isPivotCommitted(db ethdb.Database, pivot *types.Header) bool {
|
||||||
|
// A reorg across the pivot means the committed sync was undone, not
|
||||||
|
// advanced past, so the pivot must still be canonical.
|
||||||
|
if rawdb.ReadCanonicalHash(db, pivot.Number.Uint64()) != pivot.Hash() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
head := rawdb.ReadHeadBlockHash(db)
|
head := rawdb.ReadHeadBlockHash(db)
|
||||||
if head == (common.Hash{}) {
|
if head == (common.Hash{}) {
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
|
|
@ -1387,23 +1387,31 @@ func TestIsPivotCommitted(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
head int64 // head block number, -1 for no head block at all
|
head int64 // head block number, -1 for no head block at all
|
||||||
pivot uint64
|
pivot uint64
|
||||||
|
canonical bool // pivot still canonical at its height
|
||||||
committed bool
|
committed bool
|
||||||
}{
|
}{
|
||||||
{-1, 100, false}, // no head block, nothing committed
|
{-1, 100, true, false}, // no head block, nothing committed
|
||||||
{50, 100, false}, // head behind the pivot, crash before the commit
|
{50, 100, true, false}, // head behind the pivot, crash before the commit
|
||||||
{100, 100, true}, // head at the pivot, the commit just happened
|
{100, 100, true, true}, // head at the pivot, the commit just happened
|
||||||
{103, 100, true}, // head past the pivot, full sync ran after
|
{103, 100, true, true}, // head past the pivot, full sync ran after
|
||||||
{0, 0, false}, // genesis head is just an empty chain
|
{0, 0, true, false}, // genesis head is just an empty chain
|
||||||
|
{103, 100, false, false}, // pivot reorged out, head past it on a fork
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
|
pivot := mkPivot(tt.pivot, common.HexToHash("0xaaaa"))
|
||||||
|
if tt.canonical {
|
||||||
|
rawdb.WriteCanonicalHash(db, pivot.Hash(), tt.pivot)
|
||||||
|
} else {
|
||||||
|
rawdb.WriteCanonicalHash(db, common.HexToHash("0xdead"), tt.pivot)
|
||||||
|
}
|
||||||
if tt.head >= 0 {
|
if tt.head >= 0 {
|
||||||
head := mkPivot(uint64(tt.head), common.HexToHash("0xbbbb"))
|
head := mkPivot(uint64(tt.head), common.HexToHash("0xbbbb"))
|
||||||
rawdb.WriteHeader(db, head)
|
rawdb.WriteHeader(db, head)
|
||||||
rawdb.WriteHeadBlockHash(db, head.Hash())
|
rawdb.WriteHeadBlockHash(db, head.Hash())
|
||||||
}
|
}
|
||||||
if have := isPivotCommitted(db, mkPivot(tt.pivot, common.HexToHash("0xaaaa"))); have != tt.committed {
|
if have := isPivotCommitted(db, pivot); have != tt.committed {
|
||||||
t.Errorf("head %d pivot %d: isPivotCommitted = %v, want %v", tt.head, tt.pivot, have, tt.committed)
|
t.Errorf("head %d pivot %d canonical %v: isPivotCommitted = %v, want %v", tt.head, tt.pivot, tt.canonical, have, tt.committed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue