diff --git a/rpc/dcrd.go b/rpc/dcrd.go index 38cea2d..ab23896 100644 --- a/rpc/dcrd.go +++ b/rpc/dcrd.go @@ -210,30 +210,6 @@ func (c *DcrdRPC) ExistsLiveTicket(ticketHash string) (bool, error) { return bitset.Bytes(existsBytes).Get(0), nil } -// 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(rawTx *dcrdtypes.TxRawResult, netParams *chaincfg.Params) (bool, error) { - - // Tickets which have more than (TicketMaturity+TicketExpiry+1) - // confirmations are too old to vote. - if rawTx.Confirmations > int64(uint32(netParams.TicketMaturity)+netParams.TicketExpiry)+1 { - return false, nil - } - - // If ticket is currently immature, it will be able to vote in future. - if rawTx.Confirmations <= int64(netParams.TicketMaturity) { - return true, nil - } - - // If ticket is currently live, it will be able to vote in future. - live, err := c.ExistsLiveTicket(rawTx.Txid) - if err != nil { - return false, err - } - - return live, nil -} - // ParseBlockConnectedNotification extracts the block header from a // blockconnected JSON-RPC notification. func ParseBlockConnectedNotification(params json.RawMessage) (*wire.BlockHeader, error) { diff --git a/webapi/getfeeaddress.go b/webapi/getfeeaddress.go index eab0b5a..075416d 100644 --- a/webapi/getfeeaddress.go +++ b/webapi/getfeeaddress.go @@ -123,9 +123,9 @@ func (s *Server) feeAddress(c *gin.Context) { } // Ensure this ticket is eligible to vote at some point in the future. - canVote, err := dcrdClient.CanTicketVote(rawTicket, s.cfg.NetParams) + canVote, err := canTicketVote(rawTicket, dcrdClient, s.cfg.NetParams) if err != nil { - log.Errorf("%s: dcrd.CanTicketVote error (ticketHash=%s): %v", funcName, ticketHash, err) + log.Errorf("%s: canTicketVote error (ticketHash=%s): %v", funcName, ticketHash, err) s.sendError(errInternalError, c) return } diff --git a/webapi/helpers.go b/webapi/helpers.go index cc5c4af..dc83a8b 100644 --- a/webapi/helpers.go +++ b/webapi/helpers.go @@ -14,6 +14,7 @@ import ( "github.com/decred/dcrd/chaincfg/v3" "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/decred/dcrd/dcrutil/v4" + dcrdtypes "github.com/decred/dcrd/rpc/jsonrpc/types/v3" "github.com/decred/dcrd/wire" "github.com/decred/vspd/database" "github.com/decred/vspd/rpc" @@ -194,3 +195,27 @@ func getCommitmentAddress(hash string, dcrdClient *rpc.DcrdRPC, params *chaincfg return addr.String(), nil } + +// 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 canTicketVote(rawTx *dcrdtypes.TxRawResult, dcrdClient Node, netParams *chaincfg.Params) (bool, error) { + + // Tickets which have more than (TicketMaturity+TicketExpiry+1) + // confirmations are too old to vote. + if rawTx.Confirmations > int64(uint32(netParams.TicketMaturity)+netParams.TicketExpiry)+1 { + return false, nil + } + + // If ticket is currently immature, it will be able to vote in future. + if rawTx.Confirmations <= int64(netParams.TicketMaturity) { + return true, nil + } + + // If ticket is currently live, it will be able to vote in future. + live, err := dcrdClient.ExistsLiveTicket(rawTx.Txid) + if err != nil { + return false, fmt.Errorf("dcrd.ExistsLiveTicket error: %w", err) + } + + return live, nil +} diff --git a/webapi/payfee.go b/webapi/payfee.go index 165e70e..fc49f23 100644 --- a/webapi/payfee.go +++ b/webapi/payfee.go @@ -72,9 +72,9 @@ func (s *Server) payFee(c *gin.Context) { } // Ensure this ticket is eligible to vote at some point in the future. - canVote, err := dcrdClient.CanTicketVote(rawTicket, s.cfg.NetParams) + canVote, err := canTicketVote(rawTicket, dcrdClient, s.cfg.NetParams) if err != nil { - log.Errorf("%s: dcrd.CanTicketVote error (ticketHash=%s): %v", funcName, ticket.Hash, err) + log.Errorf("%s: canTicketVote error (ticketHash=%s): %v", funcName, ticket.Hash, err) s.sendError(errInternalError, c) return } diff --git a/webapi/setaltsignaddr.go b/webapi/setaltsignaddr.go index 25740fa..e62dac0 100644 --- a/webapi/setaltsignaddr.go +++ b/webapi/setaltsignaddr.go @@ -7,7 +7,6 @@ package webapi import ( "time" - "github.com/decred/dcrd/chaincfg/v3" dcrdtypes "github.com/decred/dcrd/rpc/jsonrpc/types/v3" "github.com/decred/dcrd/txscript/v4/stdaddr" "github.com/decred/vspd/database" @@ -21,7 +20,7 @@ var _ Node = (*rpc.DcrdRPC)(nil) // Node is satisfied by *rpc.DcrdRPC and retrieves data from the blockchain. type Node interface { - CanTicketVote(rawTx *dcrdtypes.TxRawResult, netParams *chaincfg.Params) (bool, error) + ExistsLiveTicket(ticketHash string) (bool, error) GetRawTransaction(txHash string) (*dcrdtypes.TxRawResult, error) } @@ -90,9 +89,9 @@ func (s *Server) setAltSignAddr(c *gin.Context) { } // Ensure this ticket is eligible to vote at some point in the future. - canVote, err := dcrdClient.CanTicketVote(rawTicket, s.cfg.NetParams) + canVote, err := canTicketVote(rawTicket, dcrdClient, s.cfg.NetParams) if err != nil { - log.Errorf("%s: dcrd.CanTicketVote error (ticketHash=%s): %v", funcName, ticketHash, err) + log.Errorf("%s: canTicketVote error (ticketHash=%s): %v", funcName, ticketHash, err) s.sendError(errInternalError, c) return } diff --git a/webapi/setaltsignaddr_test.go b/webapi/setaltsignaddr_test.go index 8ab2054..e749c75 100644 --- a/webapi/setaltsignaddr_test.go +++ b/webapi/setaltsignaddr_test.go @@ -115,17 +115,18 @@ func randString(length int, charset string) string { var _ Node = (*testNode)(nil) type testNode struct { - canTicketVote bool - canTicketVoteErr error + getRawTransaction *dcrdtypes.TxRawResult getRawTransactionErr error + existsLiveTicket bool + existsLiveTicketErr error } -func (n *testNode) CanTicketVote(_ *dcrdtypes.TxRawResult, _ *chaincfg.Params) (bool, error) { - return n.canTicketVote, n.canTicketVoteErr +func (n *testNode) ExistsLiveTicket(ticketHash string) (bool, error) { + return n.existsLiveTicket, n.existsLiveTicketErr } func (n *testNode) GetRawTransaction(txHash string) (*dcrdtypes.TxRawResult, error) { - return nil, n.getRawTransactionErr + return n.getRawTransaction, n.getRawTransactionErr } func TestSetAltSignAddress(t *testing.T) { @@ -143,7 +144,11 @@ func TestSetAltSignAddress(t *testing.T) { name: "ok", addr: testAddr, node: &testNode{ - canTicketVote: true, + getRawTransaction: &dcrdtypes.TxRawResult{ + Confirmations: 1000, + }, + getRawTransactionErr: nil, + existsLiveTicket: true, }, wantCode: http.StatusOK, }, { @@ -168,29 +173,39 @@ func TestSetAltSignAddress(t *testing.T) { addr: "DkM3ZigNyiwHrsXRjkDQ8t8tW6uKGW9g61qEkG3bMqQPQWYEf5X3J", wantCode: http.StatusBadRequest, }, { - name: "error getting raw tx from dcrd client", + name: "getRawTransaction error from dcrd client", addr: testAddr, node: &testNode{ - getRawTransactionErr: errors.New("get raw transaction error"), + getRawTransactionErr: errors.New("getRawTransaction error"), }, wantCode: http.StatusInternalServerError, }, { - name: "error getting can vote from dcrd client", + name: "existsLiveTicket error from dcrd client", addr: testAddr, node: &testNode{ - canTicketVoteErr: errors.New("can ticket vote error"), + getRawTransaction: &dcrdtypes.TxRawResult{ + Confirmations: 1000, + }, + existsLiveTicketErr: errors.New("existsLiveTicket error"), }, wantCode: http.StatusInternalServerError, }, { name: "ticket can't vote", addr: testAddr, node: &testNode{ - canTicketVote: false, + getRawTransaction: &dcrdtypes.TxRawResult{ + Confirmations: 1000, + }, + existsLiveTicket: false, }, wantCode: http.StatusBadRequest, }, { - name: "only one alt sign addr allowed", - addr: testAddr, + name: "only one alt sign addr allowed", + addr: testAddr, + node: &testNode{ + getRawTransaction: &dcrdtypes.TxRawResult{}, + existsLiveTicket: true, + }, isExistingAltSignAddr: true, wantCode: http.StatusBadRequest, }} @@ -253,7 +268,7 @@ func TestSetAltSignAddress(t *testing.T) { r.ServeHTTP(w, c.Request) if test.wantCode != w.Code { - t.Errorf("expected status %d, got %d", test.wantCode, w.Code) + t.Fatalf("expected status %d, got %d", test.wantCode, w.Code) } altsig, err := api.db.AltSignAddrData(ticketHash)