webapi: Wait for unknown outputs to propagate.

If broadcasting parent transaction of a ticket fails because it
references unknown outputs, there is a good chance that waiting a few
seconds will resolve the issue because the ancestor transactions will
propagate through the network and reach the mempool of the local dcrd
instance.
This commit is contained in:
jholdstock 2023-11-07 12:47:33 +00:00 committed by Jamie Holdstock
parent 9ee95f98ab
commit 34cd9d2892

View File

@ -275,12 +275,39 @@ func (w *WebAPI) broadcastTicket(c *gin.Context) {
w.log.Debugf("%s: Broadcasting parent tx %s (ticketHash=%s)", funcName, parentHash, request.TicketHash) w.log.Debugf("%s: Broadcasting parent tx %s (ticketHash=%s)", funcName, parentHash, request.TicketHash)
err = dcrdClient.SendRawTransaction(request.ParentHex) err = dcrdClient.SendRawTransaction(request.ParentHex)
if err != nil { if err != nil {
// Unknown output errors have special handling because they
// could be resolved by waiting for network propagation. Any
// other errors are returned to client immediately.
if !strings.Contains(err.Error(), rpc.ErrUnknownOutputs) {
w.log.Errorf("%s: dcrd.SendRawTransaction for parent tx failed (ticketHash=%s): %v", w.log.Errorf("%s: dcrd.SendRawTransaction for parent tx failed (ticketHash=%s): %v",
funcName, request.TicketHash, err) funcName, request.TicketHash, err)
w.sendError(types.ErrCannotBroadcastTicket, c) w.sendError(types.ErrCannotBroadcastTicket, c)
return return
} }
w.log.Debugf("%s: Parent tx references an unknown output, waiting for it in mempool (ticketHash=%s)",
funcName, request.TicketHash)
txBroadcast := func() bool {
// Wait for 1 second and try again, max 7 attempts.
for i := 0; i < 7; i++ {
time.Sleep(1 * time.Second)
err := dcrdClient.SendRawTransaction(request.ParentHex)
if err == nil {
return true
}
}
return false
}()
if !txBroadcast {
w.log.Errorf("%s: Failed to broadcast parent tx, waiting didn't help (ticketHash=%s)",
funcName, request.TicketHash)
w.sendError(types.ErrCannotBroadcastTicket, c)
return
}
}
} else { } else {
w.log.Errorf("%s: dcrd.GetRawTransaction for ticket parent failed (ticketHash=%s): %v", w.log.Errorf("%s: dcrd.GetRawTransaction for ticket parent failed (ticketHash=%s): %v",
funcName, request.TicketHash, err) funcName, request.TicketHash, err)