feat: add version state debug system
This commit is contained in:
parent
f67f494346
commit
23c60a38a4
@ -34,6 +34,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/console/prompt"
|
"github.com/ethereum/go-ethereum/console/prompt"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
@ -286,8 +287,41 @@ WARNING: This is a low-level operation which may cause database corruption!`,
|
|||||||
Description: `This commands will read current offset from kvdb, which is the current offset and starting BlockNumber
|
Description: `This commands will read current offset from kvdb, which is the current offset and starting BlockNumber
|
||||||
of ancientStore, will also displays the reserved number of blocks in ancientStore `,
|
of ancientStore, will also displays the reserved number of blocks in ancientStore `,
|
||||||
}
|
}
|
||||||
|
getVersionDBState = &cli.Command{
|
||||||
|
Action: getDebugVersionState,
|
||||||
|
Name: "get-debug-version-state",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
utils.DataDirFlag,
|
||||||
|
utils.BlockNumber,
|
||||||
|
},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func getDebugVersionState(ctx *cli.Context) error {
|
||||||
|
if !ctx.IsSet(utils.DataDirFlag.Name) {
|
||||||
|
return fmt.Errorf("please set `--datadir` flag")
|
||||||
|
}
|
||||||
|
if !ctx.IsSet(utils.BlockNumber.Name) {
|
||||||
|
return fmt.Errorf("please set `--block` flag")
|
||||||
|
}
|
||||||
|
dir := ctx.String(utils.DataDirFlag.Name)
|
||||||
|
block := ctx.Int64(utils.BlockNumber.Name)
|
||||||
|
db, err := rawdb.Open(rawdb.OpenOptions{
|
||||||
|
ReadOnly: true,
|
||||||
|
Type: "leveldb",
|
||||||
|
Directory: dir,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, err := db.Get(state.DebugStateKey(block))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(string(data))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func removeDB(ctx *cli.Context) error {
|
func removeDB(ctx *cli.Context) error {
|
||||||
stack, config := makeConfigNode(ctx)
|
stack, config := makeConfigNode(ctx)
|
||||||
|
|
||||||
|
@ -272,6 +272,7 @@ func init() {
|
|||||||
blsCommand,
|
blsCommand,
|
||||||
// See verkle.go
|
// See verkle.go
|
||||||
verkleCommand,
|
verkleCommand,
|
||||||
|
getVersionDBState,
|
||||||
}
|
}
|
||||||
if logTestCommand != nil {
|
if logTestCommand != nil {
|
||||||
app.Commands = append(app.Commands, logTestCommand)
|
app.Commands = append(app.Commands, logTestCommand)
|
||||||
|
@ -1135,6 +1135,11 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
|
|||||||
Value: params.DefaultExtraReserveForBlobRequests,
|
Value: params.DefaultExtraReserveForBlobRequests,
|
||||||
Category: flags.MiscCategory,
|
Category: flags.MiscCategory,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlockNumber = &cli.Int64Flag{
|
||||||
|
Name: "block",
|
||||||
|
Value: int64(0),
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -1815,23 +1815,6 @@ func (p *Parlia) applyTransaction(
|
|||||||
}
|
}
|
||||||
actualTx := (*receivedTxs)[0]
|
actualTx := (*receivedTxs)[0]
|
||||||
if !bytes.Equal(p.signer.Hash(actualTx).Bytes(), expectedHash.Bytes()) {
|
if !bytes.Equal(p.signer.Hash(actualTx).Bytes(), expectedHash.Bytes()) {
|
||||||
res := fmt.Sprintf("expected tx hash %v, nonce %d, to %s, value %s, gas %d, gasPrice %s, data %s",
|
|
||||||
expectedHash.String(),
|
|
||||||
expectedTx.Nonce(),
|
|
||||||
expectedTx.To().String(),
|
|
||||||
expectedTx.Value().String(),
|
|
||||||
expectedTx.Gas(),
|
|
||||||
expectedTx.GasPrice().String(),
|
|
||||||
hex.EncodeToString(expectedTx.Data()))
|
|
||||||
res += fmt.Sprintf("actual tx hash %v, nonce %d, to %s, value %s, gas %d, gasPrice %s, data %s",
|
|
||||||
actualTx.Hash().String(),
|
|
||||||
actualTx.Nonce(),
|
|
||||||
actualTx.To().String(),
|
|
||||||
actualTx.Value().String(),
|
|
||||||
actualTx.Gas(),
|
|
||||||
actualTx.GasPrice().String(),
|
|
||||||
hex.EncodeToString(actualTx.Data()))
|
|
||||||
log.Info(res)
|
|
||||||
return fmt.Errorf("expected tx hash %v, get %v, nonce %d, to %s, value %s, gas %d, gasPrice %s, data %s", expectedHash.String(), actualTx.Hash().String(),
|
return fmt.Errorf("expected tx hash %v, get %v, nonce %d, to %s, value %s, gas %d, gasPrice %s, data %s", expectedHash.String(), actualTx.Hash().String(),
|
||||||
expectedTx.Nonce(),
|
expectedTx.Nonce(),
|
||||||
expectedTx.To().String(),
|
expectedTx.To().String(),
|
||||||
|
@ -2242,8 +2242,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
|||||||
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
|
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("+++++++++++++start block", "number", block.NumberU64())
|
|
||||||
defer log.Info("+++++++++++++end block", "number", block.NumberU64())
|
|
||||||
statedb, err := state.NewWithSharedPool(parent.Root, bc.stateCache, bc.snaps)
|
statedb, err := state.NewWithSharedPool(parent.Root, bc.stateCache, bc.snaps)
|
||||||
defer bc.stateCache.Release()
|
defer bc.stateCache.Release()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -2289,7 +2287,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
|||||||
log.Error("validate state failed", "error", err)
|
log.Error("validate state failed", "error", err)
|
||||||
bc.reportBlock(block, receipts, err)
|
bc.reportBlock(block, receipts, err)
|
||||||
statedb.StopPrefetcher()
|
statedb.StopPrefetcher()
|
||||||
statedb.DebugPrint(block.NumberU64(), true)
|
|
||||||
return it.index, err
|
return it.index, err
|
||||||
}
|
}
|
||||||
vtime := time.Since(vstart)
|
vtime := time.Since(vstart)
|
||||||
|
@ -34,6 +34,8 @@ type cachingVersaDB struct {
|
|||||||
root common.Hash
|
root common.Hash
|
||||||
mode versa.StateMode
|
mode versa.StateMode
|
||||||
hasState atomic.Bool
|
hasState atomic.Bool
|
||||||
|
|
||||||
|
debug *DebugVersionState
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewVersaDatabase should be call by NewDatabaseWithNodeDB
|
// NewVersaDatabase should be call by NewDatabaseWithNodeDB
|
||||||
@ -47,6 +49,7 @@ func NewVersaDatabase(db ethdb.Database, triedb *triedb.Database, mode versa.Sta
|
|||||||
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
|
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
|
||||||
mode: mode,
|
mode: mode,
|
||||||
state: versa.ErrStateHandler,
|
state: versa.ErrStateHandler,
|
||||||
|
debug: NewDebugVersionState(db, triedb.VersaDB()), // TODO:: add config whether enable debug system
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +66,9 @@ func (cv *cachingVersaDB) Copy() Database {
|
|||||||
if cv.hasState.Load() {
|
if cv.hasState.Load() {
|
||||||
_, err := cp.OpenTrie(cv.root)
|
_, err := cp.OpenTrie(cv.root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to open trie in copy caching versa db", "error", err)
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnError(fmt.Errorf("failed to open trie in copy caching versa db, error: %s", err.Error()))
|
||||||
|
}
|
||||||
return cp
|
return cp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,14 +90,18 @@ func (cv *cachingVersaDB) CopyTrie(tr Trie) Trie {
|
|||||||
}
|
}
|
||||||
tree, err := cv.OpenTrie(vtr.root)
|
tree, err := cv.OpenTrie(vtr.root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to open trie in CopyTrie", "error", err)
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnError(fmt.Errorf("failed to open trie in copy versa trie, error: %s", err.Error()))
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return tree
|
return tree
|
||||||
} else {
|
} else {
|
||||||
tree, err := cv.OpenStorageTrie(vtr.stateRoot, vtr.address, vtr.root, nil)
|
tree, err := cv.OpenStorageTrie(vtr.stateRoot, vtr.address, vtr.root, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to open storage trie in CopyTrie", "error", err)
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnError(fmt.Errorf("failed to open storage trie in copy versa trie, error: %s", err.Error()))
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return tree
|
return tree
|
||||||
@ -113,13 +122,25 @@ func (cv *cachingVersaDB) OpenTrie(root common.Hash) (Trie, error) {
|
|||||||
// TODO:: if root tree, versa db should ignore check version, temp use -1
|
// TODO:: if root tree, versa db should ignore check version, temp use -1
|
||||||
state, err := cv.versionDB.OpenState(-1, root, cv.mode)
|
state, err := cv.versionDB.OpenState(-1, root, cv.mode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to open state", "error", err)
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnError(fmt.Errorf("failed to open state, root:%s, error: %s", root.String(), err.Error()))
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnOpenState(state)
|
||||||
|
version, err := cv.versionDB.GetStateVersion(state)
|
||||||
|
if err != nil {
|
||||||
|
cv.debug.OnError(fmt.Errorf("failed to get state version, root:%s, error: %s", root.String(), err.Error()))
|
||||||
|
}
|
||||||
|
cv.debug.SetVersion(version)
|
||||||
|
}
|
||||||
|
|
||||||
handler, err := cv.versionDB.OpenTree(state, -1, common.Hash{}, root)
|
handler, err := cv.versionDB.OpenTree(state, -1, common.Hash{}, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to open trie", "error", err)
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnError(fmt.Errorf("failed to open account trie, root:%s, error: %s", root.String(), err.Error()))
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +150,7 @@ func (cv *cachingVersaDB) OpenTrie(root common.Hash) (Trie, error) {
|
|||||||
accountTree: true,
|
accountTree: true,
|
||||||
root: root,
|
root: root,
|
||||||
mode: cv.mode,
|
mode: cv.mode,
|
||||||
|
debug: cv.debug,
|
||||||
}
|
}
|
||||||
|
|
||||||
cv.state = state
|
cv.state = state
|
||||||
@ -136,13 +158,16 @@ func (cv *cachingVersaDB) OpenTrie(root common.Hash) (Trie, error) {
|
|||||||
cv.accTree = tree
|
cv.accTree = tree
|
||||||
cv.root = root
|
cv.root = root
|
||||||
|
|
||||||
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnOpenTree(handler, common.Hash{}, common.Address{})
|
||||||
|
}
|
||||||
|
|
||||||
return tree, nil
|
return tree, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cv *cachingVersaDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, _ Trie) (Trie, error) {
|
func (cv *cachingVersaDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, _ Trie) (Trie, error) {
|
||||||
version, _, err := cv.accTree.getAccountWithVersion(address)
|
version, _, err := cv.accTree.getAccountWithVersion(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to open storage trie", "error", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return cv.openStorageTreeWithVersion(version, stateRoot, address, root)
|
return cv.openStorageTreeWithVersion(version, stateRoot, address, root)
|
||||||
@ -157,35 +182,54 @@ func (cv *cachingVersaDB) openStorageTreeWithVersion(version int64, stateRoot co
|
|||||||
panic(fmt.Sprintf("account root mismatch, on open storage tree, actual: %s, expect: %s", root.String(), cv.root.String()))
|
panic(fmt.Sprintf("account root mismatch, on open storage tree, actual: %s, expect: %s", root.String(), cv.root.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
handler, err := cv.versionDB.OpenTree(cv.state, version, crypto.Keccak256Hash(address.Bytes()), root)
|
owner := crypto.Keccak256Hash(address.Bytes())
|
||||||
|
handler, err := cv.versionDB.OpenTree(cv.state, version, owner, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to open storage trie", "error", err)
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnError(fmt.Errorf("failed to open storage trie, version: %d,stateRoot:%s, address:%s, root: %s, error: %s",
|
||||||
|
version, stateRoot.String(), address.String(), root.String(), err.Error()))
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Info("open storage tree", "address", address.String(), "hash address", crypto.Keccak256Hash(address.Bytes()).String())
|
|
||||||
|
|
||||||
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnOpenTree(handler, owner, address)
|
||||||
|
}
|
||||||
tree := &VersaTree{
|
tree := &VersaTree{
|
||||||
db: cv.versionDB,
|
db: cv.versionDB,
|
||||||
handler: handler,
|
handler: handler,
|
||||||
version: version,
|
version: version,
|
||||||
root: root,
|
root: stateRoot,
|
||||||
stateRoot: stateRoot,
|
stateRoot: root,
|
||||||
address: address,
|
address: address,
|
||||||
mode: cv.mode,
|
mode: cv.mode,
|
||||||
|
debug: cv.debug,
|
||||||
}
|
}
|
||||||
return tree, nil
|
return tree, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush unique to versa
|
// Flush unique to versa
|
||||||
func (cv *cachingVersaDB) Flush() error {
|
func (cv *cachingVersaDB) Flush() error {
|
||||||
return cv.versionDB.Flush(cv.state)
|
err := cv.versionDB.Flush(cv.state)
|
||||||
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnError(fmt.Errorf("failed to flush state, version: %d, root:%s, mode:%d, error: %s",
|
||||||
|
cv.accTree.version, cv.accTree.root.String(), cv.accTree.mode, err.Error()))
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release unique to versa
|
// Release unique to versa
|
||||||
func (cv *cachingVersaDB) Release() error {
|
func (cv *cachingVersaDB) Release() error {
|
||||||
//log.Info("close state", "state info", cv.versionDB.ParseStateHandler(cv.state))
|
//log.Info("close state", "state info", cv.versionDB.ParseStateHandler(cv.state))
|
||||||
if cv.state != versa.ErrStateHandler {
|
if cv.state != versa.ErrStateHandler {
|
||||||
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnCloseState(cv.state)
|
||||||
|
}
|
||||||
if err := cv.versionDB.CloseState(cv.state); err != nil {
|
if err := cv.versionDB.CloseState(cv.state); err != nil {
|
||||||
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnError(fmt.Errorf("failed to close state in release, version: %d, root:%s, mode:%d, error: %s",
|
||||||
|
cv.accTree.version, cv.accTree.root.String(), cv.accTree.mode, err.Error()))
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cv.hasState.Store(false)
|
cv.hasState.Store(false)
|
||||||
@ -220,6 +264,9 @@ func (cv *cachingVersaDB) Scheme() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cv *cachingVersaDB) ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error) {
|
func (cv *cachingVersaDB) ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error) {
|
||||||
|
if cv.debug != nil {
|
||||||
|
cv.debug.OnGetCode(codeHash)
|
||||||
|
}
|
||||||
code, _ := cv.codeCache.Get(codeHash)
|
code, _ := cv.codeCache.Get(codeHash)
|
||||||
if len(code) > 0 {
|
if len(code) > 0 {
|
||||||
return code, nil
|
return code, nil
|
||||||
@ -273,6 +320,7 @@ type VersaTree struct {
|
|||||||
handler versa.TreeHandler
|
handler versa.TreeHandler
|
||||||
version int64
|
version int64
|
||||||
accountTree bool
|
accountTree bool
|
||||||
|
debug *DebugVersionState
|
||||||
|
|
||||||
// TODO:: debugging, used for logging
|
// TODO:: debugging, used for logging
|
||||||
stateRoot common.Hash
|
stateRoot common.Hash
|
||||||
@ -291,9 +339,6 @@ func (vt *VersaTree) GetKey(key []byte) []byte {
|
|||||||
|
|
||||||
func (vt *VersaTree) GetAccount(address common.Address) (*types.StateAccount, error) {
|
func (vt *VersaTree) GetAccount(address common.Address) (*types.StateAccount, error) {
|
||||||
_, res, err := vt.getAccountWithVersion(address)
|
_, res, err := vt.getAccountWithVersion(address)
|
||||||
if err != nil {
|
|
||||||
log.Error("failed to get account", "error", err)
|
|
||||||
}
|
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,11 +346,23 @@ func (vt *VersaTree) getAccountWithVersion(address common.Address) (int64, *type
|
|||||||
vt.CheckAccountTree()
|
vt.CheckAccountTree()
|
||||||
ver, res, err := vt.db.Get(vt.handler, address.Bytes())
|
ver, res, err := vt.db.Get(vt.handler, address.Bytes())
|
||||||
if res == nil || err != nil {
|
if res == nil || err != nil {
|
||||||
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnError(fmt.Errorf("failed to get account, root: %s, address: %s, error: %s",
|
||||||
|
vt.root.String(), address.String(), err.Error()))
|
||||||
|
}
|
||||||
return ver, nil, err
|
return ver, nil, err
|
||||||
}
|
}
|
||||||
ret := new(types.StateAccount)
|
ret := new(types.StateAccount)
|
||||||
err = rlp.DecodeBytes(res, ret)
|
err = rlp.DecodeBytes(res, ret)
|
||||||
log.Info("get account", "mode", vt.mode, "addr", address.String(), "nonce", ret.Nonce, "balance", ret.Balance, "root", ret.Root.String(), "code", common.Bytes2Hex(ret.CodeHash), "version", ver)
|
if err != nil {
|
||||||
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnError(fmt.Errorf("failed to rlp decode account, root: %s, address: %s, error: %s",
|
||||||
|
vt.root.String(), address.String(), err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnGetAccount(address, ret)
|
||||||
|
}
|
||||||
return ver, ret, err
|
return ver, ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,12 +373,21 @@ func (vt *VersaTree) GetStorage(address common.Address, key []byte) ([]byte, err
|
|||||||
vt.CheckStorageTree()
|
vt.CheckStorageTree()
|
||||||
_, enc, err := vt.db.Get(vt.handler, key)
|
_, enc, err := vt.db.Get(vt.handler, key)
|
||||||
if err != nil || len(enc) == 0 {
|
if err != nil || len(enc) == 0 {
|
||||||
|
if err != nil && vt.debug != nil {
|
||||||
|
vt.debug.OnError(fmt.Errorf("failed to get storage, root: %s, stateRoot: %s, address:%s, key: %s, error: %s",
|
||||||
|
vt.root.String(), vt.stateRoot.String(), address.String(), common.Bytes2Hex(key), err.Error()))
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, content, _, err := rlp.Split(enc)
|
_, content, _, err := rlp.Split(enc)
|
||||||
log.Info("get storage", "mode", vt.mode, "handler", vt.handler, "owner", address.String(), "key", common.Bytes2Hex(key), "val", common.Bytes2Hex(content), "stateRoot", vt.stateRoot.String(), "root", vt.root.String(), "version", vt.version)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to get storage", "error", err)
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnError(fmt.Errorf("failed to rlp decode storage, root: %s, stateRoot: %s, address: %s, key: %s,error: %s",
|
||||||
|
vt.root.String(), vt.stateRoot.String(), address.String(), common.Bytes2Hex(key), err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnGetStorage(vt.handler, address, key, content)
|
||||||
}
|
}
|
||||||
return content, err
|
return content, err
|
||||||
}
|
}
|
||||||
@ -330,10 +396,15 @@ func (vt *VersaTree) UpdateAccount(address common.Address, account *types.StateA
|
|||||||
vt.CheckAccountTree()
|
vt.CheckAccountTree()
|
||||||
data, err := rlp.EncodeToBytes(account)
|
data, err := rlp.EncodeToBytes(account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to update account", "error", err)
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnError(fmt.Errorf("failed to update account, root: %s, address: %s, error: %s",
|
||||||
|
vt.root.String(), address.String(), err.Error()))
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Info("update account", "mode", vt.mode, "addr", address.String(), "nonce", account.Nonce, "balance", account.Balance, "root", account.Root.String(), "code", common.Bytes2Hex(account.CodeHash))
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnUpdateAccount(address, account)
|
||||||
|
}
|
||||||
return vt.db.Put(vt.handler, address.Bytes(), data)
|
return vt.db.Put(vt.handler, address.Bytes(), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,10 +414,15 @@ func (vt *VersaTree) UpdateStorage(address common.Address, key, value []byte) er
|
|||||||
}
|
}
|
||||||
vt.CheckStorageTree()
|
vt.CheckStorageTree()
|
||||||
v, _ := rlp.EncodeToBytes(value)
|
v, _ := rlp.EncodeToBytes(value)
|
||||||
log.Info("update storage", "mode", vt.mode, "handler", vt.handler, "owner", address.String(), "key", common.Bytes2Hex(key), "val", common.Bytes2Hex(value), "stateRoot", vt.stateRoot.String(), "root", vt.root.String())
|
|
||||||
err := vt.db.Put(vt.handler, key, v)
|
err := vt.db.Put(vt.handler, key, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to update storage", "error", err)
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnError(fmt.Errorf("failed to update storage, root: %s, stateRoot: %s, address: %s, key: %s, val: %s, error: %s",
|
||||||
|
vt.root.String(), vt.stateRoot.String(), address.String(), common.Bytes2Hex(key), common.Bytes2Hex(value), err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnUpdateStorage(vt.handler, address, key, value)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -355,9 +431,14 @@ func (vt *VersaTree) DeleteAccount(address common.Address) error {
|
|||||||
vt.CheckAccountTree()
|
vt.CheckAccountTree()
|
||||||
err := vt.db.Delete(vt.handler, address.Bytes())
|
err := vt.db.Delete(vt.handler, address.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to delete account", "error", err)
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnError(fmt.Errorf("failed to delete account, root: %s, address: %s, error: %s",
|
||||||
|
vt.root.String(), address.String(), err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnDeleteAccount(address)
|
||||||
}
|
}
|
||||||
log.Info("delete account", "mode", vt.mode, "addr", address.String())
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,9 +446,14 @@ func (vt *VersaTree) DeleteStorage(address common.Address, key []byte) error {
|
|||||||
vt.CheckStorageTree()
|
vt.CheckStorageTree()
|
||||||
err := vt.db.Delete(vt.handler, key)
|
err := vt.db.Delete(vt.handler, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to delete storage", "error", err)
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnError(fmt.Errorf("failed to delete storage, root: %s, stateRoot: %s, address: %s, key: %s, error: %s",
|
||||||
|
vt.root.String(), vt.stateRoot.String(), address.String(), common.Bytes2Hex(key), err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnDeleteStorage(vt.handler, address, key)
|
||||||
}
|
}
|
||||||
log.Info("delete storage", "mode", vt.mode, "handler", vt.handler, "owner", address.String(), "key", common.Bytes2Hex(key), "stateRoot", vt.stateRoot.String(), "root", vt.root.String())
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,8 +464,10 @@ func (vt *VersaTree) UpdateContractCode(address common.Address, codeHash common.
|
|||||||
func (vt *VersaTree) Hash() common.Hash {
|
func (vt *VersaTree) Hash() common.Hash {
|
||||||
hash, err := vt.db.CalcRootHash(vt.handler)
|
hash, err := vt.db.CalcRootHash(vt.handler)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO:: debug code, will be change to log error
|
if vt.debug != nil {
|
||||||
log.Crit("calc tree root hash", "tree handler info", vt.db.ParseTreeHandler(vt.handler), "error", err.Error())
|
vt.debug.OnError(fmt.Errorf("failed to calc root, root: %s, stateRoot%s, error:%s",
|
||||||
|
vt.root.String(), vt.stateRoot.String(), err.Error()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
@ -387,7 +475,13 @@ func (vt *VersaTree) Hash() common.Hash {
|
|||||||
func (vt *VersaTree) Commit(_ bool) (common.Hash, *trienode.NodeSet, error) {
|
func (vt *VersaTree) Commit(_ bool) (common.Hash, *trienode.NodeSet, error) {
|
||||||
hash, err := vt.db.Commit(vt.handler)
|
hash, err := vt.db.Commit(vt.handler)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("failed to commit versa tree", "error", err)
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnError(fmt.Errorf("failed to commit versa tree, root: %s, stateRoot: %s, error: %s",
|
||||||
|
vt.root.String(), vt.stateRoot.String(), err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vt.debug != nil {
|
||||||
|
vt.debug.OnCommitTree(vt.handler)
|
||||||
}
|
}
|
||||||
return hash, nil, err
|
return hash, nil, err
|
||||||
}
|
}
|
||||||
|
@ -1509,90 +1509,6 @@ func (s *StateDB) handleDestruction(nodes *trienode.MergedNodeSet) (map[common.A
|
|||||||
return incomplete, nil
|
return incomplete, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StateDB) DebugPrint(block uint64, deleteEmptyObjects bool) {
|
|
||||||
if block != 373559 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Info("================== block start ===============", "number", block)
|
|
||||||
hash := s.IntermediateRoot(deleteEmptyObjects)
|
|
||||||
log.Info("mpt root", "hash", hash)
|
|
||||||
|
|
||||||
addrs := make([]common.Address, 0)
|
|
||||||
for addr := range s.stateObjectsDirty {
|
|
||||||
if _, ok := s.stateObjects[addr]; ok {
|
|
||||||
addrs = append(addrs, addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sort.SliceStable(addrs, func(i, j int) bool {
|
|
||||||
return addrs[i].Cmp(addrs[j]) < 0
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, addr := range addrs {
|
|
||||||
obj := s.stateObjects[addr]
|
|
||||||
log.Info("state object", "address", obj.address)
|
|
||||||
log.Info("state object", "addrHash", obj.addrHash)
|
|
||||||
log.Info("state object", "dirtyCode", obj.dirtyCode)
|
|
||||||
log.Info("state object", "selfDestructed", obj.selfDestructed)
|
|
||||||
log.Info("state object", "deleted", obj.deleted)
|
|
||||||
log.Info("state object", "created", obj.created)
|
|
||||||
log.Info("....................origin state object .......................")
|
|
||||||
if obj.origin != nil {
|
|
||||||
log.Info("state object origin", "Nonce", obj.origin.Nonce)
|
|
||||||
log.Info("state object origin", "Balance", obj.origin.Balance)
|
|
||||||
log.Info("state object origin", "Root", obj.origin.Root)
|
|
||||||
log.Info("state object origin", "CodeHash", common.Bytes2Hex(obj.origin.CodeHash))
|
|
||||||
} else {
|
|
||||||
log.Info("state object origin is nil")
|
|
||||||
}
|
|
||||||
log.Info("....................new state object.......................")
|
|
||||||
log.Info("state object new", "Nonce", obj.data.Nonce)
|
|
||||||
log.Info("state object new", "Balance", obj.data.Balance)
|
|
||||||
log.Info("state object new", "Root", obj.data.Root)
|
|
||||||
log.Info("state object new", "CodeHash", common.Bytes2Hex(obj.data.CodeHash))
|
|
||||||
log.Info("....................tree handler.......................")
|
|
||||||
if obj.trie != nil {
|
|
||||||
vtr := obj.trie.(*VersaTree)
|
|
||||||
log.Info(vtr.db.ParseTreeHandler(vtr.handler))
|
|
||||||
}
|
|
||||||
log.Info("....................originStorage.......................")
|
|
||||||
keys := make([]common.Hash, 0)
|
|
||||||
for key := range obj.originStorage {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
sort.SliceStable(keys, func(i, j int) bool {
|
|
||||||
return keys[i].Cmp(keys[j]) < 0
|
|
||||||
})
|
|
||||||
for _, k := range keys {
|
|
||||||
log.Info("originStorage,", "key: ", k.String(), "val: ", obj.originStorage[k].String())
|
|
||||||
}
|
|
||||||
log.Info("....................pendingStorage.......................")
|
|
||||||
keys = make([]common.Hash, 0)
|
|
||||||
for key := range obj.pendingStorage {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
sort.SliceStable(keys, func(i, j int) bool {
|
|
||||||
return keys[i].Cmp(keys[j]) < 0
|
|
||||||
})
|
|
||||||
for _, k := range keys {
|
|
||||||
log.Info("originStorage,", "key: ", k.String(), "val: ", obj.pendingStorage[k].String())
|
|
||||||
}
|
|
||||||
log.Info("..................dirtyStorage.........................")
|
|
||||||
keys = make([]common.Hash, 0)
|
|
||||||
for key := range obj.dirtyStorage {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
sort.SliceStable(keys, func(i, j int) bool {
|
|
||||||
return keys[i].Cmp(keys[j]) < 0
|
|
||||||
})
|
|
||||||
for _, k := range keys {
|
|
||||||
log.Info("originStorage,", "key: ", k.String(), "val: ", obj.dirtyStorage[k].String())
|
|
||||||
}
|
|
||||||
log.Info("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^")
|
|
||||||
}
|
|
||||||
log.Info("================== block end ================", "number", block)
|
|
||||||
log.Crit("exit....")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Once the state is committed, tries cached in stateDB (including account
|
// Once the state is committed, tries cached in stateDB (including account
|
||||||
// trie, storage tries) will no longer be functional. A new state instance
|
// trie, storage tries) will no longer be functional. A new state instance
|
||||||
// must be created with new root and updated database for accessing post-
|
// must be created with new root and updated database for accessing post-
|
||||||
|
255
core/state/statedb_debug.go
Normal file
255
core/state/statedb_debug.go
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
package state
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
versa "github.com/bnb-chain/versioned-state-database"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type VersaAccountInfo struct {
|
||||||
|
Address common.Address
|
||||||
|
Account *types.StateAccount
|
||||||
|
}
|
||||||
|
|
||||||
|
type VersaStorageInfo struct {
|
||||||
|
Handler versa.TreeHandler
|
||||||
|
Address common.Address
|
||||||
|
Key string
|
||||||
|
Val string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DebugVersionState struct {
|
||||||
|
disk ethdb.KeyValueStore
|
||||||
|
versionDB versa.Database
|
||||||
|
lock sync.Mutex
|
||||||
|
|
||||||
|
Version int64
|
||||||
|
PreState *versa.StateInfo
|
||||||
|
PostState *versa.StateInfo
|
||||||
|
AccessTrees []*versa.TreeInfo
|
||||||
|
CommitTrees []versa.TreeHandler
|
||||||
|
|
||||||
|
GetAccounts []*VersaAccountInfo
|
||||||
|
UpdateAccounts []*VersaAccountInfo
|
||||||
|
DeleteAccounts []common.Address
|
||||||
|
|
||||||
|
GetStorage []*VersaStorageInfo
|
||||||
|
UpdateStorage []*VersaStorageInfo
|
||||||
|
DeleteStorage []*VersaStorageInfo
|
||||||
|
StorageAddr2Owner map[common.Address]common.Hash
|
||||||
|
|
||||||
|
GetCode []common.Hash
|
||||||
|
UpdateCode []common.Hash
|
||||||
|
|
||||||
|
Errs []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDebugVersionState(disk ethdb.KeyValueStore, versionDB versa.Database) *DebugVersionState {
|
||||||
|
return &DebugVersionState{
|
||||||
|
disk: disk,
|
||||||
|
versionDB: versionDB,
|
||||||
|
AccessTrees: make([]*versa.TreeInfo, 0),
|
||||||
|
CommitTrees: make([]versa.TreeHandler, 0),
|
||||||
|
GetAccounts: make([]*VersaAccountInfo, 0),
|
||||||
|
UpdateAccounts: make([]*VersaAccountInfo, 0),
|
||||||
|
DeleteAccounts: make([]common.Address, 0),
|
||||||
|
GetStorage: make([]*VersaStorageInfo, 0),
|
||||||
|
UpdateStorage: make([]*VersaStorageInfo, 0),
|
||||||
|
DeleteStorage: make([]*VersaStorageInfo, 0),
|
||||||
|
StorageAddr2Owner: make(map[common.Address]common.Hash),
|
||||||
|
GetCode: make([]common.Hash, 0),
|
||||||
|
UpdateCode: make([]common.Hash, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (ds *DebugVersionState) SetVersion(version int64) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
ds.Version = version
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnOpenState(handler versa.StateHandler) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
|
||||||
|
stateInfo, err := ds.versionDB.GetStateInfo(handler)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("failed to get state info on open state, err: %s", err.Error()))
|
||||||
|
}
|
||||||
|
ds.PreState = stateInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnOpenTree(handler versa.TreeHandler, owner common.Hash, address common.Address) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
|
||||||
|
treeInfo, err := ds.versionDB.GetTreeInfo(handler)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("failed to get tree info on open tree, err: %s", err.Error()))
|
||||||
|
}
|
||||||
|
ds.AccessTrees = append(ds.AccessTrees, treeInfo)
|
||||||
|
if owner != (common.Hash{}) && address != (common.Address{}) {
|
||||||
|
ds.StorageAddr2Owner[address] = owner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnGetAccount(addr common.Address, acc *types.StateAccount) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
ds.GetAccounts = append(ds.GetAccounts, &VersaAccountInfo{
|
||||||
|
Address: addr,
|
||||||
|
Account: acc,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnUpdateAccount(addr common.Address, acc *types.StateAccount) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
ds.UpdateAccounts = append(ds.UpdateAccounts, &VersaAccountInfo{
|
||||||
|
Address: addr,
|
||||||
|
Account: acc,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnDeleteAccount(address common.Address) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
ds.DeleteAccounts = append(ds.DeleteAccounts, address)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnGetStorage(handler versa.TreeHandler, address common.Address, key []byte, val []byte) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
|
||||||
|
ds.GetStorage = append(ds.GetStorage, &VersaStorageInfo{
|
||||||
|
Handler: handler,
|
||||||
|
Address: address,
|
||||||
|
Key: common.Bytes2Hex(key),
|
||||||
|
Val: common.Bytes2Hex(val),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnUpdateStorage(handler versa.TreeHandler, address common.Address, key []byte, val []byte) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
|
||||||
|
ds.UpdateStorage = append(ds.UpdateStorage, &VersaStorageInfo{
|
||||||
|
Handler: handler,
|
||||||
|
Address: address,
|
||||||
|
Key: common.Bytes2Hex(key),
|
||||||
|
Val: common.Bytes2Hex(val),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnDeleteStorage(handler versa.TreeHandler, address common.Address, key []byte) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
|
||||||
|
ds.DeleteStorage = append(ds.DeleteStorage, &VersaStorageInfo{
|
||||||
|
Handler: handler,
|
||||||
|
Address: address,
|
||||||
|
Key: common.Bytes2Hex(key),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnGetCode(codeHash common.Hash) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
ds.GetCode = append(ds.GetCode, codeHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnUpdateCode(codeHash common.Hash) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
ds.UpdateCode = append(ds.UpdateCode, codeHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnCommitTree(handler versa.TreeHandler) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
ds.CommitTrees = append(ds.CommitTrees, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnError(err error) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
ds.Errs = append(ds.Errs, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) OnCloseState(handler versa.StateHandler) {
|
||||||
|
ds.lock.Lock()
|
||||||
|
defer ds.lock.Unlock()
|
||||||
|
|
||||||
|
stateInfo, err := ds.versionDB.GetStateInfo(handler)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("failed to get state info on close state, err: %s", err.Error()))
|
||||||
|
}
|
||||||
|
ds.PostState = stateInfo
|
||||||
|
|
||||||
|
data, err := json.Marshal(ds)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("failed to json encode debug info, err: %s", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ds.Errs) != 0 {
|
||||||
|
log.Info("version state occurs error", "debug info", string(data))
|
||||||
|
log.Crit("exit....")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ds.disk.Put(DebugStateKey(ds.Version), data)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("failed to put debug version state into disk, err: %s", err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DebugVersionState) sortItems() {
|
||||||
|
sort.Slice(ds.GetAccounts, func(i, j int) bool {
|
||||||
|
return ds.GetAccounts[i].Address.Cmp(ds.GetAccounts[j].Address) < 0
|
||||||
|
})
|
||||||
|
sort.Slice(ds.UpdateAccounts, func(i, j int) bool {
|
||||||
|
return ds.UpdateAccounts[i].Address.Cmp(ds.UpdateAccounts[j].Address) < 0
|
||||||
|
})
|
||||||
|
sort.Slice(ds.DeleteAccounts, func(i, j int) bool {
|
||||||
|
return ds.DeleteAccounts[i].Cmp(ds.DeleteAccounts[j]) < 0
|
||||||
|
})
|
||||||
|
|
||||||
|
sort.Slice(ds.GetStorage, func(i, j int) bool {
|
||||||
|
if ds.GetStorage[i].Address.Cmp(ds.GetStorage[j].Address) == 0 {
|
||||||
|
return ds.GetStorage[i].Key < ds.GetStorage[j].Key
|
||||||
|
}
|
||||||
|
return ds.GetStorage[i].Address.Cmp(ds.GetStorage[j].Address) < 0
|
||||||
|
})
|
||||||
|
|
||||||
|
sort.Slice(ds.UpdateStorage, func(i, j int) bool {
|
||||||
|
if ds.UpdateStorage[i].Address.Cmp(ds.UpdateStorage[j].Address) == 0 {
|
||||||
|
return ds.UpdateStorage[i].Key < ds.UpdateStorage[j].Key
|
||||||
|
}
|
||||||
|
return ds.UpdateStorage[i].Address.Cmp(ds.UpdateStorage[j].Address) < 0
|
||||||
|
})
|
||||||
|
|
||||||
|
sort.Slice(ds.DeleteStorage, func(i, j int) bool {
|
||||||
|
if ds.DeleteStorage[i].Address.Cmp(ds.DeleteStorage[j].Address) == 0 {
|
||||||
|
return ds.DeleteStorage[i].Key < ds.DeleteStorage[j].Key
|
||||||
|
}
|
||||||
|
return ds.DeleteStorage[i].Address.Cmp(ds.DeleteStorage[j].Address) < 0
|
||||||
|
})
|
||||||
|
|
||||||
|
sort.Slice(ds.GetCode, func(i, j int) bool {
|
||||||
|
return ds.GetCode[i].Cmp(ds.GetCode[j]) < 0
|
||||||
|
})
|
||||||
|
sort.Slice(ds.UpdateCode, func(i, j int) bool {
|
||||||
|
return ds.UpdateCode[i].Cmp(ds.UpdateCode[j]) < 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func DebugStateKey(version int64) []byte {
|
||||||
|
key := "debug_version_prefix" + strconv.FormatInt(version, 10)
|
||||||
|
return []byte(key)
|
||||||
|
}
|
@ -126,11 +126,15 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
|||||||
onlyFullSync := false
|
onlyFullSync := false
|
||||||
if config.StateScheme == rawdb.VersionScheme {
|
if config.StateScheme == rawdb.VersionScheme {
|
||||||
config.SnapshotCache = 0
|
config.SnapshotCache = 0
|
||||||
log.Info("version triedb has forbidden snapshot")
|
|
||||||
onlyFullSync = true
|
onlyFullSync = true
|
||||||
config.SyncMode = downloader.FullSync
|
config.SyncMode = downloader.FullSync
|
||||||
log.Info("version triedb only support full sync")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO:: debug code
|
||||||
|
config.SnapshotCache = 0
|
||||||
|
onlyFullSync = true
|
||||||
|
config.SyncMode = downloader.FullSync
|
||||||
|
|
||||||
// Ensure configuration values are compatible and sane
|
// Ensure configuration values are compatible and sane
|
||||||
if config.SyncMode == downloader.LightSync {
|
if config.SyncMode == downloader.LightSync {
|
||||||
return nil, errors.New("can't run eth.Ethereum in light sync mode, light mode has been deprecated")
|
return nil, errors.New("can't run eth.Ethereum in light sync mode, light mode has been deprecated")
|
||||||
|
Loading…
Reference in New Issue
Block a user