mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +00:00
Merge pull request #685 from gzliudan/emptyroot
all: use unified emptyRootHash and emptyCodeHash
This commit is contained in:
commit
b68b9c64ea
11 changed files with 67 additions and 34 deletions
|
|
@ -697,11 +697,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,
|
||||||
|
|
|
||||||
|
|
@ -231,13 +231,15 @@ 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()
|
||||||
|
|
||||||
rawdb.WriteHeader(db, header)
|
rawdb.WriteHeader(db, header)
|
||||||
rawdb.WriteCanonicalHash(db, hash, n)
|
rawdb.WriteCanonicalHash(db, hash, n)
|
||||||
WriteTd(db, hash, n, big.NewInt(int64(n+1)))
|
WriteTd(db, hash, n, big.NewInt(int64(n+1)))
|
||||||
|
|
||||||
if full || n == 0 {
|
if full || n == 0 {
|
||||||
block := types.NewBlockWithHeader(header)
|
block := types.NewBlockWithHeader(header)
|
||||||
rawdb.WriteBody(db, hash, n, block.Body())
|
rawdb.WriteBody(db, hash, n, block.Body())
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||||
"github.com/XinFinOrg/XDPoSChain/trie"
|
"github.com/XinFinOrg/XDPoSChain/trie"
|
||||||
)
|
)
|
||||||
|
|
@ -116,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))
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,11 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var emptyCodeHash = crypto.Keccak256(nil)
|
|
||||||
|
|
||||||
type Code []byte
|
type Code []byte
|
||||||
|
|
||||||
func (c Code) String() string {
|
func (c Code) String() string {
|
||||||
|
|
@ -93,7 +92,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())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account is the Ethereum consensus representation of accounts.
|
// Account is the Ethereum consensus representation of accounts.
|
||||||
|
|
@ -111,7 +110,7 @@ func newObject(db *StateDB, address common.Address, data Account, onDirty func(a
|
||||||
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()
|
||||||
}
|
}
|
||||||
return &stateObject{
|
return &stateObject{
|
||||||
db: db,
|
db: db,
|
||||||
|
|
@ -372,7 +371,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()))
|
||||||
|
|
|
||||||
|
|
@ -36,14 +36,6 @@ type revision struct {
|
||||||
journalIndex int
|
journalIndex int
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
// emptyState is the known hash of an empty state trie entry.
|
|
||||||
emptyState = crypto.Keccak256Hash(nil)
|
|
||||||
|
|
||||||
// emptyCode is the known hash of the empty EVM bytecode.
|
|
||||||
emptyCode = crypto.Keccak256Hash(nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// StateDBs within the ethereum protocol are used to store anything
|
// StateDBs within the ethereum protocol are used to store anything
|
||||||
// within the merkle trie. StateDBs take care of caching and storing
|
// within the merkle trie. StateDBs take care of caching and storing
|
||||||
// nested states. It's the general query interface to retrieve:
|
// nested states. It's the general query interface to retrieve:
|
||||||
|
|
@ -714,11 +706,11 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error)
|
||||||
if err := rlp.DecodeBytes(leaf, &account); err != nil {
|
if err := rlp.DecodeBytes(leaf, &account); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if account.Root != emptyState {
|
if account.Root != types.EmptyRootHash {
|
||||||
s.db.TrieDB().Reference(account.Root, parent)
|
s.db.TrieDB().Reference(account.Root, parent)
|
||||||
}
|
}
|
||||||
code := common.BytesToHash(account.CodeHash)
|
code := common.BytesToHash(account.CodeHash)
|
||||||
if code != emptyCode {
|
if code != types.EmptyCodeHash {
|
||||||
s.db.TrieDB().Reference(code, parent)
|
s.db.TrieDB().Reference(code, parent)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import (
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb/memorydb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb/memorydb"
|
||||||
|
|
@ -125,8 +126,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) {
|
||||||
empty := common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
if req := NewStateSync(types.EmptyRootHash, rawdb.NewMemoryDatabase(), trie.NewSyncBloom(1, memorydb.New())).Missing(1); len(req) != 0 {
|
||||||
if req := NewStateSync(empty, rawdb.NewMemoryDatabase(), trie.NewSyncBloom(1, memorydb.New())).Missing(1); len(req) != 0 {
|
|
||||||
t.Errorf("content requested for empty state: %v", req)
|
t.Errorf("content requested for empty state: %v", req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
EmptyRootHash = DeriveSha(Transactions{})
|
|
||||||
EmptyUncleHash = CalcUncleHash(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.
|
||||||
|
|
@ -222,7 +217,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))
|
b.header.TxHash = DeriveSha(Transactions(txs))
|
||||||
b.transactions = make(Transactions, len(txs))
|
b.transactions = make(Transactions, len(txs))
|
||||||
|
|
@ -230,7 +225,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))
|
b.header.ReceiptHash = DeriveSha(Receipts(receipts))
|
||||||
b.header.Bloom = CreateBloom(receipts)
|
b.header.Bloom = CreateBloom(receipts)
|
||||||
|
|
|
||||||
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/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/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")
|
||||||
|
)
|
||||||
|
|
@ -110,10 +110,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, errors.New("server returned empty uncle list but block header indicates uncles")
|
return nil, errors.New("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, errors.New("server returned non-empty transaction list but block header indicates no transactions")
|
return nil, errors.New("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, errors.New("server returned empty transaction list but block header indicates transactions")
|
return nil, errors.New("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.
|
||||||
|
|
|
||||||
|
|
@ -250,8 +250,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()
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// TODO: remove file core/types/derive_sha.go, then remove emptyRoot and emptyState
|
||||||
|
|
||||||
// emptyRoot is the known root hash of an empty trie.
|
// emptyRoot is the known root hash of an empty trie.
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue