Skip to content

Commit b8d6373

Browse files
committed
update testcase
1 parent 5fd554a commit b8d6373

File tree

4 files changed

+145
-18
lines changed

4 files changed

+145
-18
lines changed

core/blockchain.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ const (
9393
diffLayerFreezerRecheckInterval = 3 * time.Second
9494
diffLayerFreezerBlockLimit = 864000 // The number of diff layers that should be kept in disk.
9595
diffLayerPruneRecheckInterval = 1 * time.Second // The interval to prune unverified diff layers
96-
maxDiffQueueDist = 64 // Maximum allowed distance from the chain head to queue diffLayers
96+
maxDiffQueueDist = 128 // Maximum allowed distance from the chain head to queue diffLayers
9797
maxDiffLimit = 128 // Maximum number of unique diff layers a peer may have delivered
9898
maxDiffForkDist = 11 // Maximum allowed backward distance from the chain head
9999

@@ -2442,7 +2442,7 @@ func (bc *BlockChain) trustedDiffLayerFreezeLoop() {
24422442
diffLayer := diff.(*types.DiffLayer)
24432443

24442444
// if the block old enough
2445-
if int64(currentHeight)+prio > int64(bc.triesInMemory) {
2445+
if int64(currentHeight)+prio >= int64(bc.triesInMemory) {
24462446
canonicalHash := bc.GetCanonicalHash(uint64(-prio))
24472447
// on the canonical chain
24482448
if canonicalHash == diffLayer.BlockHash {
@@ -2587,7 +2587,7 @@ func (bc *BlockChain) pruneDiffLayer() {
25872587
for diffHash := range staleDiffHashes {
25882588
for p, diffHashes := range bc.diffPeersToDiffHashes {
25892589
delete(diffHashes, diffHash)
2590-
if len(diffHash) == 0 {
2590+
if len(diffHashes) == 0 {
25912591
delete(bc.diffPeersToDiffHashes, p)
25922592
}
25932593
}

core/blockchain_diff_test.go

+137-12
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,19 @@ package core
2323
import (
2424
"math/big"
2525
"testing"
26+
"time"
2627

2728
"golang.org/x/crypto/sha3"
2829

2930
"github.com/ethereum/go-ethereum/common"
3031
"github.com/ethereum/go-ethereum/consensus/ethash"
3132
"github.com/ethereum/go-ethereum/core/rawdb"
33+
"github.com/ethereum/go-ethereum/core/state/snapshot"
3234
"github.com/ethereum/go-ethereum/core/types"
3335
"github.com/ethereum/go-ethereum/core/vm"
3436
"github.com/ethereum/go-ethereum/crypto"
3537
"github.com/ethereum/go-ethereum/ethdb"
38+
"github.com/ethereum/go-ethereum/ethdb/memorydb"
3639
"github.com/ethereum/go-ethereum/params"
3740
"github.com/ethereum/go-ethereum/rlp"
3841
)
@@ -63,6 +66,7 @@ func newTestBackendWithGenerator(blocks int, lightProcess bool) *testBackend {
6366
signer := types.HomesteadSigner{}
6467
// Create a database pre-initialize with a genesis block
6568
db := rawdb.NewMemoryDatabase()
69+
db.SetDiffStore(memorydb.New())
6670
(&Genesis{
6771
Config: params.TestChainConfig,
6872
Alloc: GenesisAlloc{testAddr: {Balance: big.NewInt(100000000000000000)}},
@@ -103,36 +107,157 @@ func (b *testBackend) close() {
103107

104108
func (b *testBackend) Chain() *BlockChain { return b.chain }
105109

106-
func TestHandleDiffLayer(t *testing.T) {
110+
func rawDataToDiffLayer(data rlp.RawValue) (*types.DiffLayer, error) {
111+
var diff types.DiffLayer
112+
hasher := sha3.NewLegacyKeccak256()
113+
err := rlp.DecodeBytes(data, &diff)
114+
if err != nil {
115+
return nil, err
116+
}
117+
hasher.Write(data)
118+
var diffHash common.Hash
119+
hasher.Sum(diffHash[:0])
120+
hasher.Reset()
121+
diff.DiffHash = diffHash
122+
return &diff, nil
123+
}
124+
125+
func TestProcessDiffLayer(t *testing.T) {
107126
t.Parallel()
108127

109128
blockNum := maxDiffLimit - 1
110129
fullBackend := newTestBackend(blockNum, false)
130+
falseDiff := 5
111131
defer fullBackend.close()
112132

113133
lightBackend := newTestBackend(0, true)
114-
for i := 1; i <= blockNum; i++ {
134+
defer lightBackend.close()
135+
for i := 1; i <= blockNum-falseDiff; i++ {
115136
block := fullBackend.chain.GetBlockByNumber(uint64(i))
116137
if block == nil {
117138
t.Fatal("block should not be nil")
118139
}
119140
blockHash := block.Hash()
120141
rawDiff := fullBackend.chain.GetDiffLayerRLP(blockHash)
121-
var diff types.DiffLayer
122-
hasher := sha3.NewLegacyKeccak256()
123-
err := rlp.DecodeBytes(rawDiff, &diff)
142+
diff, err := rawDataToDiffLayer(rawDiff)
124143
if err != nil {
125-
t.Fatal("decode raw data failed")
144+
t.Errorf("failed to decode rawdata %v", err)
126145
}
127-
hasher.Write(rawDiff)
128-
var diffHash common.Hash
129-
hasher.Sum(diffHash[:0])
130-
hasher.Reset()
131-
diff.DiffHash = diffHash
132-
lightBackend.Chain().HandleDiffLayer(&diff, "testpid")
146+
lightBackend.Chain().HandleDiffLayer(diff, "testpid")
133147
_, err = lightBackend.chain.insertChain([]*types.Block{block}, true)
134148
if err != nil {
135149
t.Errorf("failed to insert block %v", err)
136150
}
137151
}
152+
currentBlock := lightBackend.chain.CurrentBlock()
153+
nextBlock := fullBackend.chain.GetBlockByNumber(currentBlock.NumberU64() + 1)
154+
rawDiff := fullBackend.chain.GetDiffLayerRLP(nextBlock.Hash())
155+
diff, _ := rawDataToDiffLayer(rawDiff)
156+
latestAccount, _ := snapshot.FullAccount(diff.Accounts[0].Blob)
157+
latestAccount.Balance = big.NewInt(0)
158+
bz, _ := rlp.EncodeToBytes(&latestAccount)
159+
diff.Accounts[0].Blob = bz
160+
161+
lightBackend.Chain().HandleDiffLayer(diff, "testpid")
162+
163+
_, err := lightBackend.chain.insertChain([]*types.Block{nextBlock}, true)
164+
if err != nil {
165+
t.Errorf("failed to process block %v", err)
166+
}
167+
168+
// the diff cache should be cleared
169+
if len(lightBackend.chain.diffPeersToDiffHashes) != 0 {
170+
t.Errorf("the size of diffPeersToDiffHashes should be 0, but get %d", len(lightBackend.chain.diffPeersToDiffHashes))
171+
}
172+
if len(lightBackend.chain.diffHashToPeers) != 0 {
173+
t.Errorf("the size of diffHashToPeers should be 0, but get %d", len(lightBackend.chain.diffHashToPeers))
174+
}
175+
if len(lightBackend.chain.diffHashToBlockHash) != 0 {
176+
t.Errorf("the size of diffHashToBlockHash should be 0, but get %d", len(lightBackend.chain.diffHashToBlockHash))
177+
}
178+
if len(lightBackend.chain.blockHashToDiffLayers) != 0 {
179+
t.Errorf("the size of blockHashToDiffLayers should be 0, but get %d", len(lightBackend.chain.blockHashToDiffLayers))
180+
}
181+
}
182+
183+
func TestFreezeDiffLayer(t *testing.T) {
184+
t.Parallel()
185+
186+
blockNum := 1024
187+
fullBackend := newTestBackend(blockNum, true)
188+
defer fullBackend.close()
189+
if fullBackend.chain.diffQueue.Size() != blockNum {
190+
t.Errorf("size of diff queue is wrong, expected: %d, get: %d", blockNum, fullBackend.chain.diffQueue.Size())
191+
}
192+
time.Sleep(diffLayerFreezerRecheckInterval + 1*time.Second)
193+
if fullBackend.chain.diffQueue.Size() != int(fullBackend.chain.triesInMemory) {
194+
t.Errorf("size of diff queue is wrong, expected: %d, get: %d", blockNum, fullBackend.chain.diffQueue.Size())
195+
}
196+
197+
block := fullBackend.chain.GetBlockByNumber(uint64(blockNum / 2))
198+
diffStore := fullBackend.chain.db.DiffStore()
199+
rawData := rawdb.ReadDiffLayerRLP(diffStore, block.Hash())
200+
if len(rawData) == 0 {
201+
t.Error("do not find diff layer in db")
202+
}
203+
}
204+
205+
func TestPruneDiffLayer(t *testing.T) {
206+
t.Parallel()
207+
208+
blockNum := 1024
209+
fullBackend := newTestBackend(blockNum, true)
210+
defer fullBackend.close()
211+
212+
anotherFullBackend := newTestBackend(2*blockNum, true)
213+
defer anotherFullBackend.close()
214+
215+
for num := uint64(1); num < uint64(blockNum); num++ {
216+
header := fullBackend.chain.GetHeaderByNumber(num)
217+
rawDiff := fullBackend.chain.GetDiffLayerRLP(header.Hash())
218+
diff, _ := rawDataToDiffLayer(rawDiff)
219+
fullBackend.Chain().HandleDiffLayer(diff, "testpid1")
220+
fullBackend.Chain().HandleDiffLayer(diff, "testpid2")
221+
222+
}
223+
fullBackend.chain.pruneDiffLayer()
224+
if len(fullBackend.chain.diffNumToBlockHashes) != maxDiffForkDist {
225+
t.Error("unexpected size of diffNumToBlockHashes")
226+
}
227+
if len(fullBackend.chain.diffPeersToDiffHashes) != 2 {
228+
t.Error("unexpected size of diffPeersToDiffHashes")
229+
}
230+
if len(fullBackend.chain.blockHashToDiffLayers) != maxDiffForkDist {
231+
t.Error("unexpected size of diffNumToBlockHashes")
232+
}
233+
if len(fullBackend.chain.diffHashToBlockHash) != maxDiffForkDist {
234+
t.Error("unexpected size of diffHashToBlockHash")
235+
}
236+
if len(fullBackend.chain.diffHashToPeers) != maxDiffForkDist {
237+
t.Error("unexpected size of diffHashToPeers")
238+
}
239+
240+
blocks := make([]*types.Block, 0, blockNum)
241+
for i := blockNum + 1; i <= 2*blockNum; i++ {
242+
b := anotherFullBackend.chain.GetBlockByNumber(uint64(i))
243+
blocks = append(blocks, b)
244+
}
245+
fullBackend.chain.insertChain(blocks, true)
246+
fullBackend.chain.pruneDiffLayer()
247+
if len(fullBackend.chain.diffNumToBlockHashes) != 0 {
248+
t.Error("unexpected size of diffNumToBlockHashes")
249+
}
250+
if len(fullBackend.chain.diffPeersToDiffHashes) != 0 {
251+
t.Error("unexpected size of diffPeersToDiffHashes")
252+
}
253+
if len(fullBackend.chain.blockHashToDiffLayers) != 0 {
254+
t.Error("unexpected size of diffNumToBlockHashes")
255+
}
256+
if len(fullBackend.chain.diffHashToBlockHash) != 0 {
257+
t.Error("unexpected size of diffHashToBlockHash")
258+
}
259+
if len(fullBackend.chain.diffHashToPeers) != 0 {
260+
t.Error("unexpected size of diffHashToPeers")
261+
}
262+
138263
}

core/rawdb/database.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ func (frdb *freezerdb) Freeze(threshold uint64) error {
9494
// nofreezedb is a database wrapper that disables freezer data retrievals.
9595
type nofreezedb struct {
9696
ethdb.KeyValueStore
97+
diffStore ethdb.KeyValueStore
9798
}
9899

99100
// HasAncient returns an error as we don't have a backing chain freezer.
@@ -132,11 +133,11 @@ func (db *nofreezedb) Sync() error {
132133
}
133134

134135
func (db *nofreezedb) DiffStore() ethdb.KeyValueStore {
135-
return nil
136+
return db.diffStore
136137
}
137138

138139
func (db *nofreezedb) SetDiffStore(diff ethdb.KeyValueStore) {
139-
panic("not implement")
140+
db.diffStore = diff
140141
}
141142

142143
// NewDatabase creates a high level database on top of a given key-value data

core/state_processor.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ func (p *LightStateProcessor) Process(block *types.Block, statedb *state.StateDB
8989
}
9090
receipts, logs, gasUsed, err := p.LightProcess(diffLayer, block, statedb, cfg)
9191
if err == nil {
92+
log.Error("do light process success at block %d\n", block.NumberU64())
9293
return statedb, receipts, logs, gasUsed, nil
9394
} else {
94-
log.Error("do light sync err %d, %v\n", block.NumberU64(), err)
95+
log.Error("do light process err %d, %v\n", block.NumberU64(), err)
9596
p.bc.removeDiffLayers(diffLayer.DiffHash)
9697
// prepare new statedb
9798
statedb.StopPrefetcher()

0 commit comments

Comments
 (0)