diff --git a/chain/lf3/f3.go b/chain/lf3/f3.go index 0b702bb73a..1c36ed491b 100644 --- a/chain/lf3/f3.go +++ b/chain/lf3/f3.go @@ -141,20 +141,28 @@ func (fff *F3) runSigningLoop(ctx context.Context) { msgCh := fff.inner.MessagesToSign() -loop: + var mb *gpbft.MessageBuilder + alreadyParticipated := make(map[uint64]struct{}) for ctx.Err() == nil { select { case <-ctx.Done(): return - case mb, ok := <-msgCh: - if !ok { - continue loop + case <-fff.leaser.notifyParticipation: + if mb == nil { + continue } - participants := fff.leaser.getParticipantsByInstance(mb.Payload.Instance) - for _, id := range participants { - if err := participateOnce(ctx, mb, id); err != nil { - log.Errorf("while participating for miner f0%d: %+v", id, err) - } + case mb = <-msgCh: // never closed + clear(alreadyParticipated) + } + + participants := fff.leaser.getParticipantsByInstance(mb.Payload.Instance) + for _, id := range participants { + if _, ok := alreadyParticipated[id]; ok { + continue + } else if err := participateOnce(ctx, mb, id); err != nil { + log.Errorf("while participating for miner f0%d: %+v", id, err) + } else { + alreadyParticipated[id] = struct{}{} } } } diff --git a/chain/lf3/participation_lease.go b/chain/lf3/participation_lease.go index 042d48301d..b1587c5351 100644 --- a/chain/lf3/participation_lease.go +++ b/chain/lf3/participation_lease.go @@ -23,6 +23,8 @@ type leaser struct { issuer peer.ID status f3Status maxLeasableInstances uint64 + // Signals that a lease was created and/or updated. + notifyParticipation chan struct{} } func newParticipationLeaser(nodeId peer.ID, status f3Status, maxLeasedInstances uint64) *leaser { @@ -30,6 +32,7 @@ func newParticipationLeaser(nodeId peer.ID, status f3Status, maxLeasedInstances leases: make(map[uint64]api.F3ParticipationLease), issuer: nodeId, status: status, + notifyParticipation: make(chan struct{}, 1), maxLeasableInstances: maxLeasedInstances, } } @@ -99,6 +102,10 @@ func (l *leaser) participate(ticket api.F3ParticipationTicket) (api.F3Participat return api.F3ParticipationLease{}, api.ErrF3ParticipationTicketStartBeforeExisting } l.leases[newLease.MinerID] = newLease + select { + case l.notifyParticipation <- struct{}{}: + default: + } return newLease, nil }