mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
eth/trie: Implement upgrade process for direct cache
This commit is contained in:
parent
548487b968
commit
0b12010d84
2 changed files with 38 additions and 10 deletions
|
|
@ -26,11 +26,13 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
||||||
var useSequentialKeys = []byte("dbUpgrade_20160530sequentialKeys")
|
var useSequentialKeys = []byte("dbUpgrade_20160530sequentialKeys")
|
||||||
|
|
@ -355,6 +357,32 @@ func addMipmapBloomBins(db ethdb.Database) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func populateDirectCache(db ethdb.Database, blockchain *core.BlockChain) error {
|
func populateDirectCache(db ethdb.Database, bc *core.BlockChain) error {
|
||||||
|
blockHash, status := trie.GetMigrationState(state.DirectCachePrefix, db)
|
||||||
|
if status == trie.NotStarted {
|
||||||
|
blockHash = core.GetHeadBlockHash(db)
|
||||||
|
status = trie.Running
|
||||||
|
trie.SetMigrationState(state.DirectCachePrefix, blockHash, status, db)
|
||||||
|
}
|
||||||
|
blockNum := core.GetBlockNumber(db, blockHash)
|
||||||
|
|
||||||
|
if status == trie.Running {
|
||||||
|
tr, err := trie.New(core.GetBlock(db, blockHash, blockNum).Root(), db, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dc := trie.NewDirectCache(tr, db, state.DirectCachePrefix, blockNum, blockHash, bc, false)
|
||||||
|
go func() {
|
||||||
|
for core.GetBlockNumber(db, core.GetHeadBlockHash(db)) < blockNum + 8 {
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
}
|
||||||
|
glog.Infof("Beginning direct cache upgrade at block %v", blockNum)
|
||||||
|
|
||||||
|
if err := dc.Populate(); err != nil {
|
||||||
|
glog.Errorf("Direct cache upgrade failed: %v", err)
|
||||||
|
}
|
||||||
|
trie.SetMigrationState(state.DirectCachePrefix, blockHash, trie.Complete, db)
|
||||||
|
}()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ func (dc *DirectCache) Populate() (err error) {
|
||||||
it := dc.Iterator()
|
it := dc.Iterator()
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
if err := DirectCacheTransaction(func() error {
|
if err := DirectCacheTransaction(func() error {
|
||||||
if HasDirectCache(dc.keyPrefix, it.Key, dc.db) {
|
if !HasDirectCache(dc.keyPrefix, it.Key, dc.db) {
|
||||||
writes += 1
|
writes += 1
|
||||||
if err = WriteDirectCache(dc.keyPrefix, it.Key, it.Value, dc.blockNum, dc.blockHash, dc.db); err != nil {
|
if err = WriteDirectCache(dc.keyPrefix, it.Key, it.Value, dc.blockNum, dc.blockHash, dc.db); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -202,7 +202,7 @@ func (dc *DirectCache) Populate() (err error) {
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
if i % 10000 == 0 && glog.V(logger.Info) {
|
if i % 10000 == 0 && glog.V(logger.Info) {
|
||||||
glog.V(logger.Info).Infof("Constructing direct cache: processed %v entries, writing %v", i, writes)
|
glog.V(logger.Info).Infof("Constructing direct cache: processed %v entries, written %v", i, writes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -271,29 +271,29 @@ func HasDirectCache(prefix, key []byte, db Database) bool {
|
||||||
|
|
||||||
type migrationState struct {
|
type migrationState struct {
|
||||||
Status MigrationStatus
|
Status MigrationStatus
|
||||||
Number uint64
|
Hash common.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMigrationState returns the block number of the migration to the direct cache, and
|
// GetMigrationState returns the block number of the migration to the direct cache, and
|
||||||
// whether or not it's complete.
|
// whether or not it's complete.
|
||||||
func GetMigrationState(prefix []byte, db Database) (uint64, MigrationStatus) {
|
func GetMigrationState(prefix []byte, db Database) (common.Hash, MigrationStatus) {
|
||||||
enc, _ := db.Get(append(MigrationPrefix, prefix...))
|
enc, _ := db.Get(append(MigrationPrefix, prefix...))
|
||||||
if len(enc) == 0 {
|
if len(enc) == 0 {
|
||||||
return 0, NotStarted
|
return common.Hash{}, NotStarted
|
||||||
}
|
}
|
||||||
|
|
||||||
var data migrationState
|
var data migrationState
|
||||||
if err := rlp.DecodeBytes(enc, &data); err != nil {
|
if err := rlp.DecodeBytes(enc, &data); err != nil {
|
||||||
glog.Errorf("Could not decode migration status: %v", err)
|
glog.Errorf("Could not decode migration status: %v", err)
|
||||||
return 0, NotStarted
|
return common.Hash{}, NotStarted
|
||||||
}
|
}
|
||||||
|
|
||||||
return data.Number, data.Status
|
return data.Hash, data.Status
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMigrationState updates the migration state in the database
|
// SetMigrationState updates the migration state in the database
|
||||||
func SetMigrationState(prefix []byte, blockNum uint64, status MigrationStatus, db Database) error {
|
func SetMigrationState(prefix []byte, blockHash common.Hash, status MigrationStatus, db Database) error {
|
||||||
enc, _ := rlp.EncodeToBytes(migrationState{status, blockNum})
|
enc, _ := rlp.EncodeToBytes(migrationState{status, blockHash})
|
||||||
return db.Put(append(MigrationPrefix, prefix...), enc)
|
return db.Put(append(MigrationPrefix, prefix...), enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue