core/rawdb: don't check different lenghts in freezer

This commit is contained in:
Marius van der Wijden 2025-03-12 17:50:55 +01:00 committed by Felix Lange
parent f9f1172d59
commit b22bb9869c

View file

@ -336,33 +336,68 @@ func (f *Freezer) Sync() error {
return nil return nil
} }
// splitTables splits tables in header and non-header tables
func splitTables(tables map[string]*freezerTable) (map[string]*freezerTable, map[string]*freezerTable) {
var (
headTables = make(map[string]*freezerTable)
otherTables = make(map[string]*freezerTable)
)
for kind, table := range tables {
if kind == ChainFreezerHeaderTable || kind == ChainFreezerHashTable {
headTables[kind] = table
} else {
otherTables[kind] = table
}
}
return headTables, otherTables
}
// validate checks that every table has the same boundary. // validate checks that every table has the same boundary.
// Used instead of `repair` in readonly mode. // Used instead of `repair` in readonly mode.
func (f *Freezer) validate() error { func (f *Freezer) validate() error {
if len(f.tables) == 0 { if len(f.tables) == 0 {
return nil return nil
} }
var (
head uint64 check := func(tables map[string]*freezerTable) (uint64, uint64, error) {
tail uint64 var (
name string head uint64
) tail uint64
// Hack to get boundary of any table name string
for kind, table := range f.tables { )
head = table.items.Load() // Hack to get boundary of any table
tail = table.itemHidden.Load() for kind, table := range tables {
name = kind head = table.items.Load()
break tail = table.itemHidden.Load()
} name = kind
// Now check every table against those boundaries. break
for kind, table := range f.tables {
if head != table.items.Load() {
return fmt.Errorf("freezer tables %s and %s have differing head: %d != %d", kind, name, table.items.Load(), head)
} }
if tail != table.itemHidden.Load() { // Now check every table against those boundaries.
return fmt.Errorf("freezer tables %s and %s have differing tail: %d != %d", kind, name, table.itemHidden.Load(), tail) for kind, table := range tables {
if head != table.items.Load() {
return 0, 0, fmt.Errorf("freezer tables %s and %s have differing head: %d != %d", kind, name, table.items.Load(), head)
}
if tail != table.itemHidden.Load() {
return 0, 0, fmt.Errorf("freezer tables %s and %s have differing tail: %d != %d", kind, name, table.itemHidden.Load(), tail)
}
}
return head, tail, nil
}
headTables, otherTables := splitTables(f.tables)
// verify that all the non-header tables have the same size
head, tail, err := check(otherTables)
if err != nil {
return err
}
// verify that the header tables have the same size
if len(headTables) != 0 {
head, tail, err = check(headTables)
if err != nil {
return err
} }
} }
f.frozen.Store(head) f.frozen.Store(head)
f.tail.Store(tail) f.tail.Store(tail)
return nil return nil
@ -370,28 +405,40 @@ func (f *Freezer) validate() error {
// repair truncates all data tables to the same length. // repair truncates all data tables to the same length.
func (f *Freezer) repair() error { func (f *Freezer) repair() error {
var ( repair := func(tables map[string]*freezerTable) (uint64, uint64, error) {
head = uint64(math.MaxUint64) var (
tail = uint64(0) head = uint64(math.MaxUint64)
) tail = uint64(0)
for _, table := range f.tables { )
items := table.items.Load() for _, table := range tables {
if head > items { head = min(head, table.items.Load())
head = items tail = max(tail, table.itemHidden.Load())
} }
hidden := table.itemHidden.Load() for _, table := range tables {
if hidden > tail { if err := table.truncateHead(head); err != nil {
tail = hidden return 0, 0, err
}
if err := table.truncateTail(tail); err != nil {
return 0, 0, err
}
} }
return head, tail, nil
} }
for _, table := range f.tables {
if err := table.truncateHead(head); err != nil { headTables, otherTables := splitTables(f.tables)
return err // verify that all the non-header tables have the same size
} head, tail, err := repair(otherTables)
if err := table.truncateTail(tail); err != nil { if err != nil {
return err
}
// verify that the header tables have the same size
if len(headTables) != 0 {
head, tail, err = repair(headTables)
if err != nil {
return err return err
} }
} }
f.frozen.Store(head) f.frozen.Store(head)
f.tail.Store(tail) f.tail.Store(tail)
return nil return nil