Compare commits
2 Commits
versa_debu
...
versa_rewi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0af2fb4324 | ||
|
|
3e8e74d5c2 |
@@ -424,78 +424,101 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
|||||||
// Make sure the state associated with the block is available, or log out
|
// Make sure the state associated with the block is available, or log out
|
||||||
// if there is no available state, waiting for state sync.
|
// if there is no available state, waiting for state sync.
|
||||||
head := bc.CurrentBlock()
|
head := bc.CurrentBlock()
|
||||||
if !bc.HasState(head.Root) {
|
if bc.triedb.Scheme() != rawdb.VersionScheme {
|
||||||
if head.Number.Uint64() == 0 {
|
if !bc.HasState(head.Root) {
|
||||||
// The genesis state is missing, which is only possible in the path-based
|
if head.Number.Uint64() == 0 {
|
||||||
// scheme. This situation occurs when the initial state sync is not finished
|
// The genesis state is missing, which is only possible in the path-based
|
||||||
// yet, or the chain head is rewound below the pivot point. In both scenarios,
|
// scheme. This situation occurs when the initial state sync is not finished
|
||||||
// there is no possible recovery approach except for rerunning a snap sync.
|
// yet, or the chain head is rewound below the pivot point. In both scenarios,
|
||||||
// Do nothing here until the state syncer picks it up.
|
// there is no possible recovery approach except for rerunning a snap sync.
|
||||||
log.Info("Genesis state is missing, wait state sync")
|
// Do nothing here until the state syncer picks it up.
|
||||||
} else {
|
log.Info("Genesis state is missing, wait state sync")
|
||||||
// Head state is missing, before the state recovery, find out the
|
|
||||||
// disk layer point of snapshot(if it's enabled). Make sure the
|
|
||||||
// rewound point is lower than disk layer.
|
|
||||||
var diskRoot common.Hash
|
|
||||||
if bc.cacheConfig.SnapshotLimit > 0 {
|
|
||||||
diskRoot = rawdb.ReadSnapshotRoot(bc.db)
|
|
||||||
}
|
|
||||||
if bc.triedb.Scheme() == rawdb.PathScheme && !bc.NoTries() {
|
|
||||||
recoverable, _ := bc.triedb.Recoverable(diskRoot)
|
|
||||||
if !bc.HasState(diskRoot) && !recoverable {
|
|
||||||
diskRoot = bc.triedb.Head()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if diskRoot != (common.Hash{}) {
|
|
||||||
log.Warn("Head state missing, repairing", "number", head.Number, "hash", head.Hash(), "diskRoot", diskRoot)
|
|
||||||
|
|
||||||
snapDisk, err := bc.setHeadBeyondRoot(head.Number.Uint64(), 0, diskRoot, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Chain rewound, persist old snapshot number to indicate recovery procedure
|
|
||||||
if snapDisk != 0 {
|
|
||||||
rawdb.WriteSnapshotRecoveryNumber(bc.db, snapDisk)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log.Warn("Head state missing, repairing", "number", head.Number, "hash", head.Hash())
|
// Head state is missing, before the state recovery, find out the
|
||||||
if _, err := bc.setHeadBeyondRoot(head.Number.Uint64(), 0, common.Hash{}, true); err != nil {
|
// disk layer point of snapshot(if it's enabled). Make sure the
|
||||||
|
// rewound point is lower than disk layer.
|
||||||
|
var diskRoot common.Hash
|
||||||
|
if bc.cacheConfig.SnapshotLimit > 0 {
|
||||||
|
diskRoot = rawdb.ReadSnapshotRoot(bc.db)
|
||||||
|
}
|
||||||
|
if bc.triedb.Scheme() == rawdb.PathScheme && !bc.NoTries() {
|
||||||
|
recoverable, _ := bc.triedb.Recoverable(diskRoot)
|
||||||
|
if !bc.HasState(diskRoot) && !recoverable {
|
||||||
|
diskRoot = bc.triedb.Head()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if diskRoot != (common.Hash{}) {
|
||||||
|
log.Warn("Head state missing, repairing", "number", head.Number, "hash", head.Hash(), "diskRoot", diskRoot)
|
||||||
|
|
||||||
|
snapDisk, err := bc.setHeadBeyondRoot(head.Number.Uint64(), 0, diskRoot, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Chain rewound, persist old snapshot number to indicate recovery procedure
|
||||||
|
if snapDisk != 0 {
|
||||||
|
rawdb.WriteSnapshotRecoveryNumber(bc.db, snapDisk)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Warn("Head state missing, repairing", "number", head.Number, "hash", head.Hash())
|
||||||
|
if _, err := bc.setHeadBeyondRoot(head.Number.Uint64(), 0, common.Hash{}, true); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Warn("versa db no recovery, rewind in load state")
|
||||||
|
}
|
||||||
|
// Ensure that a previous crash in SetHead doesn't leave extra ancients
|
||||||
|
if bc.triedb.Scheme() != rawdb.VersionScheme {
|
||||||
|
if frozen, err := bc.db.BlockStore().ItemAmountInAncient(); err == nil && frozen > 0 {
|
||||||
|
frozen, err = bc.db.BlockStore().Ancients()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
needRewind bool
|
||||||
|
low uint64
|
||||||
|
)
|
||||||
|
// The head full block may be rolled back to a very low height due to
|
||||||
|
// blockchain repair. If the head full block is even lower than the ancient
|
||||||
|
// chain, truncate the ancient store.
|
||||||
|
fullBlock := bc.CurrentBlock()
|
||||||
|
if fullBlock != nil && fullBlock.Hash() != bc.genesisBlock.Hash() && fullBlock.Number.Uint64() < frozen-1 {
|
||||||
|
needRewind = true
|
||||||
|
low = fullBlock.Number.Uint64()
|
||||||
|
}
|
||||||
|
// In snap sync, it may happen that ancient data has been written to the
|
||||||
|
// ancient store, but the LastFastBlock has not been updated, truncate the
|
||||||
|
// extra data here.
|
||||||
|
snapBlock := bc.CurrentSnapBlock()
|
||||||
|
if snapBlock != nil && snapBlock.Number.Uint64() < frozen-1 {
|
||||||
|
needRewind = true
|
||||||
|
if snapBlock.Number.Uint64() < low || low == 0 {
|
||||||
|
low = snapBlock.Number.Uint64()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if needRewind {
|
||||||
|
log.Error("Truncating ancient chain", "from", bc.CurrentHeader().Number.Uint64(), "to", low)
|
||||||
|
if err := bc.SetHead(low); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
// Ensure that a previous crash in SetHead doesn't leave extra ancients
|
//TODO:: need consider the offline and inline prune block
|
||||||
if frozen, err := bc.db.BlockStore().ItemAmountInAncient(); err == nil && frozen > 0 {
|
frozen, err := bc.db.BlockStore().Ancients()
|
||||||
frozen, err = bc.db.BlockStore().Ancients()
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items, err := bc.db.BlockStore().ItemAmountInAncient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var (
|
|
||||||
needRewind bool
|
|
||||||
low uint64
|
|
||||||
)
|
|
||||||
// The head full block may be rolled back to a very low height due to
|
|
||||||
// blockchain repair. If the head full block is even lower than the ancient
|
|
||||||
// chain, truncate the ancient store.
|
|
||||||
fullBlock := bc.CurrentBlock()
|
fullBlock := bc.CurrentBlock()
|
||||||
if fullBlock != nil && fullBlock.Hash() != bc.genesisBlock.Hash() && fullBlock.Number.Uint64() < frozen-1 {
|
log.Info("version mode rewind ancient store", "target", fullBlock.Number.Uint64(), "old head", frozen, "items", items, "offset", bc.db.BlockStore().AncientOffSet())
|
||||||
needRewind = true
|
if frozen >= fullBlock.Number.Uint64() {
|
||||||
low = fullBlock.Number.Uint64()
|
if _, err = bc.db.BlockStore().TruncateTail(fullBlock.Number.Uint64()); err != nil {
|
||||||
}
|
|
||||||
// In snap sync, it may happen that ancient data has been written to the
|
|
||||||
// ancient store, but the LastFastBlock has not been updated, truncate the
|
|
||||||
// extra data here.
|
|
||||||
snapBlock := bc.CurrentSnapBlock()
|
|
||||||
if snapBlock != nil && snapBlock.Number.Uint64() < frozen-1 {
|
|
||||||
needRewind = true
|
|
||||||
if snapBlock.Number.Uint64() < low || low == 0 {
|
|
||||||
low = snapBlock.Number.Uint64()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if needRewind {
|
|
||||||
log.Error("Truncating ancient chain", "from", bc.CurrentHeader().Number.Uint64(), "to", low)
|
|
||||||
if err := bc.SetHead(low); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -702,20 +725,54 @@ func (bc *BlockChain) getFinalizedNumber(header *types.Header) uint64 {
|
|||||||
// loadLastState loads the last known chain state from the database. This method
|
// loadLastState loads the last known chain state from the database. This method
|
||||||
// assumes that the chain manager mutex is held.
|
// assumes that the chain manager mutex is held.
|
||||||
func (bc *BlockChain) loadLastState() error {
|
func (bc *BlockChain) loadLastState() error {
|
||||||
// Restore the last known head block
|
// TODO:: before versa db support recovery, only rewind
|
||||||
head := rawdb.ReadHeadBlockHash(bc.db)
|
var headBlock *types.Block
|
||||||
if head == (common.Hash{}) {
|
if bc.triedb.Scheme() == rawdb.VersionScheme {
|
||||||
// Corrupt or empty database, init from scratch
|
head := rawdb.ReadHeadBlockHash(bc.db)
|
||||||
log.Warn("Empty database, resetting chain")
|
headBlock = bc.GetBlockByHash(head)
|
||||||
return bc.Reset()
|
|
||||||
}
|
versa := bc.triedb.VersaDB()
|
||||||
// Make sure the entire head block is available
|
archiveVersion, _ := versa.LatestStoreDiskVersionInfo()
|
||||||
headBlock := bc.GetBlockByHash(head)
|
// empty chain
|
||||||
if headBlock == nil {
|
if archiveVersion == -1 {
|
||||||
// Corrupt or empty database, init from scratch
|
archiveVersion = 0
|
||||||
log.Warn("Head block missing, resetting chain", "hash", head)
|
}
|
||||||
return bc.Reset()
|
|
||||||
|
if int64(headBlock.NumberU64()) < archiveVersion {
|
||||||
|
log.Crit("versa db disk version large than header block", "head number", headBlock.NumberU64(), "versa archive number", archiveVersion)
|
||||||
|
}
|
||||||
|
log.Info("begin rewind versa db head", "target", archiveVersion)
|
||||||
|
for {
|
||||||
|
if int64(headBlock.NumberU64()) == archiveVersion {
|
||||||
|
rawdb.WriteCanonicalHash(bc.db, headBlock.Hash(), headBlock.NumberU64())
|
||||||
|
rawdb.WriteHeadHeaderHash(bc.db, headBlock.Hash())
|
||||||
|
rawdb.WriteHeadBlockHash(bc.db, headBlock.Hash())
|
||||||
|
rawdb.WriteHeadFastBlockHash(bc.db, headBlock.Hash())
|
||||||
|
log.Info("reset versa db head block", "number", headBlock.NumberU64(), "hash", headBlock.Hash())
|
||||||
|
break
|
||||||
|
}
|
||||||
|
headBlock = rawdb.ReadBlock(bc.db, headBlock.ParentHash(), headBlock.NumberU64()-1)
|
||||||
|
if headBlock == nil {
|
||||||
|
panic("versa db rewind head is nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Restore the last known head block
|
||||||
|
head := rawdb.ReadHeadBlockHash(bc.db)
|
||||||
|
if head == (common.Hash{}) {
|
||||||
|
// Corrupt or empty database, init from scratch
|
||||||
|
log.Warn("Empty database, resetting chain")
|
||||||
|
return bc.Reset()
|
||||||
|
}
|
||||||
|
// Make sure the entire head block is available
|
||||||
|
headBlock = bc.GetBlockByHash(head)
|
||||||
|
if headBlock == nil {
|
||||||
|
// Corrupt or empty database, init from scratch
|
||||||
|
log.Warn("Head block missing, resetting chain", "hash", head)
|
||||||
|
return bc.Reset()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
log.Info("load state head block", "number", headBlock.NumberU64())
|
||||||
|
|
||||||
// Everything seems to be fine, set as the head block
|
// Everything seems to be fine, set as the head block
|
||||||
bc.currentBlock.Store(headBlock.Header())
|
bc.currentBlock.Store(headBlock.Header())
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ type cachingVersaDB struct {
|
|||||||
mode versa.StateMode
|
mode versa.StateMode
|
||||||
hasState atomic.Bool
|
hasState atomic.Bool
|
||||||
|
|
||||||
debug *DebugVersionState
|
//debug *DebugVersionState
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewVersaDatabase should be call by NewDatabaseWithNodeDB
|
// NewVersaDatabase should be call by NewDatabaseWithNodeDB
|
||||||
@@ -66,9 +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 {
|
||||||
if cv.debug != nil {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnError(fmt.Errorf("failed to open trie in copy caching versa db, error: %s", err.Error()))
|
// cv.debug.OnError(fmt.Errorf("failed to open trie in copy caching versa db, error: %s", err.Error()))
|
||||||
}
|
//}
|
||||||
return cp
|
return cp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,18 +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 {
|
||||||
if cv.debug != nil {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnError(fmt.Errorf("failed to open trie in copy versa trie, error: %s", err.Error()))
|
// 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 {
|
||||||
if cv.debug != nil {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnError(fmt.Errorf("failed to open storage trie in copy versa trie, error: %s", err.Error()))
|
// 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
|
||||||
@@ -122,20 +122,20 @@ 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(cv.version, root, cv.mode)
|
state, err := cv.versionDB.OpenState(cv.version, root, cv.mode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if cv.debug != nil {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnError(fmt.Errorf("failed to open state, root:%s, error: %s", root.String(), err.Error()))
|
// 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 {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnOpenState(state)
|
// cv.debug.OnOpenState(state)
|
||||||
}
|
//}
|
||||||
|
|
||||||
handler, err := cv.versionDB.OpenTree(state, cv.version, common.Hash{}, root)
|
handler, err := cv.versionDB.OpenTree(state, cv.version, common.Hash{}, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if cv.debug != nil {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnError(fmt.Errorf("failed to open account trie, root:%s, error: %s", root.String(), err.Error()))
|
// cv.debug.OnError(fmt.Errorf("failed to open account trie, root:%s, error: %s", root.String(), err.Error()))
|
||||||
}
|
//}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,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,
|
//debug: cv.debug,
|
||||||
}
|
}
|
||||||
|
|
||||||
cv.state = state
|
cv.state = state
|
||||||
@@ -153,9 +153,9 @@ 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 {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnOpenTree(handler, common.Hash{}, common.Address{})
|
// cv.debug.OnOpenTree(handler, common.Hash{}, common.Address{})
|
||||||
}
|
//}
|
||||||
|
|
||||||
return tree, nil
|
return tree, nil
|
||||||
}
|
}
|
||||||
@@ -180,16 +180,16 @@ func (cv *cachingVersaDB) openStorageTreeWithVersion(version int64, stateRoot co
|
|||||||
owner := crypto.Keccak256Hash(address.Bytes())
|
owner := crypto.Keccak256Hash(address.Bytes())
|
||||||
handler, err := cv.versionDB.OpenTree(cv.state, version, owner, root)
|
handler, err := cv.versionDB.OpenTree(cv.state, version, owner, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if cv.debug != nil {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnError(fmt.Errorf("failed to open storage trie, version: %d,stateRoot:%s, address:%s, root: %s, error: %s",
|
// 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()))
|
// version, stateRoot.String(), address.String(), root.String(), err.Error()))
|
||||||
}
|
//}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if cv.debug != nil {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnOpenTree(handler, owner, address)
|
// cv.debug.OnOpenTree(handler, owner, address)
|
||||||
}
|
//}
|
||||||
tree := &VersaTree{
|
tree := &VersaTree{
|
||||||
db: cv.versionDB,
|
db: cv.versionDB,
|
||||||
handler: handler,
|
handler: handler,
|
||||||
@@ -198,7 +198,7 @@ func (cv *cachingVersaDB) openStorageTreeWithVersion(version int64, stateRoot co
|
|||||||
stateRoot: root,
|
stateRoot: root,
|
||||||
address: address,
|
address: address,
|
||||||
mode: cv.mode,
|
mode: cv.mode,
|
||||||
debug: cv.debug,
|
//debug: cv.debug,
|
||||||
}
|
}
|
||||||
return tree, nil
|
return tree, nil
|
||||||
}
|
}
|
||||||
@@ -206,17 +206,17 @@ func (cv *cachingVersaDB) openStorageTreeWithVersion(version int64, stateRoot co
|
|||||||
// Flush unique to versa
|
// Flush unique to versa
|
||||||
func (cv *cachingVersaDB) Flush() error {
|
func (cv *cachingVersaDB) Flush() error {
|
||||||
err := cv.versionDB.Flush(cv.state)
|
err := cv.versionDB.Flush(cv.state)
|
||||||
if err != nil && cv.debug != nil {
|
//if err != nil && cv.debug != nil {
|
||||||
cv.debug.OnError(fmt.Errorf("failed to flush state, version: %d, root:%s, mode:%d, error: %s",
|
// 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()))
|
// cv.accTree.version, cv.accTree.root.String(), cv.accTree.mode, err.Error()))
|
||||||
}
|
//}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cv *cachingVersaDB) SetVersion(version int64) {
|
func (cv *cachingVersaDB) SetVersion(version int64) {
|
||||||
cv.version = version - 1
|
cv.version = version - 1
|
||||||
cv.debug = NewDebugVersionState(cv.codeDB, cv.versionDB)
|
//cv.debug = NewDebugVersionState(cv.codeDB, cv.versionDB)
|
||||||
cv.debug.Version = version
|
//cv.debug.Version = version
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cv *cachingVersaDB) GetVersion() int64 {
|
func (cv *cachingVersaDB) GetVersion() int64 {
|
||||||
@@ -227,21 +227,21 @@ func (cv *cachingVersaDB) GetVersion() int64 {
|
|||||||
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 {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnCloseState(cv.state)
|
// 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 {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnError(fmt.Errorf("failed to close state in release, version: %d, root:%s, mode:%d, error: %s",
|
// 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()))
|
// cv.accTree.version, cv.accTree.root.String(), cv.accTree.mode, err.Error()))
|
||||||
}
|
//}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cv.hasState.Store(false)
|
cv.hasState.Store(false)
|
||||||
cv.accTree = nil
|
cv.accTree = nil
|
||||||
cv.state = versa.ErrStateHandler
|
cv.state = versa.ErrStateHandler
|
||||||
cv.root = common.Hash{}
|
cv.root = common.Hash{}
|
||||||
cv.debug = nil
|
//cv.debug = nil
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -270,9 +270,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 {
|
//if cv.debug != nil {
|
||||||
cv.debug.OnGetCode(addr, codeHash)
|
// cv.debug.OnGetCode(addr, 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
|
||||||
@@ -326,7 +326,7 @@ type VersaTree struct {
|
|||||||
handler versa.TreeHandler
|
handler versa.TreeHandler
|
||||||
version int64
|
version int64
|
||||||
accountTree bool
|
accountTree bool
|
||||||
debug *DebugVersionState
|
//debug *DebugVersionState
|
||||||
|
|
||||||
// TODO:: debugging, used for logging
|
// TODO:: debugging, used for logging
|
||||||
stateRoot common.Hash
|
stateRoot common.Hash
|
||||||
@@ -352,23 +352,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 err != nil && vt.debug != nil {
|
//if err != nil && vt.debug != nil {
|
||||||
vt.debug.OnError(fmt.Errorf("failed to get account, root: %s, address: %s, error: %s",
|
// vt.debug.OnError(fmt.Errorf("failed to get account, root: %s, address: %s, error: %s",
|
||||||
vt.root.String(), address.String(), err.Error()))
|
// 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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if vt.debug != nil {
|
//if vt.debug != nil {
|
||||||
vt.debug.OnError(fmt.Errorf("failed to rlp decode account, root: %s, address: %s, error: %s",
|
// vt.debug.OnError(fmt.Errorf("failed to rlp decode account, root: %s, address: %s, error: %s",
|
||||||
vt.root.String(), address.String(), err.Error()))
|
// vt.root.String(), address.String(), err.Error()))
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
if vt.debug != nil {
|
|
||||||
vt.debug.OnGetAccount(address, ret)
|
|
||||||
}
|
}
|
||||||
|
//if vt.debug != nil {
|
||||||
|
// vt.debug.OnGetAccount(address, ret)
|
||||||
|
//}
|
||||||
return ver, ret, err
|
return ver, ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,22 +379,22 @@ 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 {
|
//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.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()))
|
// 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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if vt.debug != nil {
|
//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.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()))
|
// 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)
|
|
||||||
}
|
}
|
||||||
|
//if vt.debug != nil {
|
||||||
|
// vt.debug.OnGetStorage(vt.handler, address, key, content)
|
||||||
|
//}
|
||||||
return content, err
|
return content, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,15 +402,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 {
|
||||||
if vt.debug != nil {
|
//if vt.debug != nil {
|
||||||
vt.debug.OnError(fmt.Errorf("failed to update account, root: %s, address: %s, account: %s, error: %s",
|
// vt.debug.OnError(fmt.Errorf("failed to update account, root: %s, address: %s, account: %s, error: %s",
|
||||||
vt.root.String(), address.String(), account.String(), err.Error()))
|
// vt.root.String(), address.String(), account.String(), err.Error()))
|
||||||
}
|
//}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if vt.debug != nil {
|
//if vt.debug != nil {
|
||||||
vt.debug.OnUpdateAccount(address, account)
|
// vt.debug.OnUpdateAccount(address, account)
|
||||||
}
|
//}
|
||||||
return vt.db.Put(vt.handler, address.Bytes(), data)
|
return vt.db.Put(vt.handler, address.Bytes(), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,14 +422,14 @@ func (vt *VersaTree) UpdateStorage(address common.Address, key, value []byte) er
|
|||||||
v, _ := rlp.EncodeToBytes(value)
|
v, _ := rlp.EncodeToBytes(value)
|
||||||
err := vt.db.Put(vt.handler, key, v)
|
err := vt.db.Put(vt.handler, key, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if vt.debug != nil {
|
//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.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()))
|
// 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)
|
|
||||||
}
|
}
|
||||||
|
//if vt.debug != nil {
|
||||||
|
// vt.debug.OnUpdateStorage(vt.handler, address, key, value)
|
||||||
|
//}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,14 +437,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 {
|
||||||
if vt.debug != nil {
|
//if vt.debug != nil {
|
||||||
vt.debug.OnError(fmt.Errorf("failed to delete account, root: %s, address: %s, error: %s",
|
// vt.debug.OnError(fmt.Errorf("failed to delete account, root: %s, address: %s, error: %s",
|
||||||
vt.root.String(), address.String(), err.Error()))
|
// vt.root.String(), address.String(), err.Error()))
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
if vt.debug != nil {
|
|
||||||
vt.debug.OnDeleteAccount(address)
|
|
||||||
}
|
}
|
||||||
|
//if vt.debug != nil {
|
||||||
|
// vt.debug.OnDeleteAccount(address)
|
||||||
|
//}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,14 +452,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 {
|
||||||
if vt.debug != nil {
|
//if vt.debug != nil {
|
||||||
vt.debug.OnError(fmt.Errorf("failed to delete storage, root: %s, stateRoot: %s, address: %s, key: %s, error: %s",
|
// 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()))
|
// vt.root.String(), vt.stateRoot.String(), address.String(), common.Bytes2Hex(key), err.Error()))
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
if vt.debug != nil {
|
|
||||||
vt.debug.OnDeleteStorage(vt.handler, address, key)
|
|
||||||
}
|
}
|
||||||
|
//if vt.debug != nil {
|
||||||
|
// vt.debug.OnDeleteStorage(vt.handler, address, key)
|
||||||
|
//}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,29 +470,29 @@ 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 {
|
||||||
if vt.debug != nil {
|
//if vt.debug != nil {
|
||||||
vt.debug.OnError(fmt.Errorf("failed to calc root, root: %s, stateRoot%s, error:%s",
|
// vt.debug.OnError(fmt.Errorf("failed to calc root, root: %s, stateRoot%s, error:%s",
|
||||||
vt.root.String(), vt.stateRoot.String(), err.Error()))
|
// vt.root.String(), vt.stateRoot.String(), err.Error()))
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
if vt.debug != nil {
|
|
||||||
vt.debug.OnCalcHash(vt.address, hash)
|
|
||||||
}
|
}
|
||||||
|
//if vt.debug != nil {
|
||||||
|
// vt.debug.OnCalcHash(vt.address, hash)
|
||||||
|
//}
|
||||||
return hash
|
return 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 {
|
||||||
if vt.debug != nil {
|
//if vt.debug != nil {
|
||||||
vt.debug.OnError(fmt.Errorf("failed to commit versa tree, root: %s, stateRoot: %s, error: %s",
|
// vt.debug.OnError(fmt.Errorf("failed to commit versa tree, root: %s, stateRoot: %s, error: %s",
|
||||||
vt.root.String(), vt.stateRoot.String(), err.Error()))
|
// vt.root.String(), vt.stateRoot.String(), err.Error()))
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
if vt.debug != nil {
|
|
||||||
vt.debug.OnCalcHash(vt.address, hash)
|
|
||||||
vt.debug.OnCommitTree(vt.address, vt.handler)
|
|
||||||
}
|
}
|
||||||
|
//if vt.debug != nil {
|
||||||
|
// vt.debug.OnCalcHash(vt.address, hash)
|
||||||
|
// vt.debug.OnCommitTree(vt.address, vt.handler)
|
||||||
|
//}
|
||||||
return hash, nil, err
|
return hash, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ type cachingDB struct {
|
|||||||
triedb *triedb.Database
|
triedb *triedb.Database
|
||||||
noTries bool
|
noTries bool
|
||||||
|
|
||||||
debug *DebugHashState
|
//debug *DebugHashState
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenTrie opens the main account trie at a specific root hash.
|
// OpenTrie opens the main account trie at a specific root hash.
|
||||||
@@ -240,22 +240,23 @@ func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
|||||||
}
|
}
|
||||||
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
|
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if db.debug != nil {
|
//if db.debug != nil {
|
||||||
db.debug.OnError(fmt.Errorf("failed to open tree, root: %s, error: %s", root.String(), err.Error()))
|
// db.debug.OnError(fmt.Errorf("failed to open tree, root: %s, error: %s", root.String(), err.Error()))
|
||||||
}
|
//}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ht := &HashTrie{
|
//ht := &HashTrie{
|
||||||
trie: tr,
|
// trie: tr,
|
||||||
root: root,
|
// root: root,
|
||||||
address: common.Address{},
|
// address: common.Address{},
|
||||||
owner: common.Hash{},
|
// owner: common.Hash{},
|
||||||
debug: db.debug,
|
// debug: db.debug,
|
||||||
}
|
//}
|
||||||
if db.debug != nil {
|
//if db.debug != nil {
|
||||||
db.debug.OnOpenTree(root, common.Hash{}, common.Address{})
|
// db.debug.OnOpenTree(root, common.Hash{}, common.Address{})
|
||||||
}
|
//}
|
||||||
return ht, nil
|
//return ht, nil
|
||||||
|
return tr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenStorageTrie opens the storage trie of an account.
|
// OpenStorageTrie opens the storage trie of an account.
|
||||||
@@ -273,24 +274,25 @@ func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Addre
|
|||||||
owner := crypto.Keccak256Hash(address.Bytes())
|
owner := crypto.Keccak256Hash(address.Bytes())
|
||||||
tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, owner, root), db.triedb)
|
tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, owner, root), db.triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if db.debug != nil {
|
//if db.debug != nil {
|
||||||
db.debug.OnError(fmt.Errorf("failed to storage open tree, stateRoot: %s, address: %s, root: %s, error: %s",
|
// db.debug.OnError(fmt.Errorf("failed to storage open tree, stateRoot: %s, address: %s, root: %s, error: %s",
|
||||||
stateRoot.String(), address.String(), root.String(), err.Error()))
|
// stateRoot.String(), address.String(), root.String(), err.Error()))
|
||||||
}
|
//}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ht := &HashTrie{
|
//ht := &HashTrie{
|
||||||
trie: tr,
|
// trie: tr,
|
||||||
root: stateRoot,
|
// root: stateRoot,
|
||||||
statRoot: root,
|
// statRoot: root,
|
||||||
address: address,
|
// address: address,
|
||||||
owner: owner,
|
// owner: owner,
|
||||||
debug: db.debug,
|
// debug: db.debug,
|
||||||
}
|
//}
|
||||||
if db.debug != nil {
|
//if db.debug != nil {
|
||||||
db.debug.OnOpenTree(root, owner, address)
|
// db.debug.OnOpenTree(root, owner, address)
|
||||||
}
|
//}
|
||||||
return ht, nil
|
//return ht, nil
|
||||||
|
return tr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *cachingDB) NoTries() bool {
|
func (db *cachingDB) NoTries() bool {
|
||||||
@@ -307,8 +309,8 @@ func (db *cachingDB) CopyTrie(t Trie) Trie {
|
|||||||
return t.Copy()
|
return t.Copy()
|
||||||
case *trie.EmptyTrie:
|
case *trie.EmptyTrie:
|
||||||
return t.Copy()
|
return t.Copy()
|
||||||
case *HashTrie:
|
//case *HashTrie:
|
||||||
return db.CopyTrie(t.trie)
|
// return db.CopyTrie(t.trie)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unknown trie type %T", t))
|
panic(fmt.Errorf("unknown trie type %T", t))
|
||||||
}
|
}
|
||||||
@@ -316,9 +318,9 @@ func (db *cachingDB) CopyTrie(t Trie) Trie {
|
|||||||
|
|
||||||
// ContractCode retrieves a particular contract's code.
|
// ContractCode retrieves a particular contract's code.
|
||||||
func (db *cachingDB) ContractCode(address common.Address, codeHash common.Hash) ([]byte, error) {
|
func (db *cachingDB) ContractCode(address common.Address, codeHash common.Hash) ([]byte, error) {
|
||||||
if db.debug != nil {
|
//if db.debug != nil {
|
||||||
db.debug.OnGetCode(address, codeHash)
|
// db.debug.OnGetCode(address, codeHash)
|
||||||
}
|
//}
|
||||||
code, _ := db.codeCache.Get(codeHash)
|
code, _ := db.codeCache.Get(codeHash)
|
||||||
if len(code) > 0 {
|
if len(code) > 0 {
|
||||||
return code, nil
|
return code, nil
|
||||||
@@ -381,18 +383,19 @@ func (db *cachingDB) Flush() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db *cachingDB) Release() error {
|
func (db *cachingDB) Release() error {
|
||||||
db.debug.flush()
|
//db.debug.flush()
|
||||||
db.debug = nil
|
//db.debug = nil
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *cachingDB) SetVersion(version int64) {
|
func (db *cachingDB) SetVersion(version int64) {
|
||||||
db.debug = NewDebugHashState(db.disk)
|
//db.debug = NewDebugHashState(db.disk)
|
||||||
db.debug.Version = version
|
//db.debug.Version = version
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *cachingDB) GetVersion() int64 {
|
func (db *cachingDB) GetVersion() int64 {
|
||||||
return db.debug.Version
|
//return db.debug.Version
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *cachingDB) Copy() Database {
|
func (db *cachingDB) Copy() Database {
|
||||||
@@ -408,137 +411,137 @@ func (db *cachingDB) HasTreeExpired(_ Trie) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type HashTrie struct {
|
//type HashTrie struct {
|
||||||
trie Trie
|
// trie Trie
|
||||||
root common.Hash
|
// root common.Hash
|
||||||
statRoot common.Hash
|
// statRoot common.Hash
|
||||||
address common.Address
|
// address common.Address
|
||||||
owner common.Hash
|
// owner common.Hash
|
||||||
|
//
|
||||||
debug *DebugHashState
|
// debug *DebugHashState
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) GetKey(key []byte) []byte {
|
//func (ht *HashTrie) GetKey(key []byte) []byte {
|
||||||
return ht.trie.GetKey(key)
|
// return ht.trie.GetKey(key)
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) GetAccount(address common.Address) (*types.StateAccount, error) {
|
//func (ht *HashTrie) GetAccount(address common.Address) (*types.StateAccount, error) {
|
||||||
acc, err := ht.trie.GetAccount(address)
|
// acc, err := ht.trie.GetAccount(address)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnError(fmt.Errorf("failed to get account, address: %s, error: %s", address.String(), err.Error()))
|
// ht.debug.OnError(fmt.Errorf("failed to get account, address: %s, error: %s", address.String(), err.Error()))
|
||||||
}
|
// }
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnGetAccount(address, acc)
|
// ht.debug.OnGetAccount(address, acc)
|
||||||
}
|
// }
|
||||||
return acc, nil
|
// return acc, nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) GetStorage(addr common.Address, key []byte) ([]byte, error) {
|
//func (ht *HashTrie) GetStorage(addr common.Address, key []byte) ([]byte, error) {
|
||||||
val, err := ht.trie.GetStorage(addr, key)
|
// val, err := ht.trie.GetStorage(addr, key)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnError(fmt.Errorf("failed to get storage, address: %s, error: %s", addr.String(), err.Error()))
|
// ht.debug.OnError(fmt.Errorf("failed to get storage, address: %s, error: %s", addr.String(), err.Error()))
|
||||||
}
|
// }
|
||||||
return val, err
|
// return val, err
|
||||||
}
|
// }
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnGetStorage(addr, key, val)
|
// ht.debug.OnGetStorage(addr, key, val)
|
||||||
}
|
// }
|
||||||
return val, err
|
// return val, err
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) UpdateAccount(address common.Address, account *types.StateAccount) error {
|
//func (ht *HashTrie) UpdateAccount(address common.Address, account *types.StateAccount) error {
|
||||||
err := ht.trie.UpdateAccount(address, account)
|
// err := ht.trie.UpdateAccount(address, account)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnError(fmt.Errorf("failed to update account, address: %s, account: %s, error: %s",
|
// ht.debug.OnError(fmt.Errorf("failed to update account, address: %s, account: %s, error: %s",
|
||||||
address.String(), account.String(), err.Error()))
|
// address.String(), account.String(), err.Error()))
|
||||||
}
|
// }
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnUpdateAccount(address, account)
|
// ht.debug.OnUpdateAccount(address, account)
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) UpdateStorage(addr common.Address, key, value []byte) error {
|
//func (ht *HashTrie) UpdateStorage(addr common.Address, key, value []byte) error {
|
||||||
err := ht.trie.UpdateStorage(addr, key, value)
|
// err := ht.trie.UpdateStorage(addr, key, value)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnError(fmt.Errorf("failed to update storage, address: %s, key: %s, val: %s, error: %s",
|
// ht.debug.OnError(fmt.Errorf("failed to update storage, address: %s, key: %s, val: %s, error: %s",
|
||||||
addr.String(), common.Bytes2Hex(key), common.Bytes2Hex(value), err.Error()))
|
// addr.String(), common.Bytes2Hex(key), common.Bytes2Hex(value), err.Error()))
|
||||||
}
|
// }
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnUpdateStorage(addr, key, value)
|
// ht.debug.OnUpdateStorage(addr, key, value)
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) DeleteAccount(address common.Address) error {
|
//func (ht *HashTrie) DeleteAccount(address common.Address) error {
|
||||||
err := ht.trie.DeleteAccount(address)
|
// err := ht.trie.DeleteAccount(address)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnError(fmt.Errorf("failed to delete account, address: %s, error: %s", address.String(), err.Error()))
|
// ht.debug.OnError(fmt.Errorf("failed to delete account, address: %s, error: %s", address.String(), err.Error()))
|
||||||
}
|
// }
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnDeleteAccount(address)
|
// ht.debug.OnDeleteAccount(address)
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) DeleteStorage(addr common.Address, key []byte) error {
|
//func (ht *HashTrie) DeleteStorage(addr common.Address, key []byte) error {
|
||||||
err := ht.trie.DeleteStorage(addr, key)
|
// err := ht.trie.DeleteStorage(addr, key)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnError(fmt.Errorf("failed to update storage, address: %s, key: %s, error: %s",
|
// ht.debug.OnError(fmt.Errorf("failed to update storage, address: %s, key: %s, error: %s",
|
||||||
addr.String(), common.Bytes2Hex(key), err.Error()))
|
// addr.String(), common.Bytes2Hex(key), err.Error()))
|
||||||
}
|
// }
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnDeleteStorage(addr, key)
|
// ht.debug.OnDeleteStorage(addr, key)
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) UpdateContractCode(address common.Address, codeHash common.Hash, code []byte) error {
|
//func (ht *HashTrie) UpdateContractCode(address common.Address, codeHash common.Hash, code []byte) error {
|
||||||
return ht.trie.UpdateContractCode(address, codeHash, code)
|
// return ht.trie.UpdateContractCode(address, codeHash, code)
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) Hash() common.Hash {
|
//func (ht *HashTrie) Hash() common.Hash {
|
||||||
root := ht.trie.Hash()
|
// root := ht.trie.Hash()
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnCalcHash(ht.address, root)
|
// ht.debug.OnCalcHash(ht.address, root)
|
||||||
}
|
// }
|
||||||
return root
|
// return root
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) {
|
//func (ht *HashTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) {
|
||||||
hash, set, err := ht.trie.Commit(collectLeaf)
|
// hash, set, err := ht.trie.Commit(collectLeaf)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
ht.debug.OnError(fmt.Errorf("failed to commit tree, address: %s, error: %s",
|
// ht.debug.OnError(fmt.Errorf("failed to commit tree, address: %s, error: %s",
|
||||||
ht.address.String(), err.Error()))
|
// ht.address.String(), err.Error()))
|
||||||
return hash, set, err
|
// return hash, set, err
|
||||||
}
|
// }
|
||||||
if ht.debug != nil {
|
// if ht.debug != nil {
|
||||||
ht.debug.OnCalcHash(ht.address, hash)
|
// ht.debug.OnCalcHash(ht.address, hash)
|
||||||
ht.debug.OnCommitTree(ht.address, hash)
|
// ht.debug.OnCommitTree(ht.address, hash)
|
||||||
}
|
// }
|
||||||
return hash, set, nil
|
// return hash, set, nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) NodeIterator(startKey []byte) (trie.NodeIterator, error) {
|
//func (ht *HashTrie) NodeIterator(startKey []byte) (trie.NodeIterator, error) {
|
||||||
return ht.trie.NodeIterator(startKey)
|
// return ht.trie.NodeIterator(startKey)
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (ht *HashTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error {
|
//func (ht *HashTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error {
|
||||||
return ht.trie.Prove(key, proofDb)
|
// return ht.trie.Prove(key, proofDb)
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -1713,18 +1713,18 @@ func (s *StateDB) Commit(block uint64, failPostCommitFunc func(), postCommitFunc
|
|||||||
// Write any contract code associated with the state object
|
// Write any contract code associated with the state object
|
||||||
if obj.code != nil && obj.dirtyCode {
|
if obj.code != nil && obj.dirtyCode {
|
||||||
rawdb.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code)
|
rawdb.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code)
|
||||||
switch d := s.db.(type) {
|
//switch d := s.db.(type) {
|
||||||
case *cachingVersaDB:
|
//case *cachingVersaDB:
|
||||||
if d.debug != nil {
|
// if d.debug != nil {
|
||||||
d.debug.OnUpdateCode(obj.address, common.BytesToHash(obj.CodeHash()))
|
// d.debug.OnUpdateCode(obj.address, common.BytesToHash(obj.CodeHash()))
|
||||||
}
|
// }
|
||||||
case *cachingDB:
|
//case *cachingDB:
|
||||||
if d.debug != nil {
|
// if d.debug != nil {
|
||||||
d.debug.OnUpdateCode(obj.address, common.BytesToHash(obj.CodeHash()))
|
// d.debug.OnUpdateCode(obj.address, common.BytesToHash(obj.CodeHash()))
|
||||||
}
|
// }
|
||||||
default:
|
//default:
|
||||||
panic("caching db type error")
|
// panic("caching db type error")
|
||||||
}
|
//}
|
||||||
obj.dirtyCode = false
|
obj.dirtyCode = false
|
||||||
if s.snap != nil {
|
if s.snap != nil {
|
||||||
panic("snapshot is not nil")
|
panic("snapshot is not nil")
|
||||||
|
|||||||
51
eth/sync.go
51
eth/sync.go
@@ -191,33 +191,40 @@ func peerToSyncOp(mode downloader.SyncMode, p *eth.Peer) *chainSyncOp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cs *chainSyncer) modeAndLocalHead() (downloader.SyncMode, *big.Int) {
|
func (cs *chainSyncer) modeAndLocalHead() (downloader.SyncMode, *big.Int) {
|
||||||
// If we're in snap sync mode, return that directly
|
|
||||||
if cs.handler.snapSync.Load() {
|
|
||||||
block := cs.handler.chain.CurrentSnapBlock()
|
|
||||||
td := cs.handler.chain.GetTd(block.Hash(), block.Number.Uint64())
|
|
||||||
return downloader.SnapSync, td
|
|
||||||
}
|
|
||||||
// We are probably in full sync, but we might have rewound to before the
|
|
||||||
// snap sync pivot, check if we should re-enable snap sync.
|
|
||||||
head := cs.handler.chain.CurrentBlock()
|
head := cs.handler.chain.CurrentBlock()
|
||||||
if pivot := rawdb.ReadLastPivotNumber(cs.handler.database); pivot != nil {
|
if cs.handler.chain.TrieDB().Scheme() != rawdb.VersionScheme {
|
||||||
if head.Number.Uint64() < *pivot {
|
// If we're in snap sync mode, return that directly
|
||||||
if rawdb.ReadAncientType(cs.handler.database) == rawdb.PruneFreezerType {
|
if cs.handler.snapSync.Load() {
|
||||||
log.Crit("Current rewound to before the fast sync pivot, can't enable pruneancient mode", "current block number", head.Number.Uint64(), "pivot", *pivot)
|
|
||||||
}
|
|
||||||
block := cs.handler.chain.CurrentSnapBlock()
|
block := cs.handler.chain.CurrentSnapBlock()
|
||||||
td := cs.handler.chain.GetTd(block.Hash(), block.Number.Uint64())
|
td := cs.handler.chain.GetTd(block.Hash(), block.Number.Uint64())
|
||||||
return downloader.SnapSync, td
|
return downloader.SnapSync, td
|
||||||
}
|
}
|
||||||
}
|
// We are probably in full sync, but we might have rewound to before the
|
||||||
// We are in a full sync, but the associated head state is missing. To complete
|
// snap sync pivot, check if we should re-enable snap sync.
|
||||||
// the head state, forcefully rerun the snap sync. Note it doesn't mean the
|
head = cs.handler.chain.CurrentBlock()
|
||||||
// persistent state is corrupted, just mismatch with the head block.
|
if pivot := rawdb.ReadLastPivotNumber(cs.handler.database); pivot != nil {
|
||||||
if !cs.handler.chain.NoTries() && !cs.handler.chain.HasState(head.Root) {
|
if head.Number.Uint64() < *pivot {
|
||||||
block := cs.handler.chain.CurrentSnapBlock()
|
if rawdb.ReadAncientType(cs.handler.database) == rawdb.PruneFreezerType {
|
||||||
td := cs.handler.chain.GetTd(block.Hash(), block.Number.Uint64())
|
log.Crit("Current rewound to before the fast sync pivot, can't enable pruneancient mode", "current block number", head.Number.Uint64(), "pivot", *pivot)
|
||||||
log.Info("Reenabled snap sync as chain is stateless")
|
}
|
||||||
return downloader.SnapSync, td
|
block := cs.handler.chain.CurrentSnapBlock()
|
||||||
|
td := cs.handler.chain.GetTd(block.Hash(), block.Number.Uint64())
|
||||||
|
return downloader.SnapSync, td
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We are in a full sync, but the associated head state is missing. To complete
|
||||||
|
// the head state, forcefully rerun the snap sync. Note it doesn't mean the
|
||||||
|
// persistent state is corrupted, just mismatch with the head block.
|
||||||
|
if !cs.handler.chain.NoTries() && !cs.handler.chain.HasState(head.Root) {
|
||||||
|
block := cs.handler.chain.CurrentSnapBlock()
|
||||||
|
td := cs.handler.chain.GetTd(block.Hash(), block.Number.Uint64())
|
||||||
|
log.Info("Reenabled snap sync as chain is stateless")
|
||||||
|
return downloader.SnapSync, td
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !cs.handler.chain.HasState(head.Root) {
|
||||||
|
panic("version db not support snap sync")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Nope, we're really full syncing
|
// Nope, we're really full syncing
|
||||||
td := cs.handler.chain.GetTd(head.Hash(), head.Number.Uint64())
|
td := cs.handler.chain.GetTd(head.Hash(), head.Number.Uint64())
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ func (v *VersionDB) Scheme() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *VersionDB) Initialized(genesisRoot common.Hash) bool {
|
func (v *VersionDB) Initialized(genesisRoot common.Hash) bool {
|
||||||
return v.db.HasState(genesisRoot)
|
version, _ := v.db.LatestStoreDiskVersionInfo()
|
||||||
|
return version >= 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VersionDB) Size() (common.StorageSize, common.StorageSize, common.StorageSize) {
|
func (v *VersionDB) Size() (common.StorageSize, common.StorageSize, common.StorageSize) {
|
||||||
|
|||||||
Reference in New Issue
Block a user