Skip to content

Commit

Permalink
core,trie,triedb: add getAccount/Storage in pathdb
Browse files Browse the repository at this point in the history
  • Loading branch information
fynnss committed May 11, 2024
1 parent 3e896c8 commit 462e2bf
Show file tree
Hide file tree
Showing 20 changed files with 620 additions and 18 deletions.
54 changes: 54 additions & 0 deletions core/rawdb/accessors_trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package rawdb

import (
"fmt"
"math/big"
"strings"
"sync"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -94,6 +96,58 @@ func DeleteAccountTrieNode(db ethdb.KeyValueWriter, path []byte) {
}
}

func EncodeNibbles(bytes []byte) []byte {
nibbles := make([]byte, len(bytes)*2)
for i, b := range bytes {
nibbles[i*2] = b >> 4 // 取字节高4位
nibbles[i*2+1] = b & 0x0F // 取字节低4位
}
return nibbles
}

func ReadAccountFromTrieDirectly(db ethdb.Database, key []byte) ([]byte, []byte, common.Hash) {
it := db.NewIterator(TrieNodeAccountPrefix, []byte(""))
defer it.Release()

if it.Seek(accountTrieNodeKey(EncodeNibbles(key))) && it.Error() == nil {
dbKey := common.CopyBytes(it.Key())
if strings.HasPrefix(string(accountTrieNodeKey(EncodeNibbles(key))), string(dbKey)) {
data := common.CopyBytes(it.Value())
return data, dbKey[1:], common.Hash{}
} else {
log.Debug("ReadAccountFromTrieDirectly", "dbKey", common.Bytes2Hex(dbKey), "target key", common.Bytes2Hex(accountTrieNodeKey(EncodeNibbles(key))))
}
} else {
log.Error("ReadAccountFromTrieDirectly", "iterater error", it.Error())
}
return nil, nil, common.Hash{}
}

func ReadStorageFromTrieDirectly(db ethdb.Database, accountHash common.Hash, key []byte) ([]byte, []byte, common.Hash) {
it := db.NewIterator(append(TrieNodeStoragePrefix, accountHash.Bytes()...), []byte(""))
defer it.Release()

if it.Seek(storageTrieNodeKey(accountHash, EncodeNibbles(key))) && it.Error() == nil {
dbKey := common.CopyBytes(it.Key())
if strings.HasPrefix(string(storageTrieNodeKey(accountHash, EncodeNibbles(key))), string(dbKey)) {
data := common.CopyBytes(it.Value())
return data, dbKey[1:], common.Hash{}
}
}
return nil, nil, common.Hash{}
}

func DeleteStorageTrie(db ethdb.KeyValueWriter, accountHash common.Hash) {
nextAccountHash := common.BigToHash(accountHash.Big().Add(accountHash.Big(), big.NewInt(1)))
if err := db.DeleteRange(storageTrieNodeKey(accountHash, nil), storageTrieNodeKey(nextAccountHash, nil)); err != nil {
log.Crit("Failed to delete storage trie", "err", err)
}
}

func IterateStorageTrieNodes(db ethdb.Iteratee, accountHash common.Hash) ethdb.Iterator {
return db.NewIterator(storageTrieNodeKey(accountHash, nil), nil)
}

