@@ -18,6 +18,7 @@ package core
18
18
19
19
import (
20
20
"fmt"
21
+ "time"
21
22
22
23
"github.com/ethereum/go-ethereum/consensus"
23
24
"github.com/ethereum/go-ethereum/core/state"
@@ -26,6 +27,8 @@ import (
26
27
"github.com/ethereum/go-ethereum/trie"
27
28
)
28
29
30
+ const badBlockCacheExpire = 30 * time .Second
31
+
29
32
// BlockValidator is responsible for validating block headers, uncles and
30
33
// processed state.
31
34
//
@@ -54,6 +57,9 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
54
57
if v .bc .HasBlockAndState (block .Hash (), block .NumberU64 ()) {
55
58
return ErrKnownBlock
56
59
}
60
+ if v .bc .isCachedBadBlock (block ) {
61
+ return ErrKnownBadBlock
62
+ }
57
63
// Header validity is known at this point, check the uncles and transactions
58
64
header := block .Header ()
59
65
if err := v .engine .VerifyUncles (v .bc , block ); err != nil {
@@ -106,7 +112,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
106
112
// transition, such as amount of used gas, the receipt roots and the state root
107
113
// itself. ValidateState returns a database batch if the validation was a success
108
114
// otherwise nil and an error is returned.
109
- func (v * BlockValidator ) ValidateState (block * types.Block , statedb * state.StateDB , receipts types.Receipts , usedGas uint64 ) error {
115
+ func (v * BlockValidator ) ValidateState (block * types.Block , statedb * state.StateDB , receipts types.Receipts , usedGas uint64 , skipHeavyVerify bool ) error {
110
116
header := block .Header ()
111
117
if block .GasUsed () != usedGas {
112
118
return fmt .Errorf ("invalid gas used (remote: %d local: %d)" , block .GasUsed (), usedGas )
@@ -125,17 +131,26 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
125
131
receiptSha := types .DeriveSha (receipts , trie .NewStackTrie (nil ))
126
132
if receiptSha != header .ReceiptHash {
127
133
return fmt .Errorf ("invalid receipt root hash (remote: %x local: %x)" , header .ReceiptHash , receiptSha )
128
- } else {
129
- return nil
130
134
}
135
+ return nil
131
136
},
132
- func () error {
137
+ }
138
+ if skipHeavyVerify {
139
+ validateFuns = append (validateFuns , func () error {
140
+ if err := statedb .WaitPipeVerification (); err != nil {
141
+ return err
142
+ }
143
+ statedb .Finalise (v .config .IsEIP158 (header .Number ))
144
+ statedb .AccountsIntermediateRoot ()
145
+ return nil
146
+ })
147
+ } else {
148
+ validateFuns = append (validateFuns , func () error {
133
149
if root := statedb .IntermediateRoot (v .config .IsEIP158 (header .Number )); header .Root != root {
134
150
return fmt .Errorf ("invalid merkle root (remote: %x local: %x)" , header .Root , root )
135
- } else {
136
- return nil
137
151
}
138
- },
152
+ return nil
153
+ })
139
154
}
140
155
validateRes := make (chan error , len (validateFuns ))
141
156
for _ , f := range validateFuns {
0 commit comments