rpcclient: Add net params to Client (#1467)

* rpcclient: replace futures mainnet with params

Adds a chaincfg.Params to the Client

rpcclient: parse config to assign params

* rpcclient: change address commands to Address

 * Change address future struct to contain a network field, so futures
   can return the correct type for Receive
This commit is contained in:
John C. Vernaleo 2020-03-05 16:46:29 -05:00 committed by GitHub
parent 06e5c43499
commit e9f15eda7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 55 deletions

View file

@ -25,6 +25,7 @@ import (
"time" "time"
"github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/go-socks/socks" "github.com/btcsuite/go-socks/socks"
"github.com/btcsuite/websocket" "github.com/btcsuite/websocket"
) )
@ -138,6 +139,10 @@ type Client struct {
// config holds the connection configuration assoiated with this client. // config holds the connection configuration assoiated with this client.
config *ConnConfig config *ConnConfig
// chainParams holds the params for the chain that this client is using,
// and is used for many wallet methods.
chainParams *chaincfg.Params
// wsConn is the underlying websocket connection when not in HTTP POST // wsConn is the underlying websocket connection when not in HTTP POST
// mode. // mode.
wsConn *websocket.Conn wsConn *websocket.Conn
@ -283,31 +288,29 @@ func (c *Client) trackRegisteredNtfns(cmd interface{}) {
} }
} }
type ( // inMessage is the first type that an incoming message is unmarshaled
// inMessage is the first type that an incoming message is unmarshaled // into. It supports both requests (for notification support) and
// into. It supports both requests (for notification support) and // responses. The partially-unmarshaled message is a notification if
// responses. The partially-unmarshaled message is a notification if // the embedded ID (from the response) is nil. Otherwise, it is a
// the embedded ID (from the response) is nil. Otherwise, it is a // response.
// response. type inMessage struct {
inMessage struct { ID *float64 `json:"id"`
ID *float64 `json:"id"` *rawNotification
*rawNotification *rawResponse
*rawResponse }
}
// rawNotification is a partially-unmarshaled JSON-RPC notification. // rawNotification is a partially-unmarshaled JSON-RPC notification.
rawNotification struct { type rawNotification struct {
Method string `json:"method"` Method string `json:"method"`
Params []json.RawMessage `json:"params"` Params []json.RawMessage `json:"params"`
} }
// rawResponse is a partially-unmarshaled JSON-RPC response. For this // rawResponse is a partially-unmarshaled JSON-RPC response. For this
// to be valid (according to JSON-RPC 1.0 spec), ID may not be nil. // to be valid (according to JSON-RPC 1.0 spec), ID may not be nil.
rawResponse struct { type rawResponse struct {
Result json.RawMessage `json:"result"` Result json.RawMessage `json:"result"`
Error *btcjson.RPCError `json:"error"` Error *btcjson.RPCError `json:"error"`
} }
)
// response is the raw bytes of a JSON-RPC result, or the error if the response // response is the raw bytes of a JSON-RPC result, or the error if the response
// error object was non-null. // error object was non-null.
@ -1093,6 +1096,11 @@ type ConnConfig struct {
// Pass is the passphrase to use to authenticate to the RPC server. // Pass is the passphrase to use to authenticate to the RPC server.
Pass string Pass string
// Params is the string representing the network that the server
// is running. If there is no parameter set in the config, then
// mainnet will be used by default.
Params string
// DisableTLS specifies whether transport layer security should be // DisableTLS specifies whether transport layer security should be
// disabled. It is recommended to always use TLS if the RPC server // disabled. It is recommended to always use TLS if the RPC server
// supports it as otherwise your username and password is sent across // supports it as otherwise your username and password is sent across
@ -1290,6 +1298,23 @@ func New(config *ConnConfig, ntfnHandlers *NotificationHandlers) (*Client, error
shutdown: make(chan struct{}), shutdown: make(chan struct{}),
} }
// Default network is mainnet, no parameters are necessary but if mainnet
// is specified it will be the param
switch config.Params {
case "":
fallthrough
case chaincfg.MainNetParams.Name:
client.chainParams = &chaincfg.MainNetParams
case chaincfg.TestNet3Params.Name:
client.chainParams = &chaincfg.TestNet3Params
case chaincfg.RegressionNetParams.Name:
client.chainParams = &chaincfg.RegressionNetParams
case chaincfg.SimNetParams.Name:
client.chainParams = &chaincfg.SimNetParams
default:
return nil, fmt.Errorf("rpcclient.New: Unknown chain %s", config.Params)
}
if start { if start {
log.Infof("Established connection to RPC server %s", log.Infof("Established connection to RPC server %s",
config.Host) config.Host)

View file

@ -753,13 +753,16 @@ func (c *Client) SendManyComment(fromAccount string,
// FutureAddMultisigAddressResult is a future promise to deliver the result of a // FutureAddMultisigAddressResult is a future promise to deliver the result of a
// AddMultisigAddressAsync RPC invocation (or an applicable error). // AddMultisigAddressAsync RPC invocation (or an applicable error).
type FutureAddMultisigAddressResult chan *response type FutureAddMultisigAddressResult struct {
responseChannel chan *response
network *chaincfg.Params
}
// Receive waits for the response promised by the future and returns the // Receive waits for the response promised by the future and returns the
// multisignature address that requires the specified number of signatures for // multisignature address that requires the specified number of signatures for
// the provided addresses. // the provided addresses.
func (r FutureAddMultisigAddressResult) Receive() (btcutil.Address, error) { func (r FutureAddMultisigAddressResult) Receive() (btcutil.Address, error) {
res, err := receiveFuture(r) res, err := receiveFuture(r.responseChannel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -771,7 +774,7 @@ func (r FutureAddMultisigAddressResult) Receive() (btcutil.Address, error) {
return nil, err return nil, err
} }
return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) return btcutil.DecodeAddress(addr, r.network)
} }
// AddMultisigAddressAsync returns an instance of a type that can be used to get // AddMultisigAddressAsync returns an instance of a type that can be used to get
@ -786,14 +789,17 @@ func (c *Client) AddMultisigAddressAsync(requiredSigs int, addresses []btcutil.A
} }
cmd := btcjson.NewAddMultisigAddressCmd(requiredSigs, addrs, &account) cmd := btcjson.NewAddMultisigAddressCmd(requiredSigs, addrs, &account)
return c.sendCmd(cmd) result := FutureAddMultisigAddressResult{
network: c.chainParams,
responseChannel: c.sendCmd(cmd),
}
return result
} }
// AddMultisigAddress adds a multisignature address that requires the specified // AddMultisigAddress adds a multisignature address that requires the specified
// number of signatures for the provided addresses to the wallet. // number of signatures for the provided addresses to the wallet.
func (c *Client) AddMultisigAddress(requiredSigs int, addresses []btcutil.Address, account string) (btcutil.Address, error) { func (c *Client) AddMultisigAddress(requiredSigs int, addresses []btcutil.Address, account string) (btcutil.Address, error) {
return c.AddMultisigAddressAsync(requiredSigs, addresses, return c.AddMultisigAddressAsync(requiredSigs, addresses, account).Receive()
account).Receive()
} }
// FutureCreateMultisigResult is a future promise to deliver the result of a // FutureCreateMultisigResult is a future promise to deliver the result of a
@ -868,12 +874,15 @@ func (c *Client) CreateNewAccount(account string) error {
// FutureGetNewAddressResult is a future promise to deliver the result of a // FutureGetNewAddressResult is a future promise to deliver the result of a
// GetNewAddressAsync RPC invocation (or an applicable error). // GetNewAddressAsync RPC invocation (or an applicable error).
type FutureGetNewAddressResult chan *response type FutureGetNewAddressResult struct {
responseChannel chan *response
network *chaincfg.Params
}
// Receive waits for the response promised by the future and returns a new // Receive waits for the response promised by the future and returns a new
// address. // address.
func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) { func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) {
res, err := receiveFuture(r) res, err := receiveFuture(r.responseChannel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -885,7 +894,7 @@ func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) {
return nil, err return nil, err
} }
return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) return btcutil.DecodeAddress(addr, r.network)
} }
// GetNewAddressAsync returns an instance of a type that can be used to get the // GetNewAddressAsync returns an instance of a type that can be used to get the
@ -895,23 +904,31 @@ func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) {
// See GetNewAddress for the blocking version and more details. // See GetNewAddress for the blocking version and more details.
func (c *Client) GetNewAddressAsync(account string) FutureGetNewAddressResult { func (c *Client) GetNewAddressAsync(account string) FutureGetNewAddressResult {
cmd := btcjson.NewGetNewAddressCmd(&account) cmd := btcjson.NewGetNewAddressCmd(&account)
return c.sendCmd(cmd) result := FutureGetNewAddressResult{
network: c.chainParams,
responseChannel: c.sendCmd(cmd),
}
return result
} }
// GetNewAddress returns a new address. // GetNewAddress returns a new address, and decodes based on the client's
// chain params.
func (c *Client) GetNewAddress(account string) (btcutil.Address, error) { func (c *Client) GetNewAddress(account string) (btcutil.Address, error) {
return c.GetNewAddressAsync(account).Receive() return c.GetNewAddressAsync(account).Receive()
} }
// FutureGetRawChangeAddressResult is a future promise to deliver the result of // FutureGetRawChangeAddressResult is a future promise to deliver the result of
// a GetRawChangeAddressAsync RPC invocation (or an applicable error). // a GetRawChangeAddressAsync RPC invocation (or an applicable error).
type FutureGetRawChangeAddressResult chan *response type FutureGetRawChangeAddressResult struct {
responseChannel chan *response
network *chaincfg.Params
}
// Receive waits for the response promised by the future and returns a new // Receive waits for the response promised by the future and returns a new
// address for receiving change that will be associated with the provided // address for receiving change that will be associated with the provided
// account. Note that this is only for raw transactions and NOT for normal use. // account. Note that this is only for raw transactions and NOT for normal use.
func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) { func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) {
res, err := receiveFuture(r) res, err := receiveFuture(r.responseChannel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -923,7 +940,7 @@ func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) {
return nil, err return nil, err
} }
return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) return btcutil.DecodeAddress(addr, r.network)
} }
// GetRawChangeAddressAsync returns an instance of a type that can be used to // GetRawChangeAddressAsync returns an instance of a type that can be used to
@ -933,7 +950,11 @@ func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) {
// See GetRawChangeAddress for the blocking version and more details. // See GetRawChangeAddress for the blocking version and more details.
func (c *Client) GetRawChangeAddressAsync(account string) FutureGetRawChangeAddressResult { func (c *Client) GetRawChangeAddressAsync(account string) FutureGetRawChangeAddressResult {
cmd := btcjson.NewGetRawChangeAddressCmd(&account) cmd := btcjson.NewGetRawChangeAddressCmd(&account)
return c.sendCmd(cmd) result := FutureGetRawChangeAddressResult{
network: c.chainParams,
responseChannel: c.sendCmd(cmd),
}
return result
} }
// GetRawChangeAddress returns a new address for receiving change that will be // GetRawChangeAddress returns a new address for receiving change that will be
@ -945,12 +966,15 @@ func (c *Client) GetRawChangeAddress(account string) (btcutil.Address, error) {
// FutureAddWitnessAddressResult is a future promise to deliver the result of // FutureAddWitnessAddressResult is a future promise to deliver the result of
// a AddWitnessAddressAsync RPC invocation (or an applicable error). // a AddWitnessAddressAsync RPC invocation (or an applicable error).
type FutureAddWitnessAddressResult chan *response type FutureAddWitnessAddressResult struct {
responseChannel chan *response
network *chaincfg.Params
}
// Receive waits for the response promised by the future and returns the new // Receive waits for the response promised by the future and returns the new
// address. // address.
func (r FutureAddWitnessAddressResult) Receive() (btcutil.Address, error) { func (r FutureAddWitnessAddressResult) Receive() (btcutil.Address, error) {
res, err := receiveFuture(r) res, err := receiveFuture(r.responseChannel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -962,7 +986,7 @@ func (r FutureAddWitnessAddressResult) Receive() (btcutil.Address, error) {
return nil, err return nil, err
} }
return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) return btcutil.DecodeAddress(addr, r.network)
} }
// AddWitnessAddressAsync returns an instance of a type that can be used to get // AddWitnessAddressAsync returns an instance of a type that can be used to get
@ -972,7 +996,11 @@ func (r FutureAddWitnessAddressResult) Receive() (btcutil.Address, error) {
// See AddWitnessAddress for the blocking version and more details. // See AddWitnessAddress for the blocking version and more details.
func (c *Client) AddWitnessAddressAsync(address string) FutureAddWitnessAddressResult { func (c *Client) AddWitnessAddressAsync(address string) FutureAddWitnessAddressResult {
cmd := btcjson.NewAddWitnessAddressCmd(address) cmd := btcjson.NewAddWitnessAddressCmd(address)
return c.sendCmd(cmd) response := FutureAddWitnessAddressResult{
network: c.chainParams,
responseChannel: c.sendCmd(cmd),
}
return response
} }
// AddWitnessAddress adds a witness address for a script and returns the new // AddWitnessAddress adds a witness address for a script and returns the new
@ -983,12 +1011,15 @@ func (c *Client) AddWitnessAddress(address string) (btcutil.Address, error) {
// FutureGetAccountAddressResult is a future promise to deliver the result of a // FutureGetAccountAddressResult is a future promise to deliver the result of a
// GetAccountAddressAsync RPC invocation (or an applicable error). // GetAccountAddressAsync RPC invocation (or an applicable error).
type FutureGetAccountAddressResult chan *response type FutureGetAccountAddressResult struct {
responseChannel chan *response
network *chaincfg.Params
}
// Receive waits for the response promised by the future and returns the current // Receive waits for the response promised by the future and returns the current
// Bitcoin address for receiving payments to the specified account. // Bitcoin address for receiving payments to the specified account.
func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) { func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) {
res, err := receiveFuture(r) res, err := receiveFuture(r.responseChannel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1000,7 +1031,7 @@ func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) {
return nil, err return nil, err
} }
return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) return btcutil.DecodeAddress(addr, r.network)
} }
// GetAccountAddressAsync returns an instance of a type that can be used to get // GetAccountAddressAsync returns an instance of a type that can be used to get
@ -1010,7 +1041,11 @@ func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) {
// See GetAccountAddress for the blocking version and more details. // See GetAccountAddress for the blocking version and more details.
func (c *Client) GetAccountAddressAsync(account string) FutureGetAccountAddressResult { func (c *Client) GetAccountAddressAsync(account string) FutureGetAccountAddressResult {
cmd := btcjson.NewGetAccountAddressCmd(account) cmd := btcjson.NewGetAccountAddressCmd(account)
return c.sendCmd(cmd) result := FutureGetAccountAddressResult{
network: c.chainParams,
responseChannel: c.sendCmd(cmd),
}
return result
} }
// GetAccountAddress returns the current Bitcoin address for receiving payments // GetAccountAddress returns the current Bitcoin address for receiving payments
@ -1086,12 +1121,15 @@ func (c *Client) SetAccount(address btcutil.Address, account string) error {
// FutureGetAddressesByAccountResult is a future promise to deliver the result // FutureGetAddressesByAccountResult is a future promise to deliver the result
// of a GetAddressesByAccountAsync RPC invocation (or an applicable error). // of a GetAddressesByAccountAsync RPC invocation (or an applicable error).
type FutureGetAddressesByAccountResult chan *response type FutureGetAddressesByAccountResult struct {
responseChannel chan *response
network *chaincfg.Params
}
// Receive waits for the response promised by the future and returns the list of // Receive waits for the response promised by the future and returns the list of
// addresses associated with the passed account. // addresses associated with the passed account.
func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) { func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) {
res, err := receiveFuture(r) res, err := receiveFuture(r.responseChannel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1103,17 +1141,15 @@ func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error)
return nil, err return nil, err
} }
addrs := make([]btcutil.Address, 0, len(addrStrings)) addresses := make([]btcutil.Address, len(addrStrings))
for _, addrStr := range addrStrings { for i, addrString := range addrStrings {
addr, err := btcutil.DecodeAddress(addrStr, addresses[i], err = btcutil.DecodeAddress(addrString, r.network)
&chaincfg.MainNetParams)
if err != nil { if err != nil {
return nil, err return nil, err
} }
addrs = append(addrs, addr)
} }
return addrs, nil return addresses, nil
} }
// GetAddressesByAccountAsync returns an instance of a type that can be used to // GetAddressesByAccountAsync returns an instance of a type that can be used to
@ -1123,7 +1159,11 @@ func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error)
// See GetAddressesByAccount for the blocking version and more details. // See GetAddressesByAccount for the blocking version and more details.
func (c *Client) GetAddressesByAccountAsync(account string) FutureGetAddressesByAccountResult { func (c *Client) GetAddressesByAccountAsync(account string) FutureGetAddressesByAccountResult {
cmd := btcjson.NewGetAddressesByAccountCmd(account) cmd := btcjson.NewGetAddressesByAccountCmd(account)
return c.sendCmd(cmd) result := FutureGetAddressesByAccountResult{
network: c.chainParams,
responseChannel: c.sendCmd(cmd),
}
return result
} }
// GetAddressesByAccount returns the list of addresses associated with the // GetAddressesByAccount returns the list of addresses associated with the