From 41ab497c2266b001c74f1124e91df612d695ffc3 Mon Sep 17 00:00:00 2001 From: joeycli Date: Fri, 9 Aug 2024 17:29:47 +0800 Subject: [PATCH] feat: setup versa db --- core/rawdb/accessors_trie.go | 2 + core/state/caching_versa_db.go | 297 +++++++++++++++++++++++++++++++++ go.mod | 25 +-- go.sum | 49 +++--- triedb/database.go | 25 ++- triedb/versiondb/versadb.go | 80 +++++++++ 6 files changed, 443 insertions(+), 35 deletions(-) create mode 100644 core/state/caching_versa_db.go create mode 100644 triedb/versiondb/versadb.go diff --git a/core/rawdb/accessors_trie.go b/core/rawdb/accessors_trie.go index 886c1c469..7c5669622 100644 --- a/core/rawdb/accessors_trie.go +++ b/core/rawdb/accessors_trie.go @@ -46,6 +46,8 @@ const HashScheme = "hash" // on extra state diffs to survive deep reorg. const PathScheme = "path" +const VersionScheme = "version" + // hasher is used to compute the sha256 hash of the provided data. type hasher struct{ sha crypto.KeccakState } diff --git a/core/state/caching_versa_db.go b/core/state/caching_versa_db.go new file mode 100644 index 000000000..3503daac2 --- /dev/null +++ b/core/state/caching_versa_db.go @@ -0,0 +1,297 @@ +package state + +import ( + "errors" + "fmt" + "sync/atomic" + + versa "github.com/bnb-chain/versioned-state-database" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/lru" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/trie/trienode" + "github.com/ethereum/go-ethereum/triedb" +) + +type cachingVersaDB struct { + triedb *triedb.Database + versionDB versa.Database + codeDB ethdb.KeyValueStore + codeSizeCache *lru.Cache[common.Hash, int] + codeCache *lru.SizeConstrainedCache[common.Hash, []byte] + + accTree *VersaTree + state versa.StateHandler + root common.Hash + mode versa.StateMode + hasState atomic.Bool +} + +// NewVersaDatabase should be call by NewDatabaseWithNodeDB +// TODO:: NewDatabaseWithNodeDB should add mode param. +func NewVersaDatabase(db ethdb.Database, triedb *triedb.Database, mode versa.StateMode) Database { + return &cachingVersaDB{ + triedb: triedb, + versionDB: triedb.VersaDB(), + codeDB: db, + codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), + codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), + } +} + +func (cv *cachingVersaDB) OpenTrie(root common.Hash) (Trie, error) { + if cv.hasState.Load() { + //TODO:: will change to log.Error after stabilization + panic("account tree has open") + } + + // TODO:: if root tree, versa db shouldb ignore check version + state, err := cv.versionDB.OpenState(0, root, cv.mode) + if err != nil { + return nil, err + } + + handler, err := cv.versionDB.OpenTree(state, 0, common.Hash{}, root) + if err != nil { + return nil, err + } + + tree := &VersaTree{ + db: cv.versionDB, + handler: handler, + accountTree: true, + root: root, + } + + cv.state = state + cv.hasState.Store(true) // if set, can't change + cv.accTree = tree + cv.root = root + + return tree, nil +} + +func (cv *cachingVersaDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, _ Trie) (Trie, error) { + if !cv.hasState.Load() { + //TODO:: will change to log.Error after stabilization + panic("open account tree, before open storage tree") + } + if cv.root.Cmp(root) != 0 { + panic("account root mismatch, on open storage tree") + } + + version, account, err := cv.accTree.getAccountWithVersion(address) + if err != nil { + return nil, err + } + if account.Root.Cmp(stateRoot) != 0 { + return nil, fmt.Errorf("state root mismatch") + } + + handler, err := cv.versionDB.OpenTree(cv.state, version, crypto.Keccak256Hash(address.Bytes()), stateRoot) + if err != nil { + return nil, err + } + + tree := &VersaTree{ + db: cv.versionDB, + handler: handler, + version: version, + root: root, + stateRoot: stateRoot, + address: address, + } + return tree, nil +} + +// Flush unique to versa +func (cv *cachingVersaDB) Flush() error { + return cv.versionDB.Flush(cv.state) +} + +// Release unique to versa +func (cv *cachingVersaDB) Release() error { + if err := cv.versionDB.CloseState(cv.state); err != nil { + return nil + } + cv.release() + return nil +} + +func (cv *cachingVersaDB) release() { + cv.hasState.Store(false) + cv.accTree = nil +} + +func (cv *cachingVersaDB) CopyTrie(Trie) Trie { + //TODO:: support in the future + return nil +} + +func (cv *cachingVersaDB) ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error) { + code, _ := cv.codeCache.Get(codeHash) + if len(code) > 0 { + return code, nil + } + code = rawdb.ReadCodeWithPrefix(cv.codeDB, codeHash) + if len(code) > 0 { + cv.codeCache.Add(codeHash, code) + cv.codeSizeCache.Add(codeHash, len(code)) + return code, nil + } + return nil, errors.New("not found") +} + +func (cv *cachingVersaDB) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) { + if cached, ok := cv.codeSizeCache.Get(codeHash); ok { + return cached, nil + } + code, err := cv.ContractCode(addr, codeHash) + return len(code), err +} + +func (cv *cachingVersaDB) ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error) { + code, _ := cv.codeCache.Get(codeHash) + if len(code) > 0 { + return code, nil + } + code = rawdb.ReadCodeWithPrefix(cv.codeDB, codeHash) + if len(code) > 0 { + cv.codeCache.Add(codeHash, code) + cv.codeSizeCache.Add(codeHash, len(code)) + return code, nil + } + return nil, errors.New("not found") +} + +func (cv *cachingVersaDB) DiskDB() ethdb.KeyValueStore { + return cv.codeDB +} + +func (cv *cachingVersaDB) TrieDB() *triedb.Database { + return cv.triedb +} + +func (cv *cachingVersaDB) NoTries() bool { + // TODO:: not support fastnode + return false +} + +type VersaTree struct { + db versa.Database + handler versa.TreeHandler + version int64 + accountTree bool + + // TODO:: debugging, used for logging + root common.Hash + stateRoot common.Hash + address common.Address +} + +func (vt *VersaTree) GetKey(key []byte) []byte { + _, val, err := vt.db.Get(vt.handler, key) + if err != nil { + log.Warn("failed to get key from version db") + } + return val +} + +func (vt *VersaTree) GetAccount(address common.Address) (*types.StateAccount, error) { + _, res, err := vt.getAccountWithVersion(address) + return res, err +} + +func (vt *VersaTree) getAccountWithVersion(address common.Address) (int64, *types.StateAccount, error) { + vt.CheckAccountTree() + ver, res, err := vt.db.Get(vt.handler, address.Bytes()) + if res == nil || err != nil { + return ver, nil, err + } + ret := new(types.StateAccount) + err = rlp.DecodeBytes(res, ret) + return ver, ret, err +} + +func (vt *VersaTree) GetStorage(_ common.Address, key []byte) ([]byte, error) { + vt.CheckStorageTree() + _, res, err := vt.db.Get(vt.handler, key) + if res == nil || err != nil { + return nil, err + } + return res, err +} + +func (vt *VersaTree) UpdateAccount(address common.Address, account *types.StateAccount) error { + vt.CheckAccountTree() + data, err := rlp.EncodeToBytes(account) + if err != nil { + return err + } + return vt.db.Put(vt.handler, address.Bytes(), data) +} + +func (vt *VersaTree) UpdateStorage(_ common.Address, key, value []byte) error { + vt.CheckStorageTree() + return vt.db.Put(vt.handler, key, value) +} + +func (vt *VersaTree) DeleteAccount(address common.Address) error { + vt.CheckAccountTree() + return vt.db.Delete(vt.handler, address.Bytes()) +} + +func (vt *VersaTree) DeleteStorage(_ common.Address, key []byte) error { + vt.CheckStorageTree() + return vt.db.Delete(vt.handler, key) +} + +func (vt *VersaTree) UpdateContractCode(address common.Address, codeHash common.Hash, code []byte) error { + return nil +} + +func (vt *VersaTree) Hash() common.Hash { + hash, err := vt.db.CalcRootHash(vt.handler) + if err != nil { + log.Warn("failed to cacl versa tree hash", "error", err) + } + return hash +} + +func (vt *VersaTree) Commit(_ bool) (common.Hash, *trienode.NodeSet, error) { + hash, err := vt.db.Commit(vt.handler) + if err != nil { + log.Warn("failed to commit versa tree", "error", err) + } + return hash, nil, nil +} + +func (vt *VersaTree) NodeIterator(startKey []byte) (trie.NodeIterator, error) { + panic("versa tree not support iterate") + return nil, nil +} + +func (vt *VersaTree) Prove(key []byte, proofDb ethdb.KeyValueWriter) error { + panic("versa tree not support prove") + return nil +} + +// TODO:: test code, will be deleted after stabilization +func (vt *VersaTree) CheckAccountTree() { + if !vt.accountTree { + panic("sub tree can't operate account") + } +} + +// TODO:: test code, will be deleted after stabilization +func (vt *VersaTree) CheckStorageTree() { + if vt.accountTree { + panic("root tree can't operate storage") + } +} diff --git a/go.mod b/go.mod index 153f7770a..c17d26c0d 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/route53 v1.30.2 github.com/bnb-chain/fastssz v0.1.2 github.com/bnb-chain/ics23 v0.1.0 + github.com/bnb-chain/versioned-state-database v0.0.0-20240809035848-76ffc0e09a92 github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/cespare/cp v1.1.1 github.com/cloudflare/cloudflare-go v0.79.0 @@ -44,7 +45,7 @@ require ( github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 github.com/holiman/bloomfilter/v2 v2.0.3 - github.com/holiman/uint256 v1.2.4 + github.com/holiman/uint256 v1.3.0 github.com/huin/goupnp v1.3.0 github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c @@ -67,7 +68,7 @@ require ( github.com/rs/cors v1.8.2 github.com/shirou/gopsutil v3.21.11+incompatible github.com/status-im/keycard-go v0.2.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 github.com/supranational/blst v0.3.11 github.com/syndtr/goleveldb v1.0.1 github.com/tendermint/go-amino v0.14.1 @@ -79,13 +80,13 @@ require ( github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3 github.com/willf/bitset v1.1.3 go.uber.org/automaxprocs v1.5.2 - golang.org/x/crypto v0.21.0 + golang.org/x/crypto v0.25.0 golang.org/x/exp v0.0.0-20240213143201-ec583247a57a - golang.org/x/sync v0.6.0 - golang.org/x/sys v0.20.0 - golang.org/x/text v0.14.0 + golang.org/x/sync v0.7.0 + golang.org/x/sys v0.22.0 + golang.org/x/text v0.16.0 golang.org/x/time v0.5.0 - golang.org/x/tools v0.18.0 + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -111,7 +112,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.11.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -251,6 +252,7 @@ require ( github.com/spf13/afero v1.10.0 // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect + github.com/tidwall/btree v1.7.0 // indirect github.com/tidwall/gjson v1.10.2 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect @@ -271,10 +273,10 @@ require ( go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.23.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/term v0.22.0 // indirect google.golang.org/api v0.44.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect @@ -295,6 +297,7 @@ require ( ) replace ( + github.com/bnb-chain/versioned-state-database => ../versioned-state-database github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v1.3.1 github.com/grpc-ecosystem/grpc-gateway/v2 => github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1 github.com/syndtr/goleveldb v1.0.1 => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 diff --git a/go.sum b/go.sum index b0461489a..213c42a47 100644 --- a/go.sum +++ b/go.sum @@ -185,8 +185,9 @@ github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= @@ -326,7 +327,6 @@ github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= @@ -614,8 +614,8 @@ github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6w github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= -github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.0 h1:4wdcm/tnd0xXdu7iS3ruNvxkWwrb4aeBQv19ayYn8F4= +github.com/holiman/uint256 v1.3.0/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= @@ -1121,8 +1121,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1133,8 +1134,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= @@ -1151,6 +1152,8 @@ github.com/tendermint/iavl v0.12.0 h1:xcaFAr+ycqCj7WN1RzL2EfcBioRDOHcU1oWcg83K02 github.com/tendermint/iavl v0.12.0/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM= github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e h1:cR8/SYRgyQCt5cNCMniB/ZScMkhI9nk8U5C7SbISXjo= github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e/go.mod h1:Tu4lItkATkonrYuvtVjG0/rhy15qrNGNTjPdaphtZ/8= +github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= +github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -1286,8 +1289,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1326,8 +1329,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1379,8 +1382,8 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1411,8 +1414,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1503,13 +1506,13 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1520,8 +1523,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1595,8 +1598,8 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/triedb/database.go b/triedb/database.go index 66c274091..0a0628dd8 100644 --- a/triedb/database.go +++ b/triedb/database.go @@ -20,6 +20,7 @@ import ( "errors" "strings" + versa "github.com/bnb-chain/versioned-state-database" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" @@ -30,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/triedb/database" "github.com/ethereum/go-ethereum/triedb/hashdb" "github.com/ethereum/go-ethereum/triedb/pathdb" + "github.com/ethereum/go-ethereum/triedb/versiondb" ) // Config defines all necessary options for database. @@ -37,7 +39,9 @@ type Config struct { Preimages bool // Flag whether the preimage of node key is recorded Cache int NoTries bool - IsVerkle bool // Flag whether the db is holding a verkle tree + IsVerkle bool // Flag whether the db is holding a verkle tree + IsVersion bool + VersionDB *versiondb.Config HashDB *hashdb.Config // Configs for hash-based scheme PathDB *pathdb.Config // Configs for experimental path-based scheme } @@ -92,6 +96,16 @@ type Database struct { // NewDatabase initializes the trie database with default settings, note // the legacy hash-based scheme is used by default. func NewDatabase(diskdb ethdb.Database, config *Config) *Database { + if config.IsVersion { + // TODO:: Wait for debugging to stabilize, and then consider initialization compatibility with other databases + db := &Database{ + config: config, + diskdb: diskdb, + backend: versiondb.New(config.VersionDB), + } + return db + } + // Sanitize the config and use the default one if it's not specified. var triediskdb ethdb.Database if diskdb != nil && diskdb.StateStore() != nil { @@ -409,3 +423,12 @@ func (db *Database) GetAllRooHash() [][]string { func (db *Database) IsVerkle() bool { return db.config.IsVerkle } + +// VersaDB returns versioned database instance, it is useless for hashdb and pathdb +func (db *Database) VersaDB() versa.Database { + vdb, ok := db.backend.(*versiondb.VersionDB) + if !ok { + log.Crit("only version db support") + } + return vdb.VersaDB() +} diff --git a/triedb/versiondb/versadb.go b/triedb/versiondb/versadb.go new file mode 100644 index 000000000..165ed365e --- /dev/null +++ b/triedb/versiondb/versadb.go @@ -0,0 +1,80 @@ +package versiondb + +import ( + versa "github.com/bnb-chain/versioned-state-database" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/trie/trienode" + "github.com/ethereum/go-ethereum/trie/triestate" +) + +type Config struct { + Path string + FlushInterval int64 + MaxStatesInMem int + EnableHashChecker bool +} + +type VersionDB struct { + db versa.Database +} + +func New(config *Config) *VersionDB { + cfg := &versa.VersaDBConfig{ + FlushInterval: config.FlushInterval, + MaxStatesInMem: config.MaxStatesInMem, + EnableHashChecker: config.EnableHashChecker, + } + db, err := versa.NewVersaDB(config.Path, cfg) + if err != nil { + log.Crit("failed to new version db", "error", err) + } + v := &VersionDB{ + db: db, + } + return v +} + +// Scheme returns the identifier of used storage scheme. +func (v *VersionDB) Scheme() string { + return rawdb.VersionScheme +} + +// Initialized returns an indicator if the state data is already initialized +// according to the state scheme. +func (v *VersionDB) Initialized(genesisRoot common.Hash) bool { + return v.db == nil +} + +// Size returns the current storage size of the memory cache in front of the +// persistent database layer. +func (v *VersionDB) Size() (common.StorageSize, common.StorageSize, common.StorageSize) { + // TODO:: waiting versa db supported + return 0, 0, 0 +} + +// Update performs a state transition by committing dirty nodes contained +// in the given set in order to update state from the specified parent to +// the specified root. +// +// The passed in maps(nodes, states) will be retained to avoid copying +// everything. Therefore, these maps must not be changed afterwards. +func (v *VersionDB) Update(root common.Hash, parent common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *triestate.Set) error { + panic("version db not supported") +} + +// Commit writes all relevant trie nodes belonging to the specified state +// to disk. Report specifies whether logs will be displayed in info level. +func (v *VersionDB) Commit(root common.Hash, report bool) error { + panic("version db not supported") +} + +// Close closes the trie database backend and releases all held resources. +func (v *VersionDB) Close() error { + return v.db.Close() +} + +func (v *VersionDB) VersaDB() versa.Database { + return v.db +}