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

[Non-breaking changes] Refactor trie interfaces #378

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
8253211
implements RLP encoding/decoding processing for structs
trinhdn97 Jun 16, 2023
fa67be8
Update RLP lib
trinhdn97 Jun 16, 2023
9b5dadb
Implement RLP encoder code generation tool
trinhdn97 Jun 16, 2023
ddf35f8
Update unit tests and benchmark
trinhdn97 Jun 16, 2023
17e4876
Include RLPgen tool to CI
trinhdn97 Jun 20, 2023
aa7c4b4
Add benchmarks for types RLP encoding/decoding
trinhdn97 Jun 21, 2023
ac89cd3
Generate RLP encoder for some structs
trinhdn97 Jun 21, 2023
060f4ce
Convert status of receipts from uint to uint64
trinhdn97 Jun 21, 2023
8fdaf68
Unify multiple keccak interface into one inside crypto package
trinhdn97 Jul 16, 2023
c7be6cc
Merge branch 'refactor/keccak-state' into ft/stacktrie
trinhdn97 Jul 16, 2023
340bf2b
Add encode method to Node interface
trinhdn97 Jul 16, 2023
33149c9
Implement stacktrie
trinhdn97 Jul 16, 2023
2e9abc4
Add encode method for rawShortNode and rawFullNode
trinhdn97 Jul 16, 2023
008274f
Fix import cycle
trinhdn97 Jul 16, 2023
f88dba4
Fix stacktrie unit tests
trinhdn97 Jul 16, 2023
327c90d
Remove rlpLog RLP encoder
trinhdn97 Jul 17, 2023
4d22f8d
Fix unit tests
trinhdn97 Jul 18, 2023
c37affb
Move statedb.Account struct to types.StateAccount
trinhdn97 Jul 20, 2023
e0776fb
Move database_util.go to rawdb package
trinhdn97 Jul 20, 2023
5ce901b
Move db keys to schema.go
trinhdn97 Jul 20, 2023
36373e7
Refine db keys
trinhdn97 Jul 20, 2023
6392afd
Rename
trinhdn97 Jul 20, 2023
cf62b98
Split into sub accessor files
trinhdn97 Jul 20, 2023
024181b
chore: remove intPool
c98tristan Jul 17, 2023
c384646
Feat: Update derive SHA for stacktrie
c98tristan Jul 19, 2023
b8421e5
Chore: Add benchmark for Stacktrie
c98tristan Jul 19, 2023
6099609
Chore: Fix Update function missing return type
c98tristan Jul 19, 2023
ae6ca82
Chore: Change GetRlp to EncodeIndex in LendingTransaction and OrderTr…
c98tristan Jul 24, 2023
515a614
Update DeriveSha with new Hasher and DerivableList interface
trinhdn97 Jul 19, 2023
44d2c54
Chore: Add intPool in interpreter.go
c98tristan Jul 24, 2023
5fae822
Merge branch 'refactor/state-account' into refactor/rawdb
trinhdn97 Jul 24, 2023
72ca227
Chore: Change parameter of NewBlock function from Trie to Stacktrie
c98tristan Jul 25, 2023
530cbb1
Chore: Sorting imported library
c98tristan Jul 25, 2023
260f47e
Chore: Sorting imported library
c98tristan Jul 25, 2023
a6098a1
Merge remote-tracking branch 'c98tristan/feat/update-trie-to-stacktri…
trinhdn97 Jul 25, 2023
b1cb0fc
Resolve conflicts after merged
trinhdn97 Jul 25, 2023
5e8bde3
Refactor some rawdb methods
trinhdn97 Jul 31, 2023
cb81493
[WIP] Implement new trie interface and separate preimageStore
trinhdn97 Jul 31, 2023
a409636
Refactor NewDatabaseWithConfig
trinhdn97 Jul 31, 2023
4e70b3e
Include configs when init trie databases
trinhdn97 Jul 31, 2023
1b9882d
Nitpick
trinhdn97 Jul 31, 2023
943f500
Fix UpdateStorage in trie
trinhdn97 Aug 3, 2023
be70268
Fix trie unit tests
trinhdn97 Aug 3, 2023
bf41851
Fix GetCommittedState and GetState
trinhdn97 Aug 3, 2023
12d08d0
Fix state test
trinhdn97 Aug 4, 2023
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
Prev Previous commit
Next Next commit
[WIP] Implement new trie interface and separate preimageStore
  • Loading branch information
