Skip to content

Commit 7477856

Browse files
authored
fix(f3): send the last gpbft message for each new participant (#4912)
1 parent efca75f commit 7477856

File tree

1 file changed

+60
-16
lines changed

1 file changed

+60
-16
lines changed

f3-sidecar/run.go

+60-16
Original file line numberDiff line numberDiff line change
@@ -150,34 +150,78 @@ func run(ctx context.Context, rpcEndpoint string, jwt string, f3RpcEndpoint stri
150150
}
151151
}()
152152

153+
var lastMsgToSignTimestamp time.Time
154+
var lastMsgToSign *gpbft.MessageBuilder
155+
lastMsgSigningMiners := make(map[uint64]struct{})
156+
157+
// Send the last gpbft message for each new participant,
158+
// see <https://github.com/filecoin-project/lotus/pull/12577>
159+
if isJwtProvided {
160+
go func() {
161+
for {
162+
// Send only when no messages are received in the last 10s.
163+
// This is to avoid a deadlock situation where everyone is waiting
164+
// for the next round to participate, but we'll never get there
165+
// because not enough participants acted in the current round.
166+
if lastMsgToSign != nil && lastMsgToSignTimestamp.Add(10*time.Second).Before(time.Now()) {
167+
if miners, err := ec.f3api.GetParticipatingMinerIDs(ctx); err == nil {
168+
for _, miner := range miners {
169+
if _, ok := lastMsgSigningMiners[miner]; ok {
170+
continue
171+
} else if err := participate(ctx, f3Module, &ec, lastMsgToSign, miner); err != nil {
172+
logger.Warn(err)
173+
} else {
174+
lastMsgSigningMiners[miner] = struct{}{}
175+
}
176+
}
177+
}
178+
}
179+
180+
time.Sleep(1 * time.Second)
181+
}
182+
}()
183+
}
184+
153185
for {
154186
msgToSign := <-f3Module.MessagesToSign()
187+
lastMsgToSignTimestamp = time.Now()
188+
lastMsgToSign = msgToSign
155189
miners, err := ec.f3api.GetParticipatingMinerIDs(ctx)
156190
if err != nil {
157191
continue
158192
}
193+
// Clear the map
194+
clear(lastMsgSigningMiners)
159195
if !isJwtProvided && len(miners) > 0 {
160196
logger.Warn("Unable to sign messages, jwt for Forest RPC endpoint is not provided.")
161197
}
162-
if isJwtProvided {
198+
if isJwtProvided && msgToSign != nil {
163199
for _, miner := range miners {
164-
signatureBuilder, err := msgToSign.PrepareSigningInputs(gpbft.ActorID(miner))
165-
if err != nil {
166-
if errors.Is(err, gpbft.ErrNoPower) {
167-
// we don't have any power in F3, continue
168-
logger.Warnf("no power to participate in F3: %+v", err)
169-
} else {
170-
logger.Warnf("preparing signing inputs: %+v", err)
171-
}
172-
continue
200+
if err := participate(ctx, f3Module, &ec, msgToSign, miner); err != nil {
201+
logger.Warn(err)
202+
} else {
203+
lastMsgSigningMiners[miner] = struct{}{}
173204
}
174-
payloadSig, vrfSig, err := signatureBuilder.Sign(ctx, &ec)
175-
if err != nil {
176-
logger.Warnf("signing message: %+v", err)
177-
}
178-
logger.Debugf("miner with id %d is sending message in F3", miner)
179-
f3Module.Broadcast(ctx, signatureBuilder, payloadSig, vrfSig)
180205
}
181206
}
182207
}
183208
}
209+
210+
func participate(ctx context.Context, f3Module *f3.F3, signer gpbft.Signer, msgToSign *gpbft.MessageBuilder, miner uint64) error {
211+
signatureBuilder, err := msgToSign.PrepareSigningInputs(gpbft.ActorID(miner))
212+
if err != nil {
213+
if errors.Is(err, gpbft.ErrNoPower) {
214+
// we don't have any power in F3, continue
215+
return fmt.Errorf("no power to participate in F3: %+v", err)
216+
} else {
217+
return fmt.Errorf("preparing signing inputs: %+v", err)
218+
}
219+
}
220+
payloadSig, vrfSig, err := signatureBuilder.Sign(ctx, signer)
221+
if err != nil {
222+
logger.Warnf("signing message: %+v", err)
223+
}
224+
logger.Debugf("miner with id %d is sending message in F3", miner)
225+
f3Module.Broadcast(ctx, signatureBuilder, payloadSig, vrfSig)
226+
return nil
227+
}

0 commit comments

Comments
 (0)