mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
core/rawdb: don't check different lenghts in freezer
This commit is contained in:
parent
f9f1172d59
commit
b22bb9869c
1 changed files with 81 additions and 34 deletions
|
|
@ -336,33 +336,68 @@ func (f *Freezer) Sync() error {
|
|||
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.
|
||||
// Used instead of `repair` in readonly mode.
|
||||
func (f *Freezer) validate() error {
|
||||
if len(f.tables) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
check := func(tables map[string]*freezerTable) (uint64, uint64, error) {
|
||||
var (
|
||||
head uint64
|
||||
tail uint64
|
||||
name string
|
||||
)
|
||||
// Hack to get boundary of any table
|
||||
for kind, table := range f.tables {
|
||||
for kind, table := range tables {
|
||||
head = table.items.Load()
|
||||
tail = table.itemHidden.Load()
|
||||
name = kind
|
||||
break
|
||||
}
|
||||
// Now check every table against those boundaries.
|
||||
for kind, table := range f.tables {
|
||||
for kind, table := range 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)
|
||||
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 fmt.Errorf("freezer tables %s and %s have differing tail: %d != %d", kind, name, table.itemHidden.Load(), tail)
|
||||
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.tail.Store(tail)
|
||||
return nil
|
||||
|
|
@ -370,28 +405,40 @@ func (f *Freezer) validate() error {
|
|||
|
||||
// repair truncates all data tables to the same length.
|
||||
func (f *Freezer) repair() error {
|
||||
repair := func(tables map[string]*freezerTable) (uint64, uint64, error) {
|
||||
var (
|
||||
head = uint64(math.MaxUint64)
|
||||
tail = uint64(0)
|
||||
)
|
||||
for _, table := range f.tables {
|
||||
items := table.items.Load()
|
||||
if head > items {
|
||||
head = items
|
||||
for _, table := range tables {
|
||||
head = min(head, table.items.Load())
|
||||
tail = max(tail, table.itemHidden.Load())
|
||||
}
|
||||
hidden := table.itemHidden.Load()
|
||||
if hidden > tail {
|
||||
tail = hidden
|
||||
}
|
||||
}
|
||||
for _, table := range f.tables {
|
||||
for _, table := range tables {
|
||||
if err := table.truncateHead(head); err != nil {
|
||||
return err
|
||||
return 0, 0, err
|
||||
}
|
||||
if err := table.truncateTail(tail); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
}
|
||||
return head, tail, nil
|
||||
}
|
||||
|
||||
headTables, otherTables := splitTables(f.tables)
|
||||
// verify that all the non-header tables have the same size
|
||||
head, tail, err := repair(otherTables)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
f.frozen.Store(head)
|
||||
f.tail.Store(tail)
|
||||
return nil
|
||||
|
|
|
|||
Loading…
Reference in a new issue