vspd: Wrap RPC connection details in a struct.

Returning a single struct which contains multiple named fields reduces
the chance of a mistake in the calling code, as compared to returning
multiple unnamed values which are all of the same type.
This commit is contained in:
jholdstock 2024-05-29 12:47:22 +01:00 committed by Jamie Holdstock
parent 086143fed2
commit 1a2b02466c
2 changed files with 55 additions and 24 deletions

View File

@ -118,14 +118,14 @@ func run() int {
// Create RPC client for local dcrd instance (used for broadcasting and // Create RPC client for local dcrd instance (used for broadcasting and
// checking the status of fee transactions). // checking the status of fee transactions).
dUser, dPass, dHost, dCert := cfg.DcrdDetails() dd := cfg.DcrdDetails()
dcrd := rpc.SetupDcrd(dUser, dPass, dHost, dCert, network.Params, rpcLog, blockNotifChan) dcrd := rpc.SetupDcrd(dd.User, dd.Password, dd.Host, dd.Cert, network.Params, rpcLog, blockNotifChan)
defer dcrd.Close() defer dcrd.Close()
// Create RPC client for remote dcrwallet instances (used for voting). // Create RPC client for remote dcrwallet instances (used for voting).
wUsers, wPasswords, wHosts, wCerts := cfg.WalletDetails() wd := cfg.WalletDetails()
wallets := rpc.SetupWallet(wUsers, wPasswords, wHosts, wCerts, network.Params, rpcLog) wallets := rpc.SetupWallet(wd.Users, wd.Passwords, wd.Hosts, wd.Certs, network.Params, rpcLog)
defer wallets.Close() defer wallets.Close()
// Create webapi server. // Create webapi server.

View File

@ -60,11 +60,24 @@ type Config struct {
ConfigFile string `long:"configfile" no-ini:"true" description:"DEPRECATED: This behavior is no longer available and this option will be removed in a future version of the software."` ConfigFile string `long:"configfile" no-ini:"true" description:"DEPRECATED: This behavior is no longer available and this option will be removed in a future version of the software."`
// The following fields are derived from the above fields by LoadConfig(). // The following fields are derived from the above fields by LoadConfig().
dataDir string dataDir string
network *config.Network network *config.Network
dcrdCert []byte dcrdDetails *DcrdDetails
walletHosts, walletUsers, walletPasswords []string walletDetails *WalletDetails
walletCerts [][]byte }
type DcrdDetails struct {
User string
Password string
Host string
Cert []byte
}
type WalletDetails struct {
Users []string
Passwords []string
Hosts []string
Certs [][]byte
} }
func (cfg *Config) Network() *config.Network { func (cfg *Config) Network() *config.Network {
@ -79,12 +92,12 @@ func (cfg *Config) DatabaseFile() string {
return filepath.Join(cfg.dataDir, dbFilename) return filepath.Join(cfg.dataDir, dbFilename)
} }
func (cfg *Config) DcrdDetails() (string, string, string, []byte) { func (cfg *Config) DcrdDetails() *DcrdDetails {
return cfg.DcrdUser, cfg.DcrdPass, cfg.DcrdHost, cfg.dcrdCert return cfg.dcrdDetails
} }
func (cfg *Config) WalletDetails() ([]string, []string, []string, [][]byte) { func (cfg *Config) WalletDetails() *WalletDetails {
return cfg.walletUsers, cfg.walletPasswords, cfg.walletHosts, cfg.walletCerts return cfg.walletDetails
} }
var DefaultConfig = Config{ var DefaultConfig = Config{
@ -319,11 +332,22 @@ func LoadConfig() (*Config, error) {
// Load dcrd RPC certificate. // Load dcrd RPC certificate.
cfg.DcrdCert = cleanAndExpandPath(cfg.DcrdCert) cfg.DcrdCert = cleanAndExpandPath(cfg.DcrdCert)
cfg.dcrdCert, err = os.ReadFile(cfg.DcrdCert) dcrdCert, err := os.ReadFile(cfg.DcrdCert)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to read dcrd cert file: %w", err) return nil, fmt.Errorf("failed to read dcrd cert file: %w", err)
} }
// Add default port for the active network if there is no port specified.
cfg.DcrdHost = normalizeAddress(cfg.DcrdHost, cfg.network.DcrdRPCServerPort)
// All dcrd connection details are validated and preprocessed.
cfg.dcrdDetails = &DcrdDetails{
User: cfg.DcrdUser,
Password: cfg.DcrdPass,
Host: cfg.DcrdHost,
Cert: dcrdCert,
}
// Ensure the dcrwallet RPC username is set. // Ensure the dcrwallet RPC username is set.
if cfg.WalletUsers == "" { if cfg.WalletUsers == "" {
return nil, errors.New("the walletuser option is not set") return nil, errors.New("the walletuser option is not set")
@ -340,20 +364,20 @@ func LoadConfig() (*Config, error) {
} }
// Parse list of wallet hosts. // Parse list of wallet hosts.
cfg.walletHosts = strings.Split(cfg.WalletHosts, ",") walletHosts := strings.Split(cfg.WalletHosts, ",")
numHost := len(cfg.walletHosts) numHost := len(walletHosts)
// An RPC username must be specified for each wallet host. // An RPC username must be specified for each wallet host.
cfg.walletUsers = strings.Split(cfg.WalletUsers, ",") walletUsers := strings.Split(cfg.WalletUsers, ",")
numUser := len(cfg.walletUsers) numUser := len(walletUsers)
if numUser != numHost { if numUser != numHost {
return nil, fmt.Errorf("%d wallet hosts specified, expected %d RPC usernames, got %d", return nil, fmt.Errorf("%d wallet hosts specified, expected %d RPC usernames, got %d",
numHost, numHost, numUser) numHost, numHost, numUser)
} }
// An RPC password must be specified for each wallet host. // An RPC password must be specified for each wallet host.
cfg.walletPasswords = strings.Split(cfg.WalletPasswords, ",") walletPasswords := strings.Split(cfg.WalletPasswords, ",")
numPass := len(cfg.walletPasswords) numPass := len(walletPasswords)
if numPass != numHost { if numPass != numHost {
return nil, fmt.Errorf("%d wallet hosts specified, expected %d RPC passwords, got %d", return nil, fmt.Errorf("%d wallet hosts specified, expected %d RPC passwords, got %d",
numHost, numHost, numPass) numHost, numHost, numPass)
@ -368,10 +392,10 @@ func LoadConfig() (*Config, error) {
} }
// Load dcrwallet RPC certificate(s). // Load dcrwallet RPC certificate(s).
cfg.walletCerts = make([][]byte, numCert) walletCerts := make([][]byte, numCert)
for i := 0; i < numCert; i++ { for i := 0; i < numCert; i++ {
certs[i] = cleanAndExpandPath(certs[i]) certs[i] = cleanAndExpandPath(certs[i])
cfg.walletCerts[i], err = os.ReadFile(certs[i]) walletCerts[i], err = os.ReadFile(certs[i])
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to read dcrwallet cert file: %w", err) return nil, fmt.Errorf("failed to read dcrwallet cert file: %w", err)
} }
@ -385,9 +409,16 @@ func LoadConfig() (*Config, error) {
// Add default port for the active network if there is no port specified. // Add default port for the active network if there is no port specified.
for i := 0; i < numHost; i++ { for i := 0; i < numHost; i++ {
cfg.walletHosts[i] = normalizeAddress(cfg.walletHosts[i], cfg.network.WalletRPCServerPort) walletHosts[i] = normalizeAddress(walletHosts[i], cfg.network.WalletRPCServerPort)
}
// All dcrwallet connection details are validated and preprocessed.
cfg.walletDetails = &WalletDetails{
Users: walletUsers,
Passwords: walletPasswords,
Hosts: walletHosts,
Certs: walletCerts,
} }
cfg.DcrdHost = normalizeAddress(cfg.DcrdHost, cfg.network.DcrdRPCServerPort)
// Create the data directory. // Create the data directory.
cfg.dataDir = filepath.Join(cfg.HomeDir, "data", cfg.network.Name) cfg.dataDir = filepath.Join(cfg.HomeDir, "data", cfg.network.Name)