mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
core/rawdb: un-embed freezer instance in chainFreezer
This commit is contained in:
parent
cc914b49e0
commit
9b1b2f69b8
1 changed files with 52 additions and 25 deletions
|
|
@ -44,7 +44,7 @@ const (
|
||||||
// feature. The background thread will keep moving ancient chain segments from
|
// feature. The background thread will keep moving ancient chain segments from
|
||||||
// key-value database to flat files for saving space on live database.
|
// key-value database to flat files for saving space on live database.
|
||||||
type chainFreezer struct {
|
type chainFreezer struct {
|
||||||
ethdb.AncientStore // Ancient store for storing cold chain segment
|
ancients ethdb.AncientStore // Ancient store for storing cold chain segment
|
||||||
|
|
||||||
// Optional Era database used as a backup for the pruned chain.
|
// Optional Era database used as a backup for the pruned chain.
|
||||||
eradb *eradb.Store
|
eradb *eradb.Store
|
||||||
|
|
@ -63,9 +63,9 @@ type chainFreezer struct {
|
||||||
func newChainFreezer(datadir string, namespace string, readonly bool, eraDir string) (*chainFreezer, error) {
|
func newChainFreezer(datadir string, namespace string, readonly bool, eraDir string) (*chainFreezer, error) {
|
||||||
if datadir == "" {
|
if datadir == "" {
|
||||||
return &chainFreezer{
|
return &chainFreezer{
|
||||||
AncientStore: NewMemoryFreezer(readonly, chainFreezerTableConfigs),
|
ancients: NewMemoryFreezer(readonly, chainFreezerTableConfigs),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
trigger: make(chan chan struct{}),
|
trigger: make(chan chan struct{}),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
freezer, err := NewFreezer(datadir, namespace, readonly, freezerTableSize, chainFreezerTableConfigs)
|
freezer, err := NewFreezer(datadir, namespace, readonly, freezerTableSize, chainFreezerTableConfigs)
|
||||||
|
|
@ -80,10 +80,10 @@ func newChainFreezer(datadir string, namespace string, readonly bool, eraDir str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &chainFreezer{
|
return &chainFreezer{
|
||||||
AncientStore: freezer,
|
ancients: freezer,
|
||||||
eradb: edb,
|
eradb: edb,
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
trigger: make(chan chan struct{}),
|
trigger: make(chan chan struct{}),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,13 +96,10 @@ func (f *chainFreezer) Close() error {
|
||||||
}
|
}
|
||||||
f.wg.Wait()
|
f.wg.Wait()
|
||||||
|
|
||||||
var errs []error
|
|
||||||
if f.eradb != nil {
|
if f.eradb != nil {
|
||||||
f.eradb.Close()
|
f.eradb.Close()
|
||||||
}
|
}
|
||||||
errs = append(errs, f.AncientStore.Close())
|
return f.ancients.Close()
|
||||||
|
|
||||||
return errors.Join(errs...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// readHeadNumber returns the number of chain head block. 0 is returned if the
|
// readHeadNumber returns the number of chain head block. 0 is returned if the
|
||||||
|
|
@ -199,7 +196,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) {
|
||||||
log.Debug("Current full block not old enough to freeze", "err", err)
|
log.Debug("Current full block not old enough to freeze", "err", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
frozen, _ := f.Ancients() // no error will occur, safe to ignore
|
frozen, _ := f.ancients.Ancients() // no error will occur, safe to ignore
|
||||||
|
|
||||||
// Short circuit if the blocks below threshold are already frozen.
|
// Short circuit if the blocks below threshold are already frozen.
|
||||||
if frozen != 0 && frozen-1 >= threshold {
|
if frozen != 0 && frozen-1 >= threshold {
|
||||||
|
|
@ -242,7 +239,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) {
|
||||||
|
|
||||||
// Wipe out side chains also and track dangling side chains
|
// Wipe out side chains also and track dangling side chains
|
||||||
var dangling []common.Hash
|
var dangling []common.Hash
|
||||||
frozen, _ = f.Ancients() // Needs reload after during freezeRange
|
frozen, _ = f.ancients.Ancients() // Needs reload after during freezeRange
|
||||||
for number := first; number < frozen; number++ {
|
for number := first; number < frozen; number++ {
|
||||||
// Always keep the genesis block in active database
|
// Always keep the genesis block in active database
|
||||||
if number != 0 {
|
if number != 0 {
|
||||||
|
|
@ -314,7 +311,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) {
|
||||||
func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hashes []common.Hash, err error) {
|
func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hashes []common.Hash, err error) {
|
||||||
hashes = make([]common.Hash, 0, limit-number+1)
|
hashes = make([]common.Hash, 0, limit-number+1)
|
||||||
|
|
||||||
_, err = f.ModifyAncients(func(op ethdb.AncientWriteOp) error {
|
_, err = f.ancients.ModifyAncients(func(op ethdb.AncientWriteOp) error {
|
||||||
for ; number <= limit; number++ {
|
for ; number <= limit; number++ {
|
||||||
// Retrieve all the components of the canonical block.
|
// Retrieve all the components of the canonical block.
|
||||||
hash := ReadCanonicalHash(nfdb, number)
|
hash := ReadCanonicalHash(nfdb, number)
|
||||||
|
|
@ -358,15 +355,15 @@ func (f *chainFreezer) Ancient(kind string, number uint64) ([]byte, error) {
|
||||||
// Lookup the entry in the underlying ancient store, assuming that
|
// Lookup the entry in the underlying ancient store, assuming that
|
||||||
// headers and hashes are always available.
|
// headers and hashes are always available.
|
||||||
if kind == ChainFreezerHeaderTable || kind == ChainFreezerHashTable {
|
if kind == ChainFreezerHeaderTable || kind == ChainFreezerHashTable {
|
||||||
return f.AncientStore.Ancient(kind, number)
|
return f.ancients.Ancient(kind, number)
|
||||||
}
|
}
|
||||||
tail, err := f.Tail()
|
tail, err := f.ancients.Tail()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Lookup the entry in the underlying ancient store if it's not pruned
|
// Lookup the entry in the underlying ancient store if it's not pruned
|
||||||
if number >= tail {
|
if number >= tail {
|
||||||
return f.AncientStore.Ancient(kind, number)
|
return f.ancients.Ancient(kind, number)
|
||||||
}
|
}
|
||||||
// Lookup the entry in the optional era backend
|
// Lookup the entry in the optional era backend
|
||||||
if f.eradb == nil {
|
if f.eradb == nil {
|
||||||
|
|
@ -381,16 +378,46 @@ func (f *chainFreezer) Ancient(kind string, number uint64) ([]byte, error) {
|
||||||
return nil, errUnknownTable
|
return nil, errUnknownTable
|
||||||
}
|
}
|
||||||
|
|
||||||
// AncientRange retrieves multiple items in sequence, starting from the index 'start'.
|
// ReadAncients executes an operation while preventing mutations to the freezer,
|
||||||
// It will return
|
// i.e. if fn performs multiple reads, they will be consistent with each other.
|
||||||
// - at most 'count' items,
|
|
||||||
// - if maxBytes is specified: at least 1 item (even if exceeding the maxByteSize),
|
|
||||||
// but will otherwise return as many items as fit into maxByteSize.
|
|
||||||
// - if maxBytes is not specified, 'count' items will be returned if they are present.
|
|
||||||
func (f *chainFreezer) ReadAncients(fn func(ethdb.AncientReaderOp) error) (err error) {
|
func (f *chainFreezer) ReadAncients(fn func(ethdb.AncientReaderOp) error) (err error) {
|
||||||
if store, ok := f.AncientStore.(*Freezer); ok {
|
if store, ok := f.ancients.(*Freezer); ok {
|
||||||
store.writeLock.Lock()
|
store.writeLock.Lock()
|
||||||
defer store.writeLock.Unlock()
|
defer store.writeLock.Unlock()
|
||||||
}
|
}
|
||||||
return fn(f)
|
return fn(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Methods below are just pass-through to the underlying ancient store.
|
||||||
|
|
||||||
|
func (f *chainFreezer) Ancients() (uint64, error) {
|
||||||
|
return f.ancients.Ancients()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *chainFreezer) Tail() (uint64, error) {
|
||||||
|
return f.ancients.Tail()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *chainFreezer) AncientSize(kind string) (uint64, error) {
|
||||||
|
return f.ancients.AncientSize(kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *chainFreezer) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) {
|
||||||
|
return f.ancients.AncientRange(kind, start, count, maxBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *chainFreezer) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (int64, error) {
|
||||||
|
return f.ancients.ModifyAncients(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *chainFreezer) TruncateHead(items uint64) (uint64, error) {
|
||||||
|
return f.ancients.TruncateHead(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *chainFreezer) TruncateTail(items uint64) (uint64, error) {
|
||||||
|
return f.ancients.TruncateTail(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *chainFreezer) SyncAncient() error {
|
||||||
|
return f.ancients.SyncAncient()
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue