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  }