all: use unified emptyRootHash and emptyCodeHash (#26718)
The EmptyRootHash and EmptyCodeHash are defined everywhere in the codebase, this PR replaces all of them with unified one defined in core/types package, and also defines constants for TxRoot, WithdrawalsRoot and UncleRoot
This commit is contained in:
parent
2f20fd31ee
commit
fe01a2f63b
@ -23,6 +23,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/protocols/snap"
|
"github.com/ethereum/go-ethereum/eth/protocols/snap"
|
||||||
"github.com/ethereum/go-ethereum/internal/utesting"
|
"github.com/ethereum/go-ethereum/internal/utesting"
|
||||||
@ -210,13 +211,6 @@ type byteCodesTest struct {
|
|||||||
expHashes int
|
expHashes int
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
// emptyRoot is the known root hash of an empty trie.
|
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
|
||||||
// emptyCode is the known hash of the empty EVM bytecode.
|
|
||||||
emptyCode = common.HexToHash("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
|
|
||||||
)
|
|
||||||
|
|
||||||
// TestSnapGetByteCodes various forms of GetByteCodes requests.
|
// TestSnapGetByteCodes various forms of GetByteCodes requests.
|
||||||
func (s *Suite) TestSnapGetByteCodes(t *utesting.T) {
|
func (s *Suite) TestSnapGetByteCodes(t *utesting.T) {
|
||||||
// The halfchain import should yield these bytecodes
|
// The halfchain import should yield these bytecodes
|
||||||
@ -263,15 +257,15 @@ func (s *Suite) TestSnapGetByteCodes(t *utesting.T) {
|
|||||||
},
|
},
|
||||||
// Empties
|
// Empties
|
||||||
{
|
{
|
||||||
nBytes: 10000, hashes: []common.Hash{emptyRoot},
|
nBytes: 10000, hashes: []common.Hash{types.EmptyRootHash},
|
||||||
expHashes: 0,
|
expHashes: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
nBytes: 10000, hashes: []common.Hash{emptyCode},
|
nBytes: 10000, hashes: []common.Hash{types.EmptyCodeHash},
|
||||||
expHashes: 1,
|
expHashes: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
nBytes: 10000, hashes: []common.Hash{emptyCode, emptyCode, emptyCode},
|
nBytes: 10000, hashes: []common.Hash{types.EmptyCodeHash, types.EmptyCodeHash, types.EmptyCodeHash},
|
||||||
expHashes: 3,
|
expHashes: 3,
|
||||||
},
|
},
|
||||||
// The existing bytecodes
|
// The existing bytecodes
|
||||||
@ -363,7 +357,7 @@ func (s *Suite) TestSnapTrieNodes(t *utesting.T) {
|
|||||||
for i := 1; i <= 65; i++ {
|
for i := 1; i <= 65; i++ {
|
||||||
accPaths = append(accPaths, pathTo(i))
|
accPaths = append(accPaths, pathTo(i))
|
||||||
}
|
}
|
||||||
empty := emptyCode
|
empty := types.EmptyCodeHash
|
||||||
for i, tc := range []trieNodesTest{
|
for i, tc := range []trieNodesTest{
|
||||||
{
|
{
|
||||||
root: s.chain.RootAt(999),
|
root: s.chain.RootAt(999),
|
||||||
|
@ -120,8 +120,8 @@ func (i *bbInput) ToBlock() *types.Block {
|
|||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
Coinbase: common.Address{},
|
Coinbase: common.Address{},
|
||||||
Root: i.Header.Root,
|
Root: i.Header.Root,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
Bloom: i.Header.Bloom,
|
Bloom: i.Header.Bloom,
|
||||||
Difficulty: common.Big0,
|
Difficulty: common.Big0,
|
||||||
Number: i.Header.Number,
|
Number: i.Header.Number,
|
||||||
|
@ -38,14 +38,6 @@ import (
|
|||||||
cli "github.com/urfave/cli/v2"
|
cli "github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// emptyRoot is the known root hash of an empty trie.
|
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
|
||||||
|
|
||||||
// emptyCode is the known hash of the empty EVM bytecode.
|
|
||||||
emptyCode = crypto.Keccak256(nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
snapshotCommand = &cli.Command{
|
snapshotCommand = &cli.Command{
|
||||||
Name: "snapshot",
|
Name: "snapshot",
|
||||||
@ -308,7 +300,7 @@ func traverseState(ctx *cli.Context) error {
|
|||||||
log.Error("Invalid account encountered during traversal", "err", err)
|
log.Error("Invalid account encountered during traversal", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if acc.Root != emptyRoot {
|
if acc.Root != types.EmptyRootHash {
|
||||||
id := trie.StorageTrieID(root, common.BytesToHash(accIter.Key), acc.Root)
|
id := trie.StorageTrieID(root, common.BytesToHash(accIter.Key), acc.Root)
|
||||||
storageTrie, err := trie.NewStateTrie(id, triedb)
|
storageTrie, err := trie.NewStateTrie(id, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -324,7 +316,7 @@ func traverseState(ctx *cli.Context) error {
|
|||||||
return storageIter.Err
|
return storageIter.Err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !bytes.Equal(acc.CodeHash, emptyCode) {
|
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||||
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
|
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
|
||||||
log.Error("Code is missing", "hash", common.BytesToHash(acc.CodeHash))
|
log.Error("Code is missing", "hash", common.BytesToHash(acc.CodeHash))
|
||||||
return errors.New("missing code")
|
return errors.New("missing code")
|
||||||
@ -423,7 +415,7 @@ func traverseRawState(ctx *cli.Context) error {
|
|||||||
log.Error("Invalid account encountered during traversal", "err", err)
|
log.Error("Invalid account encountered during traversal", "err", err)
|
||||||
return errors.New("invalid account")
|
return errors.New("invalid account")
|
||||||
}
|
}
|
||||||
if acc.Root != emptyRoot {
|
if acc.Root != types.EmptyRootHash {
|
||||||
id := trie.StorageTrieID(root, common.BytesToHash(accIter.LeafKey()), acc.Root)
|
id := trie.StorageTrieID(root, common.BytesToHash(accIter.LeafKey()), acc.Root)
|
||||||
storageTrie, err := trie.NewStateTrie(id, triedb)
|
storageTrie, err := trie.NewStateTrie(id, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -461,7 +453,7 @@ func traverseRawState(ctx *cli.Context) error {
|
|||||||
return storageIter.Error()
|
return storageIter.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !bytes.Equal(acc.CodeHash, emptyCode) {
|
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||||
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
|
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
|
||||||
log.Error("Code is missing", "account", common.BytesToHash(accIter.LeafKey()))
|
log.Error("Code is missing", "account", common.BytesToHash(accIter.LeafKey()))
|
||||||
return errors.New("missing code")
|
return errors.New("missing code")
|
||||||
@ -536,7 +528,7 @@ func dumpState(ctx *cli.Context) error {
|
|||||||
CodeHash: account.CodeHash,
|
CodeHash: account.CodeHash,
|
||||||
SecureKey: accIt.Hash().Bytes(),
|
SecureKey: accIt.Hash().Bytes(),
|
||||||
}
|
}
|
||||||
if !conf.SkipCode && !bytes.Equal(account.CodeHash, emptyCode) {
|
if !conf.SkipCode && !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||||
da.Code = rawdb.ReadCode(db, common.BytesToHash(account.CodeHash))
|
da.Code = rawdb.ReadCode(db, common.BytesToHash(account.CodeHash))
|
||||||
}
|
}
|
||||||
if !conf.SkipStorage {
|
if !conf.SkipStorage {
|
||||||
|
@ -709,11 +709,11 @@ func TestConcurrentDiskCacheGeneration(t *testing.T) {
|
|||||||
block := types.NewBlockWithHeader(&types.Header{
|
block := types.NewBlockWithHeader(&types.Header{
|
||||||
Number: big.NewInt(3311058),
|
Number: big.NewInt(3311058),
|
||||||
ParentHash: common.HexToHash("0xd783efa4d392943503f28438ad5830b2d5964696ffc285f338585e9fe0a37a05"),
|
ParentHash: common.HexToHash("0xd783efa4d392943503f28438ad5830b2d5964696ffc285f338585e9fe0a37a05"),
|
||||||
UncleHash: common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"),
|
UncleHash: types.EmptyUncleHash,
|
||||||
Coinbase: common.HexToAddress("0xc0ea08a2d404d3172d2add29a45be56da40e2949"),
|
Coinbase: common.HexToAddress("0xc0ea08a2d404d3172d2add29a45be56da40e2949"),
|
||||||
Root: common.HexToHash("0x77d14e10470b5850332524f8cd6f69ad21f070ce92dca33ab2858300242ef2f1"),
|
Root: common.HexToHash("0x77d14e10470b5850332524f8cd6f69ad21f070ce92dca33ab2858300242ef2f1"),
|
||||||
TxHash: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
Difficulty: big.NewInt(167925187834220),
|
Difficulty: big.NewInt(167925187834220),
|
||||||
GasLimit: 4015682,
|
GasLimit: 4015682,
|
||||||
GasUsed: 0,
|
GasUsed: 0,
|
||||||
|
@ -252,8 +252,8 @@ func makeChainForBench(db ethdb.Database, full bool, count uint64) {
|
|||||||
ParentHash: hash,
|
ParentHash: hash,
|
||||||
Difficulty: big.NewInt(1),
|
Difficulty: big.NewInt(1),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
}
|
}
|
||||||
hash = header.Hash()
|
hash = header.Hash()
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ func (g *Genesis) ToBlock() *types.Block {
|
|||||||
}
|
}
|
||||||
var withdrawals []*types.Withdrawal
|
var withdrawals []*types.Withdrawal
|
||||||
if g.Config != nil && g.Config.IsShanghai(g.Timestamp) {
|
if g.Config != nil && g.Config.IsShanghai(g.Timestamp) {
|
||||||
head.WithdrawalsHash = &types.EmptyRootHash
|
head.WithdrawalsHash = &types.EmptyWithdrawalsHash
|
||||||
withdrawals = make([]*types.Withdrawal, 0)
|
withdrawals = make([]*types.Withdrawal, 0)
|
||||||
}
|
}
|
||||||
return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)).WithWithdrawals(withdrawals)
|
return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)).WithWithdrawals(withdrawals)
|
||||||
|
@ -113,8 +113,8 @@ func TestBlockStorage(t *testing.T) {
|
|||||||
block := types.NewBlockWithHeader(&types.Header{
|
block := types.NewBlockWithHeader(&types.Header{
|
||||||
Extra: []byte("test block"),
|
Extra: []byte("test block"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
})
|
})
|
||||||
if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
|
if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
|
||||||
t.Fatalf("Non existent block returned: %v", entry)
|
t.Fatalf("Non existent block returned: %v", entry)
|
||||||
@ -161,8 +161,8 @@ func TestPartialBlockStorage(t *testing.T) {
|
|||||||
block := types.NewBlockWithHeader(&types.Header{
|
block := types.NewBlockWithHeader(&types.Header{
|
||||||
Extra: []byte("test block"),
|
Extra: []byte("test block"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
})
|
})
|
||||||
// Store a header and check that it's not recognized as a block
|
// Store a header and check that it's not recognized as a block
|
||||||
WriteHeader(db, block.Header())
|
WriteHeader(db, block.Header())
|
||||||
@ -198,8 +198,8 @@ func TestBadBlockStorage(t *testing.T) {
|
|||||||
Number: big.NewInt(1),
|
Number: big.NewInt(1),
|
||||||
Extra: []byte("bad block"),
|
Extra: []byte("bad block"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
})
|
})
|
||||||
if entry := ReadBadBlock(db, block.Hash()); entry != nil {
|
if entry := ReadBadBlock(db, block.Hash()); entry != nil {
|
||||||
t.Fatalf("Non existent block returned: %v", entry)
|
t.Fatalf("Non existent block returned: %v", entry)
|
||||||
@ -216,8 +216,8 @@ func TestBadBlockStorage(t *testing.T) {
|
|||||||
Number: big.NewInt(2),
|
Number: big.NewInt(2),
|
||||||
Extra: []byte("bad block two"),
|
Extra: []byte("bad block two"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
})
|
})
|
||||||
WriteBadBlock(db, blockTwo)
|
WriteBadBlock(db, blockTwo)
|
||||||
|
|
||||||
@ -235,8 +235,8 @@ func TestBadBlockStorage(t *testing.T) {
|
|||||||
Number: big.NewInt(int64(n)),
|
Number: big.NewInt(int64(n)),
|
||||||
Extra: []byte("bad block"),
|
Extra: []byte("bad block"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
})
|
})
|
||||||
WriteBadBlock(db, block)
|
WriteBadBlock(db, block)
|
||||||
}
|
}
|
||||||
@ -446,8 +446,8 @@ func TestAncientStorage(t *testing.T) {
|
|||||||
Number: big.NewInt(0),
|
Number: big.NewInt(0),
|
||||||
Extra: []byte("test block"),
|
Extra: []byte("test block"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
})
|
})
|
||||||
// Ensure nothing non-existent will be read
|
// Ensure nothing non-existent will be read
|
||||||
hash, number := block.Hash(), block.NumberU64()
|
hash, number := block.Hash(), block.NumberU64()
|
||||||
@ -889,8 +889,8 @@ func TestHeadersRLPStorage(t *testing.T) {
|
|||||||
Number: big.NewInt(int64(i)),
|
Number: big.NewInt(int64(i)),
|
||||||
Extra: []byte("test block"),
|
Extra: []byte("test block"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
ParentHash: pHash,
|
ParentHash: pHash,
|
||||||
})
|
})
|
||||||
chain = append(chain, block)
|
chain = append(chain, block)
|
||||||
|
@ -117,7 +117,7 @@ func (it *NodeIterator) step() error {
|
|||||||
if !it.dataIt.Next(true) {
|
if !it.dataIt.Next(true) {
|
||||||
it.dataIt = nil
|
it.dataIt = nil
|
||||||
}
|
}
|
||||||
if !bytes.Equal(account.CodeHash, emptyCodeHash) {
|
if !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||||
it.codeHash = common.BytesToHash(account.CodeHash)
|
it.codeHash = common.BytesToHash(account.CodeHash)
|
||||||
addrHash := common.BytesToHash(it.stateIt.LeafKey())
|
addrHash := common.BytesToHash(it.stateIt.LeafKey())
|
||||||
it.code, err = it.state.db.ContractCode(addrHash, common.BytesToHash(account.CodeHash))
|
it.code, err = it.state.db.ContractCode(addrHash, common.BytesToHash(account.CodeHash))
|
||||||
|
@ -31,7 +31,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
"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/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"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
@ -55,14 +54,6 @@ const (
|
|||||||
rangeCompactionThreshold = 100000
|
rangeCompactionThreshold = 100000
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// emptyRoot is the known root hash of an empty trie.
|
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
|
||||||
|
|
||||||
// emptyCode is the known hash of the empty EVM bytecode.
|
|
||||||
emptyCode = crypto.Keccak256(nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config includes all the configurations for pruning.
|
// Config includes all the configurations for pruning.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Datadir string // The directory of the state database
|
Datadir string // The directory of the state database
|
||||||
@ -446,7 +437,7 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
|
|||||||
if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil {
|
if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if acc.Root != emptyRoot {
|
if acc.Root != types.EmptyRootHash {
|
||||||
id := trie.StorageTrieID(genesis.Root(), common.BytesToHash(accIter.LeafKey()), acc.Root)
|
id := trie.StorageTrieID(genesis.Root(), common.BytesToHash(accIter.LeafKey()), acc.Root)
|
||||||
storageTrie, err := trie.NewStateTrie(id, trie.NewDatabase(db))
|
storageTrie, err := trie.NewStateTrie(id, trie.NewDatabase(db))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -463,7 +454,7 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
|
|||||||
return storageIter.Error()
|
return storageIter.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !bytes.Equal(acc.CodeHash, emptyCode) {
|
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||||
stateBloom.Put(acc.CodeHash, nil)
|
stateBloom.Put(acc.CodeHash, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"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"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,10 +42,10 @@ func SlimAccount(nonce uint64, balance *big.Int, root common.Hash, codehash []by
|
|||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
Balance: balance,
|
Balance: balance,
|
||||||
}
|
}
|
||||||
if root != emptyRoot {
|
if root != types.EmptyRootHash {
|
||||||
slim.Root = root[:]
|
slim.Root = root[:]
|
||||||
}
|
}
|
||||||
if !bytes.Equal(codehash, emptyCode[:]) {
|
if !bytes.Equal(codehash, types.EmptyCodeHash[:]) {
|
||||||
slim.CodeHash = codehash
|
slim.CodeHash = codehash
|
||||||
}
|
}
|
||||||
return slim
|
return slim
|
||||||
@ -68,10 +69,10 @@ func FullAccount(data []byte) (Account, error) {
|
|||||||
return Account{}, err
|
return Account{}, err
|
||||||
}
|
}
|
||||||
if len(account.Root) == 0 {
|
if len(account.Root) == 0 {
|
||||||
account.Root = emptyRoot[:]
|
account.Root = types.EmptyRootHash[:]
|
||||||
}
|
}
|
||||||
if len(account.CodeHash) == 0 {
|
if len(account.CodeHash) == 0 {
|
||||||
account.CodeHash = emptyCode[:]
|
account.CodeHash = types.EmptyCodeHash[:]
|
||||||
}
|
}
|
||||||
return account, nil
|
return account, nil
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,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/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
@ -74,7 +75,7 @@ func GenerateTrie(snaptree *Tree, root common.Hash, src ethdb.Database, dst ethd
|
|||||||
scheme := snaptree.triedb.Scheme()
|
scheme := snaptree.triedb.Scheme()
|
||||||
got, err := generateTrieRoot(dst, scheme, acctIt, common.Hash{}, stackTrieGenerate, func(dst ethdb.KeyValueWriter, accountHash, codeHash common.Hash, stat *generateStats) (common.Hash, error) {
|
got, err := generateTrieRoot(dst, scheme, acctIt, common.Hash{}, stackTrieGenerate, func(dst ethdb.KeyValueWriter, accountHash, codeHash common.Hash, stat *generateStats) (common.Hash, error) {
|
||||||
// Migrate the code first, commit the contract code into the tmp db.
|
// Migrate the code first, commit the contract code into the tmp db.
|
||||||
if codeHash != emptyCode {
|
if codeHash != types.EmptyCodeHash {
|
||||||
code := rawdb.ReadCode(src, codeHash)
|
code := rawdb.ReadCode(src, codeHash)
|
||||||
if len(code) == 0 {
|
if len(code) == 0 {
|
||||||
return common.Hash{}, errors.New("failed to read contract code")
|
return common.Hash{}, errors.New("failed to read contract code")
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"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"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
@ -35,12 +35,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// emptyRoot is the known root hash of an empty trie.
|
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
|
||||||
|
|
||||||
// emptyCode is the known hash of the empty EVM bytecode.
|
|
||||||
emptyCode = crypto.Keccak256Hash(nil)
|
|
||||||
|
|
||||||
// accountCheckRange is the upper limit of the number of accounts involved in
|
// accountCheckRange is the upper limit of the number of accounts involved in
|
||||||
// each range check. This is a value estimated based on experience. If this
|
// each range check. This is a value estimated based on experience. If this
|
||||||
// range is too large, the failure rate of range proof will increase. Otherwise,
|
// range is too large, the failure rate of range proof will increase. Otherwise,
|
||||||
@ -591,10 +585,10 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
|||||||
if accMarker == nil || !bytes.Equal(account[:], accMarker) {
|
if accMarker == nil || !bytes.Equal(account[:], accMarker) {
|
||||||
dataLen := len(val) // Approximate size, saves us a round of RLP-encoding
|
dataLen := len(val) // Approximate size, saves us a round of RLP-encoding
|
||||||
if !write {
|
if !write {
|
||||||
if bytes.Equal(acc.CodeHash, emptyCode[:]) {
|
if bytes.Equal(acc.CodeHash, types.EmptyCodeHash[:]) {
|
||||||
dataLen -= 32
|
dataLen -= 32
|
||||||
}
|
}
|
||||||
if acc.Root == emptyRoot {
|
if acc.Root == types.EmptyRootHash {
|
||||||
dataLen -= 32
|
dataLen -= 32
|
||||||
}
|
}
|
||||||
snapRecoveredAccountMeter.Mark(1)
|
snapRecoveredAccountMeter.Mark(1)
|
||||||
@ -621,7 +615,7 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
|||||||
|
|
||||||
// If the iterated account is the contract, create a further loop to
|
// If the iterated account is the contract, create a further loop to
|
||||||
// verify or regenerate the contract storage.
|
// verify or regenerate the contract storage.
|
||||||
if acc.Root == emptyRoot {
|
if acc.Root == types.EmptyRootHash {
|
||||||
ctx.removeStorageAt(account)
|
ctx.removeStorageAt(account)
|
||||||
} else {
|
} else {
|
||||||
var storeMarker []byte
|
var storeMarker []byte
|
||||||
|
@ -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/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
@ -49,9 +50,9 @@ func TestGeneration(t *testing.T) {
|
|||||||
var helper = newHelper()
|
var helper = newHelper()
|
||||||
stRoot := helper.makeStorageTrie(common.Hash{}, common.Hash{}, []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, false)
|
stRoot := helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
@ -83,16 +84,16 @@ func TestGenerateExistentState(t *testing.T) {
|
|||||||
var helper = newHelper()
|
var helper = newHelper()
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
|
helper.addSnapAccount("acc-1", &Account{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: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
|
helper.addSnapAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
stRoot = helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot = helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: emptyCode.Bytes()})
|
helper.addSnapAccount("acc-3", &Account{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()
|
||||||
@ -235,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: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
|
helper.addAccount("acc-1", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), 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(common.Hash{}, hashData([]byte("acc-2")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-2", &Account{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(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-3", &Account{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(common.Hash{}, hashData([]byte("acc-4")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-4", &Account{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(common.Hash{}, hashData([]byte("acc-5")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-5", &Account{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"})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,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(common.Hash{}, hashData([]byte("acc-6")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-6", &Account{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(common.Hash{}, hashData([]byte("acc-7")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-7", &Account{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(common.Hash{}, hashData([]byte("acc-8")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-8", &Account{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(common.Hash{}, hashData([]byte("acc-9")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-9", &Account{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"})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,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(common.Hash{}, hashData([]byte("acc-10")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-10", &Account{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(common.Hash{}, hashData([]byte("acc-11")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-11", &Account{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(common.Hash{}, hashData([]byte("acc-12")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-12", &Account{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"})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,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: emptyCode.Bytes()}) // Beginning
|
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Beginning
|
||||||
helper.addTrieAccount("acc-4", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()}) // Middle
|
helper.addTrieAccount("acc-4", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Middle
|
||||||
helper.addTrieAccount("acc-6", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()}) // End
|
helper.addTrieAccount("acc-6", &Account{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: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-2", &Account{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", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: common.Hex2Bytes("0x1234")})
|
||||||
|
|
||||||
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-3", &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
|
helper.addSnapAccount("acc-3", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), 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: emptyRoot.Bytes()}) // before the beginning
|
helper.addSnapAccount("acc-0", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // before the beginning
|
||||||
helper.addSnapAccount("acc-5", &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: common.Hex2Bytes("0x1234")}) // Middle
|
helper.addSnapAccount("acc-5", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: common.Hex2Bytes("0x1234")}) // Middle
|
||||||
helper.addSnapAccount("acc-7", &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyRoot.Bytes()}) // after the end
|
helper.addSnapAccount("acc-7", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // after the end
|
||||||
}
|
}
|
||||||
|
|
||||||
root, snap := helper.CommitAndGenerate()
|
root, snap := helper.CommitAndGenerate()
|
||||||
@ -384,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: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074
|
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||||
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4
|
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4
|
||||||
|
|
||||||
root := helper.Commit() // Root: 0xa04693ea110a31037fb5ee814308a6f1d76bdab0b11676bdf4541d2de55ba978
|
root := helper.Commit() // Root: 0xa04693ea110a31037fb5ee814308a6f1d76bdab0b11676bdf4541d2de55ba978
|
||||||
|
|
||||||
@ -419,10 +420,10 @@ func TestGenerateMissingStorageTrie(t *testing.T) {
|
|||||||
helper := newHelper()
|
helper := newHelper()
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
stRoot := helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||||
stRoot = helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot = helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
||||||
|
|
||||||
root := helper.Commit()
|
root := helper.Commit()
|
||||||
|
|
||||||
@ -453,10 +454,10 @@ func TestGenerateCorruptStorageTrie(t *testing.T) {
|
|||||||
helper := newHelper()
|
helper := newHelper()
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
stRoot := helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||||
stRoot = helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot = helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
||||||
|
|
||||||
root := helper.Commit()
|
root := helper.Commit()
|
||||||
|
|
||||||
@ -488,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: emptyCode.Bytes()}
|
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
helper.accTrie.Update([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
helper.accTrie.Update([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||||
|
|
||||||
@ -508,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: emptyCode.Bytes()}
|
acc := &Account{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)
|
||||||
@ -559,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: emptyCode.Bytes()}
|
acc := &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
helper.accTrie.Update([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
helper.accTrie.Update([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||||
|
|
||||||
@ -573,8 +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: stTrie.Hash().Bytes(), CodeHash: emptyCode.Bytes()}
|
acc := &Account{Balance: big.NewInt(int64(i)), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
acc := &Account{Balance: big.NewInt(int64(i)), Root: emptyRoot.Bytes(), CodeHash: emptyCode.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)
|
||||||
@ -611,7 +611,7 @@ func TestGenerateWithExtraBeforeAndAfter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
helper := newHelper()
|
helper := newHelper()
|
||||||
{
|
{
|
||||||
acc := &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}
|
acc := &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
helper.accTrie.Update(common.HexToHash("0x03").Bytes(), val)
|
helper.accTrie.Update(common.HexToHash("0x03").Bytes(), val)
|
||||||
helper.accTrie.Update(common.HexToHash("0x07").Bytes(), val)
|
helper.accTrie.Update(common.HexToHash("0x07").Bytes(), val)
|
||||||
@ -648,7 +648,7 @@ func TestGenerateWithMalformedSnapdata(t *testing.T) {
|
|||||||
}
|
}
|
||||||
helper := newHelper()
|
helper := newHelper()
|
||||||
{
|
{
|
||||||
acc := &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()}
|
acc := &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
helper.accTrie.Update(common.HexToHash("0x03").Bytes(), val)
|
helper.accTrie.Update(common.HexToHash("0x03").Bytes(), val)
|
||||||
|
|
||||||
@ -687,7 +687,7 @@ func TestGenerateFromEmptySnap(t *testing.T) {
|
|||||||
for i := 0; i < 400; i++ {
|
for i := 0; i < 400; i++ {
|
||||||
stRoot := helper.makeStorageTrie(common.Hash{}, 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(common.Hash{}, 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: emptyCode.Bytes()})
|
&Account{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
|
||||||
@ -724,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(common.Hash{}, hashData([]byte(accKey)), stKeys, stVals, true)
|
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte(accKey)), stKeys, stVals, true)
|
||||||
helper.addAccount(accKey, &Account{Balance: big.NewInt(int64(i)), Root: stRoot, CodeHash: emptyCode.Bytes()})
|
helper.addAccount(accKey, &Account{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++ {
|
||||||
@ -816,11 +816,11 @@ func TestGenerateCompleteSnapshotWithDanglingStorage(t *testing.T) {
|
|||||||
var helper = newHelper()
|
var helper = newHelper()
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addAccount("acc-2", &Account{Balance: big.NewInt(1), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
|
helper.addAccount("acc-2", &Account{Balance: big.NewInt(1), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addAccount("acc-3", &Account{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"})
|
||||||
@ -851,11 +851,11 @@ func TestGenerateBrokenSnapshotWithDanglingStorage(t *testing.T) {
|
|||||||
var helper = newHelper()
|
var helper = newHelper()
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-1", &Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: emptyRoot.Bytes(), CodeHash: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-2", &Account{Balance: big.NewInt(2), Root: types.EmptyRootHash.Bytes(), CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
helper.makeStorageTrie(common.Hash{}, hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie(common.Hash{}, 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: emptyCode.Bytes()})
|
helper.addTrieAccount("acc-3", &Account{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
populateDangling(helper.diskdb)
|
populateDangling(helper.diskdb)
|
||||||
|
|
||||||
|
@ -28,6 +28,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/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ func randomAccount() []byte {
|
|||||||
Balance: big.NewInt(rand.Int63()),
|
Balance: big.NewInt(rand.Int63()),
|
||||||
Nonce: rand.Uint64(),
|
Nonce: rand.Uint64(),
|
||||||
Root: root[:],
|
Root: root[:],
|
||||||
CodeHash: emptyCode[:],
|
CodeHash: types.EmptyCodeHash[:],
|
||||||
}
|
}
|
||||||
data, _ := rlp.EncodeToBytes(a)
|
data, _ := rlp.EncodeToBytes(a)
|
||||||
return data
|
return data
|
||||||
|
@ -31,8 +31,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
||||||
var emptyCodeHash = crypto.Keccak256(nil)
|
|
||||||
|
|
||||||
type Code []byte
|
type Code []byte
|
||||||
|
|
||||||
func (c Code) String() string {
|
func (c Code) String() string {
|
||||||
@ -95,7 +93,7 @@ type stateObject struct {
|
|||||||
|
|
||||||
// empty returns whether the account is considered empty.
|
// empty returns whether the account is considered empty.
|
||||||
func (s *stateObject) empty() bool {
|
func (s *stateObject) empty() bool {
|
||||||
return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
|
return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, types.EmptyCodeHash.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// newObject creates a state object.
|
// newObject creates a state object.
|
||||||
@ -104,10 +102,10 @@ func newObject(db *StateDB, address common.Address, data types.StateAccount) *st
|
|||||||
data.Balance = new(big.Int)
|
data.Balance = new(big.Int)
|
||||||
}
|
}
|
||||||
if data.CodeHash == nil {
|
if data.CodeHash == nil {
|
||||||
data.CodeHash = emptyCodeHash
|
data.CodeHash = types.EmptyCodeHash.Bytes()
|
||||||
}
|
}
|
||||||
if data.Root == (common.Hash{}) {
|
if data.Root == (common.Hash{}) {
|
||||||
data.Root = emptyRoot
|
data.Root = types.EmptyRootHash
|
||||||
}
|
}
|
||||||
return &stateObject{
|
return &stateObject{
|
||||||
db: db,
|
db: db,
|
||||||
@ -154,7 +152,7 @@ func (s *stateObject) getTrie(db Database) (Trie, error) {
|
|||||||
if s.trie == nil {
|
if s.trie == nil {
|
||||||
// Try fetching from prefetcher first
|
// Try fetching from prefetcher first
|
||||||
// We don't prefetch empty tries
|
// We don't prefetch empty tries
|
||||||
if s.data.Root != emptyRoot && s.db.prefetcher != nil {
|
if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil {
|
||||||
// When the miner is creating the pending state, there is no
|
// When the miner is creating the pending state, there is no
|
||||||
// prefetcher
|
// prefetcher
|
||||||
s.trie = s.db.prefetcher.trie(s.addrHash, s.data.Root)
|
s.trie = s.db.prefetcher.trie(s.addrHash, s.data.Root)
|
||||||
@ -270,7 +268,7 @@ func (s *stateObject) finalise(prefetch bool) {
|
|||||||
slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure
|
slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != emptyRoot {
|
if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash {
|
||||||
s.db.prefetcher.prefetch(s.addrHash, s.data.Root, slotsToPrefetch)
|
s.db.prefetcher.prefetch(s.addrHash, s.data.Root, slotsToPrefetch)
|
||||||
}
|
}
|
||||||
if len(s.dirtyStorage) > 0 {
|
if len(s.dirtyStorage) > 0 {
|
||||||
@ -454,7 +452,7 @@ func (s *stateObject) Code(db Database) []byte {
|
|||||||
if s.code != nil {
|
if s.code != nil {
|
||||||
return s.code
|
return s.code
|
||||||
}
|
}
|
||||||
if bytes.Equal(s.CodeHash(), emptyCodeHash) {
|
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash()))
|
code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash()))
|
||||||
@ -472,7 +470,7 @@ func (s *stateObject) CodeSize(db Database) int {
|
|||||||
if s.code != nil {
|
if s.code != nil {
|
||||||
return len(s.code)
|
return len(s.code)
|
||||||
}
|
}
|
||||||
if bytes.Equal(s.CodeHash(), emptyCodeHash) {
|
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
size, err := db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash()))
|
size, err := db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash()))
|
||||||
|
@ -41,11 +41,6 @@ type revision struct {
|
|||||||
journalIndex int
|
journalIndex int
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
// emptyRoot is the known root hash of an empty trie.
|
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
|
||||||
)
|
|
||||||
|
|
||||||
type proofList [][]byte
|
type proofList [][]byte
|
||||||
|
|
||||||
func (n *proofList) Put(key []byte, value []byte) error {
|
func (n *proofList) Put(key []byte, value []byte) error {
|
||||||
@ -580,10 +575,10 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
|
|||||||
Root: common.BytesToHash(acc.Root),
|
Root: common.BytesToHash(acc.Root),
|
||||||
}
|
}
|
||||||
if len(data.CodeHash) == 0 {
|
if len(data.CodeHash) == 0 {
|
||||||
data.CodeHash = emptyCodeHash
|
data.CodeHash = types.EmptyCodeHash.Bytes()
|
||||||
}
|
}
|
||||||
if data.Root == (common.Hash{}) {
|
if data.Root == (common.Hash{}) {
|
||||||
data.Root = emptyRoot
|
data.Root = types.EmptyRootHash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1066,11 +1061,11 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
|
|||||||
s.stateObjectsDestruct = make(map[common.Address]struct{})
|
s.stateObjectsDestruct = make(map[common.Address]struct{})
|
||||||
}
|
}
|
||||||
if root == (common.Hash{}) {
|
if root == (common.Hash{}) {
|
||||||
root = emptyRoot
|
root = types.EmptyRootHash
|
||||||
}
|
}
|
||||||
origin := s.originalRoot
|
origin := s.originalRoot
|
||||||
if origin == (common.Hash{}) {
|
if origin == (common.Hash{}) {
|
||||||
origin = emptyRoot
|
origin = types.EmptyRootHash
|
||||||
}
|
}
|
||||||
if root != origin {
|
if root != origin {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
@ -134,8 +134,7 @@ func checkStateConsistency(db ethdb.Database, root common.Hash) error {
|
|||||||
// Tests that an empty state is not scheduled for syncing.
|
// Tests that an empty state is not scheduled for syncing.
|
||||||
func TestEmptyStateSync(t *testing.T) {
|
func TestEmptyStateSync(t *testing.T) {
|
||||||
db := trie.NewDatabase(rawdb.NewMemoryDatabase())
|
db := trie.NewDatabase(rawdb.NewMemoryDatabase())
|
||||||
empty := common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
sync := NewStateSync(types.EmptyRootHash, rawdb.NewMemoryDatabase(), nil, db.Scheme())
|
||||||
sync := NewStateSync(empty, rawdb.NewMemoryDatabase(), nil, db.Scheme())
|
|
||||||
if paths, nodes, codes := sync.Missing(1); len(paths) != 0 || len(nodes) != 0 || len(codes) != 0 {
|
if paths, nodes, codes := sync.Missing(1); len(paths) != 0 || len(nodes) != 0 || len(codes) != 0 {
|
||||||
t.Errorf("content requested for empty state: %v, %v, %v", nodes, paths, codes)
|
t.Errorf("content requested for empty state: %v, %v, %v", nodes, paths, codes)
|
||||||
}
|
}
|
||||||
@ -555,7 +554,7 @@ func TestIncompleteStateSync(t *testing.T) {
|
|||||||
isCode[crypto.Keccak256Hash(acc.code)] = struct{}{}
|
isCode[crypto.Keccak256Hash(acc.code)] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isCode[common.BytesToHash(emptyCodeHash)] = struct{}{}
|
isCode[types.EmptyCodeHash] = struct{}{}
|
||||||
checkTrieConsistency(db, srcRoot)
|
checkTrieConsistency(db, srcRoot)
|
||||||
|
|
||||||
// Create a destination state and sync with the scheduler
|
// Create a destination state and sync with the scheduler
|
||||||
|
@ -404,7 +404,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
|
|||||||
header.BaseFee = misc.CalcBaseFee(config, parent.Header())
|
header.BaseFee = misc.CalcBaseFee(config, parent.Header())
|
||||||
}
|
}
|
||||||
if config.IsShanghai(header.Time) {
|
if config.IsShanghai(header.Time) {
|
||||||
header.WithdrawalsHash = &types.EmptyRootHash
|
header.WithdrawalsHash = &types.EmptyWithdrawalsHash
|
||||||
}
|
}
|
||||||
var receipts []*types.Receipt
|
var receipts []*types.Receipt
|
||||||
// The post-state result doesn't need to be correct (this is a bad block), but we do need something there
|
// The post-state result doesn't need to be correct (this is a bad block), but we do need something there
|
||||||
|
@ -31,11 +31,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
EmptyRootHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
|
||||||
EmptyUncleHash = rlpHash([]*Header(nil))
|
|
||||||
)
|
|
||||||
|
|
||||||
// A BlockNonce is a 64-bit hash which proves (combined with the
|
// A BlockNonce is a 64-bit hash which proves (combined with the
|
||||||
// mix-hash) that a sufficient amount of computation has been carried
|
// mix-hash) that a sufficient amount of computation has been carried
|
||||||
// out on a block.
|
// out on a block.
|
||||||
@ -155,14 +150,14 @@ func (h *Header) SanityCheck() error {
|
|||||||
// that is: no transactions, no uncles and no withdrawals.
|
// that is: no transactions, no uncles and no withdrawals.
|
||||||
func (h *Header) EmptyBody() bool {
|
func (h *Header) EmptyBody() bool {
|
||||||
if h.WithdrawalsHash == nil {
|
if h.WithdrawalsHash == nil {
|
||||||
return h.TxHash == EmptyRootHash && h.UncleHash == EmptyUncleHash
|
return h.TxHash == EmptyTxsHash && h.UncleHash == EmptyUncleHash
|
||||||
}
|
}
|
||||||
return h.TxHash == EmptyRootHash && h.UncleHash == EmptyUncleHash && *h.WithdrawalsHash == EmptyRootHash
|
return h.TxHash == EmptyTxsHash && h.UncleHash == EmptyUncleHash && *h.WithdrawalsHash == EmptyWithdrawalsHash
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmptyReceipts returns true if there are no receipts for this header/block.
|
// EmptyReceipts returns true if there are no receipts for this header/block.
|
||||||
func (h *Header) EmptyReceipts() bool {
|
func (h *Header) EmptyReceipts() bool {
|
||||||
return h.ReceiptHash == EmptyRootHash
|
return h.ReceiptHash == EmptyReceiptsHash
|
||||||
}
|
}
|
||||||
|
|
||||||
// Body is a simple (mutable, non-safe) data container for storing and moving
|
// Body is a simple (mutable, non-safe) data container for storing and moving
|
||||||
@ -210,7 +205,7 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*
|
|||||||
|
|
||||||
// TODO: panic if len(txs) != len(receipts)
|
// TODO: panic if len(txs) != len(receipts)
|
||||||
if len(txs) == 0 {
|
if len(txs) == 0 {
|
||||||
b.header.TxHash = EmptyRootHash
|
b.header.TxHash = EmptyTxsHash
|
||||||
} else {
|
} else {
|
||||||
b.header.TxHash = DeriveSha(Transactions(txs), hasher)
|
b.header.TxHash = DeriveSha(Transactions(txs), hasher)
|
||||||
b.transactions = make(Transactions, len(txs))
|
b.transactions = make(Transactions, len(txs))
|
||||||
@ -218,7 +213,7 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(receipts) == 0 {
|
if len(receipts) == 0 {
|
||||||
b.header.ReceiptHash = EmptyRootHash
|
b.header.ReceiptHash = EmptyReceiptsHash
|
||||||
} else {
|
} else {
|
||||||
b.header.ReceiptHash = DeriveSha(Receipts(receipts), hasher)
|
b.header.ReceiptHash = DeriveSha(Receipts(receipts), hasher)
|
||||||
b.header.Bloom = CreateBloom(receipts)
|
b.header.Bloom = CreateBloom(receipts)
|
||||||
@ -250,7 +245,7 @@ func NewBlockWithWithdrawals(header *Header, txs []*Transaction, uncles []*Heade
|
|||||||
if withdrawals == nil {
|
if withdrawals == nil {
|
||||||
b.header.WithdrawalsHash = nil
|
b.header.WithdrawalsHash = nil
|
||||||
} else if len(withdrawals) == 0 {
|
} else if len(withdrawals) == 0 {
|
||||||
b.header.WithdrawalsHash = &EmptyRootHash
|
b.header.WithdrawalsHash = &EmptyWithdrawalsHash
|
||||||
} else {
|
} else {
|
||||||
h := DeriveSha(Withdrawals(withdrawals), hasher)
|
h := DeriveSha(Withdrawals(withdrawals), hasher)
|
||||||
b.header.WithdrawalsHash = &h
|
b.header.WithdrawalsHash = &h
|
||||||
|
42
core/types/hashes.go
Normal file
42
core/types/hashes.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2023 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 types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// EmptyRootHash is the known root hash of an empty trie.
|
||||||
|
EmptyRootHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
|
|
||||||
|
// EmptyUncleHash is the known hash of the empty uncle set.
|
||||||
|
EmptyUncleHash = rlpHash([]*Header(nil)) // 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
|
||||||
|
|
||||||
|
// EmptyCodeHash is the known hash of the empty EVM bytecode.
|
||||||
|
EmptyCodeHash = crypto.Keccak256Hash(nil) // c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
|
||||||
|
|
||||||
|
// EmptyTxsHash is the known hash of the empty transaction set.
|
||||||
|
EmptyTxsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
|
|
||||||
|
// EmptyReceiptsHash is the known hash of the empty receipt set.
|
||||||
|
EmptyReceiptsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
|
|
||||||
|
// EmptyWithdrawalsHash is the known hash of the empty withdrawal set.
|
||||||
|
EmptyWithdrawalsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
|
)
|
@ -599,7 +599,7 @@ func (f *BlockFetcher) loop() {
|
|||||||
announce.time = task.time
|
announce.time = task.time
|
||||||
|
|
||||||
// If the block is empty (header only), short circuit into the final import queue
|
// If the block is empty (header only), short circuit into the final import queue
|
||||||
if header.TxHash == types.EmptyRootHash && header.UncleHash == types.EmptyUncleHash {
|
if header.TxHash == types.EmptyTxsHash && header.UncleHash == types.EmptyUncleHash {
|
||||||
log.Trace("Block empty, skipping body retrieval", "peer", announce.origin, "number", header.Number, "hash", header.Hash())
|
log.Trace("Block empty, skipping body retrieval", "peer", announce.origin, "number", header.Number, "hash", header.Hash())
|
||||||
|
|
||||||
block := types.NewBlockWithHeader(header)
|
block := types.NewBlockWithHeader(header)
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/light"
|
"github.com/ethereum/go-ethereum/light"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
@ -464,7 +465,7 @@ func ServiceGetByteCodesQuery(chain *core.BlockChain, req *GetByteCodesPacket) [
|
|||||||
bytes uint64
|
bytes uint64
|
||||||
)
|
)
|
||||||
for _, hash := range req.Hashes {
|
for _, hash := range req.Hashes {
|
||||||
if hash == emptyCode {
|
if hash == types.EmptyCodeHash {
|
||||||
// Peers should not request the empty code, but if they do, at
|
// Peers should not request the empty code, but if they do, at
|
||||||
// least sent them back a correct response without db lookups
|
// least sent them back a correct response without db lookups
|
||||||
codes = append(codes, []byte{})
|
codes = append(codes, []byte{})
|
||||||
|
@ -46,14 +46,6 @@ import (
|
|||||||
"golang.org/x/crypto/sha3"
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// emptyRoot is the known root hash of an empty trie.
|
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
|
||||||
|
|
||||||
// emptyCode is the known hash of the empty EVM bytecode.
|
|
||||||
emptyCode = crypto.Keccak256Hash(nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// minRequestSize is the minimum number of bytes to request from a remote peer.
|
// minRequestSize is the minimum number of bytes to request from a remote peer.
|
||||||
// This number is used as the low cap for account and storage range requests.
|
// This number is used as the low cap for account and storage range requests.
|
||||||
@ -1833,7 +1825,7 @@ func (s *Syncer) processAccountResponse(res *accountResponse) {
|
|||||||
res.task.pend = 0
|
res.task.pend = 0
|
||||||
for i, account := range res.accounts {
|
for i, account := range res.accounts {
|
||||||
// Check if the account is a contract with an unknown code
|
// Check if the account is a contract with an unknown code
|
||||||
if !bytes.Equal(account.CodeHash, emptyCode[:]) {
|
if !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||||
if !rawdb.HasCodeWithPrefix(s.db, common.BytesToHash(account.CodeHash)) {
|
if !rawdb.HasCodeWithPrefix(s.db, common.BytesToHash(account.CodeHash)) {
|
||||||
res.task.codeTasks[common.BytesToHash(account.CodeHash)] = struct{}{}
|
res.task.codeTasks[common.BytesToHash(account.CodeHash)] = struct{}{}
|
||||||
res.task.needCode[i] = true
|
res.task.needCode[i] = true
|
||||||
@ -1841,7 +1833,7 @@ func (s *Syncer) processAccountResponse(res *accountResponse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if the account is a contract with an unknown storage trie
|
// Check if the account is a contract with an unknown storage trie
|
||||||
if account.Root != emptyRoot {
|
if account.Root != types.EmptyRootHash {
|
||||||
if !rawdb.HasTrieNode(s.db, res.hashes[i], nil, account.Root, s.scheme) {
|
if !rawdb.HasTrieNode(s.db, res.hashes[i], nil, account.Root, s.scheme) {
|
||||||
// If there was a previous large state retrieval in progress,
|
// If there was a previous large state retrieval in progress,
|
||||||
// don't restart it from scratch. This happens if a sync cycle
|
// don't restart it from scratch. This happens if a sync cycle
|
||||||
|
@ -1354,7 +1354,7 @@ func getCodeHash(i uint64) []byte {
|
|||||||
|
|
||||||
// getCodeByHash convenience function to lookup the code from the code hash
|
// getCodeByHash convenience function to lookup the code from the code hash
|
||||||
func getCodeByHash(hash common.Hash) []byte {
|
func getCodeByHash(hash common.Hash) []byte {
|
||||||
if hash == emptyCode {
|
if hash == types.EmptyCodeHash {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for i, h := range codehashes {
|
for i, h := range codehashes {
|
||||||
@ -1376,7 +1376,7 @@ func makeAccountTrieNoStorage(n int) (string, *trie.Trie, entrySlice) {
|
|||||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||||
Nonce: i,
|
Nonce: i,
|
||||||
Balance: big.NewInt(int64(i)),
|
Balance: big.NewInt(int64(i)),
|
||||||
Root: emptyRoot,
|
Root: types.EmptyRootHash,
|
||||||
CodeHash: getCodeHash(i),
|
CodeHash: getCodeHash(i),
|
||||||
})
|
})
|
||||||
key := key32(i)
|
key := key32(i)
|
||||||
@ -1427,7 +1427,7 @@ func makeBoundaryAccountTrie(n int) (string, *trie.Trie, entrySlice) {
|
|||||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||||
Nonce: uint64(0),
|
Nonce: uint64(0),
|
||||||
Balance: big.NewInt(int64(i)),
|
Balance: big.NewInt(int64(i)),
|
||||||
Root: emptyRoot,
|
Root: types.EmptyRootHash,
|
||||||
CodeHash: getCodeHash(uint64(i)),
|
CodeHash: getCodeHash(uint64(i)),
|
||||||
})
|
})
|
||||||
elem := &kv{boundaries[i].Bytes(), value}
|
elem := &kv{boundaries[i].Bytes(), value}
|
||||||
@ -1439,7 +1439,7 @@ func makeBoundaryAccountTrie(n int) (string, *trie.Trie, entrySlice) {
|
|||||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||||
Nonce: i,
|
Nonce: i,
|
||||||
Balance: big.NewInt(int64(i)),
|
Balance: big.NewInt(int64(i)),
|
||||||
Root: emptyRoot,
|
Root: types.EmptyRootHash,
|
||||||
CodeHash: getCodeHash(i),
|
CodeHash: getCodeHash(i),
|
||||||
})
|
})
|
||||||
elem := &kv{key32(i), value}
|
elem := &kv{key32(i), value}
|
||||||
@ -1472,7 +1472,7 @@ func makeAccountTrieWithStorageWithUniqueStorage(accounts, slots int, code bool)
|
|||||||
// Create n accounts in the trie
|
// Create n accounts in the trie
|
||||||
for i := uint64(1); i <= uint64(accounts); i++ {
|
for i := uint64(1); i <= uint64(accounts); i++ {
|
||||||
key := key32(i)
|
key := key32(i)
|
||||||
codehash := emptyCode[:]
|
codehash := types.EmptyCodeHash.Bytes()
|
||||||
if code {
|
if code {
|
||||||
codehash = getCodeHash(i)
|
codehash = getCodeHash(i)
|
||||||
}
|
}
|
||||||
@ -1527,7 +1527,7 @@ func makeAccountTrieWithStorage(accounts, slots int, code, boundary bool) (strin
|
|||||||
// Create n accounts in the trie
|
// Create n accounts in the trie
|
||||||
for i := uint64(1); i <= uint64(accounts); i++ {
|
for i := uint64(1); i <= uint64(accounts); i++ {
|
||||||
key := key32(i)
|
key := key32(i)
|
||||||
codehash := emptyCode[:]
|
codehash := types.EmptyCodeHash.Bytes()
|
||||||
if code {
|
if code {
|
||||||
codehash = getCodeHash(i)
|
codehash = getCodeHash(i)
|
||||||
}
|
}
|
||||||
@ -1678,7 +1678,7 @@ func verifyTrie(db ethdb.KeyValueStore, root common.Hash, t *testing.T) {
|
|||||||
log.Crit("Invalid account encountered during snapshot creation", "err", err)
|
log.Crit("Invalid account encountered during snapshot creation", "err", err)
|
||||||
}
|
}
|
||||||
accounts++
|
accounts++
|
||||||
if acc.Root != emptyRoot {
|
if acc.Root != types.EmptyRootHash {
|
||||||
id := trie.StorageTrieID(root, common.BytesToHash(accIt.Key), acc.Root)
|
id := trie.StorageTrieID(root, common.BytesToHash(accIt.Key), acc.Root)
|
||||||
storeTrie, err := trie.NewStateTrie(id, triedb)
|
storeTrie, err := trie.NewStateTrie(id, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -131,10 +131,10 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface
|
|||||||
if head.UncleHash != types.EmptyUncleHash && len(body.UncleHashes) == 0 {
|
if head.UncleHash != types.EmptyUncleHash && len(body.UncleHashes) == 0 {
|
||||||
return nil, fmt.Errorf("server returned empty uncle list but block header indicates uncles")
|
return nil, fmt.Errorf("server returned empty uncle list but block header indicates uncles")
|
||||||
}
|
}
|
||||||
if head.TxHash == types.EmptyRootHash && len(body.Transactions) > 0 {
|
if head.TxHash == types.EmptyTxsHash && len(body.Transactions) > 0 {
|
||||||
return nil, fmt.Errorf("server returned non-empty transaction list but block header indicates no transactions")
|
return nil, fmt.Errorf("server returned non-empty transaction list but block header indicates no transactions")
|
||||||
}
|
}
|
||||||
if head.TxHash != types.EmptyRootHash && len(body.Transactions) == 0 {
|
if head.TxHash != types.EmptyTxsHash && len(body.Transactions) == 0 {
|
||||||
return nil, fmt.Errorf("server returned empty transaction list but block header indicates transactions")
|
return nil, fmt.Errorf("server returned empty transaction list but block header indicates transactions")
|
||||||
}
|
}
|
||||||
// Load uncles because they are not included in the block response.
|
// Load uncles because they are not included in the block response.
|
||||||
|
@ -548,7 +548,7 @@ func (f *BlockFetcher) loop() {
|
|||||||
announce.time = task.time
|
announce.time = task.time
|
||||||
|
|
||||||
// If the block is empty (header only), short circuit into the final import queue
|
// If the block is empty (header only), short circuit into the final import queue
|
||||||
if header.TxHash == types.EmptyRootHash && header.UncleHash == types.EmptyUncleHash {
|
if header.TxHash == types.EmptyTxsHash && header.UncleHash == types.EmptyUncleHash {
|
||||||
log.Trace("Block empty, skipping body retrieval", "peer", announce.origin, "number", header.Number, "hash", header.Hash())
|
log.Trace("Block empty, skipping body retrieval", "peer", announce.origin, "number", header.Number, "hash", header.Hash())
|
||||||
|
|
||||||
block := types.NewBlockWithHeader(header)
|
block := types.NewBlockWithHeader(header)
|
||||||
|
@ -348,7 +348,7 @@ func handleGetReceipts(msg Decoder) (serveRequestFn, uint64, uint64, error) {
|
|||||||
// Retrieve the requested block's receipts, skipping if unknown to us
|
// Retrieve the requested block's receipts, skipping if unknown to us
|
||||||
results := bc.GetReceiptsByHash(hash)
|
results := bc.GetReceiptsByHash(hash)
|
||||||
if results == nil {
|
if results == nil {
|
||||||
if header := bc.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
|
if header := bc.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyReceiptsHash {
|
||||||
p.bumpInvalid()
|
p.bumpInvalid()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -253,8 +253,8 @@ func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.
|
|||||||
Number: big.NewInt(int64(i + 1)),
|
Number: big.NewInt(int64(i + 1)),
|
||||||
Difficulty: big.NewInt(int64(difficulty)),
|
Difficulty: big.NewInt(int64(difficulty)),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
}
|
}
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
header.ParentHash = genesis.Hash()
|
header.ParentHash = genesis.Hash()
|
||||||
|
@ -808,7 +808,7 @@ func (db *Database) Update(nodes *MergedNodeSet) error {
|
|||||||
if err := rlp.DecodeBytes(n.blob, &account); err != nil {
|
if err := rlp.DecodeBytes(n.blob, &account); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if account.Root != emptyRoot {
|
if account.Root != types.EmptyRootHash {
|
||||||
db.reference(account.Root, n.parent)
|
db.reference(account.Root, n.parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NodeResolver is used for looking up trie nodes before reaching into the real
|
// NodeResolver is used for looking up trie nodes before reaching into the real
|
||||||
@ -160,7 +161,7 @@ func (e seekError) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newNodeIterator(trie *Trie, start []byte) NodeIterator {
|
func newNodeIterator(trie *Trie, start []byte) NodeIterator {
|
||||||
if trie.Hash() == emptyRoot {
|
if trie.Hash() == types.EmptyRootHash {
|
||||||
return &nodeIterator{
|
return &nodeIterator{
|
||||||
trie: trie,
|
trie: trie,
|
||||||
err: errIteratorEnd,
|
err: errIteratorEnd,
|
||||||
@ -302,7 +303,7 @@ func (it *nodeIterator) seek(prefix []byte) error {
|
|||||||
func (it *nodeIterator) init() (*nodeIteratorState, error) {
|
func (it *nodeIterator) init() (*nodeIteratorState, error) {
|
||||||
root := it.trie.Hash()
|
root := it.trie.Hash()
|
||||||
state := &nodeIteratorState{node: it.trie.root, index: -1}
|
state := &nodeIteratorState{node: it.trie.root, index: -1}
|
||||||
if root != emptyRoot {
|
if root != types.EmptyRootHash {
|
||||||
state.hash = root
|
state.hash = root
|
||||||
}
|
}
|
||||||
return state, state.resolve(it, nil)
|
return state, state.resolve(it, nil)
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -407,7 +408,7 @@ func (st *StackTrie) hashRec(hasher *hasher, path []byte) {
|
|||||||
return
|
return
|
||||||
|
|
||||||
case emptyNode:
|
case emptyNode:
|
||||||
st.val = emptyRoot.Bytes()
|
st.val = types.EmptyRootHash.Bytes()
|
||||||
st.key = st.key[:0]
|
st.key = st.key[:0]
|
||||||
st.nodeType = hashedNode
|
st.nodeType = hashedNode
|
||||||
return
|
return
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/prque"
|
"github.com/ethereum/go-ethereum/common/prque"
|
||||||
"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"
|
||||||
)
|
)
|
||||||
@ -184,7 +185,7 @@ func NewSync(root common.Hash, database ethdb.KeyValueReader, callback LeafCallb
|
|||||||
// hex format and contain all the parent path if it's layered trie node.
|
// hex format and contain all the parent path if it's layered trie node.
|
||||||
func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, parentPath []byte, callback LeafCallback) {
|
func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, parentPath []byte, callback LeafCallback) {
|
||||||
// Short circuit if the trie is empty or already known
|
// Short circuit if the trie is empty or already known
|
||||||
if root == emptyRoot {
|
if root == types.EmptyRootHash {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s.membatch.hasNode(path) {
|
if s.membatch.hasNode(path) {
|
||||||
@ -217,7 +218,7 @@ func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, par
|
|||||||
// as is.
|
// as is.
|
||||||
func (s *Sync) AddCodeEntry(hash common.Hash, path []byte, parent common.Hash, parentPath []byte) {
|
func (s *Sync) AddCodeEntry(hash common.Hash, path []byte, parent common.Hash, parentPath []byte) {
|
||||||
// Short circuit if the entry is empty or already known
|
// Short circuit if the entry is empty or already known
|
||||||
if hash == emptyState {
|
if hash == types.EmptyCodeHash {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s.membatch.hasCode(hash) {
|
if s.membatch.hasCode(hash) {
|
||||||
|
@ -23,6 +23,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/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
||||||
)
|
)
|
||||||
@ -104,7 +105,7 @@ func TestEmptySync(t *testing.T) {
|
|||||||
dbA := NewDatabase(rawdb.NewMemoryDatabase())
|
dbA := NewDatabase(rawdb.NewMemoryDatabase())
|
||||||
dbB := NewDatabase(rawdb.NewMemoryDatabase())
|
dbB := NewDatabase(rawdb.NewMemoryDatabase())
|
||||||
emptyA, _ := New(TrieID(common.Hash{}), dbA)
|
emptyA, _ := New(TrieID(common.Hash{}), dbA)
|
||||||
emptyB, _ := New(TrieID(emptyRoot), dbB)
|
emptyB, _ := New(TrieID(types.EmptyRootHash), dbB)
|
||||||
|
|
||||||
for i, trie := range []*Trie{emptyA, emptyB} {
|
for i, trie := range []*Trie{emptyA, emptyB} {
|
||||||
sync := NewSync(trie.Hash(), memorydb.New(), nil, []*Database{dbA, dbB}[i].Scheme())
|
sync := NewSync(trie.Hash(), memorydb.New(), nil, []*Database{dbA, dbB}[i].Scheme())
|
||||||
|
16
trie/trie.go
16
trie/trie.go
@ -23,18 +23,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// emptyRoot is the known root hash of an empty trie.
|
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
|
||||||
|
|
||||||
// emptyState is the known hash of an empty state trie entry.
|
|
||||||
emptyState = crypto.Keccak256Hash(nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Trie is a Merkle Patricia Trie. Use New to create a trie that sits on
|
// Trie is a Merkle Patricia Trie. Use New to create a trie that sits on
|
||||||
// top of a database. Whenever trie performs a commit operation, the generated
|
// top of a database. Whenever trie performs a commit operation, the generated
|
||||||
// nodes will be gathered and returned in a set. Once the trie is committed,
|
// nodes will be gathered and returned in a set. Once the trie is committed,
|
||||||
@ -91,7 +83,7 @@ func New(id *ID, db NodeReader) (*Trie, error) {
|
|||||||
reader: reader,
|
reader: reader,
|
||||||
//tracer: newTracer(),
|
//tracer: newTracer(),
|
||||||
}
|
}
|
||||||
if id.Root != (common.Hash{}) && id.Root != emptyRoot {
|
if id.Root != (common.Hash{}) && id.Root != types.EmptyRootHash {
|
||||||
rootnode, err := trie.resolveAndTrack(id.Root[:], nil)
|
rootnode, err := trie.resolveAndTrack(id.Root[:], nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -576,7 +568,7 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *NodeSet) {
|
|||||||
// Wrap tracked deletions as the return
|
// Wrap tracked deletions as the return
|
||||||
set := NewNodeSet(t.owner)
|
set := NewNodeSet(t.owner)
|
||||||
t.tracer.markDeletions(set)
|
t.tracer.markDeletions(set)
|
||||||
return emptyRoot, set
|
return types.EmptyRootHash, set
|
||||||
}
|
}
|
||||||
// Derive the hash for all dirty nodes first. We hold the assumption
|
// Derive the hash for all dirty nodes first. We hold the assumption
|
||||||
// in the following procedure that all nodes are hashed.
|
// in the following procedure that all nodes are hashed.
|
||||||
@ -599,7 +591,7 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *NodeSet) {
|
|||||||
// hashRoot calculates the root hash of the given trie
|
// hashRoot calculates the root hash of the given trie
|
||||||
func (t *Trie) hashRoot() (node, node, error) {
|
func (t *Trie) hashRoot() (node, node, error) {
|
||||||
if t.root == nil {
|
if t.root == nil {
|
||||||
return hashNode(emptyRoot.Bytes()), nil, nil
|
return hashNode(types.EmptyRootHash.Bytes()), nil, nil
|
||||||
}
|
}
|
||||||
// If the number of changes is below 100, we let one thread handle it
|
// If the number of changes is below 100, we let one thread handle it
|
||||||
h := newHasher(t.unhashed >= 100)
|
h := newHasher(t.unhashed >= 100)
|
||||||
|
@ -47,7 +47,7 @@ func init() {
|
|||||||
func TestEmptyTrie(t *testing.T) {
|
func TestEmptyTrie(t *testing.T) {
|
||||||
trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
|
trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
|
||||||
res := trie.Hash()
|
res := trie.Hash()
|
||||||
exp := emptyRoot
|
exp := types.EmptyRootHash
|
||||||
if res != exp {
|
if res != exp {
|
||||||
t.Errorf("expected %x got %x", exp, res)
|
t.Errorf("expected %x got %x", exp, res)
|
||||||
}
|
}
|
||||||
@ -431,7 +431,7 @@ func runRandTest(rt randTest) bool {
|
|||||||
}
|
}
|
||||||
case opProve:
|
case opProve:
|
||||||
hash := tr.Hash()
|
hash := tr.Hash()
|
||||||
if hash == emptyRoot {
|
if hash == types.EmptyRootHash {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
proofDb := rawdb.NewMemoryDatabase()
|
proofDb := rawdb.NewMemoryDatabase()
|
||||||
@ -718,7 +718,7 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
|
|||||||
for i := 0; i < len(accounts); i++ {
|
for i := 0; i < len(accounts); i++ {
|
||||||
var (
|
var (
|
||||||
nonce = uint64(random.Int63())
|
nonce = uint64(random.Int63())
|
||||||
root = emptyRoot
|
root = types.EmptyRootHash
|
||||||
code = crypto.Keccak256(nil)
|
code = crypto.Keccak256(nil)
|
||||||
)
|
)
|
||||||
// The big.Rand function is not deterministic with regards to 64 vs 32 bit systems,
|
// The big.Rand function is not deterministic with regards to 64 vs 32 bit systems,
|
||||||
|
@ -22,6 +22,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"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tests if the trie diffs are tracked correctly.
|
// Tests if the trie diffs are tracked correctly.
|
||||||
@ -286,7 +287,7 @@ func TestDeleteAll(t *testing.T) {
|
|||||||
trie.Delete([]byte(val.k))
|
trie.Delete([]byte(val.k))
|
||||||
}
|
}
|
||||||
root, set = trie.Commit(false)
|
root, set = trie.Commit(false)
|
||||||
if root != emptyRoot {
|
if root != types.EmptyRootHash {
|
||||||
t.Fatalf("Invalid trie root %v", root)
|
t.Fatalf("Invalid trie root %v", root)
|
||||||
}
|
}
|
||||||
for path, blob := range set.deletes {
|
for path, blob := range set.deletes {
|
||||||
|
Loading…
Reference in New Issue
Block a user