mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
core/state, light, trie: Rename Trie to Storage; remove Hash() and Root() methods
This commit is contained in:
parent
342312acab
commit
9683a38895
7 changed files with 86 additions and 98 deletions
|
|
@ -44,9 +44,9 @@ func (self *StateDB) RawDump() Dump {
|
||||||
Accounts: make(map[string]DumpAccount),
|
Accounts: make(map[string]DumpAccount),
|
||||||
}
|
}
|
||||||
|
|
||||||
it := self.trie.Iterator()
|
it := self.storage.Iterator()
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
addr := self.trie.GetKey(it.Key)
|
addr := self.storage.GetKey(it.Key)
|
||||||
var data Account
|
var data Account
|
||||||
if err := rlp.DecodeBytes(it.Value, &data); err != nil {
|
if err := rlp.DecodeBytes(it.Value, &data); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
@ -61,9 +61,9 @@ func (self *StateDB) RawDump() Dump {
|
||||||
Code: common.Bytes2Hex(obj.Code(self.db)),
|
Code: common.Bytes2Hex(obj.Code(self.db)),
|
||||||
Storage: make(map[string]string),
|
Storage: make(map[string]string),
|
||||||
}
|
}
|
||||||
storageIt := obj.getTrie(self.db).Iterator()
|
storageIt := obj.getStorage(self.db).Iterator()
|
||||||
for storageIt.Next() {
|
for storageIt.Next() {
|
||||||
account.Storage[common.Bytes2Hex(self.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(storageIt.Value)
|
account.Storage[common.Bytes2Hex(self.storage.GetKey(storageIt.Key))] = common.Bytes2Hex(storageIt.Value)
|
||||||
}
|
}
|
||||||
dump.Accounts[common.Bytes2Hex(addr)] = account
|
dump.Accounts[common.Bytes2Hex(addr)] = account
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,8 @@ type StateObject struct {
|
||||||
dbErr error
|
dbErr error
|
||||||
|
|
||||||
// Write caches.
|
// Write caches.
|
||||||
trie *trie.SecureTrie // storage trie, which becomes non-nil on first access
|
trie *trie.SimpleTrie // storage trie, which becomes non-nil on first access
|
||||||
|
storage *trie.SecureTrie // Interface to storage
|
||||||
code Code // contract bytecode, which gets set when code is loaded
|
code Code // contract bytecode, which gets set when code is loaded
|
||||||
|
|
||||||
cachedStorage Storage // Storage entry cache to avoid duplicate reads
|
cachedStorage Storage // Storage entry cache to avoid duplicate reads
|
||||||
|
|
@ -134,17 +135,17 @@ func (self *StateObject) markSuicided() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StateObject) getTrie(db trie.Database) *trie.SecureTrie {
|
func (c *StateObject) getStorage(db trie.Database) *trie.SecureTrie {
|
||||||
if c.trie == nil {
|
if c.trie == nil {
|
||||||
var err error
|
var err error
|
||||||
t, err := trie.New(c.data.Root, db, 0)
|
c.trie, err = trie.New(c.data.Root, db, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t, _ = trie.New(common.Hash{}, nil, 0)
|
c.trie, _ = trie.New(common.Hash{}, nil, 0)
|
||||||
c.setError(fmt.Errorf("can't create storage trie: %v", err))
|
c.setError(fmt.Errorf("can't create storage trie: %v", err))
|
||||||
}
|
}
|
||||||
c.trie = trie.NewSecure(t, db)
|
c.storage = trie.NewSecure(c.trie, db)
|
||||||
}
|
}
|
||||||
return c.trie
|
return c.storage
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetState returns a value in account storage.
|
// GetState returns a value in account storage.
|
||||||
|
|
@ -154,7 +155,7 @@ func (self *StateObject) GetState(db trie.Database, key common.Hash) common.Hash
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
// Load from DB in case it is missing.
|
// Load from DB in case it is missing.
|
||||||
if enc := self.getTrie(db).Get(key[:]); len(enc) > 0 {
|
if enc := self.getStorage(db).Get(key[:]); len(enc) > 0 {
|
||||||
_, content, _, err := rlp.Split(enc)
|
_, content, _, err := rlp.Split(enc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
self.setError(err)
|
self.setError(err)
|
||||||
|
|
@ -189,7 +190,7 @@ func (self *StateObject) setState(key, value common.Hash) {
|
||||||
|
|
||||||
// updateTrie writes cached storage modifications into the object's storage trie.
|
// updateTrie writes cached storage modifications into the object's storage trie.
|
||||||
func (self *StateObject) updateTrie(db trie.Database) {
|
func (self *StateObject) updateTrie(db trie.Database) {
|
||||||
tr := self.getTrie(db)
|
tr := self.getStorage(db)
|
||||||
for key, value := range self.dirtyStorage {
|
for key, value := range self.dirtyStorage {
|
||||||
delete(self.dirtyStorage, key)
|
delete(self.dirtyStorage, key)
|
||||||
if (value == common.Hash{}) {
|
if (value == common.Hash{}) {
|
||||||
|
|
@ -215,7 +216,7 @@ func (self *StateObject) CommitTrie(db trie.Database, dbw trie.DatabaseWriter) e
|
||||||
if self.dbErr != nil {
|
if self.dbErr != nil {
|
||||||
return self.dbErr
|
return self.dbErr
|
||||||
}
|
}
|
||||||
root, err := self.trie.CommitTo(dbw)
|
root, err := self.storage.CommitTo(dbw)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
self.data.Root = root
|
self.data.Root = root
|
||||||
}
|
}
|
||||||
|
|
@ -266,6 +267,7 @@ func (c *StateObject) ReturnGas(gas, price *big.Int) {}
|
||||||
func (self *StateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *StateObject {
|
func (self *StateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *StateObject {
|
||||||
stateObject := newObject(db, self.address, self.data, onDirty)
|
stateObject := newObject(db, self.address, self.data, onDirty)
|
||||||
stateObject.trie = self.trie
|
stateObject.trie = self.trie
|
||||||
|
stateObject.storage = self.storage
|
||||||
stateObject.code = self.code
|
stateObject.code = self.code
|
||||||
stateObject.dirtyStorage = self.dirtyStorage.Copy()
|
stateObject.dirtyStorage = self.dirtyStorage.Copy()
|
||||||
stateObject.cachedStorage = self.dirtyStorage.Copy()
|
stateObject.cachedStorage = self.dirtyStorage.Copy()
|
||||||
|
|
@ -361,10 +363,10 @@ func (self *StateObject) ForEachStorage(cb func(key, value common.Hash) bool) {
|
||||||
cb(h, value)
|
cb(h, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
it := self.getTrie(self.db.db).Iterator()
|
it := self.getStorage(self.db.db).Iterator()
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
// ignore cached values
|
// ignore cached values
|
||||||
key := common.BytesToHash(self.trie.GetKey(it.Key))
|
key := common.BytesToHash(self.storage.GetKey(it.Key))
|
||||||
if _, ok := self.cachedStorage[key]; !ok {
|
if _, ok := self.cachedStorage[key]; !ok {
|
||||||
cb(key, common.BytesToHash(it.Value))
|
cb(key, common.BytesToHash(it.Value))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,9 @@ type revision struct {
|
||||||
// * Accounts
|
// * Accounts
|
||||||
type StateDB struct {
|
type StateDB struct {
|
||||||
db ethdb.Database
|
db ethdb.Database
|
||||||
trie *trie.SecureTrie
|
trie *trie.SimpleTrie
|
||||||
pastTries []*trie.SecureTrie
|
storage *trie.SecureTrie
|
||||||
|
pastTries []*trie.SimpleTrie
|
||||||
codeSizeCache *lru.Cache
|
codeSizeCache *lru.Cache
|
||||||
|
|
||||||
// This map holds 'live' objects, which will get modified while processing a state transition.
|
// This map holds 'live' objects, which will get modified while processing a state transition.
|
||||||
|
|
@ -93,11 +94,11 @@ func New(root common.Hash, db ethdb.Database) (*StateDB, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
st := trie.NewSecure(tr, db)
|
|
||||||
csc, _ := lru.New(codeSizeCacheSize)
|
csc, _ := lru.New(codeSizeCacheSize)
|
||||||
return &StateDB{
|
return &StateDB{
|
||||||
db: db,
|
db: db,
|
||||||
trie: st,
|
trie: tr,
|
||||||
|
storage: trie.NewSecure(tr, db),
|
||||||
codeSizeCache: csc,
|
codeSizeCache: csc,
|
||||||
stateObjects: make(map[common.Address]*StateObject),
|
stateObjects: make(map[common.Address]*StateObject),
|
||||||
stateObjectsDirty: make(map[common.Address]struct{}),
|
stateObjectsDirty: make(map[common.Address]struct{}),
|
||||||
|
|
@ -119,6 +120,7 @@ func (self *StateDB) New(root common.Hash) (*StateDB, error) {
|
||||||
return &StateDB{
|
return &StateDB{
|
||||||
db: self.db,
|
db: self.db,
|
||||||
trie: tr,
|
trie: tr,
|
||||||
|
storage: trie.NewSecure(tr, self.db),
|
||||||
codeSizeCache: self.codeSizeCache,
|
codeSizeCache: self.codeSizeCache,
|
||||||
stateObjects: make(map[common.Address]*StateObject),
|
stateObjects: make(map[common.Address]*StateObject),
|
||||||
stateObjectsDirty: make(map[common.Address]struct{}),
|
stateObjectsDirty: make(map[common.Address]struct{}),
|
||||||
|
|
@ -138,6 +140,7 @@ func (self *StateDB) Reset(root common.Hash) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
self.trie = tr
|
self.trie = tr
|
||||||
|
self.storage = trie.NewSecure(tr, self.db)
|
||||||
self.stateObjects = make(map[common.Address]*StateObject)
|
self.stateObjects = make(map[common.Address]*StateObject)
|
||||||
self.stateObjectsDirty = make(map[common.Address]struct{})
|
self.stateObjectsDirty = make(map[common.Address]struct{})
|
||||||
self.thash = common.Hash{}
|
self.thash = common.Hash{}
|
||||||
|
|
@ -152,21 +155,17 @@ func (self *StateDB) Reset(root common.Hash) error {
|
||||||
|
|
||||||
// openTrie creates a trie. It uses an existing trie if one is available
|
// openTrie creates a trie. It uses an existing trie if one is available
|
||||||
// from the journal if available.
|
// from the journal if available.
|
||||||
func (self *StateDB) openTrie(root common.Hash) (*trie.SecureTrie, error) {
|
func (self *StateDB) openTrie(root common.Hash) (*trie.SimpleTrie, error) {
|
||||||
for i := len(self.pastTries) - 1; i >= 0; i-- {
|
for i := len(self.pastTries) - 1; i >= 0; i-- {
|
||||||
if self.pastTries[i].Hash() == root {
|
if self.pastTries[i].Hash() == root {
|
||||||
tr := *self.pastTries[i]
|
tr := *self.pastTries[i]
|
||||||
return &tr, nil
|
return &tr, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t, err := trie.New(root, self.db, MaxTrieCacheGen)
|
return trie.New(root, self.db, MaxTrieCacheGen)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return trie.NewSecure(t, self.db), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) pushTrie(t *trie.SecureTrie) {
|
func (self *StateDB) pushTrie(t *trie.SimpleTrie) {
|
||||||
self.lock.Lock()
|
self.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer self.lock.Unlock()
|
||||||
|
|
||||||
|
|
@ -361,14 +360,14 @@ func (self *StateDB) updateStateObject(stateObject *StateObject) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err))
|
panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err))
|
||||||
}
|
}
|
||||||
self.trie.Update(addr[:], data)
|
self.storage.Update(addr[:], data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteStateObject removes the given object from the state trie.
|
// deleteStateObject removes the given object from the state trie.
|
||||||
func (self *StateDB) deleteStateObject(stateObject *StateObject) {
|
func (self *StateDB) deleteStateObject(stateObject *StateObject) {
|
||||||
stateObject.deleted = true
|
stateObject.deleted = true
|
||||||
addr := stateObject.Address()
|
addr := stateObject.Address()
|
||||||
self.trie.Delete(addr[:])
|
self.storage.Delete(addr[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve a state object given my the address. Returns nil if not found.
|
// Retrieve a state object given my the address. Returns nil if not found.
|
||||||
|
|
@ -382,7 +381,7 @@ func (self *StateDB) GetStateObject(addr common.Address) (stateObject *StateObje
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the object from the database.
|
// Load the object from the database.
|
||||||
enc := self.trie.Get(addr[:])
|
enc := self.storage.Get(addr[:])
|
||||||
if len(enc) == 0 {
|
if len(enc) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -462,6 +461,7 @@ func (self *StateDB) Copy() *StateDB {
|
||||||
state := &StateDB{
|
state := &StateDB{
|
||||||
db: self.db,
|
db: self.db,
|
||||||
trie: self.trie,
|
trie: self.trie,
|
||||||
|
storage: self.storage,
|
||||||
pastTries: self.pastTries,
|
pastTries: self.pastTries,
|
||||||
codeSizeCache: self.codeSizeCache,
|
codeSizeCache: self.codeSizeCache,
|
||||||
stateObjects: make(map[common.Address]*StateObject, len(self.stateObjectsDirty)),
|
stateObjects: make(map[common.Address]*StateObject, len(self.stateObjectsDirty)),
|
||||||
|
|
@ -607,7 +607,7 @@ func (s *StateDB) commit(dbw trie.DatabaseWriter) (root common.Hash, err error)
|
||||||
delete(s.stateObjectsDirty, addr)
|
delete(s.stateObjectsDirty, addr)
|
||||||
}
|
}
|
||||||
// Write trie changes.
|
// Write trie changes.
|
||||||
root, err = s.trie.CommitTo(dbw)
|
root, err = s.storage.CommitTo(dbw)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
s.pushTrie(s.trie)
|
s.pushTrie(s.trie)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import (
|
||||||
|
|
||||||
// LightTrie is an ODR-capable wrapper around trie.SecureTrie
|
// LightTrie is an ODR-capable wrapper around trie.SecureTrie
|
||||||
type LightTrie struct {
|
type LightTrie struct {
|
||||||
trie *trie.SecureTrie
|
storage *trie.SecureTrie
|
||||||
originalRoot common.Hash
|
originalRoot common.Hash
|
||||||
odr OdrBackend
|
odr OdrBackend
|
||||||
db ethdb.Database
|
db ethdb.Database
|
||||||
|
|
@ -74,26 +74,26 @@ func (t *LightTrie) do(ctx context.Context, fallbackKey []byte, fn func() error)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *LightTrie) getTrie() (ret *trie.SecureTrie, err error) {
|
func (t *LightTrie) getStorage() (ret *trie.SecureTrie, err error) {
|
||||||
if t.trie == nil {
|
if t.storage == nil {
|
||||||
var tr trie.Trie
|
var tr trie.Storage
|
||||||
tr, err = trie.New(t.originalRoot, t.db, 0)
|
tr, err = trie.New(t.originalRoot, t.db, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
t.trie = trie.NewSecure(tr, t.db)
|
t.storage = trie.NewSecure(tr, t.db)
|
||||||
}
|
}
|
||||||
return t.trie, nil
|
return t.storage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the value for key stored in the trie.
|
// Get returns the value for key stored in the trie.
|
||||||
// The value bytes must not be modified by the caller.
|
// The value bytes must not be modified by the caller.
|
||||||
func (t *LightTrie) Get(ctx context.Context, key []byte) (res []byte, err error) {
|
func (t *LightTrie) Get(ctx context.Context, key []byte) (res []byte, err error) {
|
||||||
err = t.do(ctx, key, func() (err error) {
|
err = t.do(ctx, key, func() (err error) {
|
||||||
var tr *trie.SecureTrie
|
var st *trie.SecureTrie
|
||||||
tr, err = t.getTrie()
|
st, err = t.getStorage()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
res, err = tr.TryGet(key)
|
res, err = st.TryGet(key)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
|
|
@ -108,10 +108,10 @@ func (t *LightTrie) Get(ctx context.Context, key []byte) (res []byte, err error)
|
||||||
// stored in the trie.
|
// stored in the trie.
|
||||||
func (t *LightTrie) Update(ctx context.Context, key, value []byte) (err error) {
|
func (t *LightTrie) Update(ctx context.Context, key, value []byte) (err error) {
|
||||||
err = t.do(ctx, key, func() (err error) {
|
err = t.do(ctx, key, func() (err error) {
|
||||||
var tr *trie.SecureTrie
|
var st *trie.SecureTrie
|
||||||
tr, err = t.getTrie()
|
st, err = t.getStorage()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = tr.TryUpdate(key, value)
|
err = st.TryUpdate(key, value)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
|
|
@ -121,10 +121,10 @@ func (t *LightTrie) Update(ctx context.Context, key, value []byte) (err error) {
|
||||||
// Delete removes any existing value for key from the trie.
|
// Delete removes any existing value for key from the trie.
|
||||||
func (t *LightTrie) Delete(ctx context.Context, key []byte) (err error) {
|
func (t *LightTrie) Delete(ctx context.Context, key []byte) (err error) {
|
||||||
err = t.do(ctx, key, func() (err error) {
|
err = t.do(ctx, key, func() (err error) {
|
||||||
var tr *trie.SecureTrie
|
var st *trie.SecureTrie
|
||||||
tr, err = t.getTrie()
|
st, err = t.getStorage()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = tr.TryDelete(key)
|
err = st.TryDelete(key)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ const secureKeyLength = 11 + 32 // Length of the above prefix + 32byte hash
|
||||||
//
|
//
|
||||||
// SecureTrie is not safe for concurrent use.
|
// SecureTrie is not safe for concurrent use.
|
||||||
type SecureTrie struct {
|
type SecureTrie struct {
|
||||||
trie Trie
|
storage Storage
|
||||||
db Database
|
db Database
|
||||||
hashKeyBuf [secureKeyLength]byte
|
hashKeyBuf [secureKeyLength]byte
|
||||||
secKeyBuf [200]byte
|
secKeyBuf [200]byte
|
||||||
|
|
@ -45,57 +45,57 @@ type SecureTrie struct {
|
||||||
secKeyCacheOwner *SecureTrie // Pointer to self, replace the key cache on mismatch
|
secKeyCacheOwner *SecureTrie // Pointer to self, replace the key cache on mismatch
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSecure creates a secure trie from an existing trie.
|
// NewSecure creates a secure Storage from an existing Storage.
|
||||||
func NewSecure(t Trie, db Database) *SecureTrie {
|
func NewSecure(s Storage, db Database) *SecureTrie {
|
||||||
if t == nil {
|
if s == nil {
|
||||||
panic("NewSecure called with nil trie")
|
panic("NewSecure called with nil storage")
|
||||||
}
|
}
|
||||||
if db == nil {
|
if db == nil {
|
||||||
panic("NewSecure called with nil database")
|
panic("NewSecure called with nil database")
|
||||||
}
|
}
|
||||||
return &SecureTrie{trie: t, db: db}
|
return &SecureTrie{storage: s, db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the value for key stored in the trie.
|
// Get returns the value for key stored in the storage.
|
||||||
// The value bytes must not be modified by the caller.
|
// The value bytes must not be modified by the caller.
|
||||||
func (t *SecureTrie) Get(key []byte) []byte {
|
func (t *SecureTrie) Get(key []byte) []byte {
|
||||||
res, err := t.TryGet(key)
|
res, err := t.TryGet(key)
|
||||||
if err != nil && glog.V(logger.Error) {
|
if err != nil && glog.V(logger.Error) {
|
||||||
glog.Errorf("Unhandled trie error: %v", err)
|
glog.Errorf("Unhandled storage error: %v", err)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryGet returns the value for key stored in the trie.
|
// TryGet returns the value for key stored in the storage.
|
||||||
// The value bytes must not be modified by the caller.
|
// The value bytes must not be modified by the caller.
|
||||||
// If a node was not found in the database, a MissingNodeError is returned.
|
// If a node was not found in the database, a MissingNodeError is returned.
|
||||||
func (t *SecureTrie) TryGet(key []byte) ([]byte, error) {
|
func (t *SecureTrie) TryGet(key []byte) ([]byte, error) {
|
||||||
return t.trie.TryGet(t.hashKey(key))
|
return t.storage.TryGet(t.hashKey(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update associates key with value in the trie. Subsequent calls to
|
// Update associates key with value in the storage. Subsequent calls to
|
||||||
// Get will return value. If value has length zero, any existing value
|
// Get will return value. If value has length zero, any existing value
|
||||||
// is deleted from the trie and calls to Get will return nil.
|
// is deleted from the storage and calls to Get will return nil.
|
||||||
//
|
//
|
||||||
// The value bytes must not be modified by the caller while they are
|
// The value bytes must not be modified by the caller while they are
|
||||||
// stored in the trie.
|
// stored in the storage.
|
||||||
func (t *SecureTrie) Update(key, value []byte) {
|
func (t *SecureTrie) Update(key, value []byte) {
|
||||||
if err := t.TryUpdate(key, value); err != nil && glog.V(logger.Error) {
|
if err := t.TryUpdate(key, value); err != nil && glog.V(logger.Error) {
|
||||||
glog.Errorf("Unhandled trie error: %v", err)
|
glog.Errorf("Unhandled storage error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryUpdate associates key with value in the trie. Subsequent calls to
|
// TryUpdate associates key with value in the storage. Subsequent calls to
|
||||||
// Get will return value. If value has length zero, any existing value
|
// Get will return value. If value has length zero, any existing value
|
||||||
// is deleted from the trie and calls to Get will return nil.
|
// is deleted from the storage and calls to Get will return nil.
|
||||||
//
|
//
|
||||||
// The value bytes must not be modified by the caller while they are
|
// The value bytes must not be modified by the caller while they are
|
||||||
// stored in the trie.
|
// stored in the storage.
|
||||||
//
|
//
|
||||||
// If a node was not found in the database, a MissingNodeError is returned.
|
// If a node was not found in the database, a MissingNodeError is returned.
|
||||||
func (t *SecureTrie) TryUpdate(key, value []byte) error {
|
func (t *SecureTrie) TryUpdate(key, value []byte) error {
|
||||||
hk := t.hashKey(key)
|
hk := t.hashKey(key)
|
||||||
err := t.trie.TryUpdate(hk, value)
|
err := t.storage.TryUpdate(hk, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -103,19 +103,19 @@ func (t *SecureTrie) TryUpdate(key, value []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete removes any existing value for key from the trie.
|
// Delete removes any existing value for key from the storage.
|
||||||
func (t *SecureTrie) Delete(key []byte) {
|
func (t *SecureTrie) Delete(key []byte) {
|
||||||
if err := t.TryDelete(key); err != nil && glog.V(logger.Error) {
|
if err := t.TryDelete(key); err != nil && glog.V(logger.Error) {
|
||||||
glog.Errorf("Unhandled trie error: %v", err)
|
glog.Errorf("Unhandled storage error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryDelete removes any existing value for key from the trie.
|
// TryDelete removes any existing value for key from the storage.
|
||||||
// If a node was not found in the database, a MissingNodeError is returned.
|
// If a node was not found in the database, a MissingNodeError is returned.
|
||||||
func (t *SecureTrie) TryDelete(key []byte) error {
|
func (t *SecureTrie) TryDelete(key []byte) error {
|
||||||
hk := t.hashKey(key)
|
hk := t.hashKey(key)
|
||||||
delete(t.getSecKeyCache(), string(hk))
|
delete(t.getSecKeyCache(), string(hk))
|
||||||
return t.trie.TryDelete(hk)
|
return t.storage.TryDelete(hk)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetKey returns the sha3 preimage of a hashed key that was
|
// GetKey returns the sha3 preimage of a hashed key that was
|
||||||
|
|
@ -128,7 +128,7 @@ func (t *SecureTrie) GetKey(shaKey []byte) []byte {
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit writes all nodes and the secure hash pre-images to the trie's database.
|
// Commit writes all nodes and the secure hash pre-images to the database.
|
||||||
// Nodes are stored with their sha3 hash as the key.
|
// Nodes are stored with their sha3 hash as the key.
|
||||||
//
|
//
|
||||||
// Committing flushes nodes from memory. Subsequent Get calls will load nodes
|
// Committing flushes nodes from memory. Subsequent Get calls will load nodes
|
||||||
|
|
@ -137,36 +137,24 @@ func (t *SecureTrie) Commit() (root common.Hash, err error) {
|
||||||
if err := t.CommitPreimages(); err != nil {
|
if err := t.CommitPreimages(); err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
return t.trie.Commit()
|
return t.storage.Commit()
|
||||||
}
|
|
||||||
|
|
||||||
func (t *SecureTrie) Hash() common.Hash {
|
|
||||||
return t.trie.Hash()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *SecureTrie) Root() []byte {
|
|
||||||
return t.trie.Root()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *SecureTrie) Iterator() *Iterator {
|
func (t *SecureTrie) Iterator() *Iterator {
|
||||||
return t.trie.Iterator()
|
return t.storage.Iterator()
|
||||||
}
|
|
||||||
|
|
||||||
func (t *SecureTrie) NodeIterator() *NodeIterator {
|
|
||||||
return t.trie.NodeIterator()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommitTo writes all nodes and the secure hash pre-images to the given database.
|
// CommitTo writes all nodes and the secure hash pre-images to the given database.
|
||||||
// Nodes are stored with their sha3 hash as the key.
|
// Nodes are stored with their sha3 hash as the key.
|
||||||
//
|
//
|
||||||
// Committing flushes nodes from memory. Subsequent Get calls will load nodes from
|
// Committing flushes nodes from memory. Subsequent Get calls will load nodes from
|
||||||
// the trie's database. Calling code must ensure that the changes made to db are
|
// the database. Calling code must ensure that the changes made to db are
|
||||||
// written back to the trie's attached database before using the trie.
|
// written back to the attached database before using the storage.
|
||||||
func (t *SecureTrie) CommitTo(db DatabaseWriter) (root common.Hash, err error) {
|
func (t *SecureTrie) CommitTo(db DatabaseWriter) (root common.Hash, err error) {
|
||||||
if err := t.CommitPreimages(); err != nil {
|
if err := t.CommitPreimages(); err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
return t.trie.CommitTo(db)
|
return t.storage.CommitTo(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *SecureTrie) CommitPreimages() error {
|
func (t *SecureTrie) CommitPreimages() error {
|
||||||
|
|
@ -203,7 +191,7 @@ func (t *SecureTrie) hashKey(key []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSecKeyCache returns the current secure key cache, creating a new one if
|
// getSecKeyCache returns the current secure key cache, creating a new one if
|
||||||
// ownership changed (i.e. the current secure trie is a copy of another owning
|
// ownership changed (i.e. the current secure storage is a copy of another owning
|
||||||
// the actual cache).
|
// the actual cache).
|
||||||
func (t *SecureTrie) getSecKeyCache() map[string][]byte {
|
func (t *SecureTrie) getSecKeyCache() map[string][]byte {
|
||||||
if t != t.secKeyCacheOwner {
|
if t != t.secKeyCacheOwner {
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,11 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newEmptySecure() *SecureTrie {
|
func newEmptySecure() (*SimpleTrie, *SecureTrie) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
tr, _ := New(common.Hash{}, db, 0)
|
tr, _ := New(common.Hash{}, db, 0)
|
||||||
st := NewSecure(tr, db)
|
st := NewSecure(tr, db)
|
||||||
return st
|
return tr, st
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeTestSecureTrie creates a large enough secure trie for testing.
|
// makeTestSecureTrie creates a large enough secure trie for testing.
|
||||||
|
|
@ -67,7 +67,7 @@ func makeTestSecureTrie() (ethdb.Database, *SecureTrie, map[string][]byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSecureDelete(t *testing.T) {
|
func TestSecureDelete(t *testing.T) {
|
||||||
trie := newEmptySecure()
|
trie, st := newEmptySecure()
|
||||||
vals := []struct{ k, v string }{
|
vals := []struct{ k, v string }{
|
||||||
{"do", "verb"},
|
{"do", "verb"},
|
||||||
{"ether", "wookiedoo"},
|
{"ether", "wookiedoo"},
|
||||||
|
|
@ -80,9 +80,9 @@ func TestSecureDelete(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, val := range vals {
|
for _, val := range vals {
|
||||||
if val.v != "" {
|
if val.v != "" {
|
||||||
trie.Update([]byte(val.k), []byte(val.v))
|
st.Update([]byte(val.k), []byte(val.v))
|
||||||
} else {
|
} else {
|
||||||
trie.Delete([]byte(val.k))
|
st.Delete([]byte(val.k))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hash := trie.Hash()
|
hash := trie.Hash()
|
||||||
|
|
@ -93,17 +93,17 @@ func TestSecureDelete(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSecureGetKey(t *testing.T) {
|
func TestSecureGetKey(t *testing.T) {
|
||||||
trie := newEmptySecure()
|
_, st := newEmptySecure()
|
||||||
trie.Update([]byte("foo"), []byte("bar"))
|
st.Update([]byte("foo"), []byte("bar"))
|
||||||
|
|
||||||
key := []byte("foo")
|
key := []byte("foo")
|
||||||
value := []byte("bar")
|
value := []byte("bar")
|
||||||
seckey := crypto.Keccak256(key)
|
seckey := crypto.Keccak256(key)
|
||||||
|
|
||||||
if !bytes.Equal(trie.Get(key), value) {
|
if !bytes.Equal(st.Get(key), value) {
|
||||||
t.Errorf("Get did not return bar")
|
t.Errorf("Get did not return bar")
|
||||||
}
|
}
|
||||||
if k := trie.GetKey(seckey); !bytes.Equal(k, key) {
|
if k := st.GetKey(seckey); !bytes.Equal(k, key) {
|
||||||
t.Errorf("GetKey returned %q, want %q", k, key)
|
t.Errorf("GetKey returned %q, want %q", k, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ type DatabaseWriter interface {
|
||||||
// Use New to create a trie that sits on top of a database.
|
// Use New to create a trie that sits on top of a database.
|
||||||
//
|
//
|
||||||
// trie is not safe for concurrent use.
|
// trie is not safe for concurrent use.
|
||||||
type Trie interface {
|
type Storage interface {
|
||||||
Iterator() *Iterator
|
Iterator() *Iterator
|
||||||
NodeIterator() *NodeIterator
|
NodeIterator() *NodeIterator
|
||||||
Get(key []byte) []byte
|
Get(key []byte) []byte
|
||||||
|
|
@ -87,8 +87,6 @@ type Trie interface {
|
||||||
TryUpdate(key, value []byte) error
|
TryUpdate(key, value []byte) error
|
||||||
Delete(key []byte)
|
Delete(key []byte)
|
||||||
TryDelete(key []byte) error
|
TryDelete(key []byte) error
|
||||||
Root() []byte
|
|
||||||
Hash() common.Hash
|
|
||||||
Commit() (root common.Hash, err error)
|
Commit() (root common.Hash, err error)
|
||||||
CommitTo(db DatabaseWriter) (root common.Hash, err error)
|
CommitTo(db DatabaseWriter) (root common.Hash, err error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue