github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/consensus/hotstuff/notifications/pubsub/participant_distributor.go (about) 1 package pubsub 2 3 import ( 4 "sync" 5 6 "github.com/onflow/flow-go/consensus/hotstuff" 7 "github.com/onflow/flow-go/consensus/hotstuff/model" 8 "github.com/onflow/flow-go/model/flow" 9 ) 10 11 // ParticipantDistributor ingests events from HotStuff's core logic and distributes them to 12 // consumers. This logic only runs inside active consensus participants proposing blocks, voting, 13 // collecting + aggregating votes to QCs, and participating in the pacemaker (sending timeouts, 14 // collecting + aggregating timeouts to TCs). 15 // Concurrently safe. 16 type ParticipantDistributor struct { 17 consumers []hotstuff.ParticipantConsumer 18 lock sync.RWMutex 19 } 20 21 var _ hotstuff.ParticipantConsumer = (*ParticipantDistributor)(nil) 22 23 func NewParticipantDistributor() *ParticipantDistributor { 24 return &ParticipantDistributor{} 25 } 26 27 func (d *ParticipantDistributor) AddParticipantConsumer(consumer hotstuff.ParticipantConsumer) { 28 d.lock.Lock() 29 defer d.lock.Unlock() 30 d.consumers = append(d.consumers, consumer) 31 } 32 33 func (d *ParticipantDistributor) OnEventProcessed() { 34 d.lock.RLock() 35 defer d.lock.RUnlock() 36 for _, subscriber := range d.consumers { 37 subscriber.OnEventProcessed() 38 } 39 } 40 41 func (d *ParticipantDistributor) OnStart(currentView uint64) { 42 d.lock.RLock() 43 defer d.lock.RUnlock() 44 for _, subscriber := range d.consumers { 45 subscriber.OnStart(currentView) 46 } 47 } 48 49 func (d *ParticipantDistributor) OnReceiveProposal(currentView uint64, proposal *model.Proposal) { 50 d.lock.RLock() 51 defer d.lock.RUnlock() 52 for _, subscriber := range d.consumers { 53 subscriber.OnReceiveProposal(currentView, proposal) 54 } 55 } 56 57 func (d *ParticipantDistributor) OnReceiveQc(currentView uint64, qc *flow.QuorumCertificate) { 58 d.lock.RLock() 59 defer d.lock.RUnlock() 60 for _, subscriber := range d.consumers { 61 subscriber.OnReceiveQc(currentView, qc) 62 } 63 } 64 65 func (d *ParticipantDistributor) OnReceiveTc(currentView uint64, tc *flow.TimeoutCertificate) { 66 d.lock.RLock() 67 defer d.lock.RUnlock() 68 for _, subscriber := range d.consumers { 69 subscriber.OnReceiveTc(currentView, tc) 70 } 71 } 72 73 func (d *ParticipantDistributor) OnPartialTc(currentView uint64, partialTc *hotstuff.PartialTcCreated) { 74 d.lock.RLock() 75 defer d.lock.RUnlock() 76 for _, subscriber := range d.consumers { 77 subscriber.OnPartialTc(currentView, partialTc) 78 } 79 } 80 81 func (d *ParticipantDistributor) OnLocalTimeout(currentView uint64) { 82 d.lock.RLock() 83 defer d.lock.RUnlock() 84 for _, subscriber := range d.consumers { 85 subscriber.OnLocalTimeout(currentView) 86 } 87 } 88 89 func (d *ParticipantDistributor) OnViewChange(oldView, newView uint64) { 90 d.lock.RLock() 91 defer d.lock.RUnlock() 92 for _, subscriber := range d.consumers { 93 subscriber.OnViewChange(oldView, newView) 94 } 95 } 96 97 func (d *ParticipantDistributor) OnQcTriggeredViewChange(oldView uint64, newView uint64, qc *flow.QuorumCertificate) { 98 d.lock.RLock() 99 defer d.lock.RUnlock() 100 for _, subscriber := range d.consumers { 101 subscriber.OnQcTriggeredViewChange(oldView, newView, qc) 102 } 103 } 104 105 func (d *ParticipantDistributor) OnTcTriggeredViewChange(oldView uint64, newView uint64, tc *flow.TimeoutCertificate) { 106 d.lock.RLock() 107 defer d.lock.RUnlock() 108 for _, subscriber := range d.consumers { 109 subscriber.OnTcTriggeredViewChange(oldView, newView, tc) 110 } 111 } 112 113 func (d *ParticipantDistributor) OnStartingTimeout(timerInfo model.TimerInfo) { 114 d.lock.RLock() 115 defer d.lock.RUnlock() 116 for _, subscriber := range d.consumers { 117 subscriber.OnStartingTimeout(timerInfo) 118 } 119 } 120 121 func (d *ParticipantDistributor) OnCurrentViewDetails(currentView, finalizedView uint64, currentLeader flow.Identifier) { 122 d.lock.RLock() 123 defer d.lock.RUnlock() 124 for _, subscriber := range d.consumers { 125 subscriber.OnCurrentViewDetails(currentView, finalizedView, currentLeader) 126 } 127 }