@@ -488,7 +488,22 @@ func (bc *BlockChain) cacheReceipts(hash common.Hash, receipts types.Receipts) {
488
488
bc .receiptsCache .Add (hash , receipts )
489
489
}
490
490
491
- func (bc * BlockChain ) cacheDiffLayer (diffLayer * types.DiffLayer ) {
491
+ func (bc * BlockChain ) cacheDiffLayer (diffLayer * types.DiffLayer , sorted bool ) {
492
+ if ! sorted {
493
+ sort .SliceStable (diffLayer .Codes , func (i , j int ) bool {
494
+ return diffLayer .Codes [i ].Hash .Hex () < diffLayer .Codes [j ].Hash .Hex ()
495
+ })
496
+ sort .SliceStable (diffLayer .Destructs , func (i , j int ) bool {
497
+ return diffLayer .Destructs [i ].Hex () < (diffLayer .Destructs [j ].Hex ())
498
+ })
499
+ sort .SliceStable (diffLayer .Accounts , func (i , j int ) bool {
500
+ return diffLayer .Accounts [i ].Account .Hex () < diffLayer .Accounts [j ].Account .Hex ()
501
+ })
502
+ sort .SliceStable (diffLayer .Storages , func (i , j int ) bool {
503
+ return diffLayer .Storages [i ].Account .Hex () < diffLayer .Storages [j ].Account .Hex ()
504
+ })
505
+ }
506
+
492
507
if bc .diffLayerCache .Len () >= diffLayerCacheLimit {
493
508
bc .diffLayerCache .RemoveOldest ()
494
509
}
@@ -1690,12 +1705,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
1690
1705
diffLayer .BlockHash = block .Hash ()
1691
1706
diffLayer .Number = block .NumberU64 ()
1692
1707
1693
- sort .Sort (types .DiffCodeSlice (diffLayer .Codes ))
1694
- sort .Sort (common .AddressSlice (diffLayer .Destructs ))
1695
- sort .Sort (types .DiffAccountSlice (diffLayer .Accounts ))
1696
- sort .Sort (types .DiffStorageSlice (diffLayer .Storages ))
1697
-
1698
- bc .cacheDiffLayer (diffLayer )
1708
+ go bc .cacheDiffLayer (diffLayer , false )
1699
1709
}
1700
1710
triedb := bc .stateCache .TrieDB ()
1701
1711
@@ -2730,9 +2740,14 @@ func (bc *BlockChain) HandleDiffLayer(diffLayer *types.DiffLayer, pid string, fu
2730
2740
return nil
2731
2741
}
2732
2742
2743
+ diffHash := common.Hash {}
2744
+ if diffLayer .DiffHash .Load () != nil {
2745
+ diffHash = diffLayer .DiffHash .Load ().(common.Hash )
2746
+ }
2747
+
2733
2748
bc .diffMux .Lock ()
2734
2749
defer bc .diffMux .Unlock ()
2735
- if blockHash , exist := bc .diffHashToBlockHash [diffLayer . DiffHash ]; exist && blockHash == diffLayer .BlockHash {
2750
+ if blockHash , exist := bc .diffHashToBlockHash [diffHash ]; exist && blockHash == diffLayer .BlockHash {
2736
2751
return nil
2737
2752
}
2738
2753
@@ -2746,28 +2761,28 @@ func (bc *BlockChain) HandleDiffLayer(diffLayer *types.DiffLayer, pid string, fu
2746
2761
return nil
2747
2762
}
2748
2763
if _ , exist := bc .diffPeersToDiffHashes [pid ]; exist {
2749
- if _ , alreadyHas := bc.diffPeersToDiffHashes [pid ][diffLayer. DiffHash ]; alreadyHas {
2764
+ if _ , alreadyHas := bc.diffPeersToDiffHashes [pid ][diffHash ]; alreadyHas {
2750
2765
return nil
2751
2766
}
2752
2767
} else {
2753
2768
bc .diffPeersToDiffHashes [pid ] = make (map [common.Hash ]struct {})
2754
2769
}
2755
- bc.diffPeersToDiffHashes [pid ][diffLayer. DiffHash ] = struct {}{}
2770
+ bc.diffPeersToDiffHashes [pid ][diffHash ] = struct {}{}
2756
2771
if _ , exist := bc .diffNumToBlockHashes [diffLayer .Number ]; ! exist {
2757
2772
bc .diffNumToBlockHashes [diffLayer .Number ] = make (map [common.Hash ]struct {})
2758
2773
}
2759
2774
bc.diffNumToBlockHashes [diffLayer.Number ][diffLayer.BlockHash ] = struct {}{}
2760
2775
2761
- if _ , exist := bc .diffHashToPeers [diffLayer . DiffHash ]; ! exist {
2762
- bc .diffHashToPeers [diffLayer . DiffHash ] = make (map [string ]struct {})
2776
+ if _ , exist := bc .diffHashToPeers [diffHash ]; ! exist {
2777
+ bc .diffHashToPeers [diffHash ] = make (map [string ]struct {})
2763
2778
}
2764
- bc.diffHashToPeers [diffLayer. DiffHash ][pid ] = struct {}{}
2779
+ bc.diffHashToPeers [diffHash ][pid ] = struct {}{}
2765
2780
2766
2781
if _ , exist := bc .blockHashToDiffLayers [diffLayer .BlockHash ]; ! exist {
2767
2782
bc .blockHashToDiffLayers [diffLayer .BlockHash ] = make (map [common.Hash ]* types.DiffLayer )
2768
2783
}
2769
- bc.blockHashToDiffLayers [diffLayer.BlockHash ][diffLayer. DiffHash ] = diffLayer
2770
- bc .diffHashToBlockHash [diffLayer . DiffHash ] = diffLayer .BlockHash
2784
+ bc.blockHashToDiffLayers [diffLayer.BlockHash ][diffHash ] = diffLayer
2785
+ bc .diffHashToBlockHash [diffHash ] = diffLayer .BlockHash
2771
2786
2772
2787
return nil
2773
2788
}
@@ -3035,60 +3050,55 @@ func EnablePersistDiff(limit uint64) BlockChainOption {
3035
3050
}
3036
3051
}
3037
3052
3038
- func (bc * BlockChain ) GetRootByDiffHash (blockNumber uint64 , blockHash common.Hash , diffHash common.Hash ) ( * types.VerifyResult , error ) {
3053
+ func (bc * BlockChain ) GetRootByDiffHash (blockNumber uint64 , blockHash common.Hash , diffHash common.Hash ) * types.VerifyResult {
3039
3054
var res types.VerifyResult
3040
3055
res .BlockNumber = blockNumber
3041
3056
res .BlockHash = blockHash
3042
3057
3043
- if blockNumber > bc .CurrentHeader ().Number .Uint64 ()+ 11 {
3058
+ if blockNumber > bc .CurrentHeader ().Number .Uint64 ()+ maxDiffForkDist {
3044
3059
res .Status = types .StatusBlockTooNew
3045
- return & res , nil
3060
+ return & res
3046
3061
} else if blockNumber > bc .CurrentHeader ().Number .Uint64 () {
3047
3062
res .Status = types .StatusBlockNewer
3048
- return & res , nil
3063
+ return & res
3064
+ }
3065
+
3066
+ header := bc .GetHeaderByHash (blockHash )
3067
+ if header == nil {
3068
+ if blockNumber > bc .CurrentHeader ().Number .Uint64 ()- maxDiffForkDist {
3069
+ res .Status = types .StatusPossibleFork
3070
+ return & res
3071
+ }
3072
+
3073
+ res .Status = types .StatusImpossibleFork
3074
+ return & res
3049
3075
}
3050
3076
3051
3077
diff := bc .GetTrustedDiffLayer (blockHash )
3052
3078
if diff != nil {
3053
- if diff .DiffHash == (common. Hash {}) {
3054
- hash , err := GetTrustedDiffHash (diff )
3079
+ if diff .DiffHash . Load () == nil {
3080
+ hash , err := CalculateDiffHash (diff )
3055
3081
if err != nil {
3056
3082
res .Status = types .StatusUnexpectedError
3057
- return & res , err
3083
+ return & res
3058
3084
}
3059
3085
3060
- diff .DiffHash = hash
3086
+ diff .DiffHash . Store ( hash )
3061
3087
}
3062
3088
3063
- if diffHash != diff .DiffHash {
3089
+ if diffHash != diff .DiffHash . Load ().(common. Hash ) {
3064
3090
res .Status = types .StatusDiffHashMismatch
3065
- return & res , nil
3091
+ return & res
3066
3092
}
3067
3093
3068
- header := bc .GetHeaderByHash (blockHash )
3069
- if header == nil {
3070
- res .Status = types .StatusUnexpectedError
3071
- return & res , fmt .Errorf ("unexpected error, header not found" )
3072
- }
3073
3094
res .Status = types .StatusFullVerified
3074
3095
res .Root = header .Root
3075
- return & res , nil
3076
- }
3077
-
3078
- header := bc .GetHeaderByHash (blockHash )
3079
- if header == nil {
3080
- if blockNumber > bc .CurrentHeader ().Number .Uint64 ()- 11 {
3081
- res .Status = types .StatusPossibleFork
3082
- return & res , nil
3083
- }
3084
-
3085
- res .Status = types .StatusImpossibleFork
3086
- return & res , nil
3096
+ return & res
3087
3097
}
3088
3098
3089
- res .Status = types .StatusUntrustedVerified
3099
+ res .Status = types .StatusPartiallyVerified
3090
3100
res .Root = header .Root
3091
- return & res , nil
3101
+ return & res
3092
3102
}
3093
3103
3094
3104
func (bc * BlockChain ) GetTrustedDiffLayer (blockHash common.Hash ) * types.DiffLayer {
@@ -3160,12 +3170,18 @@ func (bc *BlockChain) GenerateDiffLayer(blockHash common.Hash) (*types.DiffLayer
3160
3170
if diffLayer != nil {
3161
3171
diffLayer .BlockHash = blockHash
3162
3172
diffLayer .Number = block .NumberU64 ()
3173
+
3174
+ bc .cacheDiffLayer (diffLayer , true )
3163
3175
}
3164
3176
3165
3177
return diffLayer , nil
3166
3178
}
3167
3179
3168
- func GetTrustedDiffHash (d * types.DiffLayer ) (common.Hash , error ) {
3180
+ func CalculateDiffHash (d * types.DiffLayer ) (common.Hash , error ) {
3181
+ if d == nil {
3182
+ return common.Hash {}, fmt .Errorf ("nil diff layer" )
3183
+ }
3184
+
3169
3185
diff := & types.ExtDiffLayer {
3170
3186
BlockHash : d .BlockHash ,
3171
3187
Receipts : make ([]* types.ReceiptForStorage , 0 ),
0 commit comments