Skip to content

Commit 87c0ba9

Browse files
authored
core, eth, les, trie: add a prefix to contract code (#21080)
1 parent b68929c commit 87c0ba9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+579
-286
lines changed

cmd/evm/internal/t8ntool/execution.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"github.com/ethereum/go-ethereum/log"
3535
"github.com/ethereum/go-ethereum/params"
3636
"github.com/ethereum/go-ethereum/rlp"
37+
"github.com/ethereum/go-ethereum/trie"
3738
"golang.org/x/crypto/sha3"
3839
)
3940

@@ -220,8 +221,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
220221
}
221222
execRs := &ExecutionResult{
222223
StateRoot: root,
223-
TxRoot: types.DeriveSha(includedTxs),
224-
ReceiptRoot: types.DeriveSha(receipts),
224+
TxRoot: types.DeriveSha(includedTxs, new(trie.Trie)),
225+
ReceiptRoot: types.DeriveSha(receipts, new(trie.Trie)),
225226
Bloom: types.CreateBloom(receipts),
226227
LogsHash: rlpHash(statedb.Logs()),
227228
Receipts: receipts,

cmd/geth/retesteth.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ func (e *NoRewardEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader,
248248
header.Root = statedb.IntermediateRoot(chain.Config().IsEIP158(header.Number))
249249

250250
// Header seems complete, assemble into a block and return
251-
return types.NewBlock(header, txs, uncles, receipts), nil
251+
return types.NewBlock(header, txs, uncles, receipts, new(trie.Trie)), nil
252252
}
253253
}
254254

consensus/clique/clique.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"github.com/ethereum/go-ethereum/params"
4040
"github.com/ethereum/go-ethereum/rlp"
4141
"github.com/ethereum/go-ethereum/rpc"
42+
"github.com/ethereum/go-ethereum/trie"
4243
lru "github.com/hashicorp/golang-lru"
4344
"golang.org/x/crypto/sha3"
4445
)
@@ -565,7 +566,7 @@ func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
565566
header.UncleHash = types.CalcUncleHash(nil)
566567

567568
// Assemble and return the final block for sealing
568-
return types.NewBlock(header, txs, nil, receipts), nil
569+
return types.NewBlock(header, txs, nil, receipts, new(trie.Trie)), nil
569570
}
570571

571572
// Authorize injects a private key into the consensus engine to mint new blocks

consensus/ethash/consensus.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/ethereum/go-ethereum/core/types"
3434
"github.com/ethereum/go-ethereum/params"
3535
"github.com/ethereum/go-ethereum/rlp"
36+
"github.com/ethereum/go-ethereum/trie"
3637
"golang.org/x/crypto/sha3"
3738
)
3839

@@ -583,7 +584,7 @@ func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
583584
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
584585

585586
// Header seems complete, assemble into a block and return
586-
return types.NewBlock(header, txs, uncles, receipts), nil
587+
return types.NewBlock(header, txs, uncles, receipts, new(trie.Trie)), nil
587588
}
588589

589590
// SealHash returns the hash of a block prior to it being sealed.

core/block_validator.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/ethereum/go-ethereum/core/state"
2424
"github.com/ethereum/go-ethereum/core/types"
2525
"github.com/ethereum/go-ethereum/params"
26+
"github.com/ethereum/go-ethereum/trie"
2627
)
2728

2829
// BlockValidator is responsible for validating block headers, uncles and
@@ -61,7 +62,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
6162
if hash := types.CalcUncleHash(block.Uncles()); hash != header.UncleHash {
6263
return fmt.Errorf("uncle root hash mismatch: have %x, want %x", hash, header.UncleHash)
6364
}
64-
if hash := types.DeriveSha(block.Transactions()); hash != header.TxHash {
65+
if hash := types.DeriveSha(block.Transactions(), new(trie.Trie)); hash != header.TxHash {
6566
return fmt.Errorf("transaction root hash mismatch: have %x, want %x", hash, header.TxHash)
6667
}
6768
if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
@@ -89,7 +90,7 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
8990
return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom, rbloom)
9091
}
9192
// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]]))
92-
receiptSha := types.DeriveSha(receipts)
93+
receiptSha := types.DeriveSha(receipts, new(trie.Trie))
9394
if receiptSha != header.ReceiptHash {
9495
return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha)
9596
}

