mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
no more diskLayer
This commit is contained in:
parent
fd5078c779
commit
85867ad81f
4 changed files with 36 additions and 27 deletions
|
|
@ -371,8 +371,7 @@ func (db *Database) Recover(root common.Hash, loader triestate.TrieLoader) error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dl, err = dl.revert(h, loader)
|
if err = dl.revert(h, loader); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// reset layer with newly created disk layer. It must be
|
// reset layer with newly created disk layer. It must be
|
||||||
|
|
|
||||||
|
|
@ -152,5 +152,8 @@ func diffToDisk(layer *diffLayer, force bool) (layer, error) {
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Sprintf("unknown layer type: %T", layer.parentLayer()))
|
panic(fmt.Sprintf("unknown layer type: %T", layer.parentLayer()))
|
||||||
}
|
}
|
||||||
return disk.commit(layer, force)
|
if err := disk.commit(layer, force); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return disk, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ func (dl *diskLayer) update(root common.Hash, id uint64, block uint64, nodes map
|
||||||
// commit merges the given bottom-most diff layer into the node buffer
|
// commit merges the given bottom-most diff layer into the node buffer
|
||||||
// and returns a newly constructed disk layer. Note the current disk
|
// and returns a newly constructed disk layer. Note the current disk
|
||||||
// layer must be tagged as stale first to prevent re-access.
|
// layer must be tagged as stale first to prevent re-access.
|
||||||
func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
|
func (dl *diskLayer) commit(bottom *diffLayer, force bool) error {
|
||||||
dl.lock.Lock()
|
dl.lock.Lock()
|
||||||
defer dl.lock.Unlock()
|
defer dl.lock.Unlock()
|
||||||
|
|
||||||
|
|
@ -166,13 +166,13 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
|
||||||
if dl.db.freezer != nil {
|
if dl.db.freezer != nil {
|
||||||
err := writeHistory(dl.db.freezer, bottom)
|
err := writeHistory(dl.db.freezer, bottom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
// Determine if the persisted history object has exceeded the configured
|
// Determine if the persisted history object has exceeded the configured
|
||||||
// limitation, set the overflow as true if so.
|
// limitation, set the overflow as true if so.
|
||||||
tail, err := dl.db.freezer.Tail()
|
tail, err := dl.db.freezer.Tail()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
limit := dl.db.config.StateHistory
|
limit := dl.db.config.StateHistory
|
||||||
if limit != 0 && bottom.stateID()-tail > limit {
|
if limit != 0 && bottom.stateID()-tail > limit {
|
||||||
|
|
@ -194,7 +194,8 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
|
||||||
// Construct a new disk layer by merging the nodes from the provided diff
|
// Construct a new disk layer by merging the nodes from the provided diff
|
||||||
// layer, and flush the content in disk layer if there are too many nodes
|
// layer, and flush the content in disk layer if there are too many nodes
|
||||||
// cached. The clean cache is inherited from the original disk layer.
|
// cached. The clean cache is inherited from the original disk layer.
|
||||||
ndl := newDiskLayer(bottom.root, bottom.stateID(), dl.db, dl.cleans, dl.buffer.commit(bottom.nodes))
|
dl.buffer.commit(bottom.nodes)
|
||||||
|
dl.root, dl.id = bottom.root, bottom.stateID()
|
||||||
|
|
||||||
// In a unique scenario where the ID of the oldest history object (after tail
|
// In a unique scenario where the ID of the oldest history object (after tail
|
||||||
// truncation) surpasses the persisted state ID, we take the necessary action
|
// truncation) surpasses the persisted state ID, we take the necessary action
|
||||||
|
|
@ -203,35 +204,35 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
|
||||||
if !force && rawdb.ReadPersistentStateID(dl.db.diskdb) < oldest {
|
if !force && rawdb.ReadPersistentStateID(dl.db.diskdb) < oldest {
|
||||||
force = true
|
force = true
|
||||||
}
|
}
|
||||||
if err := ndl.buffer.flush(ndl.db.diskdb, ndl.cleans, ndl.id, force); err != nil {
|
if err := dl.buffer.flush(dl.db.diskdb, dl.cleans, dl.id, force); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
// To remove outdated history objects from the end, we set the 'tail' parameter
|
// To remove outdated history objects from the end, we set the 'tail' parameter
|
||||||
// to 'oldest-1' due to the offset between the freezer index and the history ID.
|
// to 'oldest-1' due to the offset between the freezer index and the history ID.
|
||||||
if overflow {
|
if overflow {
|
||||||
pruned, err := truncateFromTail(ndl.db.diskdb, ndl.db.freezer, oldest-1)
|
pruned, err := truncateFromTail(dl.db.diskdb, dl.db.freezer, oldest-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
log.Debug("Pruned state history", "items", pruned, "tailid", oldest)
|
log.Debug("Pruned state history", "items", pruned, "tailid", oldest)
|
||||||
}
|
}
|
||||||
return ndl, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// revert applies the given state history and return a reverted disk layer.
|
// revert applies the given state history and return a reverted disk layer.
|
||||||
func (dl *diskLayer) revert(h *history, loader triestate.TrieLoader) (*diskLayer, error) {
|
func (dl *diskLayer) revert(h *history, loader triestate.TrieLoader) error {
|
||||||
if h.meta.root != dl.rootHash() {
|
if h.meta.root != dl.rootHash() {
|
||||||
return nil, errUnexpectedHistory
|
return errUnexpectedHistory
|
||||||
}
|
}
|
||||||
if dl.id == 0 {
|
if dl.id == 0 {
|
||||||
return nil, fmt.Errorf("%w: zero state id", errStateUnrecoverable)
|
return fmt.Errorf("%w: zero state id", errStateUnrecoverable)
|
||||||
}
|
}
|
||||||
// Apply the reverse state changes upon the current state. This must
|
// Apply the reverse state changes upon the current state. This must
|
||||||
// be done before holding the lock in order to access state in "this"
|
// be done before holding the lock in order to access state in "this"
|
||||||
// layer.
|
// layer.
|
||||||
nodes, err := triestate.Apply(h.meta.parent, h.meta.root, h.accounts, h.storages, loader)
|
nodes, err := triestate.Apply(h.meta.parent, h.meta.root, h.accounts, h.storages, loader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
// Mark the diskLayer as stale before applying any mutations on top.
|
// Mark the diskLayer as stale before applying any mutations on top.
|
||||||
dl.lock.Lock()
|
dl.lock.Lock()
|
||||||
|
|
@ -247,7 +248,7 @@ func (dl *diskLayer) revert(h *history, loader triestate.TrieLoader) (*diskLayer
|
||||||
if !dl.buffer.empty() {
|
if !dl.buffer.empty() {
|
||||||
err := dl.buffer.revert(dl.db.diskdb, nodes)
|
err := dl.buffer.revert(dl.db.diskdb, nodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
batch := dl.db.diskdb.NewBatch()
|
batch := dl.db.diskdb.NewBatch()
|
||||||
|
|
@ -257,7 +258,10 @@ func (dl *diskLayer) revert(h *history, loader triestate.TrieLoader) (*diskLayer
|
||||||
log.Crit("Failed to write states", "err", err)
|
log.Crit("Failed to write states", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newDiskLayer(h.meta.parent, dl.id-1, dl.db, dl.cleans, dl.buffer), nil
|
|
||||||
|
dl.root, dl.id = h.meta.parent, dl.id-1
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// setBufferSize sets the node buffer size to the provided value.
|
// setBufferSize sets the node buffer size to the provided value.
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ import (
|
||||||
type layerTree struct {
|
type layerTree struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
layers map[common.Hash]layer
|
layers map[common.Hash]layer
|
||||||
|
|
||||||
|
origin *diskLayer
|
||||||
}
|
}
|
||||||
|
|
||||||
// newLayerTree constructs the layerTree with the given head layer.
|
// newLayerTree constructs the layerTree with the given head layer.
|
||||||
|
|
@ -52,6 +54,9 @@ func (tree *layerTree) reset(head layer) {
|
||||||
|
|
||||||
var layers = make(map[common.Hash]layer)
|
var layers = make(map[common.Hash]layer)
|
||||||
for head != nil {
|
for head != nil {
|
||||||
|
if disk, ok := head.(*diskLayer); ok {
|
||||||
|
tree.origin = disk
|
||||||
|
}
|
||||||
layers[head.rootHash()] = head
|
layers[head.rootHash()] = head
|
||||||
head = head.parentLayer()
|
head = head.parentLayer()
|
||||||
}
|
}
|
||||||
|
|
@ -131,6 +136,7 @@ func (tree *layerTree) cap(root common.Hash, layers int) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
tree.origin = base.(*diskLayer)
|
||||||
// Replace the entire layer tree with the flat base
|
// Replace the entire layer tree with the flat base
|
||||||
tree.layers = map[common.Hash]layer{base.rootHash(): base}
|
tree.layers = map[common.Hash]layer{base.rootHash(): base}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -161,6 +167,7 @@ func (tree *layerTree) cap(root common.Hash, layers int) error {
|
||||||
diff.lock.Unlock()
|
diff.lock.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
tree.origin = base.(*diskLayer)
|
||||||
tree.layers[base.rootHash()] = base
|
tree.layers[base.rootHash()] = base
|
||||||
diff.parent = base
|
diff.parent = base
|
||||||
|
|
||||||
|
|
@ -201,14 +208,10 @@ func (tree *layerTree) bottom() *diskLayer {
|
||||||
if len(tree.layers) == 0 {
|
if len(tree.layers) == 0 {
|
||||||
return nil // Shouldn't happen, empty tree
|
return nil // Shouldn't happen, empty tree
|
||||||
}
|
}
|
||||||
// pick a random one as the entry point
|
|
||||||
var current layer
|
if tree.origin == nil {
|
||||||
for _, layer := range tree.layers {
|
return nil
|
||||||
current = layer
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
for current.parentLayer() != nil {
|
|
||||||
current = current.parentLayer()
|
return tree.origin
|
||||||
}
|
|
||||||
return current.(*diskLayer)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue