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  }