@@ -74,10 +74,10 @@ func NewForkChoice(chainReader ChainReader, preserve func(header *types.Header)
74
74
// In the td mode, the new head is chosen if the corresponding
75
75
// total difficulty is higher. In the extern mode, the trusted
76
76
// header is always selected as the head.
77
- func (f * ForkChoice ) ReorgNeeded (current * types.Header , header * types.Header ) (bool , error ) {
77
+ func (f * ForkChoice ) ReorgNeeded (current * types.Header , extern * types.Header ) (bool , error ) {
78
78
var (
79
79
localTD = f .chain .GetTd (current .Hash (), current .Number .Uint64 ())
80
- externTd = f .chain .GetTd (header .Hash (), header .Number .Uint64 ())
80
+ externTd = f .chain .GetTd (extern .Hash (), extern .Number .Uint64 ())
81
81
)
82
82
if localTD == nil || externTd == nil {
83
83
return false , errors .New ("missing td" )
@@ -88,21 +88,26 @@ func (f *ForkChoice) ReorgNeeded(current *types.Header, header *types.Header) (b
88
88
if ttd := f .chain .Config ().TerminalTotalDifficulty ; ttd != nil && ttd .Cmp (externTd ) <= 0 {
89
89
return true , nil
90
90
}
91
+
91
92
// If the total difficulty is higher than our known, add it to the canonical chain
93
+ if diff := externTd .Cmp (localTD ); diff > 0 {
94
+ return true , nil
95
+ } else if diff < 0 {
96
+ return false , nil
97
+ }
98
+ // Local and external difficulty is identical.
92
99
// Second clause in the if statement reduces the vulnerability to selfish mining.
93
100
// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
94
- reorg := externTd .Cmp (localTD ) > 0
95
- if ! reorg && externTd .Cmp (localTD ) == 0 {
96
- number , headNumber := header .Number .Uint64 (), current .Number .Uint64 ()
97
- if number < headNumber {
98
- reorg = true
99
- } else if number == headNumber {
100
- var currentPreserve , externPreserve bool
101
- if f .preserve != nil {
102
- currentPreserve , externPreserve = f .preserve (current ), f .preserve (header )
103
- }
104
- reorg = ! currentPreserve && (externPreserve || f .rand .Float64 () < 0.5 )
101
+ reorg := false
102
+ externNum , localNum := extern .Number .Uint64 (), current .Number .Uint64 ()
103
+ if externNum < localNum {
104
+ reorg = true
105
+ } else if externNum == localNum {
106
+ var currentPreserve , externPreserve bool
107
+ if f .preserve != nil {
108
+ currentPreserve , externPreserve = f .preserve (current ), f .preserve (extern )
105
109
}
110
+ reorg = ! currentPreserve && (externPreserve || f .rand .Float64 () < 0.5 )
106
111
}
107
112
return reorg , nil
108
113
}
0 commit comments