From 2ec72321910204048d3a05174d3cad6d877e647f Mon Sep 17 00:00:00 2001 From: icodezjb Date: Wed, 22 Apr 2020 16:27:47 +0800 Subject: [PATCH] core: mirror full node reorg logic in light client too (#20931) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * core: fix the condition of reorg * core: fix nitpick to only retrieve head once * core: don't reorg if received chain is longer at same diff Co-authored-by: Péter Szilágyi --- core/headerchain.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/core/headerchain.go b/core/headerchain.go index f21dcf537..a6028d8b9 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -149,7 +149,8 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er if ptd == nil { return NonStatTy, consensus.ErrUnknownAncestor } - localTd := hc.GetTd(hc.currentHeaderHash, hc.CurrentHeader().Number.Uint64()) + head := hc.CurrentHeader().Number.Uint64() + localTd := hc.GetTd(hc.currentHeaderHash, head) externTd := new(big.Int).Add(header.Difficulty, ptd) // Irrelevant of the canonical status, write the td and header to the database @@ -165,7 +166,15 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er // If the total difficulty is higher than our known, add it to the canonical chain // Second clause in the if statement reduces the vulnerability to selfish mining. // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf - if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) { + reorg := externTd.Cmp(localTd) > 0 + if !reorg && externTd.Cmp(localTd) == 0 { + if header.Number.Uint64() < head { + reorg = true + } else if header.Number.Uint64() == head { + reorg = mrand.Float64() < 0.5 + } + } + if reorg { // If the header can be added into canonical chain, adjust the // header chain markers(canonical indexes and head header flag). //