@@ -31,7 +31,6 @@ import (
31
31
"github.com/ethereum/go-ethereum/common/mclock"
32
32
"github.com/ethereum/go-ethereum/common/prque"
33
33
"github.com/ethereum/go-ethereum/consensus"
34
- "github.com/ethereum/go-ethereum/consensus/clique"
35
34
"github.com/ethereum/go-ethereum/core/rawdb"
36
35
"github.com/ethereum/go-ethereum/core/state"
37
36
"github.com/ethereum/go-ethereum/core/types"
@@ -129,14 +128,14 @@ type BlockChain struct {
129
128
validator Validator // block and state validator interface
130
129
vmConfig vm.Config
131
130
132
- badBlocks * lru.Cache // Bad block cache
133
- isLocalFn func (common. Address ) bool // Function used to determine whether the block author is a local miner account .
131
+ badBlocks * lru.Cache // Bad block cache
132
+ shouldPreserve func (* types. Block ) bool // Function used to determine whether should preserve the given block .
134
133
}
135
134
136
135
// NewBlockChain returns a fully initialised block chain using information
137
136
// available in the database. It initialises the default Ethereum Validator and
138
137
// Processor.
139
- func NewBlockChain (db ethdb.Database , cacheConfig * CacheConfig , chainConfig * params.ChainConfig , engine consensus.Engine , vmConfig vm.Config , isLocalFn func (common. Address ) bool ) (* BlockChain , error ) {
138
+ func NewBlockChain (db ethdb.Database , cacheConfig * CacheConfig , chainConfig * params.ChainConfig , engine consensus.Engine , vmConfig vm.Config , shouldPreserve func (block * types. Block ) bool ) (* BlockChain , error ) {
140
139
if cacheConfig == nil {
141
140
cacheConfig = & CacheConfig {
142
141
TrieNodeLimit : 256 * 1024 * 1024 ,
@@ -150,20 +149,20 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
150
149
badBlocks , _ := lru .New (badBlockLimit )
151
150
152
151
bc := & BlockChain {
153
- chainConfig : chainConfig ,
154
- cacheConfig : cacheConfig ,
155
- db : db ,
156
- triegc : prque .New (nil ),
157
- stateCache : state .NewDatabase (db ),
158
- quit : make (chan struct {}),
159
- isLocalFn : isLocalFn ,
160
- bodyCache : bodyCache ,
161
- bodyRLPCache : bodyRLPCache ,
162
- blockCache : blockCache ,
163
- futureBlocks : futureBlocks ,
164
- engine : engine ,
165
- vmConfig : vmConfig ,
166
- badBlocks : badBlocks ,
152
+ chainConfig : chainConfig ,
153
+ cacheConfig : cacheConfig ,
154
+ db : db ,
155
+ triegc : prque .New (nil ),
156
+ stateCache : state .NewDatabase (db ),
157
+ quit : make (chan struct {}),
158
+ shouldPreserve : shouldPreserve ,
159
+ bodyCache : bodyCache ,
160
+ bodyRLPCache : bodyRLPCache ,
161
+ blockCache : blockCache ,
162
+ futureBlocks : futureBlocks ,
163
+ engine : engine ,
164
+ vmConfig : vmConfig ,
165
+ badBlocks : badBlocks ,
167
166
}
168
167
bc .SetValidator (NewBlockValidator (chainConfig , bc , engine ))
169
168
bc .SetProcessor (NewStateProcessor (chainConfig , bc , engine ))
@@ -975,39 +974,11 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
975
974
if block .NumberU64 () < currentBlock .NumberU64 () {
976
975
reorg = true
977
976
} else if block .NumberU64 () == currentBlock .NumberU64 () {
978
- if _ , ok := bc .engine .(* clique.Clique ); ok {
979
- // The reason we need to disable the self-reorg preserving for clique
980
- // is it can be probable to introduce a deadlock.
981
- //
982
- // e.g. If there are 7 available signers
983
- //
984
- // r1 A
985
- // r2 B
986
- // r3 C
987
- // r4 D
988
- // r5 A [X] F G
989
- // r6 [X]
990
- //
991
- // In the round5, the inturn signer E is offline, so the worst case
992
- // is A, F and G sign the block of round5 and reject the block of opponents
993
- // and in the round6, the last available signer B is offline, the whole
994
- // network is stuck.
995
- reorg = mrand .Float64 () < 0.5
996
- } else {
997
- currentAuthor , err := bc .engine .Author (currentBlock .Header ())
998
- if err != nil {
999
- return NonStatTy , err
1000
- }
1001
- blockAuthor , err := bc .engine .Author (block .Header ())
1002
- if err != nil {
1003
- return NonStatTy , err
1004
- }
1005
- var currentLocal , blockLocal bool
1006
- if bc .isLocalFn != nil {
1007
- currentLocal , blockLocal = bc .isLocalFn (currentAuthor ), bc .isLocalFn (blockAuthor )
1008
- }
1009
- reorg = ! currentLocal && (blockLocal || mrand .Float64 () < 0.5 )
977
+ var currentPreserve , blockPreserve bool
978
+ if bc .shouldPreserve != nil {
979
+ currentPreserve , blockPreserve = bc .shouldPreserve (currentBlock ), bc .shouldPreserve (block )
1010
980
}
981
+ reorg = ! currentPreserve && (blockPreserve || mrand .Float64 () < 0.5 )
1011
982
}
1012
983
}
1013
984
if reorg {
0 commit comments