@@ -23,16 +23,19 @@ package core
23
23
import (
24
24
"math/big"
25
25
"testing"
26
+ "time"
26
27
27
28
"golang.org/x/crypto/sha3"
28
29
29
30
"github.com/ethereum/go-ethereum/common"
30
31
"github.com/ethereum/go-ethereum/consensus/ethash"
31
32
"github.com/ethereum/go-ethereum/core/rawdb"
33
+ "github.com/ethereum/go-ethereum/core/state/snapshot"
32
34
"github.com/ethereum/go-ethereum/core/types"
33
35
"github.com/ethereum/go-ethereum/core/vm"
34
36
"github.com/ethereum/go-ethereum/crypto"
35
37
"github.com/ethereum/go-ethereum/ethdb"
38
+ "github.com/ethereum/go-ethereum/ethdb/memorydb"
36
39
"github.com/ethereum/go-ethereum/params"
37
40
"github.com/ethereum/go-ethereum/rlp"
38
41
)
@@ -63,6 +66,7 @@ func newTestBackendWithGenerator(blocks int, lightProcess bool) *testBackend {
63
66
signer := types.HomesteadSigner {}
64
67
// Create a database pre-initialize with a genesis block
65
68
db := rawdb .NewMemoryDatabase ()
69
+ db .SetDiffStore (memorydb .New ())
66
70
(& Genesis {
67
71
Config : params .TestChainConfig ,
68
72
Alloc : GenesisAlloc {testAddr : {Balance : big .NewInt (100000000000000000 )}},
@@ -103,36 +107,157 @@ func (b *testBackend) close() {
103
107
104
108
func (b * testBackend ) Chain () * BlockChain { return b .chain }
105
109
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 ) {
107
126
t .Parallel ()
108
127
109
128
blockNum := maxDiffLimit - 1
110
129
fullBackend := newTestBackend (blockNum , false )
130
+ falseDiff := 5
111
131
defer fullBackend .close ()
112
132
113
133
lightBackend := newTestBackend (0 , true )
114
- for i := 1 ; i <= blockNum ; i ++ {
134
+ defer lightBackend .close ()
135
+ for i := 1 ; i <= blockNum - falseDiff ; i ++ {
115
136
block := fullBackend .chain .GetBlockByNumber (uint64 (i ))
116
137
if block == nil {
117
138
t .Fatal ("block should not be nil" )
118
139
}
119
140
blockHash := block .Hash ()
120
141
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 )
124
143
if err != nil {
125
- t .Fatal ( "decode raw data failed" )
144
+ t .Errorf ( "failed to decode rawdata %v" , err )
126
145
}
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" )
133
147
_ , err = lightBackend .chain .insertChain ([]* types.Block {block }, true )
134
148
if err != nil {
135
149
t .Errorf ("failed to insert block %v" , err )
136
150
}
137
151
}
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
+
138
263
}
0 commit comments