core/blockchain.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ const (
112112
// - Version 7
113113
// The following incompatible database changes were added:
114114
// * Use freezer as the ancient database to maintain all ancient data
115-
BlockChainVersion uint64 = 7
115+
// - Version 8
116+
// The following incompatible database changes were added:
117+
// * New scheme for contract code in order to separate the codes and trie nodes
118+
BlockChainVersion uint64 = 8
116119
)
117120

118121
// CacheConfig contains the configuration values for the trie caching/pruning
@@ -895,12 +898,30 @@ func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.
895898
return uncles
896899
}
897900

898-
// TrieNode retrieves a blob of data associated with a trie node (or code hash)
901+
// TrieNode retrieves a blob of data associated with a trie node
899902
// either from ephemeral in-memory cache, or from persistent storage.
900903
func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) {
901904
return bc.stateCache.TrieDB().Node(hash)
902905
}
903906

907+
// ContractCode retrieves a blob of data associated with a contract hash
908+
// either from ephemeral in-memory cache, or from persistent storage.
909+
func (bc *BlockChain) ContractCode(hash common.Hash) ([]byte, error) {
910+
return bc.stateCache.ContractCode(common.Hash{}, hash)
911+
}
912+
913+
// ContractCodeWithPrefix retrieves a blob of data associated with a contract
914+
// hash either from ephemeral in-memory cache, or from persistent storage.
915+
//
916+
// If the code doesn't exist in the in-memory cache, check the storage with
917+
// new code scheme.
918+
func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
919+
type codeReader interface {
920+
ContractCodeWithPrefix(addrHash, codeHash common.Hash) ([]byte, error)
921+
}
922+
return bc.stateCache.(codeReader).ContractCodeWithPrefix(common.Hash{}, hash)
923+
}
924+
904925
// Stop stops the blockchain service. If any imports are currently in progress
905926
// it will abort them using the procInterrupt.
906927
func (bc *BlockChain) Stop() {

core/blockchain_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
"github.com/ethereum/go-ethereum/crypto"
3737
"github.com/ethereum/go-ethereum/ethdb"
3838
"github.com/ethereum/go-ethereum/params"
39+
"github.com/ethereum/go-ethereum/trie"
3940
)
4041

4142
// So we can deterministically seed different blockchains
@@ -681,12 +682,12 @@ func TestFastVsFullChains(t *testing.T) {
681682
}
682683
if fblock, arblock, anblock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash), ancient.GetBlockByHash(hash); fblock.Hash() != arblock.Hash() || anblock.Hash() != arblock.Hash() {
683684
t.Errorf("block #%d [%x]: block mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock, anblock, arblock)
684-
} else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(arblock.Transactions()) || types.DeriveSha(anblock.Transactions()) != types.DeriveSha(arblock.Transactions()) {
685+
} else if types.DeriveSha(fblock.Transactions(), new(trie.Trie)) != types.DeriveSha(arblock.Transactions(), new(trie.Trie)) || types.DeriveSha(anblock.Transactions(), new(trie.Trie)) != types.DeriveSha(arblock.Transactions(), new(trie.Trie)) {
685686
t.Errorf("block #%d [%x]: transactions mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Transactions(), anblock.Transactions(), arblock.Transactions())
686687
} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) || types.CalcUncleHash(anblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) {
687688
t.Errorf("block #%d [%x]: uncles mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Uncles(), anblock, arblock.Uncles())
688689
}
689-
if freceipts, anreceipts, areceipts := rawdb.ReadReceipts(fastDb, hash, *rawdb.ReadHeaderNumber(fastDb, hash), fast.Config()), rawdb.ReadReceipts(ancientDb, hash, *rawdb.ReadHeaderNumber(ancientDb, hash), fast.Config()), rawdb.ReadReceipts(archiveDb, hash, *rawdb.ReadHeaderNumber(archiveDb, hash), fast.Config()); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) {
690+
if freceipts, anreceipts, areceipts := rawdb.ReadReceipts(fastDb, hash, *rawdb.ReadHeaderNumber(fastDb, hash), fast.Config()), rawdb.ReadReceipts(ancientDb, hash, *rawdb.ReadHeaderNumber(ancientDb, hash), fast.Config()), rawdb.ReadReceipts(archiveDb, hash, *rawdb.ReadHeaderNumber(archiveDb, hash), fast.Config()); types.DeriveSha(freceipts, new(trie.Trie)) != types.DeriveSha(areceipts, new(trie.Trie)) {
690691
t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts)
691692
}
692693
}