// ReadStorageTrieNode retrieves the storage trie node with the specified node path.
func ReadStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) []byte {
data, _ := db.Get(storageTrieNodeKey(accountHash, path))
Expand Down
20 changes: 20 additions & 0 deletions core/rawdb/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ type table struct {
prefix string
}

func (t *table) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

// NewTable returns a database object that prefixes all keys with a given string.
func NewTable(db ethdb.Database, prefix string) ethdb.Database {
return &table{
Expand Down Expand Up @@ -214,6 +219,11 @@ type tableBatch struct {
prefix string
}

func (b *tableBatch) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

// Put inserts the given value into the batch for later committing.
func (b *tableBatch) Put(key, value []byte) error {
return b.batch.Put(append([]byte(b.prefix), key...), value)
Expand Down Expand Up @@ -246,6 +256,11 @@ type tableReplayer struct {
prefix string
}

func (r *tableReplayer) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

// Put implements the interface KeyValueWriter.
func (r *tableReplayer) Put(key []byte, value []byte) error {
trimmed := key[len(r.prefix):]
Expand All @@ -270,6 +285,11 @@ type tableIterator struct {
prefix string
}

func (iter *tableIterator) Seek(key []byte) bool {
// TODO implement me
panic("implement me")
}

// Next moves the iterator to the next key/value pair. It returns whether the
// iterator is exhausted.
func (iter *tableIterator) Next() bool {
Expand Down
5 changes: 5 additions & 0 deletions core/state/pruner/bloom.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ type stateBloom struct {
bloom *bloomfilter.Filter
}

func (bloom *stateBloom) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

// newStateBloomWithSize creates a brand new state bloom for state generation.
// The bloom filter will be created by the passing bloom filter size. According
// to the https://hur.st/bloomfilter/?n=600000000&p=&m=2048MB&k=4, the parameters
Expand Down
22 changes: 22 additions & 0 deletions core/types/state_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package types

import (
"bytes"
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp"
Expand Down Expand Up @@ -119,3 +120,24 @@ func FullAccountRLP(data []byte) ([]byte, error) {
}
return rlp.EncodeToBytes(account)
}

func MustFullAccountRLP(data []byte) []byte {
if data == nil {
return nil
}
val, err := FullAccountRLP(data)
if err != nil {
panic(fmt.Sprintf("must full account rlp faield, err %v", err))
}
return val
}
func FullToSlimAccountRLP(data []byte) []byte {
if data == nil {
return nil
}
var account StateAccount
if err := rlp.DecodeBytes(data, &account); err != nil {
panic(fmt.Sprintf("full to slim account rlp failed, err %v", err))
}
return SlimAccountRLP(account)
}
3 changes: 3 additions & 0 deletions ethdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ type KeyValueWriter interface {

// Delete removes the key from the key-value data store.
Delete(key []byte) error

// DeleteRange deletes all of the keys (and values) in the range [start,end)
DeleteRange(start, end []byte) error
}

// KeyValueStater wraps the Stat method of a backing data store.
Expand Down
3 changes: 3 additions & 0 deletions ethdb/iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ type Iterator interface {
// may change on the next call to Next.
Value() []byte

// Seek moves the iterator to the target key/value pair. Only support Lower-bound
Seek(key []byte) bool

// Release releases associated resources. Release should always succeed and can
// be called multiple times without causing error.
Release()
Expand Down
10 changes: 10 additions & 0 deletions ethdb/leveldb/leveldb.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ type Database struct {
log log.Logger // Contextual logger tracking the database path
}

func (db *Database) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

// New returns a wrapped LevelDB object. The namespace is the prefix that the
// metrics reporting should use for surfacing internal stats.
func New(file string, cache int, handles int, namespace string, readonly bool) (*Database, error) {
Expand Down Expand Up @@ -393,6 +398,11 @@ type batch struct {
size int
}

func (b *batch) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

// Put inserts the given value into the batch for later committing.
func (b *batch) Put(key, value []byte) error {
b.b.Put(key, value)
Expand Down
15 changes: 15 additions & 0 deletions ethdb/memorydb/memorydb.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ type Database struct {
lock sync.RWMutex
}

func (db *Database) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

// New returns a wrapped map with all the required database interface methods
// implemented.
func New() *Database {
Expand Down Expand Up @@ -220,6 +225,11 @@ type batch struct {
size int
}

func (b *batch) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

// Put inserts the given value into the batch for later committing.
func (b *batch) Put(key, value []byte) error {
b.writes = append(b.writes, keyvalue{string(key), common.CopyBytes(value), false})
Expand Down Expand Up @@ -288,6 +298,11 @@ type iterator struct {
values [][]byte
}

func (it *iterator) Seek(key []byte) bool {
// TODO implement me
panic("implement me")
}

// Next moves the iterator to the next key/value pair. It returns whether the
// iterator is exhausted.
func (it *iterator) Next() bool {
Expand Down
22 changes: 22 additions & 0 deletions ethdb/pebble/pebble.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,17 @@ func (d *Database) Delete(key []byte) error {
return d.db.Delete(key, nil)
}

// DeleteRange deletes all of the keys (and values) in the range [start,end)
// (inclusive on start, exclusive on end).
func (d *Database) DeleteRange(start, end []byte) error {
d.quitLock.RLock()
defer d.quitLock.RUnlock()
if d.closed {
return pebble.ErrClosed
}
return d.db.DeleteRange(start, end, nil)
}

// NewBatch creates a write-only key-value store that buffers changes to its host
// database until a final write is called.
func (d *Database) NewBatch() ethdb.Batch {
Expand Down Expand Up @@ -603,6 +614,13 @@ func (b *batch) Reset() {
b.size = 0
}

func (b *batch) DeleteRange(start, end []byte) error {
b.b.DeleteRange(start, end, nil)
b.size += len(start)
b.size += len(end)
return nil
}

// Replay replays the batch contents.
func (b *batch) Replay(w ethdb.KeyValueWriter) error {
reader := b.b.Reader()
Expand Down Expand Up @@ -634,6 +652,10 @@ type pebbleIterator struct {
released bool
}

func (iter *pebbleIterator) Seek(key []byte) bool {
return iter.iter.SeekLT(key)
}

// NewIterator creates a binary-alphabetical iterator over a subset
// of database content with a particular key prefix, starting at a particular
// initial key (or after, if it does not exist).
Expand Down
5 changes: 5 additions & 0 deletions ethdb/remotedb/remotedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ type Database struct {
remote *rpc.Client
}

func (db *Database) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

func (db *Database) Has(key []byte) (bool, error) {
if _, err := db.Get(key); err != nil {
return false, nil
Expand Down
5 changes: 5 additions & 0 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,11 @@ type StorageResult struct {
// hex-strings for delivery to rpc-caller.
type proofList []string

func (n *proofList) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

func (n *proofList) Put(key []byte, value []byte) error {
*n = append(*n, hexutil.Encode(value))
return nil
Expand Down
17 changes: 17 additions & 0 deletions trie/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,23 @@ func decodeRef(buf []byte) (node, []byte, error) {
}
}

// DecodeLeafNode return the Key and Val part of the shorNode
func DecodeLeafNode(hash, path, value []byte) ([]byte, []byte) {
n := mustDecodeNode(hash, value)
switch sn := n.(type) {
case *shortNode:
if val, ok := sn.Val.(valueNode); ok {
// remove the prefix key of path
key := append(path, sn.Key...)
if hasTerm(key) {
key = key[:len(key)-1]
}
return val, hexToKeybytes(append(path, sn.Key...))
}
}
return nil, nil
}

// wraps a decoding error with information about the path to the
// invalid child node (for debugging encoding issues).
type decodeError struct {
Expand Down
5 changes: 5 additions & 0 deletions trie/trienode/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ type ProofSet struct {
lock sync.RWMutex
}

func (db *ProofSet) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

// NewProofSet creates an empty node set
func NewProofSet() *ProofSet {
return &ProofSet{
Expand Down
4 changes: 4 additions & 0 deletions trie/triestate/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ type TrieLoader interface {
// The value refers to the original content of state before the transition
// is made. Nil means that the state was not present previously.
type Set struct {
LatestAccounts map[common.Hash][]byte
LatestStorages map[common.Hash]map[common.Hash][]byte
DestructSet map[common.Hash]struct{}

Accounts map[common.Address][]byte // Mutated account set, nil means the account was not present
Storages map[common.Address]map[common.Hash][]byte // Mutated storage set, nil means the slot was not present
size common.StorageSize // Approximate size of set
Expand Down
5 changes: 5 additions & 0 deletions triedb/hashdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,11 @@ type cleaner struct {
db *Database
}

func (c *cleaner) DeleteRange(start, end []byte) error {
// TODO implement me
panic("implement me")
}

// Put reacts to database writes and implements dirty data uncaching. This is the
// post-processing step of a commit operation where the already persisted trie is
// removed from the dirty cache and moved into the clean cache. The reason behind
Expand Down
7 changes: 7 additions & 0 deletions triedb/pathdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ type layer interface {
// Note, no error will be returned if the requested node is not found in database.
node(owner common.Hash, path []byte, depth int) ([]byte, common.Hash, *nodeLoc, error)

// Account directly retrieves the account data associated with a particular hash
Account(hash common.Hash) ([]byte, error)

// Storage directly retrieves the storage data associated with a particular hash,
// within a particular account.
Storage(accountHash, storageHash common.Hash) ([]byte, error)

// rootHash returns the root hash for which this layer was made.
rootHash() common.Hash

Expand Down
Loading

0 comments on commit 462e2bf

Please sign in to comment.