@@ -501,7 +501,22 @@ func (bc *BlockChain) cacheReceipts(hash common.Hash, receipts types.Receipts) {
501
501
bc .receiptsCache .Add (hash , receipts )
502
502
}
503
503
504
- func (bc * BlockChain ) cacheDiffLayer (diffLayer * types.DiffLayer ) {
504
+ func (bc * BlockChain ) cacheDiffLayer (diffLayer * types.DiffLayer , sorted bool ) {
505
+ if ! sorted {
506
+ sort .SliceStable (diffLayer .Codes , func (i , j int ) bool {
507
+ return diffLayer .Codes [i ].Hash .Hex () < diffLayer .Codes [j ].Hash .Hex ()
508
+ })
509
+ sort .SliceStable (diffLayer .Destructs , func (i , j int ) bool {
510
+ return diffLayer .Destructs [i ].Hex () < (diffLayer .Destructs [j ].Hex ())
511
+ })
512
+ sort .SliceStable (diffLayer .Accounts , func (i , j int ) bool {
513
+ return diffLayer .Accounts [i ].Account .Hex () < diffLayer .Accounts [j ].Account .Hex ()
514
+ })
515
+ sort .SliceStable (diffLayer .Storages , func (i , j int ) bool {
516
+ return diffLayer .Storages [i ].Account .Hex () < diffLayer .Storages [j ].Account .Hex ()
517
+ })
518
+ }
519
+
505
520
if bc .diffLayerCache .Len () >= diffLayerCacheLimit {
506
521
bc .diffLayerCache .RemoveOldest ()
507
522
}
@@ -1801,12 +1816,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
1801
1816
diffLayer .BlockHash = block .Hash ()
1802
1817
diffLayer .Number = block .NumberU64 ()
1803
1818
1804
- sort .Sort (types .DiffCodeSlice (diffLayer .Codes ))
1805
- sort .Sort (common .AddressSlice (diffLayer .Destructs ))
1806
- sort .Sort (types .DiffAccountSlice (diffLayer .Accounts ))
1807
- sort .Sort (types .DiffStorageSlice (diffLayer .Storages ))
1808
-
1809
- bc .cacheDiffLayer (diffLayer )
1819
+ go bc .cacheDiffLayer (diffLayer , false )
1810
1820
}
1811
1821
1812
1822
wg .Wait ()
@@ -2798,9 +2808,14 @@ func (bc *BlockChain) HandleDiffLayer(diffLayer *types.DiffLayer, pid string, fu
2798
2808
return nil
2799
2809
}
2800
2810
2811
+ diffHash := common.Hash {}
2812
+ if diffLayer .DiffHash .Load () != nil {
2813
+ diffHash = diffLayer .DiffHash .Load ().(common.Hash )
2814
+ }
2815
+
2801
2816
bc .diffMux .Lock ()
2802
2817
defer bc .diffMux .Unlock ()
2803
- if blockHash , exist := bc .diffHashToBlockHash [diffLayer . DiffHash ]; exist && blockHash == diffLayer .BlockHash {
2818
+ if blockHash , exist := bc .diffHashToBlockHash [diffHash ]; exist && blockHash == diffLayer .BlockHash {
2804
2819
return nil
2805
2820
}
2806
2821
@@ -2814,28 +2829,28 @@ func (bc *BlockChain) HandleDiffLayer(diffLayer *types.DiffLayer, pid string, fu
2814
2829
return nil
2815
2830
}
2816
2831
if _ , exist := bc .diffPeersToDiffHashes [pid ]; exist {
2817
- if _ , alreadyHas := bc.diffPeersToDiffHashes [pid ][diffLayer. DiffHash ]; alreadyHas {
2832
+ if _ , alreadyHas := bc.diffPeersToDiffHashes [pid ][diffHash ]; alreadyHas {
2818
2833
return nil
2819
2834
}
2820
2835
} else {
2821
2836
bc .diffPeersToDiffHashes [pid ] = make (map [common.Hash ]struct {})
2822
2837
}
2823
- bc.diffPeersToDiffHashes [pid ][diffLayer. DiffHash ] = struct {}{}
2838
+ bc.diffPeersToDiffHashes [pid ][diffHash ] = struct {}{}
2824
2839
if _ , exist := bc .diffNumToBlockHashes [diffLayer .Number ]; ! exist {
2825
2840
bc .diffNumToBlockHashes [diffLayer .Number ] = make (map [common.Hash ]struct {})
2826
2841
}
2827
2842
bc.diffNumToBlockHashes [diffLayer.Number ][diffLayer.BlockHash ] = struct {}{}
2828
2843
2829
- if _ , exist := bc .diffHashToPeers [diffLayer . DiffHash ]; ! exist {
2830
- bc .diffHashToPeers [diffLayer . DiffHash ] = make (map [string ]struct {})
2844
+ if _ , exist := bc .diffHashToPeers [diffHash ]; ! exist {
2845
+ bc .diffHashToPeers [diffHash ] = make (map [string ]struct {})
2831
2846
}
2832
- bc.diffHashToPeers [diffLayer. DiffHash ][pid ] = struct {}{}
2847
+ bc.diffHashToPeers [diffHash ][pid ] = struct {}{}
2833
2848
2834
2849
if _ , exist := bc .blockHashToDiffLayers [diffLayer .BlockHash ]; ! exist {
2835
2850
bc .blockHashToDiffLayers [diffLayer .BlockHash ] = make (map [common.Hash ]* types.DiffLayer )
2836
2851
}
2837
- bc.blockHashToDiffLayers [diffLayer.BlockHash ][diffLayer. DiffHash ] = diffLayer
2838
- bc .diffHashToBlockHash [diffLayer . DiffHash ] = diffLayer .BlockHash
2852
+ bc.blockHashToDiffLayers [diffLayer.BlockHash ][diffHash ] = diffLayer
2853
+ bc .diffHashToBlockHash [diffHash ] = diffLayer .BlockHash
2839
2854
2840
2855
return nil
2841
2856
}
@@ -3120,60 +3135,55 @@ func EnablePersistDiff(limit uint64) BlockChainOption {
3120
3135
}
3121
3136
}
3122
3137
3123
- func (bc * BlockChain ) GetRootByDiffHash (blockNumber uint64 , blockHash common.Hash , diffHash common.Hash ) ( * types.VerifyResult , error ) {
3138
+ func (bc * BlockChain ) GetRootByDiffHash (blockNumber uint64 , blockHash common.Hash , diffHash common.Hash ) * types.VerifyResult {
3124
3139
var res types.VerifyResult
3125
3140
res .BlockNumber = blockNumber
3126
3141
res .BlockHash = blockHash
3127
3142
3128
- if blockNumber > bc .CurrentHeader ().Number .Uint64 ()+ 11 {
3143
+ if blockNumber > bc .CurrentHeader ().Number .Uint64 ()+ maxDiffForkDist {
3129
3144
res .Status = types .StatusBlockTooNew
3130
- return & res , nil
3145
+ return & res
3131
3146
} else if blockNumber > bc .CurrentHeader ().Number .Uint64 () {
3132
3147
res .Status = types .StatusBlockNewer
3133
- return & res , nil
3148
+ return & res
3149
+ }
3150
+
3151
+ header := bc .GetHeaderByHash (blockHash )
3152
+ if header == nil {
3153
+ if blockNumber > bc .CurrentHeader ().Number .Uint64 ()- maxDiffForkDist {
3154
+ res .Status = types .StatusPossibleFork
3155
+ return & res
3156
+ }
3157
+
3158
+ res .Status = types .StatusImpossibleFork
3159
+ return & res
3134
3160
}
3135
3161
3136
3162
diff := bc .GetTrustedDiffLayer (blockHash )
3137
3163
if diff != nil {
3138
- if diff .DiffHash == (common. Hash {}) {
3139
- hash , err := GetTrustedDiffHash (diff )
3164
+ if diff .DiffHash . Load () == nil {
3165
+ hash , err := CalculateDiffHash (diff )
3140
3166
if err != nil {
3141
3167
res .Status = types .StatusUnexpectedError
3142
- return & res , err
3168
+ return & res
3143
3169
}
3144
3170
3145
- diff .DiffHash = hash
3171
+ diff .DiffHash . Store ( hash )
3146
3172
}
3147
3173
3148
- if diffHash != diff .DiffHash {
3174
+ if diffHash != diff .DiffHash . Load ().(common. Hash ) {
3149
3175
res .Status = types .StatusDiffHashMismatch
3150
- return & res , nil
3176
+ return & res
3151
3177
}
3152
3178
3153
- header := bc .GetHeaderByHash (blockHash )
3154
- if header == nil {
3155
- res .Status = types .StatusUnexpectedError
3156
- return & res , fmt .Errorf ("unexpected error, header not found" )
3157
- }
3158
3179
res .Status = types .StatusFullVerified
3159
3180
res .Root = header .Root
3160
- return & res , nil
3161
- }
3162
-
3163
- header := bc .GetHeaderByHash (blockHash )
3164
- if header == nil {
3165
- if blockNumber > bc .CurrentHeader ().Number .Uint64 ()- 11 {
3166
- res .Status = types .StatusPossibleFork
3167
- return & res , nil
3168
- }
3169
-
3170
- res .Status = types .StatusImpossibleFork
3171
- return & res , nil
3181
+ return & res
3172
3182
}
3173
3183
3174
- res .Status = types .StatusUntrustedVerified
3184
+ res .Status = types .StatusPartiallyVerified
3175
3185
res .Root = header .Root
3176
- return & res , nil
3186
+ return & res
3177
3187
}
3178
3188
3179
3189
func (bc * BlockChain ) GetTrustedDiffLayer (blockHash common.Hash ) * types.DiffLayer {
@@ -3245,12 +3255,18 @@ func (bc *BlockChain) GenerateDiffLayer(blockHash common.Hash) (*types.DiffLayer
3245
3255
if diffLayer != nil {
3246
3256
diffLayer .BlockHash = blockHash
3247
3257
diffLayer .Number = block .NumberU64 ()
3258
+
3259
+ bc .cacheDiffLayer (diffLayer , true )
3248
3260
}
3249
3261
3250
3262
return diffLayer , nil
3251
3263
}
3252
3264
3253
- func GetTrustedDiffHash (d * types.DiffLayer ) (common.Hash , error ) {
3265
+ func CalculateDiffHash (d * types.DiffLayer ) (common.Hash , error ) {
3266
+ if d == nil {
3267
+ return common.Hash {}, fmt .Errorf ("nil diff layer" )
3268
+ }
3269
+
3254
3270
diff := & types.ExtDiffLayer {
3255
3271
BlockHash : d .BlockHash ,
3256
3272
Receipts : make ([]* types.ReceiptForStorage , 0 ),
0 commit comments