Move CanTicketVote out of dcrd RPC client.

`CanTicketVote` doesn't really fit into the RPC client code as it is more of a business logic function. Moving it into the webapi package is more appropriate.
This commit is contained in:
Jamie Holdstock 2022-05-06 11:12:19 +01:00 committed by Jamie Holdstock
parent 49f68fd5ec
commit d8dd02433c
6 changed files with 61 additions and 46 deletions

View File

@ -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) {

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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,
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)