@@ -18,7 +18,6 @@ package backend
1818
1919import (
2020 "crypto/ecdsa"
21- "math/big"
2221 "sync"
2322 "time"
2423
@@ -40,6 +39,8 @@ import (
4039func New (config * istanbul.Config , eventMux * event.TypeMux , privateKey * ecdsa.PrivateKey , db ethdb.Database ) consensus.Istanbul {
4140 // Allocate the snapshot caches and create the engine
4241 recents , _ := lru .NewARC (inmemorySnapshots )
42+ recentMessages , _ := lru .NewARC (inmemoryPeers )
43+ knownMessages , _ := lru .NewARC (inmemoryMessages )
4344 backend := & backend {
4445 config : config ,
4546 eventMux : eventMux ,
@@ -52,6 +53,8 @@ func New(config *istanbul.Config, eventMux *event.TypeMux, privateKey *ecdsa.Pri
5253 recents : recents ,
5354 candidates : make (map [common.Address ]bool ),
5455 coreStarted : false ,
56+ recentMessages : recentMessages ,
57+ knownMessages : knownMessages ,
5558 }
5659 backend .core = istanbulCore .New (backend , backend .config )
5760 return backend
@@ -84,6 +87,13 @@ type backend struct {
8487 candidatesLock sync.RWMutex
8588 // Snapshots for recent block to speed up reorgs
8689 recents * lru.ARCCache
90+
91+ // event subscription for ChainHeadEvent event
92+ eventSub * event.TypeMuxSubscription
93+ broadcaster consensus.Broadcaster
94+
95+ recentMessages * lru.ARCCache // the cache of peer's messages
96+ knownMessages * lru.ARCCache // the cache of self messages
8797}
8898
8999// Address implements istanbul.Backend.Address
@@ -110,18 +120,36 @@ func (sb *backend) Broadcast(valSet istanbul.ValidatorSet, payload []byte) error
110120
111121// Broadcast implements istanbul.Backend.Gossip
112122func (sb * backend ) Gossip (valSet istanbul.ValidatorSet , payload []byte ) error {
123+ hash := istanbul .RLPHash (payload )
124+ sb .knownMessages .Add (hash , true )
125+
113126 targets := make (map [common.Address ]bool )
114127 for _ , val := range valSet .List () {
115128 if val .Address () != sb .Address () {
116129 targets [val .Address ()] = true
117130 }
118131 }
119132
120- if len (targets ) > 0 {
121- go sb .eventMux .Post (istanbul.ConsensusDataEvent {
122- Targets : targets ,
123- Data : payload ,
124- })
133+ if sb .broadcaster != nil && len (targets ) > 0 {
134+ ps := sb .broadcaster .FindPeers (targets )
135+ for addr , p := range ps {
136+ ms , ok := sb .recentMessages .Get (addr )
137+ var m * lru.ARCCache
138+ if ok {
139+ m , _ = ms .(* lru.ARCCache )
140+ if _ , k := m .Get (hash ); k {
141+ // This peer had this event, skip it
142+ continue
143+ }
144+ } else {
145+ m , _ = lru .NewARC (inmemoryMessages )
146+ }
147+
148+ m .Add (hash , true )
149+ sb .recentMessages .Add (addr , m )
150+
151+ go p .Send (istanbulMsg , payload )
152+ }
125153 }
126154 return nil
127155}
@@ -162,10 +190,10 @@ func (sb *backend) Commit(proposal istanbul.Proposal, seals [][]byte) error {
162190 if _ , err := sb .inserter (types.Blocks {block }); err != nil {
163191 return err
164192 }
165- msg := istanbul.NewCommittedEvent {
166- Block : block ,
193+
194+ if sb .broadcaster != nil {
195+ go sb .broadcaster .BroadcastBlock (block , false )
167196 }
168- go sb .eventMux .Post (msg )
169197 return nil
170198}
171199
@@ -222,11 +250,6 @@ func (sb *backend) CheckSignature(data []byte, address common.Address, sig []byt
222250 return nil
223251}
224252
225- // HasBlock implements istanbul.Backend.HashBlock
226- func (sb * backend ) HasBlock (hash common.Hash , number * big.Int ) bool {
227- return sb .chain .GetHeader (hash , number .Uint64 ()) != nil
228- }
229-
230253// GetProposer implements istanbul.Backend.GetProposer
231254func (sb * backend ) GetProposer (number uint64 ) common.Address {
232255 if h := sb .chain .GetHeaderByNumber (number ); h != nil {
@@ -236,14 +259,6 @@ func (sb *backend) GetProposer(number uint64) common.Address {
236259 return common.Address {}
237260}
238261
239- // ParentValidators implements istanbul.Backend.GetParentValidators
240- func (sb * backend ) ParentValidators (proposal istanbul.Proposal ) istanbul.ValidatorSet {
241- if block , ok := proposal .(* types.Block ); ok {
242- return sb .getValidators (block .Number ().Uint64 ()- 1 , block .ParentHash ())
243- }
244- return validator .NewSet (nil , sb .config .ProposerPolicy )
245- }
246-
247262func (sb * backend ) getValidators (number uint64 , hash common.Hash ) istanbul.ValidatorSet {
248263 snap , err := sb .snapshot (sb .chain , number , hash , nil )
249264 if err != nil {
0 commit comments