From c4e3025d230dbbab64a2f286835a65d797260ec9 Mon Sep 17 00:00:00 2001 From: Mission Liao Date: Fri, 8 Mar 2019 15:54:15 +0800 Subject: syncer: avoid attacked by older AgreementResult when syncing (#471) One possible attack for syncer is: - byzantine nodes periodically broadcast some very old types.AgreementResults. - If some syncer receive those types.AgreementResult, they might synced directly while still fall behind other nodes. A quick workaround is ignore types.AgreementResults older than the chain tip when creating the syncer.Consensus instance. --- core/syncer/consensus.go | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'core') diff --git a/core/syncer/consensus.go b/core/syncer/consensus.go index 7ba659f..3053396 100644 --- a/core/syncer/consensus.go +++ b/core/syncer/consensus.go @@ -85,6 +85,7 @@ type Consensus struct { dummyCancel context.CancelFunc dummyFinished <-chan struct{} dummyMsgBuffer []interface{} + initChainTipHeight uint64 } // NewConsensus creates an instance for Consensus (syncer consensus). @@ -116,6 +117,7 @@ func NewConsensus( randomnessResults: make(map[common.Hash]*types.BlockRandomnessResult), } con.ctx, con.ctxCancel = context.WithCancel(context.Background()) + _, con.initChainTipHeight = db.GetCompactionChainTipInfo() con.agreementModule = newAgreement( con.receiveChan, con.pullChan, con.nodeSetCache, con.logger) con.agreementWaitGroup.Add(1) @@ -466,6 +468,12 @@ func (con *Consensus) startNetwork() { switch v := val.(type) { case *types.Block: case *types.AgreementResult: + // Avoid byzantine nodes attack by broadcasting older + // agreement results. Normal nodes might report 'synced' + // while still fall behind other nodes. + if v.Position.Height <= con.initChainTipHeight { + continue loop + } case *types.BlockRandomnessResult: con.cacheRandomnessResult(v) continue loop -- cgit v1.2.3