Skip to content

Commit

Permalink
vsp: don't set/use a default policy
Browse files Browse the repository at this point in the history
This avoids the possibility of using a previously created vsp client
that has a policy different from the one intended by the caller.

In most cases already, the caller has a policy defined that should be
used rather than some previously set default policy. The only other
case where a policy to be used isn't readily handy is in the json-rpc
handler for the processUnmanagedTicket method. That method uses the
vsp client set in config and should thus use the policy set in config.
  • Loading branch information
itswisdomagain committed Jan 24, 2022
1 parent 9a8688e commit 8a73bea
Show file tree
Hide file tree
Showing 9 changed files with 719 additions and 707 deletions.
14 changes: 8 additions & 6 deletions dcrwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ func run(ctx context.Context) error {

// Open the wallet when --noinitialload was not set.
var vspClient *vsp.Client
var vspFeePolicy vsp.Policy
passphrase := []byte{}
if !cfg.NoInitialLoad {
walletPass := []byte(cfg.WalletPass)
Expand Down Expand Up @@ -267,16 +268,16 @@ func run(ctx context.Context) error {
cfg.PurchaseAccount, err)
return err
}
vspFeePolicy = vsp.Policy{
MaxFee: cfg.VSPOpts.MaxFee.Amount,
FeeAcct: purchaseAcct,
ChangeAcct: changeAcct,
}
vspCfg := vsp.Config{
URL: cfg.VSPOpts.URL,
PubKey: cfg.VSPOpts.PubKey,
Dialer: cfg.dial,
Wallet: w,
Policy: vsp.Policy{
MaxFee: cfg.VSPOpts.MaxFee.Amount,
FeeAcct: purchaseAcct,
ChangeAcct: changeAcct,
},
}
vspClient, err = ldr.VSP(vspCfg)
if err != nil {
Expand Down Expand Up @@ -354,6 +355,7 @@ func run(ctx context.Context) error {
c.TicketSplitAccount = ticketSplitAccount
c.ChangeAccount = changeAccount
c.VSP = vspClient
c.VSPFeePolicy = vspFeePolicy
})
log.Infof("Starting auto transaction creator")
tbdone := make(chan struct{})
Expand Down Expand Up @@ -421,7 +423,7 @@ func run(ctx context.Context) error {

loader.RunAfterLoad(func(w *wallet.Wallet) {
if vspClient != nil && cfg.VSPOpts.Sync {
vspClient.ProcessManagedTickets(ctx, vspClient.Policy)
vspClient.ProcessManagedTickets(ctx, vspFeePolicy)
}

if cfg.SPV {
Expand Down
17 changes: 14 additions & 3 deletions internal/rpc/jsonrpc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ package jsonrpc
import (
"context"
"net"

"github.com/decred/dcrd/dcrutil/v4"
)

// Options contains the required options for running the legacy RPC server.
Expand All @@ -24,7 +26,16 @@ type Options struct {
MixChangeAccount string
TicketSplitAccount string

VSPHost string
VSPPubKey string
Dial func(ctx context.Context, network, addr string) (net.Conn, error)
VSPOpts VSPOptions

Dial func(ctx context.Context, network, addr string) (net.Conn, error)
}

// VSPOptions defines options for processing tickets with a VSP server.
type VSPOptions struct {
Host string
PubKey string
MaxFee dcrutil.Amount
PurchaseAccount string
ChangeAccount string
}
53 changes: 41 additions & 12 deletions internal/rpc/jsonrpc/methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -3366,9 +3366,9 @@ func (s *Server) purchaseTicket(ctx context.Context, icmd interface{}) (interfac
var vspHost string
var vspPubKey string
var vspClient *vsp.Client
if s.cfg.VSPHost != "" || s.cfg.VSPPubKey != "" {
vspHost = s.cfg.VSPHost
vspPubKey = s.cfg.VSPPubKey
if s.cfg.VSPOpts.Host != "" || s.cfg.VSPOpts.PubKey != "" {
vspHost = s.cfg.VSPOpts.Host
vspPubKey = s.cfg.VSPOpts.PubKey
if vspPubKey == "" {
return nil, rpcErrorf(dcrjson.ErrRPCInvalidParameter,
"vsp pubkey can not be null")
Expand All @@ -3382,11 +3382,6 @@ func (s *Server) purchaseTicket(ctx context.Context, icmd interface{}) (interfac
PubKey: vspPubKey,
Dialer: s.cfg.Dial,
Wallet: w,
Policy: vsp.Policy{
MaxFee: 0.2e8,
FeeAcct: account,
ChangeAcct: changeAccount,
},
}
vspClient, err = loader.VSP(cfg)
if err != nil {
Expand Down Expand Up @@ -3415,7 +3410,14 @@ func (s *Server) purchaseTicket(ctx context.Context, icmd interface{}) (interfac
}

if vspClient != nil {
request.VSPFeePaymentProcess = vspClient.Process
policy := vsp.Policy{
MaxFee: 0.2e8,
FeeAcct: account,
ChangeAcct: changeAccount,
}
request.VSPFeePaymentProcess = func(ctx context.Context, ticketHash *chainhash.Hash, feeTx *wire.MsgTx) error {
return vspClient.Process(ctx, ticketHash, feeTx, policy)
}
request.VSPFeeProcess = vspClient.FeePercentage
}

Expand Down Expand Up @@ -3467,6 +3469,10 @@ func (s *Server) purchaseTicket(ctx context.Context, icmd interface{}) (interfac
// start managing it for the set vsp client from the config.
func (s *Server) processUnmanagedTicket(ctx context.Context, icmd interface{}) (interface{}, error) {
cmd := icmd.(*types.ProcessUnmanagedTicketCmd)
w, ok := s.walletLoader.LoadedWallet()
if !ok {
return nil, errUnloadedWallet
}

var ticketHash *chainhash.Hash
if cmd.TicketHash != nil {
Expand All @@ -3478,7 +3484,7 @@ func (s *Server) processUnmanagedTicket(ctx context.Context, icmd interface{}) (
} else {
return nil, rpcErrorf(dcrjson.ErrRPCInvalidParameter, "ticket hash must be provided")
}
vspHost := s.cfg.VSPHost
vspHost := s.cfg.VSPOpts.Host
if vspHost == "" {
return nil, rpcErrorf(dcrjson.ErrRPCInvalidParameter, "vsphost must be set in options")
}
Expand All @@ -3487,7 +3493,30 @@ func (s *Server) processUnmanagedTicket(ctx context.Context, icmd interface{}) (
return nil, err
}

err = vspClient.ProcessTicket(ctx, ticketHash)
purchaseAcct, err := w.AccountNumber(ctx, s.cfg.VSPOpts.PurchaseAccount)
if err != nil {
return nil, rpcErrorf(dcrjson.ErrRPCInvalidParameter, "invalid purchaseaccount set in options")
}

var changeAcct uint32
changeAccountName := s.cfg.VSPOpts.ChangeAccount
if changeAccountName == "" && s.cfg.CSPPServer == "" {
log.Warnf("Change account not set, using "+
"purchase account %q", s.cfg.VSPOpts.PurchaseAccount)
changeAcct = purchaseAcct
} else {
changeAcct, err = w.AccountNumber(ctx, changeAccountName)
if err != nil {
return nil, rpcErrorf(dcrjson.ErrRPCInvalidParameter, "invalid changeaccount set in options")
}
}

policy := vsp.Policy{
MaxFee: s.cfg.VSPOpts.MaxFee,
FeeAcct: purchaseAcct,
ChangeAcct: changeAcct,
}
err = vspClient.ProcessTicket(ctx, ticketHash, policy)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -4628,7 +4657,7 @@ func (s *Server) setVoteChoice(ctx context.Context, icmd interface{}) (interface
return nil, err
}

vspHost := s.cfg.VSPHost
vspHost := s.cfg.VSPOpts.Host
if vspHost == "" {
return nil, nil
}
Expand Down
69 changes: 32 additions & 37 deletions internal/rpc/rpcserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1747,11 +1747,6 @@ func (s *walletServer) PurchaseTickets(ctx context.Context,
PubKey: vspPubKey,
Dialer: nil,
Wallet: s.wallet,
Policy: vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.Account,
ChangeAcct: req.ChangeAccount,
},
}
vspClient, err = loader.VSP(cfg)
if err != nil {
Expand Down Expand Up @@ -1844,7 +1839,14 @@ func (s *walletServer) PurchaseTickets(ctx context.Context,
}

if vspClient != nil {
request.VSPFeePaymentProcess = vspClient.Process
policy := vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.Account,
ChangeAcct: req.ChangeAccount,
}
request.VSPFeePaymentProcess = func(ctx context.Context, ticketHash *chainhash.Hash, feeTx *wire.MsgTx) error {
return vspClient.Process(ctx, ticketHash, feeTx, policy)
}
request.VSPFeeProcess = vspClient.FeePercentage
}

Expand Down Expand Up @@ -2650,6 +2652,7 @@ func (t *ticketbuyerV2Server) RunTicketBuyer(req *pb.RunTicketBuyerRequest, svr
var vspHost string
var vspPubKey string
var vspClient *vsp.Client
var vspFeePolicy vsp.Policy
if req.VspHost != "" || req.VspPubkey != "" {
vspHost = req.VspHost
vspPubKey = req.VspPubkey
Expand All @@ -2664,16 +2667,16 @@ func (t *ticketbuyerV2Server) RunTicketBuyer(req *pb.RunTicketBuyerRequest, svr
PubKey: vspPubKey,
Dialer: nil,
Wallet: wallet,
Policy: vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.Account,
ChangeAcct: req.Account,
},
}
vspClient, err = loader.VSP(cfg)
if err != nil {
return status.Errorf(codes.Unknown, "TicketBuyerV3 instance failed to start. Error: %v", err)
}
vspFeePolicy = vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.Account,
ChangeAcct: req.Account,
}
}
if req.BalanceToMaintain < 0 {
return status.Errorf(codes.InvalidArgument, "Negative balance to maintain given")
Expand Down Expand Up @@ -2728,6 +2731,7 @@ func (t *ticketbuyerV2Server) RunTicketBuyer(req *pb.RunTicketBuyerRequest, svr
c.PoolFeeAddr = poolAddress
c.PoolFees = req.PoolFees
c.VSP = vspClient
c.VSPFeePolicy = vspFeePolicy
c.MixedAccount = mixedAccount
c.MixChange = mixedChange
c.CSPPServer = csppServer
Expand Down Expand Up @@ -3922,27 +3926,26 @@ func (s *walletServer) SyncVSPFailedTickets(ctx context.Context, req *pb.SyncVSP
if vspHost == "" {
return nil, status.Errorf(codes.InvalidArgument, "vsp host can not be null")
}
policy := vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.Account,
ChangeAcct: req.ChangeAccount,
}
cfg := vsp.Config{
URL: vspHost,
PubKey: vspPubKey,
Dialer: nil,
Wallet: s.wallet,
Policy: policy,
}
vspClient, err := loader.VSP(cfg)
if err != nil {
return nil, status.Errorf(codes.Unknown, "TicketBuyerV3 instance failed to start. Error: %v", err)
}

// process tickets fee if needed.
policy := vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.Account,
ChangeAcct: req.ChangeAccount,
}
for _, ticketHash := range failedTicketsFee {
feeTx := new(wire.MsgTx)
err := vspClient.ProcessWithPolicy(ctx, &ticketHash, feeTx, policy)
err := vspClient.Process(ctx, &ticketHash, feeTx, policy)
if err != nil {
// if it fails to process again, we log it and continue with
// the wallet start.
Expand All @@ -3963,23 +3966,22 @@ func (s *walletServer) ProcessManagedTickets(ctx context.Context, req *pb.Proces
if vspHost == "" {
return nil, status.Errorf(codes.InvalidArgument, "vsp host can not be null")
}
policy := vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.FeeAccount,
ChangeAcct: req.ChangeAccount,
}
cfg := vsp.Config{
URL: vspHost,
PubKey: vspPubKey,
Dialer: nil,
Wallet: s.wallet,
Policy: policy,
}
vspClient, err := loader.VSP(cfg)
if err != nil {
return nil, status.Errorf(codes.Unknown, "VSPClient instance failed to start. Error: %v", err)
}

policy := vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.FeeAccount,
ChangeAcct: req.ChangeAccount,
}
err = vspClient.ProcessManagedTickets(ctx, policy)
if err != nil {
return nil, status.Errorf(codes.Unknown, "ProcessManagedTickets failed. Error: %v", err)
Expand All @@ -3999,17 +4001,11 @@ func (s *walletServer) ProcessUnmanagedTickets(ctx context.Context, req *pb.Proc
if vspHost == "" {
return nil, status.Errorf(codes.InvalidArgument, "vsp host can not be null")
}
policy := vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.FeeAccount,
ChangeAcct: req.ChangeAccount,
}
cfg := vsp.Config{
URL: vspHost,
PubKey: vspPubKey,
Dialer: nil,
Wallet: s.wallet,
Policy: policy,
}
vspClient, err := loader.VSP(cfg)
if err != nil {
Expand All @@ -4025,14 +4021,19 @@ func (s *walletServer) ProcessUnmanagedTickets(ctx context.Context, req *pb.Proc
return nil
})
if errors.Is(err, errUnmanagedTickets) {
policy := vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.FeeAccount,
ChangeAcct: req.ChangeAccount,
}
vspClient.ProcessUnprocessedTickets(ctx, policy)
}

return &pb.ProcessUnmanagedTicketsResponse{}, nil
}

func (s *walletServer) SetVspdVoteChoices(ctx context.Context, req *pb.SetVspdVoteChoicesRequest) (
*pb.SetVspdVoteChoicesResponse, error) {
*pb.SetVspdVoteChoicesResponse, error) { // TODO: Remove req.FeeAccount and req.ChangeAccount.

vspHost := req.VspHost
vspPubKey := req.VspPubkey
Expand All @@ -4042,17 +4043,11 @@ func (s *walletServer) SetVspdVoteChoices(ctx context.Context, req *pb.SetVspdVo
if vspHost == "" {
return nil, status.Errorf(codes.InvalidArgument, "vsp host can not be null")
}
policy := vsp.Policy{
MaxFee: 0.1e8,
FeeAcct: req.FeeAccount,
ChangeAcct: req.ChangeAccount,
}
cfg := vsp.Config{
URL: vspHost,
PubKey: vspPubKey,
Dialer: nil,
Wallet: s.wallet,
Policy: policy,
}
vspClient, err := loader.VSP(cfg)
if err != nil {
Expand Down
Loading

0 comments on commit 8a73bea

Please sign in to comment.