core/state/snapshot, core/types, eth: move account definition to type (#27323)
* core/state/snapshot, core/types, eth: move account definition to type * core, eth: revert snapshot Account API change
This commit is contained in:
parent
c537ace249
commit
0e5d2c7c53
@ -517,14 +517,14 @@ func dumpState(ctx *cli.Context) error {
|
|||||||
Root common.Hash `json:"root"`
|
Root common.Hash `json:"root"`
|
||||||
}{root})
|
}{root})
|
||||||
for accIt.Next() {
|
for accIt.Next() {
|
||||||
account, err := snapshot.FullAccount(accIt.Account())
|
account, err := types.FullAccount(accIt.Account())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
da := &state.DumpAccount{
|
da := &state.DumpAccount{
|
||||||
Balance: account.Balance.String(),
|
Balance: account.Balance.String(),
|
||||||
Nonce: account.Nonce,
|
Nonce: account.Nonce,
|
||||||
Root: account.Root,
|
Root: account.Root.Bytes(),
|
||||||
CodeHash: account.CodeHash,
|
CodeHash: account.CodeHash,
|
||||||
SecureKey: accIt.Hash().Bytes(),
|
SecureKey: accIt.Hash().Bytes(),
|
||||||
}
|
}
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
// Copyright 2019 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package snapshot
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Account is a modified version of a state.Account, where the root is replaced
|
|
||||||
// with a byte slice. This format can be used to represent full-consensus format
|
|
||||||
// or slim-snapshot format which replaces the empty root and code hash as nil
|
|
||||||
// byte slice.
|
|
||||||
type Account struct {
|
|
||||||
Nonce uint64
|
|
||||||
Balance *big.Int
|
|
||||||
Root []byte
|
|
||||||
CodeHash []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// SlimAccount converts a state.Account content into a slim snapshot account
|
|
||||||
func SlimAccount(nonce uint64, balance *big.Int, root common.Hash, codehash []byte) Account {
|
|
||||||
slim := Account{
|
|
||||||
Nonce: nonce,
|
|
||||||
Balance: balance,
|
|
||||||
}
|
|
||||||
if root != types.EmptyRootHash {
|
|
||||||
slim.Root = root[:]
|
|
||||||
}
|
|
||||||
if !bytes.Equal(codehash, types.EmptyCodeHash[:]) {
|
|
||||||
slim.CodeHash = codehash
|
|
||||||
}
|
|
||||||
return slim
|
|
||||||
}
|
|
||||||
|
|
||||||
// SlimAccountRLP converts a state.Account content into a slim snapshot
|
|
||||||
// version RLP encoded.
|
|
||||||
func SlimAccountRLP(nonce uint64, balance *big.Int, root common.Hash, codehash []byte) []byte {
|
|
||||||
data, err := rlp.EncodeToBytes(SlimAccount(nonce, balance, root, codehash))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
// FullAccount decodes the data on the 'slim RLP' format and return
|
|
||||||
// the consensus format account.
|
|
||||||
func FullAccount(data []byte) (Account, error) {
|
|
||||||
var account Account
|
|
||||||
if err := rlp.DecodeBytes(data, &account); err != nil {
|
|
||||||
return Account{}, err
|
|
||||||
}
|
|
||||||
if len(account.Root) == 0 {
|
|
||||||
account.Root = types.EmptyRootHash[:]
|
|
||||||
}
|
|
||||||
if len(account.CodeHash) == 0 {
|
|
||||||
account.CodeHash = types.EmptyCodeHash[:]
|
|
||||||
}
|
|
||||||
return account, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FullAccountRLP converts data on the 'slim RLP' format into the full RLP-format.
|
|
||||||
func FullAccountRLP(data []byte) ([]byte, error) {
|
|
||||||
account, err := FullAccount(data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return rlp.EncodeToBytes(account)
|
|
||||||
}
|
|
@ -17,7 +17,6 @@
|
|||||||
package snapshot
|
package snapshot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -301,7 +300,7 @@ func generateTrieRoot(db ethdb.KeyValueWriter, scheme string, it Iterator, accou
|
|||||||
fullData []byte
|
fullData []byte
|
||||||
)
|
)
|
||||||
if leafCallback == nil {
|
if leafCallback == nil {
|
||||||
fullData, err = FullAccountRLP(it.(AccountIterator).Account())
|
fullData, err = types.FullAccountRLP(it.(AccountIterator).Account())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stop(err)
|
return stop(err)
|
||||||
}
|
}
|
||||||
@ -313,7 +312,7 @@ func generateTrieRoot(db ethdb.KeyValueWriter, scheme string, it Iterator, accou
|
|||||||
return stop(err)
|
return stop(err)
|
||||||
}
|
}
|
||||||
// Fetch the next account and process it concurrently
|
// Fetch the next account and process it concurrently
|
||||||
account, err := FullAccount(it.(AccountIterator).Account())
|
account, err := types.FullAccount(it.(AccountIterator).Account())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stop(err)
|
return stop(err)
|
||||||
}
|
}
|
||||||
@ -323,7 +322,7 @@ func generateTrieRoot(db ethdb.KeyValueWriter, scheme string, it Iterator, accou
|
|||||||
results <- err
|
results <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !bytes.Equal(account.Root, subroot.Bytes()) {
|
if account.Root != subroot {
|
||||||
results <- fmt.Errorf("invalid subroot(path %x), want %x, have %x", hash, account.Root, subroot)
|
results <- fmt.Errorf("invalid subroot(path %x), want %x, have %x", hash, account.Root, subroot)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
bloomfilter "github.com/holiman/bloomfilter/v2"
|
bloomfilter "github.com/holiman/bloomfilter/v2"
|
||||||
)
|
)
|
||||||
@ -272,7 +273,7 @@ func (dl *diffLayer) Stale() bool {
|
|||||||
|
|
||||||
// Account directly retrieves the account associated with a particular hash in
|
// Account directly retrieves the account associated with a particular hash in
|
||||||
// the snapshot slim data format.
|
// the snapshot slim data format.
|
||||||
func (dl *diffLayer) Account(hash common.Hash) (*Account, error) {
|
func (dl *diffLayer) Account(hash common.Hash) (*types.SlimAccount, error) {
|
||||||
data, err := dl.AccountRLP(hash)
|
data, err := dl.AccountRLP(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -280,7 +281,7 @@ func (dl *diffLayer) Account(hash common.Hash) (*Account, error) {
|
|||||||
if len(data) == 0 { // can be both nil and []byte{}
|
if len(data) == 0 { // can be both nil and []byte{}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
account := new(Account)
|
account := new(types.SlimAccount)
|
||||||
if err := rlp.DecodeBytes(data, account); err != nil {
|
if err := rlp.DecodeBytes(data, account); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -292,8 +293,8 @@ func (dl *diffLayer) Account(hash common.Hash) (*Account, error) {
|
|||||||
//
|
//
|
||||||
// Note the returned account is not a copy, please don't modify it.
|
// Note the returned account is not a copy, please don't modify it.
|
||||||
func (dl *diffLayer) AccountRLP(hash common.Hash) ([]byte, error) {
|
func (dl *diffLayer) AccountRLP(hash common.Hash) ([]byte, error) {
|
||||||
dl.lock.RLock()
|
|
||||||
// Check staleness before reaching further.
|
// Check staleness before reaching further.
|
||||||
|
dl.lock.RLock()
|
||||||
if dl.Stale() {
|
if dl.Stale() {
|
||||||
dl.lock.RUnlock()
|
dl.lock.RUnlock()
|
||||||
return nil, ErrSnapshotStale
|
return nil, ErrSnapshotStale
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/VictoriaMetrics/fastcache"
|
"github.com/VictoriaMetrics/fastcache"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
@ -65,7 +66,7 @@ func (dl *diskLayer) Stale() bool {
|
|||||||
|
|
||||||
// Account directly retrieves the account associated with a particular hash in
|
// Account directly retrieves the account associated with a particular hash in
|
||||||
// the snapshot slim data format.
|
// the snapshot slim data format.
|
||||||
func (dl *diskLayer) Account(hash common.Hash) (*Account, error) {
|
func (dl *diskLayer) Account(hash common.Hash) (*types.SlimAccount, error) {
|
||||||
data, err := dl.AccountRLP(hash)
|
data, err := dl.AccountRLP(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -73,7 +74,7 @@ func (dl *diskLayer) Account(hash common.Hash) (*Account, error) {
|
|||||||
if len(data) == 0 { // can be both nil and []byte{}
|
if len(data) == 0 { // can be both nil and []byte{}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
account := new(Account)
|
account := new(types.SlimAccount)
|
||||||
if err := rlp.DecodeBytes(data, account); err != nil {
|
if err := rlp.DecodeBytes(data, account); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/fastcache"
|
"github.com/VictoriaMetrics/fastcache"
|
||||||
@ -573,12 +572,7 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Retrieve the current account and flatten it into the internal format
|
// Retrieve the current account and flatten it into the internal format
|
||||||
var acc struct {
|
var acc types.StateAccount
|
||||||
Nonce uint64
|
|
||||||
Balance *big.Int
|
|
||||||
Root common.Hash
|
|
||||||
CodeHash []byte
|
|
||||||
}
|
|
||||||
if err := rlp.DecodeBytes(val, &acc); err != nil {
|
if err := rlp.DecodeBytes(val, &acc); err != nil {
|
||||||
log.Crit("Invalid account encountered during snapshot creation", "err", err)
|
log.Crit("Invalid account encountered during snapshot creation", "err", err)
|
||||||
}
|
}
|
||||||
@ -594,7 +588,7 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
|||||||
}
|
}
|
||||||
snapRecoveredAccountMeter.Mark(1)
|
snapRecoveredAccountMeter.Mark(1)
|
||||||
} else {
|
} else {
|
||||||
data := SlimAccountRLP(acc.Nonce, acc.Balance, acc.Root, acc.CodeHash)
|
data := types.SlimAccountRLP(acc)
|
||||||
dataLen = len(data)
|
dataLen = len(data)
|
||||||
rawdb.WriteAccountSnapshot(ctx.batch, account, data)
|
rawdb.WriteAccountSnapshot(ctx.batch, account, data)
|
||||||
snapGeneratedAccountMeter.Mark(1)
|
snapGeneratedAccountMeter.Mark(1)
|
||||||
@ -640,7 +634,7 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
|||||||
origin := common.CopyBytes(accMarker)
|
origin := common.CopyBytes(accMarker)
|
||||||
for {
|
for {
|
||||||
id := trie.StateTrieID(dl.root)
|
id := trie.StateTrieID(dl.root)
|
||||||
exhausted, last, err := dl.generateRange(ctx, id, rawdb.SnapshotAccountPrefix, snapAccount, origin, accountRange, onAccount, FullAccountRLP)
|
exhausted, last, err := dl.generateRange(ctx, id, rawdb.SnapshotAccountPrefix, snapAccount, origin, accountRange, onAccount, types.FullAccountRLP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err // The procedure it aborted, either by external signal or internal error.
|
return err // The procedure it aborted, either by external signal or internal error.
|
||||||
}
|
}
|
||||||
|
@ -51,9 +51,9 @@ func TestGeneration(t *testing.T) {
|
|||||||
var helper = newHelper()
|
var helper = newHelper()
|
||||||
stRoot := helper.makeStorageTrie(common.Hash{}, []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, false)
|
stRoot := helper.makeStorageTrie(common.Hash{}, []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, false)
|
||||||
|
|
||||||
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
@ -85,16 +85,16 @@ func TestGenerateExistentState(t *testing.T) {
|
|||||||
var helper = newHelper()
|
var helper = newHelper()
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addSnapAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||||
|
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addSnapAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
stRoot = helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot = helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addSnapAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
helper.addSnapStorage("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||||
|
|
||||||
root, snap := helper.CommitAndGenerate()
|
root, snap := helper.CommitAndGenerate()
|
||||||
@ -160,18 +160,17 @@ func newHelper() *testHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testHelper) addTrieAccount(acckey string, acc *Account) {
|
func (t *testHelper) addTrieAccount(acckey string, acc *types.StateAccount) {
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
t.accTrie.MustUpdate([]byte(acckey), val)
|
t.accTrie.MustUpdate([]byte(acckey), val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testHelper) addSnapAccount(acckey string, acc *Account) {
|
func (t *testHelper) addSnapAccount(acckey string, acc *types.StateAccount) {
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
|
||||||
key := hashData([]byte(acckey))
|
key := hashData([]byte(acckey))
|
||||||
rawdb.WriteAccountSnapshot(t.diskdb, key, val)
|
rawdb.WriteAccountSnapshot(t.diskdb, key, types.SlimAccountRLP(*acc))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testHelper) addAccount(acckey string, acc *Account) {
|
func (t *testHelper) addAccount(acckey string, acc *types.StateAccount) {
|
||||||
t.addTrieAccount(acckey, acc)
|
t.addTrieAccount(acckey, acc)
|
||||||
t.addSnapAccount(acckey, acc)
|
t.addSnapAccount(acckey, acc)
|
||||||
}
|
}
|
||||||
@ -183,20 +182,20 @@ func (t *testHelper) addSnapStorage(accKey string, keys []string, vals []string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testHelper) makeStorageTrie(owner common.Hash, keys []string, vals []string, commit bool) []byte {
|
func (t *testHelper) makeStorageTrie(owner common.Hash, keys []string, vals []string, commit bool) common.Hash {
|
||||||
id := trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash)
|
id := trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash)
|
||||||
stTrie, _ := trie.NewStateTrie(id, t.triedb)
|
stTrie, _ := trie.NewStateTrie(id, t.triedb)
|
||||||
for i, k := range keys {
|
for i, k := range keys {
|
||||||
stTrie.MustUpdate([]byte(k), []byte(vals[i]))
|
stTrie.MustUpdate([]byte(k), []byte(vals[i]))
|
||||||
}
|
}
|
||||||
if !commit {
|
if !commit {
|
||||||
return stTrie.Hash().Bytes()
|
return stTrie.Hash()
|
||||||
}
|
}
|
||||||
root, nodes := stTrie.Commit(false)
|
root, nodes := stTrie.Commit(false)
|
||||||
if nodes != nil {
|
if nodes != nil {
|
||||||
t.nodes.Merge(nodes)
|
t.nodes.Merge(nodes)
|
||||||
}
|
}
|
||||||
return root.Bytes()
|
return root
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testHelper) Commit() common.Hash {
|
func (t *testHelper) Commit() common.Hash {
|
||||||
@ -237,28 +236,28 @@ func TestGenerateExistentStateWithWrongStorage(t *testing.T) {
|
|||||||
helper := newHelper()
|
helper := newHelper()
|
||||||
|
|
||||||
// Account one, empty root but non-empty database
|
// Account one, empty root but non-empty database
|
||||||
helper.addAccount("acc-1", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||||
|
|
||||||
// Account two, non empty root but empty database
|
// Account two, non empty root but empty database
|
||||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-2")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie(hashData([]byte("acc-2")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-2", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
// Miss slots
|
// Miss slots
|
||||||
{
|
{
|
||||||
// Account three, non empty root but misses slots in the beginning
|
// Account three, non empty root but misses slots in the beginning
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-3", []string{"key-2", "key-3"}, []string{"val-2", "val-3"})
|
helper.addSnapStorage("acc-3", []string{"key-2", "key-3"}, []string{"val-2", "val-3"})
|
||||||
|
|
||||||
// Account four, non empty root but misses slots in the middle
|
// Account four, non empty root but misses slots in the middle
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-4")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-4")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-4", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-4", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-4", []string{"key-1", "key-3"}, []string{"val-1", "val-3"})
|
helper.addSnapStorage("acc-4", []string{"key-1", "key-3"}, []string{"val-1", "val-3"})
|
||||||
|
|
||||||
// Account five, non empty root but misses slots in the end
|
// Account five, non empty root but misses slots in the end
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-5")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-5")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-5", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-5", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-5", []string{"key-1", "key-2"}, []string{"val-1", "val-2"})
|
helper.addSnapStorage("acc-5", []string{"key-1", "key-2"}, []string{"val-1", "val-2"})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,22 +265,22 @@ func TestGenerateExistentStateWithWrongStorage(t *testing.T) {
|
|||||||
{
|
{
|
||||||
// Account six, non empty root but wrong slots in the beginning
|
// Account six, non empty root but wrong slots in the beginning
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-6")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-6")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-6", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-6", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-6", []string{"key-1", "key-2", "key-3"}, []string{"badval-1", "val-2", "val-3"})
|
helper.addSnapStorage("acc-6", []string{"key-1", "key-2", "key-3"}, []string{"badval-1", "val-2", "val-3"})
|
||||||
|
|
||||||
// Account seven, non empty root but wrong slots in the middle
|
// Account seven, non empty root but wrong slots in the middle
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-7")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-7")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-7", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-7", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-7", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "badval-2", "val-3"})
|
helper.addSnapStorage("acc-7", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "badval-2", "val-3"})
|
||||||
|
|
||||||
// Account eight, non empty root but wrong slots in the end
|
// Account eight, non empty root but wrong slots in the end
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-8")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-8")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-8", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-8", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-8", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "badval-3"})
|
helper.addSnapStorage("acc-8", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "badval-3"})
|
||||||
|
|
||||||
// Account 9, non empty root but rotated slots
|
// Account 9, non empty root but rotated slots
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-9")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-9")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-9", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-9", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-9", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-3", "val-2"})
|
helper.addSnapStorage("acc-9", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-3", "val-2"})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,17 +288,17 @@ func TestGenerateExistentStateWithWrongStorage(t *testing.T) {
|
|||||||
{
|
{
|
||||||
// Account 10, non empty root but extra slots in the beginning
|
// Account 10, non empty root but extra slots in the beginning
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-10")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-10")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-10", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-10", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-10", []string{"key-0", "key-1", "key-2", "key-3"}, []string{"val-0", "val-1", "val-2", "val-3"})
|
helper.addSnapStorage("acc-10", []string{"key-0", "key-1", "key-2", "key-3"}, []string{"val-0", "val-1", "val-2", "val-3"})
|
||||||
|
|
||||||
// Account 11, non empty root but extra slots in the middle
|
// Account 11, non empty root but extra slots in the middle
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-11")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-11")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-11", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-11", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-11", []string{"key-1", "key-2", "key-2-1", "key-3"}, []string{"val-1", "val-2", "val-2-1", "val-3"})
|
helper.addSnapStorage("acc-11", []string{"key-1", "key-2", "key-2-1", "key-3"}, []string{"val-1", "val-2", "val-2-1", "val-3"})
|
||||||
|
|
||||||
// Account 12, non empty root but extra slots in the end
|
// Account 12, non empty root but extra slots in the end
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-12")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-12")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-12", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-12", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-12", []string{"key-1", "key-2", "key-3", "key-4"}, []string{"val-1", "val-2", "val-3", "val-4"})
|
helper.addSnapStorage("acc-12", []string{"key-1", "key-2", "key-3", "key-4"}, []string{"val-1", "val-2", "val-3", "val-4"})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,25 +338,25 @@ func TestGenerateExistentStateWithWrongAccounts(t *testing.T) {
|
|||||||
|
|
||||||
// Missing accounts, only in the trie
|
// Missing accounts, only in the trie
|
||||||
{
|
{
|
||||||
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Beginning
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Beginning
|
||||||
helper.addTrieAccount("acc-4", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Middle
|
helper.addTrieAccount("acc-4", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Middle
|
||||||
helper.addTrieAccount("acc-6", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // End
|
helper.addTrieAccount("acc-6", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // End
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrong accounts
|
// Wrong accounts
|
||||||
{
|
{
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-2", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: common.Hex2Bytes("0x1234")})
|
helper.addSnapAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: common.Hex2Bytes("0x1234")})
|
||||||
|
|
||||||
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-3", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addSnapAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extra accounts, only in the snap
|
// Extra accounts, only in the snap
|
||||||
{
|
{
|
||||||
helper.addSnapAccount("acc-0", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // before the beginning
|
helper.addSnapAccount("acc-0", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // before the beginning
|
||||||
helper.addSnapAccount("acc-5", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: common.Hex2Bytes("0x1234")}) // Middle
|
helper.addSnapAccount("acc-5", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: common.Hex2Bytes("0x1234")}) // Middle
|
||||||
helper.addSnapAccount("acc-7", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // after the end
|
helper.addSnapAccount("acc-7", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // after the end
|
||||||
}
|
}
|
||||||
|
|
||||||
root, snap := helper.CommitAndGenerate()
|
root, snap := helper.CommitAndGenerate()
|
||||||
@ -386,9 +385,9 @@ func TestGenerateCorruptAccountTrie(t *testing.T) {
|
|||||||
// without any storage slots to keep the test smaller.
|
// without any storage slots to keep the test smaller.
|
||||||
helper := newHelper()
|
helper := newHelper()
|
||||||
|
|
||||||
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||||
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4
|
||||||
|
|
||||||
root := helper.Commit() // Root: 0xa04693ea110a31037fb5ee814308a6f1d76bdab0b11676bdf4541d2de55ba978
|
root := helper.Commit() // Root: 0xa04693ea110a31037fb5ee814308a6f1d76bdab0b11676bdf4541d2de55ba978
|
||||||
|
|
||||||
@ -420,16 +419,16 @@ func TestGenerateMissingStorageTrie(t *testing.T) {
|
|||||||
// two of which also has the same 3-slot storage trie attached.
|
// two of which also has the same 3-slot storage trie attached.
|
||||||
helper := newHelper()
|
helper := newHelper()
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
||||||
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||||
stRoot = helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot = helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
||||||
|
|
||||||
root := helper.Commit()
|
root := helper.Commit()
|
||||||
|
|
||||||
// Delete a storage trie root and ensure the generator chokes
|
// Delete a storage trie root and ensure the generator chokes
|
||||||
helper.diskdb.Delete(stRoot)
|
helper.diskdb.Delete(stRoot.Bytes())
|
||||||
|
|
||||||
snap := generateSnapshot(helper.diskdb, helper.triedb, 16, root)
|
snap := generateSnapshot(helper.diskdb, helper.triedb, 16, root)
|
||||||
select {
|
select {
|
||||||
@ -454,11 +453,11 @@ func TestGenerateCorruptStorageTrie(t *testing.T) {
|
|||||||
// two of which also has the same 3-slot storage trie attached.
|
// two of which also has the same 3-slot storage trie attached.
|
||||||
helper := newHelper()
|
helper := newHelper()
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
||||||
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||||
stRoot = helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot = helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
||||||
|
|
||||||
root := helper.Commit()
|
root := helper.Commit()
|
||||||
|
|
||||||
@ -490,7 +489,7 @@ func TestGenerateWithExtraAccounts(t *testing.T) {
|
|||||||
[]string{"val-1", "val-2", "val-3", "val-4", "val-5"},
|
[]string{"val-1", "val-2", "val-3", "val-4", "val-5"},
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
acc := &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
helper.accTrie.MustUpdate([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
helper.accTrie.MustUpdate([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||||
|
|
||||||
@ -510,7 +509,7 @@ func TestGenerateWithExtraAccounts(t *testing.T) {
|
|||||||
[]string{"val-1", "val-2", "val-3", "val-4", "val-5"},
|
[]string{"val-1", "val-2", "val-3", "val-4", "val-5"},
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
acc := &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
key := hashData([]byte("acc-2"))
|
key := hashData([]byte("acc-2"))
|
||||||
rawdb.WriteAccountSnapshot(helper.diskdb, key, val)
|
rawdb.WriteAccountSnapshot(helper.diskdb, key, val)
|
||||||
@ -561,7 +560,7 @@ func TestGenerateWithManyExtraAccounts(t *testing.T) {
|
|||||||
[]string{"val-1", "val-2", "val-3"},
|
[]string{"val-1", "val-2", "val-3"},
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
acc := &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
helper.accTrie.MustUpdate([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
helper.accTrie.MustUpdate([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||||
|
|
||||||
@ -575,7 +574,7 @@ func TestGenerateWithManyExtraAccounts(t *testing.T) {
|
|||||||
{
|
{
|
||||||
// 100 accounts exist only in snapshot
|
// 100 accounts exist only in snapshot
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
acc := &Account{Balance: big.NewInt(int64(i)), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}
|
acc := &types.StateAccount{Balance: big.NewInt(int64(i)), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
key := hashData([]byte(fmt.Sprintf("acc-%d", i)))
|
key := hashData([]byte(fmt.Sprintf("acc-%d", i)))
|
||||||
rawdb.WriteAccountSnapshot(helper.diskdb, key, val)
|
rawdb.WriteAccountSnapshot(helper.diskdb, key, val)
|
||||||
@ -612,7 +611,7 @@ func TestGenerateWithExtraBeforeAndAfter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
helper := newHelper()
|
helper := newHelper()
|
||||||
{
|
{
|
||||||
acc := &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}
|
acc := &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
helper.accTrie.MustUpdate(common.HexToHash("0x03").Bytes(), val)
|
helper.accTrie.MustUpdate(common.HexToHash("0x03").Bytes(), val)
|
||||||
helper.accTrie.MustUpdate(common.HexToHash("0x07").Bytes(), val)
|
helper.accTrie.MustUpdate(common.HexToHash("0x07").Bytes(), val)
|
||||||
@ -649,7 +648,7 @@ func TestGenerateWithMalformedSnapdata(t *testing.T) {
|
|||||||
}
|
}
|
||||||
helper := newHelper()
|
helper := newHelper()
|
||||||
{
|
{
|
||||||
acc := &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}
|
acc := &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
helper.accTrie.MustUpdate(common.HexToHash("0x03").Bytes(), val)
|
helper.accTrie.MustUpdate(common.HexToHash("0x03").Bytes(), val)
|
||||||
|
|
||||||
@ -688,7 +687,7 @@ func TestGenerateFromEmptySnap(t *testing.T) {
|
|||||||
for i := 0; i < 400; i++ {
|
for i := 0; i < 400; i++ {
|
||||||
stRoot := helper.makeStorageTrie(hashData([]byte(fmt.Sprintf("acc-%d", i))), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie(hashData([]byte(fmt.Sprintf("acc-%d", i))), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount(fmt.Sprintf("acc-%d", i),
|
helper.addTrieAccount(fmt.Sprintf("acc-%d", i),
|
||||||
&Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
&types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
}
|
}
|
||||||
root, snap := helper.CommitAndGenerate()
|
root, snap := helper.CommitAndGenerate()
|
||||||
t.Logf("Root: %#x\n", root) // Root: 0x6f7af6d2e1a1bf2b84a3beb3f8b64388465fbc1e274ca5d5d3fc787ca78f59e4
|
t.Logf("Root: %#x\n", root) // Root: 0x6f7af6d2e1a1bf2b84a3beb3f8b64388465fbc1e274ca5d5d3fc787ca78f59e4
|
||||||
@ -725,7 +724,7 @@ func TestGenerateWithIncompleteStorage(t *testing.T) {
|
|||||||
for i := 0; i < 8; i++ {
|
for i := 0; i < 8; i++ {
|
||||||
accKey := fmt.Sprintf("acc-%d", i)
|
accKey := fmt.Sprintf("acc-%d", i)
|
||||||
stRoot := helper.makeStorageTrie(hashData([]byte(accKey)), stKeys, stVals, true)
|
stRoot := helper.makeStorageTrie(hashData([]byte(accKey)), stKeys, stVals, true)
|
||||||
helper.addAccount(accKey, &Account{Balance: big.NewInt(int64(i)), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount(accKey, &types.StateAccount{Balance: big.NewInt(int64(i)), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
var moddedKeys []string
|
var moddedKeys []string
|
||||||
var moddedVals []string
|
var moddedVals []string
|
||||||
for ii := 0; ii < 8; ii++ {
|
for ii := 0; ii < 8; ii++ {
|
||||||
@ -817,11 +816,11 @@ func TestGenerateCompleteSnapshotWithDanglingStorage(t *testing.T) {
|
|||||||
var helper = newHelper()
|
var helper = newHelper()
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addAccount("acc-2", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||||
helper.addSnapStorage("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
helper.addSnapStorage("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||||
@ -852,11 +851,11 @@ func TestGenerateBrokenSnapshotWithDanglingStorage(t *testing.T) {
|
|||||||
var helper = newHelper()
|
var helper = newHelper()
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
populateDangling(helper.diskdb)
|
populateDangling(helper.diskdb)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
@ -102,7 +103,7 @@ type Snapshot interface {
|
|||||||
|
|
||||||
// Account directly retrieves the account associated with a particular hash in
|
// Account directly retrieves the account associated with a particular hash in
|
||||||
// the snapshot slim data format.
|
// the snapshot slim data format.
|
||||||
Account(hash common.Hash) (*Account, error)
|
Account(hash common.Hash) (*types.SlimAccount, error)
|
||||||
|
|
||||||
// AccountRLP directly retrieves the account RLP associated with a particular
|
// AccountRLP directly retrieves the account RLP associated with a particular
|
||||||
// hash in the snapshot slim data format.
|
// hash in the snapshot slim data format.
|
||||||
|
@ -43,11 +43,10 @@ func randomHash() common.Hash {
|
|||||||
|
|
||||||
// randomAccount generates a random account and returns it RLP encoded.
|
// randomAccount generates a random account and returns it RLP encoded.
|
||||||
func randomAccount() []byte {
|
func randomAccount() []byte {
|
||||||
root := randomHash()
|
a := &types.StateAccount{
|
||||||
a := Account{
|
|
||||||
Balance: big.NewInt(rand.Int63()),
|
Balance: big.NewInt(rand.Int63()),
|
||||||
Nonce: rand.Uint64(),
|
Nonce: rand.Uint64(),
|
||||||
Root: root[:],
|
Root: randomHash(),
|
||||||
CodeHash: types.EmptyCodeHash[:],
|
CodeHash: types.EmptyCodeHash[:],
|
||||||
}
|
}
|
||||||
data, _ := rlp.EncodeToBytes(a)
|
data, _ := rlp.EncodeToBytes(a)
|
||||||
@ -465,7 +464,7 @@ func TestReadStateDuringFlattening(t *testing.T) {
|
|||||||
snap := snaps.Snapshot(common.HexToHash("0xa3"))
|
snap := snaps.Snapshot(common.HexToHash("0xa3"))
|
||||||
|
|
||||||
// Register the testing hook to access the state after flattening
|
// Register the testing hook to access the state after flattening
|
||||||
var result = make(chan *Account)
|
var result = make(chan *types.SlimAccount)
|
||||||
snaps.onFlatten = func() {
|
snaps.onFlatten = func() {
|
||||||
// Spin up a thread to read the account from the pre-created
|
// Spin up a thread to read the account from the pre-created
|
||||||
// snapshot handler. It's expected to be blocked.
|
// snapshot handler. It's expected to be blocked.
|
||||||
|
@ -23,9 +23,9 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckDanglingStorage iterates the snap storage data, and verifies that all
|
// CheckDanglingStorage iterates the snap storage data, and verifies that all
|
||||||
@ -98,8 +98,8 @@ func CheckJournalAccount(db ethdb.KeyValueStore, hash common.Hash) error {
|
|||||||
baseRoot := rawdb.ReadSnapshotRoot(db)
|
baseRoot := rawdb.ReadSnapshotRoot(db)
|
||||||
fmt.Printf("Disklayer: Root: %x\n", baseRoot)
|
fmt.Printf("Disklayer: Root: %x\n", baseRoot)
|
||||||
if data := rawdb.ReadAccountSnapshot(db, hash); data != nil {
|
if data := rawdb.ReadAccountSnapshot(db, hash); data != nil {
|
||||||
account := new(Account)
|
account, err := types.FullAccount(data)
|
||||||
if err := rlp.DecodeBytes(data, account); err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Printf("\taccount.nonce: %d\n", account.Nonce)
|
fmt.Printf("\taccount.nonce: %d\n", account.Nonce)
|
||||||
@ -129,8 +129,8 @@ func CheckJournalAccount(db ethdb.KeyValueStore, hash common.Hash) error {
|
|||||||
}
|
}
|
||||||
fmt.Printf("Disklayer+%d: Root: %x, parent %x\n", depth, root, pRoot)
|
fmt.Printf("Disklayer+%d: Root: %x, parent %x\n", depth, root, pRoot)
|
||||||
if data, ok := accounts[hash]; ok {
|
if data, ok := accounts[hash]; ok {
|
||||||
account := new(Account)
|
account, err := types.FullAccount(data)
|
||||||
if err := rlp.DecodeBytes(data, account); err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Printf("\taccount.nonce: %d\n", account.Nonce)
|
fmt.Printf("\taccount.nonce: %d\n", account.Nonce)
|
||||||
|
@ -522,7 +522,7 @@ func (s *StateDB) updateStateObject(obj *stateObject) {
|
|||||||
// enough to track account updates at commit time, deletions need tracking
|
// enough to track account updates at commit time, deletions need tracking
|
||||||
// at transaction boundary level to ensure we capture state clearing.
|
// at transaction boundary level to ensure we capture state clearing.
|
||||||
if s.snap != nil {
|
if s.snap != nil {
|
||||||
s.snapAccounts[obj.addrHash] = snapshot.SlimAccountRLP(obj.data.Nonce, obj.data.Balance, obj.data.Root, obj.data.CodeHash)
|
s.snapAccounts[obj.addrHash] = types.SlimAccountRLP(obj.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run ../../rlp/rlpgen -type StateAccount -out gen_account_rlp.go
|
//go:generate go run ../../rlp/rlpgen -type StateAccount -out gen_account_rlp.go
|
||||||
@ -32,3 +34,65 @@ type StateAccount struct {
|
|||||||
Root common.Hash // merkle root of the storage trie
|
Root common.Hash // merkle root of the storage trie
|
||||||
CodeHash []byte
|
CodeHash []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SlimAccount is a modified version of an Account, where the root is replaced
|
||||||
|
// with a byte slice. This format can be used to represent full-consensus format
|
||||||
|
// or slim format which replaces the empty root and code hash as nil byte slice.
|
||||||
|
type SlimAccount struct {
|
||||||
|
Nonce uint64
|
||||||
|
Balance *big.Int
|
||||||
|
Root []byte // Nil if root equals to types.EmptyRootHash
|
||||||
|
CodeHash []byte // Nil if hash equals to types.EmptyCodeHash
|
||||||
|
}
|
||||||
|
|
||||||
|
// SlimAccountRLP encodes the state account in 'slim RLP' format.
|
||||||
|
func SlimAccountRLP(account StateAccount) []byte {
|
||||||
|
slim := SlimAccount{
|
||||||
|
Nonce: account.Nonce,
|
||||||
|
Balance: account.Balance,
|
||||||
|
}
|
||||||
|
if account.Root != EmptyRootHash {
|
||||||
|
slim.Root = account.Root[:]
|
||||||
|
}
|
||||||
|
if !bytes.Equal(account.CodeHash, EmptyCodeHash[:]) {
|
||||||
|
slim.CodeHash = account.CodeHash
|
||||||
|
}
|
||||||
|
data, err := rlp.EncodeToBytes(slim)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// FullAccount decodes the data on the 'slim RLP' format and return
|
||||||
|
// the consensus format account.
|
||||||
|
func FullAccount(data []byte) (*StateAccount, error) {
|
||||||
|
var slim SlimAccount
|
||||||
|
if err := rlp.DecodeBytes(data, &slim); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var account StateAccount
|
||||||
|
account.Nonce, account.Balance = slim.Nonce, slim.Balance
|
||||||
|
|
||||||
|
// Interpret the storage root and code hash in slim format.
|
||||||
|
if len(slim.Root) == 0 {
|
||||||
|
account.Root = EmptyRootHash
|
||||||
|
} else {
|
||||||
|
account.Root = common.BytesToHash(slim.Root)
|
||||||
|
}
|
||||||
|
if len(slim.CodeHash) == 0 {
|
||||||
|
account.CodeHash = EmptyCodeHash[:]
|
||||||
|
} else {
|
||||||
|
account.CodeHash = slim.CodeHash
|
||||||
|
}
|
||||||
|
return &account, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FullAccountRLP converts data on the 'slim RLP' format into the full RLP-format.
|
||||||
|
func FullAccountRLP(data []byte) ([]byte, error) {
|
||||||
|
account, err := FullAccount(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return rlp.EncodeToBytes(account)
|
||||||
|
}
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ func (p *AccountRangePacket) Unpack() ([]common.Hash, [][]byte, error) {
|
|||||||
accounts = make([][]byte, len(p.Accounts))
|
accounts = make([][]byte, len(p.Accounts))
|
||||||
)
|
)
|
||||||
for i, acc := range p.Accounts {
|
for i, acc := range p.Accounts {
|
||||||
val, err := snapshot.FullAccountRLP(acc.Body)
|
val, err := types.FullAccountRLP(acc.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("invalid account %x: %v", acc.Body, err)
|
return nil, nil, fmt.Errorf("invalid account %x: %v", acc.Body, err)
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common/math"
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
@ -2277,13 +2276,13 @@ func (s *Syncer) forwardAccountTask(task *accountTask) {
|
|||||||
if task.needCode[i] || task.needState[i] {
|
if task.needCode[i] || task.needState[i] {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
slim := snapshot.SlimAccountRLP(res.accounts[i].Nonce, res.accounts[i].Balance, res.accounts[i].Root, res.accounts[i].CodeHash)
|
slim := types.SlimAccountRLP(*res.accounts[i])
|
||||||
rawdb.WriteAccountSnapshot(batch, hash, slim)
|
rawdb.WriteAccountSnapshot(batch, hash, slim)
|
||||||
|
|
||||||
// If the task is complete, drop it into the stack trie to generate
|
// If the task is complete, drop it into the stack trie to generate
|
||||||
// account trie nodes for it
|
// account trie nodes for it
|
||||||
if !task.needHeal[i] {
|
if !task.needHeal[i] {
|
||||||
full, err := snapshot.FullAccountRLP(slim) // TODO(karalabe): Slim parsing can be omitted
|
full, err := types.FullAccountRLP(slim) // TODO(karalabe): Slim parsing can be omitted
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err) // Really shouldn't ever happen
|
panic(err) // Really shouldn't ever happen
|
||||||
}
|
}
|
||||||
@ -2902,7 +2901,7 @@ func (s *Syncer) onHealState(paths [][]byte, value []byte) error {
|
|||||||
if err := rlp.DecodeBytes(value, &account); err != nil {
|
if err := rlp.DecodeBytes(value, &account); err != nil {
|
||||||
return nil // Returning the error here would drop the remote peer
|
return nil // Returning the error here would drop the remote peer
|
||||||
}
|
}
|
||||||
blob := snapshot.SlimAccountRLP(account.Nonce, account.Balance, account.Root, account.CodeHash)
|
blob := types.SlimAccountRLP(account)
|
||||||
rawdb.WriteAccountSnapshot(s.stateWriter, common.BytesToHash(paths[0]), blob)
|
rawdb.WriteAccountSnapshot(s.stateWriter, common.BytesToHash(paths[0]), blob)
|
||||||
s.accountHealed += 1
|
s.accountHealed += 1
|
||||||
s.accountHealedBytes += common.StorageSize(1 + common.HashLength + len(blob))
|
s.accountHealedBytes += common.StorageSize(1 + common.HashLength + len(blob))
|
||||||
|
Loading…
Reference in New Issue
Block a user