Ensure provided private key matches ticket

This commit is contained in:
jholdstock 2020-06-05 08:41:06 +01:00 committed by David Hill
parent a6d9b79619
commit 1c92856303
3 changed files with 59 additions and 20 deletions

View File

@ -175,12 +175,7 @@ func (c *DcrdRPC) ExistsLiveTicket(ticketHash string) (bool, error) {
// CanTicketVote checks determines whether a ticket is able to vote at some
// point in the future by checking that it is currently either immature or live.
func (c *DcrdRPC) CanTicketVote(ticketHash string, netParams *chaincfg.Params) (bool, error) {
// Get ticket details.
rawTx, err := c.GetRawTransaction(ticketHash)
if err != nil {
return false, err
}
func (c *DcrdRPC) CanTicketVote(rawTx *dcrdtypes.TxRawResult, ticketHash string, netParams *chaincfg.Params) (bool, error) {
// Tickets which have more than (TicketMaturity+TicketExpiry+1)
// confirmations are too old to vote.

View File

@ -90,7 +90,16 @@ func feeAddress(c *gin.Context) {
return
}
canVote, err := dcrdClient.CanTicketVote(ticketHash, cfg.NetParams)
// Get ticket details.
rawTicket, err := dcrdClient.GetRawTransaction(ticketHash)
if err != nil {
log.Errorf("Could not retrieve tx %s for %s: %v", ticketHash, c.ClientIP(), err)
sendErrorResponse(err.Error(), http.StatusInternalServerError, c)
return
}
// Ensure this ticket is eligible to vote at some point in the future.
canVote, err := dcrdClient.CanTicketVote(rawTicket, ticketHash, cfg.NetParams)
if err != nil {
log.Errorf("canTicketVote error: %v", err)
sendErrorResponse("error validating ticket", http.StatusInternalServerError, c)
@ -155,14 +164,7 @@ func feeAddress(c *gin.Context) {
now := time.Now()
expire := now.Add(cfg.FeeAddressExpiration).Unix()
rawTx, err := dcrdClient.GetRawTransaction(ticketHash)
if err != nil {
log.Errorf("Could not retrieve tx %s for %s: %v", ticketHash, c.ClientIP(), err)
sendErrorResponse(err.Error(), http.StatusInternalServerError, c)
return
}
confirmed := rawTx.Confirmations >= requiredConfs
confirmed := rawTicket.Confirmations >= requiredConfs
dbTicket := database.Ticket{
Hash: ticketHash,

View File

@ -44,7 +44,16 @@ func payFee(c *gin.Context) {
return
}
canVote, err := dcrdClient.CanTicketVote(ticket.Hash, cfg.NetParams)
// Get ticket details.
rawTicket, err := dcrdClient.GetRawTransaction(ticket.Hash)
if err != nil {
log.Errorf("Could not retrieve tx %s for %s: %v", ticket.Hash, c.ClientIP(), err)
sendErrorResponse(err.Error(), http.StatusInternalServerError, c)
return
}
// Ensure this ticket is eligible to vote at some point in the future.
canVote, err := dcrdClient.CanTicketVote(rawTicket, ticket.Hash, cfg.NetParams)
if err != nil {
log.Errorf("canTicketVote error: %v", err)
sendErrorResponse("error validating ticket", http.StatusInternalServerError, c)
@ -90,8 +99,7 @@ func payFee(c *gin.Context) {
}
feeTx := wire.NewMsgTx()
err = feeTx.FromBytes(feeTxBytes)
if err != nil {
if err = feeTx.FromBytes(feeTxBytes); err != nil {
log.Warnf("Failed to deserialize tx: %v", err)
sendErrorResponse("unable to deserialize transaction", http.StatusBadRequest, c)
return
@ -125,7 +133,7 @@ findAddress:
return
}
_, err = dcrutil.NewAddressPubKeyHash(dcrutil.Hash160(votingWIF.PubKey()), cfg.NetParams,
wifAddr, err := dcrutil.NewAddressPubKeyHash(dcrutil.Hash160(votingWIF.PubKey()), cfg.NetParams,
dcrec.STEcdsaSecp256k1)
if err != nil {
log.Errorf("NewAddressPubKeyHash: %v", err)
@ -133,7 +141,41 @@ findAddress:
return
}
// TODO: DB - validate votingkey against ticket submission address
// Decode ticket transaction to get its voting address.
ticketBytes, err := hex.DecodeString(rawTicket.Hex)
if err != nil {
log.Warnf("Failed to decode tx: %v", err)
sendErrorResponse("failed to decode transaction", http.StatusBadRequest, c)
return
}
ticketTx := wire.NewMsgTx()
if err = ticketTx.FromBytes(ticketBytes); err != nil {
log.Errorf("Failed to deserialize tx: %v", err)
sendErrorResponse("unable to deserialize transaction", http.StatusInternalServerError, c)
return
}
// Get ticket voting address.
_, votingAddr, _, err := txscript.ExtractPkScriptAddrs(scriptVersion, ticketTx.TxOut[0].PkScript, cfg.NetParams)
if err != nil {
log.Errorf("ExtractPK error: %v", err)
sendErrorResponse("extract PK error", http.StatusInternalServerError, c)
return
}
if len(votingAddr) == 0 {
log.Error("No voting address found for ticket %s", ticket.Hash)
sendErrorResponse("no voting address found", http.StatusInternalServerError, c)
return
}
// Ensure provided private key will allow us to vote this ticket.
if votingAddr[0].Address() != wifAddr.Address() {
log.Warnf("Voting address does not match provided private key: "+
"votingAddr=%+v, wifAddr=%+v", votingAddr[0], wifAddr)
sendErrorResponse("voting address does not match provided private key",
http.StatusBadRequest, c)
return
}
minFee, err := dcrutil.NewAmount(ticket.FeeAmount)
if err != nil {