From 1c6f962e2be79e96690ca5b0cc5fe676fd1f83a1 Mon Sep 17 00:00:00 2001 From: David Hill Date: Fri, 20 Nov 2020 13:10:13 +0000 Subject: [PATCH] api: add optional parent transaction to feeaddress (#205) --- docs/api.md | 3 ++- webapi/middleware.go | 40 ++++++++++++++++++++++++++++++++++++++++ webapi/types.go | 1 + 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/docs/api.md b/docs/api.md index 64f66d9..7724e92 100644 --- a/docs/api.md +++ b/docs/api.md @@ -79,7 +79,8 @@ for the specified ticket. { "timestamp":1590509066, "tickethash":"1b9f5dc3b4872c47f66b148b0633647458123d72a0f0623a90890cc51a668737", - "tickethex":"0100000001a8...bfa6e4bf9c5ec1" + "tickethex":"0100000001a8...bfa6e4bf9c5ec1", + "parenthex":"0100000022a7...580771a3064710" } ``` diff --git a/webapi/middleware.go b/webapi/middleware.go index ad0fbfd..da7264a 100644 --- a/webapi/middleware.go +++ b/webapi/middleware.go @@ -27,6 +27,7 @@ type ticketHashRequest struct { type ticketRequest struct { TicketHex string `json:"tickethex" binding:"required"` TicketHash string `json:"tickethash" binding:"required"` + ParentHex string `json:"parenthex"` } // withSession middleware adds a gorilla session to the request context for @@ -163,6 +164,45 @@ func broadcastTicket() gin.HandlerFunc { dcrdClient := c.MustGet("DcrdClient").(*rpc.DcrdRPC) + if request.ParentHex != "" { + parentTx, err := decodeTransaction(request.ParentHex) + if err != nil { + log.Errorf("%s: Failed to decode parent hex (ticketHash=%s): %v", funcName, request.TicketHash, err) + sendErrorWithMsg("cannot decode parent hex", errBadRequest, c) + return + } + parentHash := parentTx.TxHash() + + _, err = dcrdClient.GetRawTransaction(parentHash.String()) + if err == nil { + // No error means dcrd already knows the parent, we are done here. + goto processTicket + } + + var found bool + for _, txIn := range msgTx.TxIn { + if !txIn.PreviousOutPoint.Hash.IsEqual(&parentHash) { + continue + } + found = true + break + } + if !found { + log.Errorf("%s: Invalid ticket parent (ticketHash=%s)", funcName, request.TicketHash) + sendErrorWithMsg("invalid ticket parent", errBadRequest, c) + return + } + log.Debugf("%s: Broadcasting parent tx %s (ticketHash=%s)", funcName, parentHash, request.TicketHash) + err = dcrdClient.SendRawTransaction(request.ParentHex) + if err != nil { + log.Errorf("%s: dcrd.SendRawTransaction for parent tx failed (ticketHash=%s): %v", + funcName, request.TicketHash, err) + sendError(errCannotBroadcastTicket, c) + return + } + } + + processTicket: // Use GetRawTransaction to check if local dcrd already knows this // ticket. _, err = dcrdClient.GetRawTransaction(request.TicketHash) diff --git a/webapi/types.go b/webapi/types.go index 5060aec..034e538 100644 --- a/webapi/types.go +++ b/webapi/types.go @@ -21,6 +21,7 @@ type feeAddressRequest struct { Timestamp int64 `json:"timestamp" binding:"required"` TicketHash string `json:"tickethash" binding:"required"` TicketHex string `json:"tickethex" binding:"required"` + ParentTx string `json:"parenthex"` } type feeAddressResponse struct {