triedb, core: polish code

This commit is contained in:
Gary Rong 2026-05-15 14:57:10 +08:00
parent e67fa13e34
commit 133ee263c8
7 changed files with 60 additions and 74 deletions

View file

@ -90,16 +90,17 @@ const (
stateHistoryStorageData = "storage.data"
)
// StateHistoryTailGroup is the tail group shared by all state history tables.
const StateHistoryTailGroup = "history"
// DefaultHistoryGroup is the tail group shared by all state/trienode history
// tables with tail pruning enabled.
const DefaultHistoryGroup = "history"
// stateFreezerTableConfigs configures the settings for tables in the state freezer.
var stateFreezerTableConfigs = map[string]freezerTableConfig{
stateHistoryMeta: {noSnappy: true, tailGroup: StateHistoryTailGroup},
stateHistoryAccountIndex: {noSnappy: false, tailGroup: StateHistoryTailGroup},
stateHistoryStorageIndex: {noSnappy: false, tailGroup: StateHistoryTailGroup},
stateHistoryAccountData: {noSnappy: false, tailGroup: StateHistoryTailGroup},
stateHistoryStorageData: {noSnappy: false, tailGroup: StateHistoryTailGroup},
stateHistoryMeta: {noSnappy: true, tailGroup: DefaultHistoryGroup},
stateHistoryAccountIndex: {noSnappy: false, tailGroup: DefaultHistoryGroup},
stateHistoryStorageIndex: {noSnappy: false, tailGroup: DefaultHistoryGroup},
stateHistoryAccountData: {noSnappy: false, tailGroup: DefaultHistoryGroup},
stateHistoryStorageData: {noSnappy: false, tailGroup: DefaultHistoryGroup},
}
const (
@ -108,18 +109,15 @@ const (
trienodeHistoryValueSectionTable = "trienode.value"
)
// TrienodeHistoryTailGroup is the tail group shared by all trienode history tables.
const TrienodeHistoryTailGroup = "history"
// trienodeFreezerTableConfigs configures the settings for tables in the trienode freezer.
var trienodeFreezerTableConfigs = map[string]freezerTableConfig{
trienodeHistoryHeaderTable: {noSnappy: false, tailGroup: TrienodeHistoryTailGroup},
trienodeHistoryHeaderTable: {noSnappy: false, tailGroup: DefaultHistoryGroup},
// Disable snappy compression to allow efficient partial read.
trienodeHistoryKeySectionTable: {noSnappy: true, tailGroup: TrienodeHistoryTailGroup},
trienodeHistoryKeySectionTable: {noSnappy: true, tailGroup: DefaultHistoryGroup},
// Disable snappy compression to allow efficient partial read.
trienodeHistoryValueSectionTable: {noSnappy: true, tailGroup: TrienodeHistoryTailGroup},
trienodeHistoryValueSectionTable: {noSnappy: true, tailGroup: DefaultHistoryGroup},
}
// The list of identifiers of ancient stores.

View file

@ -59,7 +59,8 @@ const freezerTableSize = 2 * 1000 * 1000 * 1000
// - The in-order data ensures that disk reads are always optimized.
type Freezer struct {
datadir string
head atomic.Uint64 // Number of items stored (including items removed from tail)
head atomic.Uint64 // Number of items stored (including items removed from tail)
tails map[string]*atomic.Uint64 // Per-group tail cache, keyed by tail group name
// This lock synchronizes writers and the truncate operation, as well as
// the "atomic" (batched) read operations.
@ -117,6 +118,7 @@ func NewFreezer(datadir string, namespace string, readonly bool, maxTableSize ui
datadir: datadir,
readonly: readonly,
tables: make(map[string]*freezerTable),
tails: make(map[string]*atomic.Uint64),
instanceLock: lock,
}
@ -216,32 +218,18 @@ func (f *Freezer) Ancients() (uint64, error) {
}
// Tail returns the lowest accessible item index for the given tail group.
// All tables sharing this group must agree on the tail; an empty group name
// refers to non-prunable tables and always returns 0.
// All tables sharing this group agree on the tail; an empty group name
// refers to non-prunable tables and always returns 0. Unknown groups return
// an error.
func (f *Freezer) Tail(group string) (uint64, error) {
if group == "" {
return 0, nil
}
var (
tail uint64
found bool
)
for _, table := range f.tables {
if table.config.tailGroup != group {
continue
}
h := table.itemHidden.Load()
if !found {
tail = h
found = true
} else if h != tail {
return 0, fmt.Errorf("inconsistent tail in group %q: %d vs %d", group, h, tail)
}
}
if !found {
tail, ok := f.tails[group]
if !ok {
return 0, fmt.Errorf("unknown tail group: %q", group)
}
return tail, nil
return tail.Load(), nil
}
// AncientSize returns the ancient size of the specified category.
@ -333,25 +321,14 @@ func (f *Freezer) TruncateTail(group string, tail uint64) (uint64, error) {
if group == "" {
return 0, errors.New("empty tail group")
}
cached, ok := f.tails[group]
if !ok {
return 0, fmt.Errorf("unknown tail group: %q", group)
}
f.writeLock.Lock()
defer f.writeLock.Unlock()
var (
prev uint64
found bool
)
for _, table := range f.tables {
if table.config.tailGroup != group {
continue
}
if !found {
prev = table.itemHidden.Load()
found = true
}
}
if !found {
return 0, fmt.Errorf("unknown tail group: %q", group)
}
prev := cached.Load()
for _, table := range f.tables {
if table.config.tailGroup != group {
continue
@ -360,6 +337,9 @@ func (f *Freezer) TruncateTail(group string, tail uint64) (uint64, error) {
return 0, err
}
}
if tail > prev {
cached.Store(tail)
}
// Update the head if the requested tail exceeds the current head.
if f.head.Load() < tail {
f.head.Store(tail)
@ -388,11 +368,12 @@ func (f *Freezer) validate() error {
return nil
}
var (
head uint64
headSet bool
groupTails = make(map[string]uint64)
head uint64
headSet bool
tails = make(map[string]uint64)
)
for kind, table := range f.tables {
// Validate the table head
items := table.items.Load()
if !headSet {
head = items
@ -400,6 +381,7 @@ func (f *Freezer) validate() error {
} else if items != head {
return fmt.Errorf("freezer table %s has a differing head: %d != %d", kind, items, head)
}
// Validate the table tail
if table.config.tailGroup == "" {
if table.itemHidden.Load() != 0 {
return fmt.Errorf("non-prunable freezer table '%s' has a non-zero tail: %d", kind, table.itemHidden.Load())
@ -407,15 +389,21 @@ func (f *Freezer) validate() error {
continue
}
hidden := table.itemHidden.Load()
if t, ok := groupTails[table.config.tailGroup]; ok {
if t, ok := tails[table.config.tailGroup]; ok {
if t != hidden {
return fmt.Errorf("freezer table %s has differing tail in group %q: %d != %d", kind, table.config.tailGroup, hidden, t)
}
} else {
groupTails[table.config.tailGroup] = hidden
tails[table.config.tailGroup] = hidden
}
}
f.head.Store(head)
for group, tail := range tails {
counter := new(atomic.Uint64)
counter.Store(tail)
f.tails[group] = counter
}
return nil
}
@ -463,7 +451,7 @@ func (f *Freezer) repair() error {
}
// Per-group tail alignment: take the maximum tail in each group and apply
// it to all members. Non-prunable tables must remain at tail 0.
groupTails := make(map[string]uint64)
tails := make(map[string]uint64)
for kind, table := range f.tables {
if table.config.tailGroup == "" {
if table.itemHidden.Load() != 0 {
@ -472,18 +460,24 @@ func (f *Freezer) repair() error {
continue
}
hidden := table.itemHidden.Load()
if t, ok := groupTails[table.config.tailGroup]; !ok || hidden > t {
groupTails[table.config.tailGroup] = hidden
if t, ok := tails[table.config.tailGroup]; !ok || hidden > t {
tails[table.config.tailGroup] = hidden
}
}
for _, table := range f.tables {
if table.config.tailGroup == "" {
continue
}
if err := table.truncateTail(groupTails[table.config.tailGroup]); err != nil {
if err := table.truncateTail(tails[table.config.tailGroup]); err != nil {
return err
}
}
f.head.Store(head)
for group, tail := range tails {
counter := new(atomic.Uint64)
counter.Store(tail)
f.tails[group] = counter
}
return nil
}

View file

@ -378,7 +378,7 @@ func (dl *diskLayer) writeHistory(typ historyType, diff *diffLayer) (bool, error
if limit == 0 {
return false, nil
}
tail, err := freezer.Tail(rawdb.StateHistoryTailGroup)
tail, err := freezer.Tail(rawdb.DefaultHistoryGroup)
if err != nil {
return false, err
} // firstID = tail+1

View file

@ -273,7 +273,7 @@ func truncateFromHead(store ethdb.AncientStore, typ historyType, nhead uint64) (
if err != nil {
return 0, err
}
otail, err := store.Tail(rawdb.StateHistoryTailGroup)
otail, err := store.Tail(rawdb.DefaultHistoryGroup)
if err != nil {
return 0, err
}
@ -303,13 +303,7 @@ func truncateFromTail(store ethdb.AncientStore, typ historyType, ntail uint64) (
if err != nil {
return 0, err
}
var group string
if typ == typeStateHistory {
group = rawdb.StateHistoryTailGroup
} else {
group = rawdb.TrienodeHistoryTailGroup
}
otail, err := store.Tail(group)
otail, err := store.Tail(rawdb.DefaultHistoryGroup)
if err != nil {
return 0, err
}
@ -321,7 +315,7 @@ func truncateFromTail(store ethdb.AncientStore, typ historyType, ntail uint64) (
if otail == ntail {
return 0, nil
}
otail, err = store.TruncateTail(group, ntail)
otail, err = store.TruncateTail(rawdb.DefaultHistoryGroup, ntail)
if err != nil {
return 0, err
}
@ -436,7 +430,7 @@ func repairHistory(db ethdb.Database, isUBT bool, readOnly bool, stateID uint64,
truncTo = min(truncTo, thead)
} else {
if thead == 0 {
_, err = trienodes.TruncateTail(rawdb.TrienodeHistoryTailGroup, stateID)
_, err = trienodes.TruncateTail(rawdb.DefaultHistoryGroup, stateID)
if err != nil {
return nil, nil, err
}

View file

@ -542,7 +542,7 @@ func (i *indexIniter) run(recover bool) {
// next returns the ID of the next state history to be indexed.
func (i *indexIniter) next() (uint64, error) {
tail, err := i.freezer.Tail(rawdb.StateHistoryTailGroup)
tail, err := i.freezer.Tail(rawdb.DefaultHistoryGroup)
if err != nil {
return 0, err
}

View file

@ -38,7 +38,7 @@ type HistoryStats struct {
// sanitizeRange limits the given range to fit within the local history store.
func sanitizeRange(start, end uint64, freezer ethdb.AncientReader) (uint64, uint64, error) {
// Load the id of the first history object in local store.
tail, err := freezer.Tail(rawdb.StateHistoryTailGroup)
tail, err := freezer.Tail(rawdb.DefaultHistoryGroup)
if err != nil {
return 0, 0, err
}
@ -133,7 +133,7 @@ func storageHistory(freezer ethdb.AncientReader, address common.Address, slot co
// historyRange returns the block number range of local state histories.
func historyRange(freezer ethdb.AncientReader) (uint64, uint64, error) {
// Load the id of the first history object in local store.
tail, err := freezer.Tail(rawdb.StateHistoryTailGroup)
tail, err := freezer.Tail(rawdb.DefaultHistoryGroup)
if err != nil {
return 0, 0, err
}

View file

@ -470,7 +470,7 @@ func checkStateAvail(state stateIdent, exptyp historyType, freezer ethdb.Ancient
return 0, fmt.Errorf("unsupported history type: %d, want: %v", toHistoryType(state.typ), exptyp)
}
// firstID = tail+1
tail, err := freezer.Tail(rawdb.StateHistoryTailGroup)
tail, err := freezer.Tail(rawdb.DefaultHistoryGroup)
if err != nil {
return 0, err
}