github.com/koko1123/flow-go-1@v0.29.6/consensus/hotstuff/notifications/pubsub/distributor.go (about) 1 package pubsub 2 3 import ( 4 "sync" 5 6 "github.com/koko1123/flow-go-1/consensus/hotstuff" 7 "github.com/koko1123/flow-go-1/consensus/hotstuff/model" 8 "github.com/koko1123/flow-go-1/model/flow" 9 ) 10 11 // Distributor distributes notifications to a list of subscribers (event consumers). 12 // 13 // It allows thread-safe subscription of multiple consumers to events. 14 type Distributor struct { 15 subscribers []hotstuff.Consumer 16 lock sync.RWMutex 17 } 18 19 var _ hotstuff.Consumer = (*Distributor)(nil) 20 21 func (p *Distributor) OnEventProcessed() { 22 p.lock.RLock() 23 defer p.lock.RUnlock() 24 for _, subscriber := range p.subscribers { 25 subscriber.OnEventProcessed() 26 } 27 } 28 29 func NewDistributor() *Distributor { 30 return &Distributor{} 31 } 32 33 // AddConsumer adds an a event consumer to the Distributor 34 func (p *Distributor) AddConsumer(consumer hotstuff.Consumer) { 35 p.lock.Lock() 36 defer p.lock.Unlock() 37 p.subscribers = append(p.subscribers, consumer) 38 } 39 40 func (p *Distributor) OnReceiveVote(currentView uint64, vote *model.Vote) { 41 p.lock.RLock() 42 defer p.lock.RUnlock() 43 for _, subscriber := range p.subscribers { 44 subscriber.OnReceiveVote(currentView, vote) 45 } 46 } 47 48 func (p *Distributor) OnReceiveProposal(currentView uint64, proposal *model.Proposal) { 49 p.lock.RLock() 50 defer p.lock.RUnlock() 51 for _, subscriber := range p.subscribers { 52 subscriber.OnReceiveProposal(currentView, proposal) 53 } 54 } 55 56 func (p *Distributor) OnEnteringView(view uint64, leader flow.Identifier) { 57 p.lock.RLock() 58 defer p.lock.RUnlock() 59 for _, subscriber := range p.subscribers { 60 subscriber.OnEnteringView(view, leader) 61 } 62 } 63 64 func (p *Distributor) OnQcTriggeredViewChange(qc *flow.QuorumCertificate, newView uint64) { 65 p.lock.RLock() 66 defer p.lock.RUnlock() 67 for _, subscriber := range p.subscribers { 68 subscriber.OnQcTriggeredViewChange(qc, newView) 69 } 70 } 71 72 func (p *Distributor) OnProposingBlock(proposal *model.Proposal) { 73 p.lock.RLock() 74 defer p.lock.RUnlock() 75 for _, subscriber := range p.subscribers { 76 subscriber.OnProposingBlock(proposal) 77 } 78 } 79 80 func (p *Distributor) OnVoting(vote *model.Vote) { 81 p.lock.RLock() 82 defer p.lock.RUnlock() 83 for _, subscriber := range p.subscribers { 84 subscriber.OnVoting(vote) 85 } 86 } 87 88 func (p *Distributor) OnQcConstructedFromVotes(curView uint64, qc *flow.QuorumCertificate) { 89 p.lock.RLock() 90 defer p.lock.RUnlock() 91 for _, subscriber := range p.subscribers { 92 subscriber.OnQcConstructedFromVotes(curView, qc) 93 } 94 } 95 96 func (p *Distributor) OnStartingTimeout(timerInfo *model.TimerInfo) { 97 p.lock.RLock() 98 defer p.lock.RUnlock() 99 for _, subscriber := range p.subscribers { 100 subscriber.OnStartingTimeout(timerInfo) 101 } 102 } 103 104 func (p *Distributor) OnReachedTimeout(timeout *model.TimerInfo) { 105 p.lock.RLock() 106 defer p.lock.RUnlock() 107 for _, subscriber := range p.subscribers { 108 subscriber.OnReachedTimeout(timeout) 109 } 110 } 111 112 func (p *Distributor) OnQcIncorporated(qc *flow.QuorumCertificate) { 113 p.lock.RLock() 114 defer p.lock.RUnlock() 115 for _, subscriber := range p.subscribers { 116 subscriber.OnQcIncorporated(qc) 117 } 118 } 119 120 func (p *Distributor) OnForkChoiceGenerated(curView uint64, selectedQC *flow.QuorumCertificate) { 121 p.lock.RLock() 122 defer p.lock.RUnlock() 123 for _, subscriber := range p.subscribers { 124 subscriber.OnForkChoiceGenerated(curView, selectedQC) 125 } 126 } 127 128 func (p *Distributor) OnBlockIncorporated(block *model.Block) { 129 p.lock.RLock() 130 defer p.lock.RUnlock() 131 for _, subscriber := range p.subscribers { 132 subscriber.OnBlockIncorporated(block) 133 } 134 } 135 136 func (p *Distributor) OnFinalizedBlock(block *model.Block) { 137 p.lock.RLock() 138 defer p.lock.RUnlock() 139 for _, subscriber := range p.subscribers { 140 subscriber.OnFinalizedBlock(block) 141 } 142 } 143 144 func (p *Distributor) OnDoubleProposeDetected(block1, block2 *model.Block) { 145 p.lock.RLock() 146 defer p.lock.RUnlock() 147 for _, subscriber := range p.subscribers { 148 subscriber.OnDoubleProposeDetected(block1, block2) 149 } 150 } 151 152 func (p *Distributor) OnDoubleVotingDetected(vote1, vote2 *model.Vote) { 153 p.lock.RLock() 154 defer p.lock.RUnlock() 155 for _, subscriber := range p.subscribers { 156 subscriber.OnDoubleVotingDetected(vote1, vote2) 157 } 158 } 159 160 func (p *Distributor) OnInvalidVoteDetected(vote *model.Vote) { 161 p.lock.RLock() 162 defer p.lock.RUnlock() 163 for _, subscriber := range p.subscribers { 164 subscriber.OnInvalidVoteDetected(vote) 165 } 166 } 167 168 func (p *Distributor) OnVoteForInvalidBlockDetected(vote *model.Vote, invalidProposal *model.Proposal) { 169 p.lock.RLock() 170 defer p.lock.RUnlock() 171 for _, subscriber := range p.subscribers { 172 subscriber.OnVoteForInvalidBlockDetected(vote, invalidProposal) 173 } 174 }