aboutsummaryrefslogtreecommitdiffstats
path: root/eth/backend.go
diff options
context:
space:
mode:
authorzsfelfoldi <zsfelfoldi@gmail.com>2016-04-05 21:22:04 +0800
committerzsfelfoldi <zsfelfoldi@gmail.com>2016-06-07 22:38:56 +0800
commitf9917c8c7b6d16daadebd72977e56a8adc0382b0 (patch)
treeeb11524c618a44dbd499918761ba176a9addba58 /eth/backend.go
parent5a458da42ae9a6525989c2d4515c6fa573ba8f8c (diff)
downloaddexon-f9917c8c7b6d16daadebd72977e56a8adc0382b0.tar.gz
dexon-f9917c8c7b6d16daadebd72977e56a8adc0382b0.tar.zst
dexon-f9917c8c7b6d16daadebd72977e56a8adc0382b0.zip
core: improved chainDb using sequential keys
Diffstat (limited to 'eth/backend.go')
-rw-r--r--eth/backend.go118
1 files changed, 10 insertions, 108 deletions
diff --git a/eth/backend.go b/eth/backend.go
index bb487650b..006523484 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -18,7 +18,6 @@
package eth
import (
- "bytes"
"errors"
"fmt"
"math/big"
@@ -47,7 +46,6 @@ import (
"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
)
@@ -104,9 +102,9 @@ type Config struct {
}
type Ethereum struct {
- chainConfig *core.ChainConfig
- // Channel for shutting down the ethereum
- shutdownChan chan bool
+ chainConfig *core.ChainConfig
+ shutdownChan chan bool // Channel for shutting down the ethereum
+ stopDbUpgrade func() // stop chain db sequential key upgrade
// DB interfaces
chainDb ethdb.Database // Block chain database
@@ -161,6 +159,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
if err := addMipmapBloomBins(chainDb); err != nil {
return nil, err
}
+ stopDbUpgrade := upgradeSequentialKeys(chainDb)
dappDb, err := ctx.OpenDatabase("dapp", config.DatabaseCache, config.DatabaseHandles)
if err != nil {
@@ -185,7 +184,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
chainDb = config.TestGenesisState
}
if config.TestGenesisBlock != nil {
- core.WriteTd(chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.Difficulty())
+ core.WriteTd(chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64(), config.TestGenesisBlock.Difficulty())
core.WriteBlock(chainDb, config.TestGenesisBlock)
core.WriteCanonicalHash(chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64())
core.WriteHeadBlockHash(chainDb, config.TestGenesisBlock.Hash())
@@ -202,6 +201,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
eth := &Ethereum{
shutdownChan: make(chan bool),
+ stopDbUpgrade: stopDbUpgrade,
chainDb: chainDb,
dappDb: dappDb,
eventMux: ctx.EventMux,
@@ -238,7 +238,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
// load the genesis block or write a new one if no genesis
// block is prenent in the database.
- genesis := core.GetBlock(chainDb, core.GetCanonicalHash(chainDb, 0))
+ genesis := core.GetBlock(chainDb, core.GetCanonicalHash(chainDb, 0), 0)
if genesis == nil {
genesis, err = core.WriteDefaultGenesisBlock(chainDb)
if err != nil {
@@ -415,6 +415,9 @@ func (s *Ethereum) Start(srvr *p2p.Server) error {
// Stop implements node.Service, terminating all internal goroutines used by the
// Ethereum protocol.
func (s *Ethereum) Stop() error {
+ if s.stopDbUpgrade != nil {
+ s.stopDbUpgrade()
+ }
s.blockchain.Stop()
s.protocolManager.Stop()
s.txPool.Stop()
@@ -526,104 +529,3 @@ func dagFiles(epoch uint64) (string, string) {
dag := fmt.Sprintf("full-R%d-%x", ethashRevision, seedHash[:8])
return dag, "full-R" + dag
}
-
-// upgradeChainDatabase ensures that the chain database stores block split into
-// separate header and body entries.
-func upgradeChainDatabase(db ethdb.Database) error {
- // Short circuit if the head block is stored already as separate header and body
- data, err := db.Get([]byte("LastBlock"))
- if err != nil {
- return nil
- }
- head := common.BytesToHash(data)
-
- if block := core.GetBlockByHashOld(db, head); block == nil {
- return nil
- }
- // At least some of the database is still the old format, upgrade (skip the head block!)
- glog.V(logger.Info).Info("Old database detected, upgrading...")
-
- if db, ok := db.(*ethdb.LDBDatabase); ok {
- blockPrefix := []byte("block-hash-")
- for it := db.NewIterator(); it.Next(); {
- // Skip anything other than a combined block
- if !bytes.HasPrefix(it.Key(), blockPrefix) {
- continue
- }
- // Skip the head block (merge last to signal upgrade completion)
- if bytes.HasSuffix(it.Key(), head.Bytes()) {
- continue
- }
- // Load the block, split and serialize (order!)
- block := core.GetBlockByHashOld(db, common.BytesToHash(bytes.TrimPrefix(it.Key(), blockPrefix)))
-
- if err := core.WriteTd(db, block.Hash(), block.DeprecatedTd()); err != nil {
- return err
- }
- if err := core.WriteBody(db, block.Hash(), block.Body()); err != nil {
- return err
- }
- if err := core.WriteHeader(db, block.Header()); err != nil {
- return err
- }
- if err := db.Delete(it.Key()); err != nil {
- return err
- }
- }
- // Lastly, upgrade the head block, disabling the upgrade mechanism
- current := core.GetBlockByHashOld(db, head)
-
- if err := core.WriteTd(db, current.Hash(), current.DeprecatedTd()); err != nil {
- return err
- }
- if err := core.WriteBody(db, current.Hash(), current.Body()); err != nil {
- return err
- }
- if err := core.WriteHeader(db, current.Header()); err != nil {
- return err
- }
- }
- return nil
-}
-
-func addMipmapBloomBins(db ethdb.Database) (err error) {
- const mipmapVersion uint = 2
-
- // check if the version is set. We ignore data for now since there's
- // only one version so we can easily ignore it for now
- var data []byte
- data, _ = db.Get([]byte("setting-mipmap-version"))
- if len(data) > 0 {
- var version uint
- if err := rlp.DecodeBytes(data, &version); err == nil && version == mipmapVersion {
- return nil
- }
- }
-
- defer func() {
- if err == nil {
- var val []byte
- val, err = rlp.EncodeToBytes(mipmapVersion)
- if err == nil {
- err = db.Put([]byte("setting-mipmap-version"), val)
- }
- return
- }
- }()
- latestBlock := core.GetBlock(db, core.GetHeadBlockHash(db))
- if latestBlock == nil { // clean database
- return
- }
-
- tstart := time.Now()
- glog.V(logger.Info).Infoln("upgrading db log bloom bins")
- for i := uint64(0); i <= latestBlock.NumberU64(); i++ {
- hash := core.GetCanonicalHash(db, i)
- if (hash == common.Hash{}) {
- return fmt.Errorf("chain db corrupted. Could not find block %d.", i)
- }
- core.WriteMipmapBloom(db, i, core.GetBlockReceipts(db, hash))
- }
- glog.V(logger.Info).Infoln("upgrade completed in", time.Since(tstart))
- return nil
-}