github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/consensus/hotstuff/notifications/pubsub/proposal_violation_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 // ProposalViolationDistributor ingests notifications about HotStuff-protocol violations and 12 // distributes them to consumers. Such notifications are produced by the active consensus 13 // participants and the consensus follower. 14 // Concurrently safe. 15 type ProposalViolationDistributor struct { 16 consumers []hotstuff.ProposalViolationConsumer 17 lock sync.RWMutex 18 } 19 20 var _ hotstuff.ProposalViolationConsumer = (*ProposalViolationDistributor)(nil) 21 22 func NewProtocolViolationDistributor() *ProposalViolationDistributor { 23 return &ProposalViolationDistributor{} 24 } 25 26 func (d *ProposalViolationDistributor) AddProposalViolationConsumer(consumer hotstuff.ProposalViolationConsumer) { 27 d.lock.Lock() 28 defer d.lock.Unlock() 29 d.consumers = append(d.consumers, consumer) 30 } 31 32 func (d *ProposalViolationDistributor) OnInvalidBlockDetected(err flow.Slashable[model.InvalidProposalError]) { 33 d.lock.RLock() 34 defer d.lock.RUnlock() 35 for _, subscriber := range d.consumers { 36 subscriber.OnInvalidBlockDetected(err) 37 } 38 } 39 40 func (d *ProposalViolationDistributor) OnDoubleProposeDetected(block1, block2 *model.Block) { 41 d.lock.RLock() 42 defer d.lock.RUnlock() 43 for _, subscriber := range d.consumers { 44 subscriber.OnDoubleProposeDetected(block1, block2) 45 } 46 }