core, eth, les, trie: add a prefix to contract code (#21080)

This commit is contained in:
gary rong
2020-08-21 20:10:40 +08:00
committed by GitHub
parent b68929caee
commit 87c0ba9213
42 changed files with 580 additions and 287 deletions

View File

@ -109,7 +109,7 @@ type Downloader struct {
peers *peerSet // Set of active peers from which download can proceed
stateDB ethdb.Database // Database to state sync into (and deduplicate via)
stateBloom *trie.SyncBloom // Bloom filter for fast trie node existence checks
stateBloom *trie.SyncBloom // Bloom filter for fast trie node and contract code existence checks
// Statistics
syncStatsChainOrigin uint64 // Origin block number where syncing started at

View File

@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/trie"
)
const (
@ -771,7 +772,7 @@ func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, uncleLi
q.lock.Lock()
defer q.lock.Unlock()
validate := func(index int, header *types.Header) error {
if types.DeriveSha(types.Transactions(txLists[index])) != header.TxHash {
if types.DeriveSha(types.Transactions(txLists[index]), new(trie.Trie)) != header.TxHash {
return errInvalidBody
}
if types.CalcUncleHash(uncleLists[index]) != header.UncleHash {
@ -796,7 +797,7 @@ func (q *queue) DeliverReceipts(id string, receiptList [][]*types.Receipt) (int,
q.lock.Lock()
defer q.lock.Unlock()
validate := func(index int, header *types.Header) error {
if types.DeriveSha(types.Receipts(receiptList[index])) != header.ReceiptHash {
if types.DeriveSha(types.Receipts(receiptList[index]), new(trie.Trie)) != header.ReceiptHash {
return errInvalidReceipt
}
return nil

View File

@ -474,7 +474,7 @@ func (s *stateSync) process(req *stateReq) (int, error) {
// Iterate over all the delivered data and inject one-by-one into the trie
for _, blob := range req.response {
_, hash, err := s.processNodeData(blob)
hash, err := s.processNodeData(blob)
switch err {
case nil:
s.numUncommitted++
@ -512,13 +512,13 @@ func (s *stateSync) process(req *stateReq) (int, error) {
// processNodeData tries to inject a trie node data blob delivered from a remote
// peer into the state trie, returning whether anything useful was written or any
// error occurred.
func (s *stateSync) processNodeData(blob []byte) (bool, common.Hash, error) {
func (s *stateSync) processNodeData(blob []byte) (common.Hash, error) {
res := trie.SyncResult{Data: blob}
s.keccak.Reset()
s.keccak.Write(blob)
s.keccak.Sum(res.Hash[:0])
committed, _, err := s.sched.Process([]trie.SyncResult{res})
return committed, res.Hash, err
err := s.sched.Process(res)
return res.Hash, err
}
// updateStats bumps the various state sync progress counters and displays a log

View File

@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/trie"
)
const (
@ -540,7 +541,7 @@ func (f *BlockFetcher) loop() {
announce.time = task.time
// If the block is empty (header only), short circuit into the final import queue
if header.TxHash == types.DeriveSha(types.Transactions{}) && header.UncleHash == types.CalcUncleHash([]*types.Header{}) {
if header.TxHash == types.EmptyRootHash && header.UncleHash == types.EmptyUncleHash {
log.Trace("Block empty, skipping body retrieval", "peer", announce.origin, "number", header.Number, "hash", header.Hash())
block := types.NewBlockWithHeader(header)
@ -619,7 +620,7 @@ func (f *BlockFetcher) loop() {
continue
}
if txnHash == (common.Hash{}) {
txnHash = types.DeriveSha(types.Transactions(task.transactions[i]))
txnHash = types.DeriveSha(types.Transactions(task.transactions[i]), new(trie.Trie))
}
if txnHash != announce.header.TxHash {
continue

View File

@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
)
var (
@ -38,7 +39,7 @@ var (
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
unknownBlock = types.NewBlock(&types.Header{GasLimit: params.GenesisGasLimit}, nil, nil, nil)
unknownBlock = types.NewBlock(&types.Header{GasLimit: params.GenesisGasLimit}, nil, nil, nil, new(trie.Trie))
)
// makeChain creates a chain of n blocks starting at and including parent.

View File

@ -608,7 +608,14 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
return errResp(ErrDecode, "msg %v: %v", msg, err)
}
// Retrieve the requested state entry, stopping if enough was found
if entry, err := pm.blockchain.TrieNode(hash); err == nil {
// todo now the code and trienode is mixed in the protocol level,
// separate these two types.
entry, err := pm.blockchain.TrieNode(hash)
if len(entry) == 0 || err != nil {
// Read the contract code with prefix only to save unnecessary lookups.
entry, err = pm.blockchain.ContractCodeWithPrefix(hash)
}
if err == nil && len(entry) > 0 {
data = append(data, entry)
bytes += len(entry)
}
@ -703,7 +710,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
log.Warn("Propagated block has invalid uncles", "have", hash, "exp", request.Block.UncleHash())
break // TODO(karalabe): return error eventually, but wait a few releases
}
if hash := types.DeriveSha(request.Block.Transactions()); hash != request.Block.TxHash() {
if hash := types.DeriveSha(request.Block.Transactions(), new(trie.Trie)); hash != request.Block.TxHash() {
log.Warn("Propagated block has invalid body", "have", hash, "exp", request.Block.TxHash())
break // TODO(karalabe): return error eventually, but wait a few releases
}