trinhdn97 committed Jul 31, 2023
commit cb81493257c6e989e375ab74216db44119ff5cd4
6 changes: 1 addition & 5 deletions cmd/gc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@ import (
"github.com/tomochain/tomochain/cmd/utils"
"github.com/tomochain/tomochain/common"
"github.com/tomochain/tomochain/core/rawdb"
"github.com/tomochain/tomochain/core/types"
"github.com/tomochain/tomochain/eth"
"github.com/tomochain/tomochain/ethdb"
"github.com/tomochain/tomochain/ethdb/leveldb"
"github.com/tomochain/tomochain/rlp"
"github.com/tomochain/tomochain/trie"
)

Expand Down Expand Up @@ -80,9 +78,7 @@ func main() {
atomic.StoreInt32(&finish, 1)
if running {
for _, address := range cleanAddress {
enc := trieRoot.trie.Get(address.Bytes())
var data types.StateAccount
rlp.DecodeBytes(enc, &data)
data, _ := trieRoot.trie.GetAccount(address)
fmt.Println(time.Now().Format(time.RFC3339), "Start clean state address ", address.Hex(), " at block ", trieRoot.number)
signerRoot, err := resolveHash(data.Root[:], db)
if err != nil {
Expand Down
45 changes: 33 additions & 12 deletions core/state/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

lru "github.com/hashicorp/golang-lru"
"github.com/tomochain/tomochain/common"
"github.com/tomochain/tomochain/core/types"
"github.com/tomochain/tomochain/ethdb"
"github.com/tomochain/tomochain/trie"
)
Expand Down Expand Up @@ -59,20 +60,40 @@ type Trie interface {
// TODO(fjl): remove this when SecureTrie is removed
GetKey([]byte) []byte

// TryGet returns the value for key stored in the trie. The value bytes must
// not be modified by the caller. If a node was not found in the database, a
// trie.MissingNodeError is returned.
TryGet(key []byte) ([]byte, error)

// TryUpdate associates key with value in the trie. If value has length zero, any
// existing value is deleted from the trie. The value bytes must not be modified
// GetStorage returns the value for key stored in the trie. The value bytes
// must not be modified by the caller. If a node was not found in the database,
// a trie.MissingNodeError is returned.
GetStorage(addr common.Address, key []byte) ([]byte, error)

// GetAccount abstracts an account read from the trie. It retrieves the
// account blob from the trie with provided account address and decodes it
// with associated decoding algorithm. If the specified account is not in
// the trie, nil will be returned. If the trie is corrupted(e.g. some nodes
// are missing or the account blob is incorrect for decoding), an error will
// be returned.
GetAccount(address common.Address) (*types.StateAccount, error)

// UpdateStorage associates key with value in the trie. If value has length zero,
// any existing value is deleted from the trie. The value bytes must not be modified
// by the caller while they are stored in the trie. If a node was not found in the
// database, a trie.MissingNodeError is returned.
TryUpdate(key, value []byte) error
UpdateStorage(addr common.Address, key, value []byte) error

// UpdateAccount abstracts an account write to the trie. It encodes the
// provided account object with associated algorithm and then updates it
// in the trie with provided address.
UpdateAccount(address common.Address, account *types.StateAccount) error

// UpdateContractCode abstracts code write to the trie. It is expected
// to be moved to the stateWriter interface when the latter is ready.
UpdateContractCode(address common.Address, codeHash common.Hash, code []byte) error

// DeleteStorage removes any existing value for key from the trie. If a node
// was not found in the database, a trie.MissingNodeError is returned.
DeleteStorage(addr common.Address, key []byte) error

// TryDelete removes any existing value for key from the trie. If a node was not
// found in the database, a trie.MissingNodeError is returned.
TryDelete(key []byte) error
// DeleteAccount abstracts an account deletion from the trie.
DeleteAccount(address common.Address) error

// Hash returns the root hash of the trie. It does not write to the database and
// can be used even if the trie doesn't have one.
Expand Down Expand Up @@ -109,7 +130,7 @@ func NewDatabase(db ethdb.Database) Database {
func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
csc, _ := lru.New(codeSizeCacheSize)
return &cachingDB{
db: trie.NewDatabaseWithCache(db, cache),
db: trie.NewDatabaseWithCache(db, &trie.Config{Cache: cache, Preimages: true}),
codeSizeCache: csc,
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/state/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (self *StateDB) RawDump() Dump {
panic(err)
}

obj := newObject(nil, common.BytesToAddress(addr), data, nil)
obj := newObject(nil, common.BytesToAddress(addr), &data, nil)
account := DumpAccount{
Balance: data.Balance.String(),
Nonce: data.Nonce,
Expand Down
14 changes: 7 additions & 7 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (s *stateObject) empty() bool {
}

// newObject creates a state object.
func newObject(db *StateDB, address common.Address, data types.StateAccount, onDirty func(addr common.Address)) *stateObject {
func newObject(db *StateDB, address common.Address, data *types.StateAccount, onDirty func(addr common.Address)) *stateObject {
if data.Balance == nil {
data.Balance = new(big.Int)
}
Expand All @@ -108,7 +108,7 @@ func newObject(db *StateDB, address common.Address, data types.StateAccount, onD
db: db,
address: address,
addrHash: crypto.Keccak256Hash(address[:]),
data: data,
data: *data,
cachedStorage: make(Storage),
dirtyStorage: make(Storage),
onDirty: onDirty,
Expand Down Expand Up @@ -163,7 +163,7 @@ func (c *stateObject) getTrie(db Database) Trie {
func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash {
value := common.Hash{}
// Load from DB in case it is missing.
enc, err := self.getTrie(db).TryGet(key[:])
enc, err := self.getTrie(db).GetStorage(self.address, key.Bytes())
if err != nil {
self.setError(err)
return common.Hash{}
Expand All @@ -184,7 +184,7 @@ func (self *stateObject) GetState(db Database, key common.Hash) common.Hash {
return value
}
// Load from DB in case it is missing.
enc, err := self.getTrie(db).TryGet(key[:])
enc, err := self.getTrie(db).GetStorage(self.address, key.Bytes())
if err != nil {
self.setError(err)
return common.Hash{}
Expand Down Expand Up @@ -228,12 +228,12 @@ func (self *stateObject) updateTrie(db Database) Trie {
for key, value := range self.dirtyStorage {
delete(self.dirtyStorage, key)
if (value == common.Hash{}) {
self.setError(tr.TryDelete(key[:]))
self.setError(tr.DeleteStorage(self.address, key[:]))
continue
}
// Encoding []byte cannot fail, ok to ignore the error.
v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00"))
self.setError(tr.TryUpdate(key[:], v))
self.setError(tr.UpdateStorage(self.address, key[:], v))
}
return tr
}
Expand Down Expand Up @@ -302,7 +302,7 @@ func (self *stateObject) setBalance(amount *big.Int) {
func (c *stateObject) ReturnGas(gas *big.Int) {}

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)
if self.trie != nil {
stateObject.trie = db.db.CopyTrie(self.trie)
}
Expand Down
23 changes: 10 additions & 13 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/tomochain/tomochain/common"
"github.com/tomochain/tomochain/core/types"
"github.com/tomochain/tomochain/crypto"
"github.com/tomochain/tomochain/log"
"github.com/tomochain/tomochain/rlp"
"github.com/tomochain/tomochain/trie"
)
Expand Down Expand Up @@ -360,18 +359,18 @@ func (self *StateDB) Suicide(addr common.Address) bool {
// updateStateObject writes the given object to the trie.
func (self *StateDB) updateStateObject(stateObject *stateObject) {
addr := stateObject.Address()
data, err := rlp.EncodeToBytes(stateObject)
if err != nil {
panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err))
if err := self.trie.UpdateAccount(addr, &stateObject.data); err != nil {
self.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err))
}
self.setError(self.trie.TryUpdate(addr[:], data))
}

// deleteStateObject removes the given object from the state trie.
func (self *StateDB) deleteStateObject(stateObject *stateObject) {
stateObject.deleted = true
addr := stateObject.Address()
self.setError(self.trie.TryDelete(addr[:]))
if err := self.trie.DeleteAccount(addr); err != nil {
self.setError(fmt.Errorf("deleteStateObject (%x) error: %v", addr[:], err))
}
}

// DeleteAddress removes the address from the state trie.
Expand All @@ -393,14 +392,12 @@ func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObje
}

// Load the object from the database.
enc, err := self.trie.TryGet(addr[:])
if len(enc) == 0 {
self.setError(err)
data, err := self.trie.GetAccount(addr)
if err != nil {
self.setError(fmt.Errorf("getDeleteStateObject (%x) error: %w", addr.Bytes(), err))
return nil
}
var data types.StateAccount
if err := rlp.DecodeBytes(enc, &data); err != nil {
log.Error("Failed to decode state object", "addr", addr, "err", err)
if data == nil {
return nil
}
// Insert into the live set.
Expand Down Expand Up @@ -432,7 +429,7 @@ func (self *StateDB) MarkStateObjectDirty(addr common.Address) {
// the given address, it is overwritten and returned as the second return value.
func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
prev = self.getStateObject(addr)
newobj = newObject(self, addr, types.StateAccount{}, self.MarkStateObjectDirty)
newobj = newObject(self, addr, &types.StateAccount{}, self.MarkStateObjectDirty)
newobj.setNonce(0) // sets the object to dirty
if prev == nil {
self.journal = append(self.journal, createObjectChange{account: &addr})
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ require (
github.com/stretchr/testify v1.8.1
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
golang.org/x/crypto v0.1.0
golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691
golang.org/x/net v0.8.0
golang.org/x/sync v0.1.0
golang.org/x/sys v0.7.0
Expand All @@ -55,6 +56,7 @@ require (
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
Expand All @@ -69,7 +71,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
Expand Down
9 changes: 6 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
Expand Down Expand Up @@ -245,10 +246,12 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 h1:/yRP+0AN7mf5DkD3BAI6TOFnd51gEoDEb8o35jIFtgw=
golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
Expand Down
2 changes: 1 addition & 1 deletion les/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ func (pm *ProtocolManager) getAccount(statedb *state.StateDB, root, hash common.
if err != nil {
return types.StateAccount{}, err
}
blob, err := trie.TryGet(hash[:])
blob, err := trie.Get(hash[:])
if err != nil {
return types.StateAccount{}, err
}
Expand Down
64 changes: 56 additions & 8 deletions light/trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/tomochain/tomochain/core/types"
"github.com/tomochain/tomochain/crypto"
"github.com/tomochain/tomochain/ethdb"
"github.com/tomochain/tomochain/rlp"
"github.com/tomochain/tomochain/trie"
)

Expand Down Expand Up @@ -95,27 +96,74 @@ type odrTrie struct {
trie *trie.Trie
}

func (t *odrTrie) TryGet(key []byte) ([]byte, error) {
func (t *odrTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) {
key = crypto.Keccak256(key)
var res []byte
var enc []byte
err := t.do(key, func() (err error) {
res, err = t.trie.TryGet(key)
enc, err = t.trie.Get(key)
return err
})
return res, err
if err != nil || len(enc) == 0 {
return nil, err
}
_, content, _, err := rlp.Split(enc)
return content, err
}

func (t *odrTrie) GetAccount(address common.Address) (*types.StateAccount, error) {
var (
enc []byte
key = crypto.Keccak256(address.Bytes())
)
err := t.do(key, func() (err error) {
enc, err = t.trie.Get(key)
return err
})
if err != nil || len(enc) == 0 {
return nil, err
}
acct := new(types.StateAccount)
if err := rlp.DecodeBytes(enc, acct); err != nil {
return nil, err
}
return acct, nil
}

func (t *odrTrie) UpdateAccount(address common.Address, acc *types.StateAccount) error {
key := crypto.Keccak256(address.Bytes())
value, err := rlp.EncodeToBytes(acc)
if err != nil {
return fmt.Errorf("decoding error in account update: %w", err)
}
return t.do(key, func() error {
return t.trie.Update(key, value)
})
}

func (t *odrTrie) UpdateContractCode(_ common.Address, _ common.Hash, _ []byte) error {
return nil
}

func (t *odrTrie) TryUpdate(key, value []byte) error {
func (t *odrTrie) UpdateStorage(_ common.Address, key, value []byte) error {
key = crypto.Keccak256(key)
v, _ := rlp.EncodeToBytes(value)
return t.do(key, func() error {
return t.trie.TryDelete(key)
return t.trie.Update(key, v)
})
}

func (t *odrTrie) TryDelete(key []byte) error {
func (t *odrTrie) DeleteStorage(_ common.Address, key []byte) error {
key = crypto.Keccak256(key)
return t.do(key, func() error {
return t.trie.TryDelete(key)
return t.trie.Delete(key)
})
}

// DeleteAccount abstracts an account deletion from the trie.
func (t *odrTrie) DeleteAccount(address common.Address) error {
key := crypto.Keccak256(address.Bytes())
return t.do(key, func() error {
return t.trie.Delete(key)
})
}

Expand Down
Loading