From 7a61c637b0641002abc30ecf2e7e5729ab3cab20 Mon Sep 17 00:00:00 2001 From: Aleoami Date: Thu, 21 Jul 2022 13:55:12 +0300 Subject: [PATCH] Add RPC timeout parameter to wallet daemon (#2104) Co-authored-by: Ori Newman --- cmd/kaspawallet/config.go | 4 ++-- .../daemon/server/create_unsigned_transaction.go | 16 ++++++++++------ cmd/kaspawallet/daemon/server/rpc.go | 15 +++++++++++++-- cmd/kaspawallet/daemon/server/server.go | 4 ++-- cmd/kaspawallet/start_daemon.go | 2 +- infrastructure/network/rpcclient/rpcclient.go | 7 ++++--- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/cmd/kaspawallet/config.go b/cmd/kaspawallet/config.go index 07df82465..06daff64a 100644 --- a/cmd/kaspawallet/config.go +++ b/cmd/kaspawallet/config.go @@ -111,7 +111,8 @@ type startDaemonConfig struct { KeysFile string `long:"keys-file" short:"f" description:"Keys file location (default: ~/.kaspawallet/keys.json (*nix), %USERPROFILE%\\AppData\\Local\\Kaspawallet\\key.json (Windows))"` Password string `long:"password" short:"p" description:"Wallet password"` RPCServer string `long:"rpcserver" short:"s" description:"RPC server to connect to"` - Listen string `short:"l" long:"listen" description:"Address to listen on (default: 0.0.0.0:8082)"` + Listen string `long:"listen" short:"l" description:"Address to listen on (default: 0.0.0.0:8082)"` + Timeout uint32 `long:"wait-timeout" short:"w" description:"Waiting timeout for RPC calls, seconds (default: 30 s)"` Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65536"` config.NetworkFlags } @@ -181,7 +182,6 @@ func parseCommandLine() (subCommand string, config interface{}) { parser.AddCommand(startDaemonSubCmd, "Start the wallet daemon", "Start the wallet daemon", startDaemonConf) _, err := parser.Parse() - if err != nil { var flagsErr *flags.Error if ok := errors.As(err, &flagsErr); ok && flagsErr.Type == flags.ErrHelp { diff --git a/cmd/kaspawallet/daemon/server/create_unsigned_transaction.go b/cmd/kaspawallet/daemon/server/create_unsigned_transaction.go index 265780c4a..dca075570 100644 --- a/cmd/kaspawallet/daemon/server/create_unsigned_transaction.go +++ b/cmd/kaspawallet/daemon/server/create_unsigned_transaction.go @@ -3,20 +3,22 @@ package server import ( "context" "fmt" + "time" + "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb" "github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet" "github.com/kaspanet/kaspad/domain/consensus/utils/constants" "github.com/kaspanet/kaspad/util" "github.com/pkg/errors" "golang.org/x/exp/slices" - "time" ) // TODO: Implement a better fee estimation mechanism const feePerInput = 10000 func (s *server) CreateUnsignedTransactions(_ context.Context, request *pb.CreateUnsignedTransactionsRequest) ( - *pb.CreateUnsignedTransactionsResponse, error) { + *pb.CreateUnsignedTransactionsResponse, error, +) { s.lock.Lock() defer s.lock.Unlock() @@ -33,12 +35,14 @@ func (s *server) createUnsignedTransactions(address string, amount uint64, fromA return nil, errors.Errorf("wallet daemon is not synced yet, %s", s.formatSyncStateReport()) } - err := s.refreshUTXOs() + // make sure address string is correct before proceeding to a + // potentially long UTXO refreshment operation + toAddress, err := util.DecodeAddress(address, s.params.Prefix) if err != nil { return nil, err } - toAddress, err := util.DecodeAddress(address, s.params.Prefix) + err = s.refreshUTXOs() if err != nil { return nil, err } @@ -87,8 +91,8 @@ func (s *server) createUnsignedTransactions(address string, amount uint64, fromA } func (s *server) selectUTXOs(spendAmount uint64, feePerInput uint64, fromAddresses []*walletAddress) ( - selectedUTXOs []*libkaspawallet.UTXO, changeSompi uint64, err error) { - + selectedUTXOs []*libkaspawallet.UTXO, changeSompi uint64, err error, +) { selectedUTXOs = []*libkaspawallet.UTXO{} totalValue := uint64(0) diff --git a/cmd/kaspawallet/daemon/server/rpc.go b/cmd/kaspawallet/daemon/server/rpc.go index b37e8f66a..a80fe4452 100644 --- a/cmd/kaspawallet/daemon/server/rpc.go +++ b/cmd/kaspawallet/daemon/server/rpc.go @@ -1,15 +1,26 @@ package server import ( + "time" + "github.com/kaspanet/kaspad/domain/dagconfig" "github.com/kaspanet/kaspad/infrastructure/network/rpcclient" ) -func connectToRPC(params *dagconfig.Params, rpcServer string) (*rpcclient.RPCClient, error) { +func connectToRPC(params *dagconfig.Params, rpcServer string, timeout uint32) (*rpcclient.RPCClient, error) { rpcAddress, err := params.NormalizeRPCServerAddress(rpcServer) if err != nil { return nil, err } - return rpcclient.NewRPCClient(rpcAddress) + rpcClient, err := rpcclient.NewRPCClient(rpcAddress) + if err != nil { + return nil, err + } + + if timeout != 0 { + rpcClient.SetTimeout(time.Duration(timeout) * time.Second) + } + + return rpcClient, err } diff --git a/cmd/kaspawallet/daemon/server/server.go b/cmd/kaspawallet/daemon/server/server.go index d66ff8d65..afa140319 100644 --- a/cmd/kaspawallet/daemon/server/server.go +++ b/cmd/kaspawallet/daemon/server/server.go @@ -45,7 +45,7 @@ type server struct { } // Start starts the kaspawalletd server -func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath string, profile string) error { +func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath string, profile string, timeout uint32) error { initLog(defaultLogFile, defaultErrLogFile) defer panics.HandlePanic(log, "MAIN", nil) @@ -62,7 +62,7 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri log.Infof("Listening to TCP on %s", listen) log.Infof("Connecting to a node at %s...", rpcServer) - rpcClient, err := connectToRPC(params, rpcServer) + rpcClient, err := connectToRPC(params, rpcServer, timeout) if err != nil { return (errors.Wrapf(err, "Error connecting to RPC server %s", rpcServer)) } diff --git a/cmd/kaspawallet/start_daemon.go b/cmd/kaspawallet/start_daemon.go index bf1bbdfaf..db819aa2f 100644 --- a/cmd/kaspawallet/start_daemon.go +++ b/cmd/kaspawallet/start_daemon.go @@ -3,5 +3,5 @@ package main import "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/server" func startDaemon(conf *startDaemonConfig) error { - return server.Start(conf.NetParams(), conf.Listen, conf.RPCServer, conf.KeysFile, conf.Profile) + return server.Start(conf.NetParams(), conf.Listen, conf.RPCServer, conf.KeysFile, conf.Profile, conf.Timeout) } diff --git a/infrastructure/network/rpcclient/rpcclient.go b/infrastructure/network/rpcclient/rpcclient.go index d047fd8e6..7256f6c82 100644 --- a/infrastructure/network/rpcclient/rpcclient.go +++ b/infrastructure/network/rpcclient/rpcclient.go @@ -1,6 +1,9 @@ package rpcclient import ( + "sync/atomic" + "time" + "github.com/kaspanet/kaspad/app/appmessage" "github.com/kaspanet/kaspad/infrastructure/logger" routerpkg "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router" @@ -8,8 +11,6 @@ import ( "github.com/kaspanet/kaspad/util/panics" "github.com/kaspanet/kaspad/version" "github.com/pkg/errors" - "sync/atomic" - "time" ) const defaultTimeout = 30 * time.Second @@ -28,7 +29,7 @@ type RPCClient struct { timeout time.Duration } -// NewRPCClient creates a new RPC client +// NewRPCClient сreates a new RPC client with a default call timeout value func NewRPCClient(rpcAddress string) (*RPCClient, error) { rpcClient := &RPCClient{ rpcAddress: rpcAddress,