Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add the wrapper layer of versa #2636

Open
wants to merge 93 commits into
base: versa_base
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
41ab497
feat: setup versa db
joeylichang Aug 9, 2024
d2e5c03
feat: add version commit
joeylichang Aug 12, 2024
435410f
chore: forbid versiondb rewind
joeylichang Aug 12, 2024
7f3aac3
feat: add mode for new caching db
joeylichang Aug 12, 2024
6cf5169
feat: add version scheme for startup
joeylichang Aug 12, 2024
e1a2b8e
feat: init genesis
joeylichang Aug 12, 2024
4635a45
feat: add caching db and trie copy
joeylichang Aug 12, 2024
3a34c73
feat: support has state on statedb and must fullsync under version
joeylichang Aug 12, 2024
6b7c807
chore: add debug code
joeylichang Aug 12, 2024
66bd590
chore: delete debug code and add log
joeylichang Aug 12, 2024
bb167a9
chore: add stack debug
joeylichang Aug 12, 2024
60df2fa
fix: open strorage trie param error
joeylichang Aug 12, 2024
6188aae
chore: add debug print statedb
joeylichang Aug 13, 2024
ed7aa3e
fix: storage tree value encode
joeylichang Aug 13, 2024
e8309ad
chore: delete debug print code
joeylichang Aug 13, 2024
d8c3726
fix: state object trie expire
joeylichang Aug 13, 2024
b00582c
chore: add state info debug log
joeylichang Aug 13, 2024
d162a63
chore: change panic to log
joeylichang Aug 13, 2024
83287ce
chore: add debug log
joeylichang Aug 13, 2024
ec2384a
fix: change check from tree root to tree handler
joeylichang Aug 13, 2024
04e5c17
chore: add debug panic
joeylichang Aug 13, 2024
f69ff95
fix: blockchain stateat use rw state
joeylichang Aug 13, 2024
657eced
chore: delete panic code
joeylichang Aug 13, 2024
2f0f91d
chore: delete debug log
joeylichang Aug 13, 2024
58dabc9
chore: add apply tx debug log
joeylichang Aug 13, 2024
324e4a4
chore: add panic log
joeylichang Aug 13, 2024
c572535
chore: add reset panic
joeylichang Aug 13, 2024
5b4e00c
fix: decode storage val
joeylichang Aug 13, 2024
f284358
chore: delete redundant code
joeylichang Aug 14, 2024
3a70b35
chore: dadd debug log for tx diff
joeylichang Aug 14, 2024
412c5ee
chore: add state obj debug info
joeylichang Aug 14, 2024
bfe07c5
chore: adjust state obj debug info
joeylichang Aug 14, 2024
be0a305
chore: add delete obj debug info
joeylichang Aug 14, 2024
26d7f62
chore: forbid prefetcher
joeylichang Aug 14, 2024
b73a98c
chore: forbid prefetcher
joeylichang Aug 14, 2024
0941eb6
chore: panic for snap
joeylichang Aug 14, 2024
023b092
chore: delete storage pool
joeylichang Aug 14, 2024
bd9c2ae
chore: add tx hash log
joeylichang Aug 14, 2024
a3f8c70
chore: fix build error
joeylichang Aug 14, 2024
8d7ee3a
chore: add parse state obj
joeylichang Aug 14, 2024
42b72fe
chore: add debug state after tx execute
joeylichang Aug 14, 2024
6dfcbc6
fix lint error
joeylichang Aug 14, 2024
bbef397
chore:add tree get debug info
joeylichang Aug 15, 2024
dec27d1
fix: add address check for get versa tree
joeylichang Aug 15, 2024
cf04af0
chore: add tx execute log
joeylichang Aug 15, 2024
7462078
chore: add system tx log
joeylichang Aug 15, 2024
c6d8d63
fix: get code error
joeylichang Aug 15, 2024
ac2d1a8
chore: add versa db error log
joeylichang Aug 15, 2024
2e38d06
chore: change panic to log error
joeylichang Aug 15, 2024
0a90118
chore: delete part log
joeylichang Aug 15, 2024
2e4ec39
chore: add owner and hash log
joeylichang Aug 15, 2024
7bce07a
chore: adjust state reset
joeylichang Aug 16, 2024
dc51003
feat: return version for repeat search account tree
joeylichang Aug 16, 2024
9d20658
chore: debug 24611
joeylichang Aug 16, 2024
77dea68
chore: add detete key debug log
joeylichang Aug 16, 2024
90de1d7
fix: version mismatch that add contract balance without update storag…
joeylichang Aug 16, 2024
8197064
fix: chang condition for ca
joeylichang Aug 16, 2024
3c4b452
fix: chang condition for ca
joeylichang Aug 16, 2024
b80d787
chore: add update storage debug info
joeylichang Aug 16, 2024
bf80891
chore: add update storage debug info
joeylichang Aug 16, 2024
84767d1
chore: add update storage debug info
joeylichang Aug 16, 2024
f67f494
chore: add 373559 debug breakpoint
joeylichang Aug 16, 2024
23c60a3
feat: add version state debug system
joeylichang Aug 18, 2024
e940e28
fix: access nil pointer
joeylichang Aug 18, 2024
90aa2e1
fix: change pebble to default db
joeylichang Aug 18, 2024
997d7b5
chore: delete debug log
joeylichang Aug 18, 2024
1cbdf0a
feat: add hash state db debug system
joeylichang Aug 19, 2024
7d5e6ce
feat: add version and hash state diff system
joeylichang Aug 19, 2024
55cdcfa
fix: repeat cmd error
joeylichang Aug 19, 2024
a0daf10
fix: genesis init panic
joeylichang Aug 19, 2024
aa9d518
fix: panic bug
joeylichang Aug 19, 2024
ef3f9df
fix: repeated cmd error
joeylichang Aug 19, 2024
f724941
fix: add protection for debug hash state
joeylichang Aug 19, 2024
3ad4700
fix: diff debug state error
joeylichang Aug 19, 2024
1a40f79
fix: set path mode breakpoint
joeylichang Aug 19, 2024
fa7a43a
fix: add calc hash point
joeylichang Aug 19, 2024
4764fdb
fix: the timing release debug state instance
joeylichang Aug 19, 2024
30b371d
chore: compatable empty hash
joeylichang Aug 19, 2024
d3854b4
fix: compare funx
joeylichang Aug 19, 2024
9c239db
fix: compare func
joeylichang Aug 19, 2024
74ab9ab
fix: changte the confidition for open storage tree
joeylichang Aug 19, 2024
3ad7c4e
fix: panic for updating code
joeylichang Aug 19, 2024
b8fa476
fix: get ca trie
joeylichang Aug 20, 2024
ea76d5f
chore: add debug inof for get trie version mismatch error
joeylichang Aug 20, 2024
a1d4b06
feat: check ca changeable
joeylichang Aug 20, 2024
b585984
fix: remove enable hash check
fynnss Aug 20, 2024
d5a438a
chore: add diff and disk version log
joeylichang Aug 20, 2024
d5e38ad
chore: adjust log confidition
joeylichang Aug 21, 2024
36044b0
chore: add open state version
joeylichang Aug 21, 2024
8db789b
fix: update trie error
joeylichang Aug 22, 2024
85a6b17
chore: add reopen same tree error debug info
joeylichang Aug 22, 2024
84da730
chore: add pprof service
joeylichang Aug 29, 2024
facbe6a
chore: add mgasps metrics
joeylichang Aug 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions core/rawdb/accessors_trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down
297 changes: 297 additions & 0 deletions core/state/caching_versa_db.go
Original file line number Diff line number Diff line change
@@ -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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why to have a "versionDB" here? Is there any difference with "triedb"?

Copy link
Contributor Author

@joeylichang joeylichang Aug 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no essential difference; here, versiondb is for convenience.

codeDB ethdb.KeyValueStore
codeSizeCache *lru.Cache[common.Hash, int]
codeCache *lru.SizeConstrainedCache[common.Hash, []byte]

accTree *VersaTree
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is VersaTree impl? And why to have a "accTree"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Facilitate OpenStorageTree to avoid reopen.

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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest to use the block num as the version here, not 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s fine, but currently, this version is of no use to the upper layer and has brought about a burden. The plan is to make the upper layer aware of the version only if needed in the future. The conclusion is that it can be transparent to the upper layer for the time being.

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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the version of the account should be returned to the caller, and maintained by the account itself, so that it can be provided to versaDB when opening the storage tree.

But if do this, a lot of changes will be required. Therefore, we need to do some trade off whether the version should be known to the caller.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, currently the upper layer does not have a strong dependency on the version, so it can be transparent to the upper layer for the time being. If needed in the future, it can be exposed then. The focus at this stage should not be on this.

_, 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")
}
}
25 changes: 14 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
)
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
Loading
Loading