core/genesis.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
"github.com/ethereum/go-ethereum/log"
3737
"github.com/ethereum/go-ethereum/params"
3838
"github.com/ethereum/go-ethereum/rlp"
39+
"github.com/ethereum/go-ethereum/trie"
3940
)
4041

4142
//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
@@ -287,7 +288,7 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
287288
statedb.Commit(false)
288289
statedb.Database().TrieDB().Commit(root, true, nil)
289290

290-
return types.NewBlock(head, nil, nil, nil)
291+
return types.NewBlock(head, nil, nil, nil, new(trie.Trie))
291292
}
292293

293294
// Commit writes the block and state of a genesis specification to the database.

core/rawdb/accessors_chain_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func TestBodyStorage(t *testing.T) {
8484
WriteBody(db, hash, 0, body)
8585
if entry := ReadBody(db, hash, 0); entry == nil {
8686
t.Fatalf("Stored body not found")
87-
} else if types.DeriveSha(types.Transactions(entry.Transactions)) != types.DeriveSha(types.Transactions(body.Transactions)) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(body.Uncles) {
87+
} else if types.DeriveSha(types.Transactions(entry.Transactions), newHasher()) != types.DeriveSha(types.Transactions(body.Transactions), newHasher()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(body.Uncles) {
8888
t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, body)
8989
}
9090
if entry := ReadBodyRLP(db, hash, 0); entry == nil {
@@ -138,7 +138,7 @@ func TestBlockStorage(t *testing.T) {
138138
}
139139
if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry == nil {
140140
t.Fatalf("Stored body not found")
141-
} else if types.DeriveSha(types.Transactions(entry.Transactions)) != types.DeriveSha(block.Transactions()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(block.Uncles()) {
141+
} else if types.DeriveSha(types.Transactions(entry.Transactions), newHasher()) != types.DeriveSha(block.Transactions(), newHasher()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(block.Uncles()) {
142142
t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, block.Body())
143143
}
144144
// Delete the block and verify the execution

core/rawdb/accessors_indexes_test.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package rawdb
1818

1919
import (
2020
"bytes"
21+
"hash"
2122
"math/big"
2223
"testing"
2324

@@ -26,8 +27,33 @@ import (
2627
"github.com/ethereum/go-ethereum/ethdb"
2728
"github.com/ethereum/go-ethereum/params"
2829
"github.com/ethereum/go-ethereum/rlp"
30+
"golang.org/x/crypto/sha3"
2931
)
3032

33+
// testHasher is the helper tool for transaction/receipt list hashing.
34+
// The original hasher is trie, in order to get rid of import cycle,
35+
// use the testing hasher instead.
36+
type testHasher struct {
37+
hasher hash.Hash
38+
}
39+
40+
func newHasher() *testHasher {
41+
return &testHasher{hasher: sha3.NewLegacyKeccak256()}
42+
}
43+
44+
func (h *testHasher) Reset() {
45+
h.hasher.Reset()
46+
}
47+
48+
func (h *testHasher) Update(key, val []byte) {
49+
h.hasher.Write(key)
50+
h.hasher.Write(val)
51+
}
52+
53+
func (h *testHasher) Hash() common.Hash {
54+
return common.BytesToHash(h.hasher.Sum(nil))
55+
}
56+
3157
// Tests that positional lookup metadata can be stored and retrieved.
3258
func TestLookupStorage(t *testing.T) {
3359
tests := []struct {
@@ -73,7 +99,7 @@ func TestLookupStorage(t *testing.T) {
7399
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
74100
txs := []*types.Transaction{tx1, tx2, tx3}
75101

76-
block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil)
102+
block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, newHasher())
77103

78104
// Check that no transactions entries are in a pristine database
79105
for i, tx := range txs {

0 commit comments

Comments
 (0)