source formatting
no behavior changes Signed-off-by: Ciro S. Costa <utxobr@protonmail.com>
This commit is contained in:
parent
e94f6ae0dd
commit
096ad758c2
|
@ -24,14 +24,21 @@ func (c *peerListCommand) Cmd() *cobra.Command {
|
|||
RunE: c.RunE,
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&c.NodeAddress, "node-address",
|
||||
"", "address of the node to connect to")
|
||||
cmd.Flags().StringVar(&c.NodeAddress,
|
||||
"node-address",
|
||||
"",
|
||||
"address of the node to connect to")
|
||||
_ = cmd.MarkFlagRequired("node-address")
|
||||
|
||||
cmd.Flags().DurationVar(&c.Timeout, "timeout",
|
||||
1*time.Minute, "how long to wait until considering the connection a failure")
|
||||
cmd.Flags().StringVar(&c.Proxy, "proxy",
|
||||
"", "proxy to proxy connections through (useful for tor)")
|
||||
cmd.Flags().DurationVar(&c.Timeout,
|
||||
"timeout",
|
||||
1*time.Minute,
|
||||
"how long to wait until considering the connection a failure")
|
||||
|
||||
cmd.Flags().StringVar(&c.Proxy,
|
||||
"proxy",
|
||||
"",
|
||||
"proxy to proxy connections through (useful for tor)")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -51,7 +58,8 @@ func (c *peerListCommand) RunE(_ *cobra.Command, _ []string) error {
|
|||
|
||||
contextDialer, ok := dialer.(proxy.ContextDialer)
|
||||
if !ok {
|
||||
panic("can't cast proxy dialer to proxy context dialer")
|
||||
return fmt.Errorf("can't cast proxy dialer " +
|
||||
"to proxy context dialer")
|
||||
}
|
||||
|
||||
opts = append(opts, levin.WithContextDialer(contextDialer))
|
||||
|
|
|
@ -35,7 +35,7 @@ func (o *options) Context() (context.Context, context.CancelFunc) {
|
|||
// Client instantiates a new daemon RPC client based on the options filled.
|
||||
//
|
||||
func (o *options) Client() (*daemon.Client, error) {
|
||||
httpClient, err := mhttp.NewHTTPClient(o.ClientConfig)
|
||||
httpClient, err := mhttp.NewClient(o.ClientConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("new httpclient: %w", err)
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ func (o *options) Client() (*daemon.Client, error) {
|
|||
// filled.
|
||||
//
|
||||
func (o *options) WalletClient() (*wallet.Client, error) {
|
||||
httpClient, err := mhttp.NewHTTPClient(o.ClientConfig)
|
||||
httpClient, err := mhttp.NewClient(o.ClientConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("new httpclient: %w", err)
|
||||
}
|
||||
|
@ -73,24 +73,38 @@ func (o *options) WalletClient() (*wallet.Client, error) {
|
|||
// can be filled either via comand arguments or environment variables.
|
||||
//
|
||||
func Bind(cmd *cobra.Command) {
|
||||
cmd.PersistentFlags().BoolVarP(&RootOptions.Verbose, "verbose", "v",
|
||||
false, "dump http requests and responses to stderr")
|
||||
cmd.PersistentFlags().BoolVarP(&RootOptions.Verbose,
|
||||
"verbose", "v",
|
||||
false,
|
||||
"dump http requests and responses to stderr")
|
||||
|
||||
cmd.PersistentFlags().StringVarP(&RootOptions.address, "address", "a",
|
||||
"http://localhost:18081", "full address of the monero node to reach out to")
|
||||
cmd.PersistentFlags().StringVarP(&RootOptions.address,
|
||||
"address", "a",
|
||||
"http://localhost:18081",
|
||||
"full address of the monero node to reach out to")
|
||||
|
||||
cmd.PersistentFlags().BoolVarP(&RootOptions.TLSSkipVerify, "tls-skip-verify", "k",
|
||||
false, "skip verification of certificate chain and host name")
|
||||
cmd.PersistentFlags().BoolVarP(&RootOptions.TLSSkipVerify,
|
||||
"tls-skip-verify", "k",
|
||||
false,
|
||||
"skip verification of certificate chain and host name")
|
||||
|
||||
cmd.PersistentFlags().StringVar(&RootOptions.TLSClientCert, "tls-client-cert",
|
||||
"", "tls client certificate to use when connecting")
|
||||
cmd.PersistentFlags().StringVar(&RootOptions.TLSClientCert,
|
||||
"tls-client-cert",
|
||||
"",
|
||||
"tls client certificate to use when connecting")
|
||||
|
||||
cmd.PersistentFlags().StringVar(&RootOptions.TLSClientKey, "tls-client-key",
|
||||
"", "tls client key to use when connecting")
|
||||
cmd.PersistentFlags().StringVar(&RootOptions.TLSClientKey,
|
||||
"tls-client-key",
|
||||
"",
|
||||
"tls client key to use when connecting")
|
||||
|
||||
cmd.PersistentFlags().StringVar(&RootOptions.TLSCACert, "tls-ca-cert",
|
||||
"", "certificate authority to load")
|
||||
cmd.PersistentFlags().StringVar(&RootOptions.TLSCACert,
|
||||
"tls-ca-cert",
|
||||
"",
|
||||
"certificate authority to load")
|
||||
|
||||
cmd.PersistentFlags().DurationVar(&RootOptions.RequestTimeout, "request-timeout",
|
||||
1*time.Minute, "how long to wait until considering the request a failure")
|
||||
cmd.PersistentFlags().DurationVar(&RootOptions.RequestTimeout,
|
||||
"request-timeout",
|
||||
1*time.Minute,
|
||||
"max wait time until considering the request a failure")
|
||||
}
|
||||
|
|
|
@ -7,35 +7,63 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// ClientConfig provides extra configuration to tweak the behavior of the HTTP
|
||||
// client instantiated via `NewClient`.
|
||||
//
|
||||
type ClientConfig struct {
|
||||
TLSSkipVerify bool
|
||||
TLSClientCert string
|
||||
TLSClientKey string
|
||||
TLSCACert string
|
||||
Verbose bool
|
||||
// TLSSkipVerify indicates that the client should not perform any
|
||||
// hostname or certificate chain of trust validations.
|
||||
//
|
||||
TLSSkipVerify bool
|
||||
|
||||
// TLSClientCert is the path to a TLS client certificate to be used
|
||||
// when connecting to a TLS server.
|
||||
//
|
||||
// ps.: must be supplied together with TLSClientKey.
|
||||
//
|
||||
TLSClientCert string
|
||||
|
||||
// TLSClientKey is the path to a TLS private key certificate to be used
|
||||
// when connecting to a TLS server.
|
||||
//
|
||||
// ps.: must be supplied together with TLSClientCert.
|
||||
//
|
||||
TLSClientKey string
|
||||
|
||||
// TLSCACert is the path to a certificate authority certificate that
|
||||
// should be included in the chain of trust.
|
||||
//
|
||||
TLSCACert string
|
||||
|
||||
// Verbose dictates whether the transport should dump all request and
|
||||
// response information to stderr.
|
||||
//
|
||||
Verbose bool
|
||||
|
||||
// RequestTimeout places a deadline on every request issued by this
|
||||
// client.
|
||||
//
|
||||
RequestTimeout time.Duration
|
||||
}
|
||||
|
||||
func (c ClientConfig) Validate() error {
|
||||
if c.TLSClientCert != "" && c.TLSClientKey == "" {
|
||||
return fmt.Errorf("tls client certificate specified but tls client key not")
|
||||
return fmt.Errorf("tls client certificate specified " +
|
||||
"but tls client key not")
|
||||
}
|
||||
|
||||
if c.TLSClientKey != "" && c.TLSClientCert == "" {
|
||||
return fmt.Errorf("tls client key specified but tls client key")
|
||||
return fmt.Errorf("tls client key specified but " +
|
||||
"tls client key")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewHTTPClient instantiates a new `http.Client` with a few defaults.
|
||||
// NewClient instantiates a new `http.Client` based on the client configuration
|
||||
// supplied.
|
||||
//
|
||||
// `verbose`: if set, adds a transport that dumps all requests and responses to
|
||||
// stdout.
|
||||
//
|
||||
// `skipTLSVerify`: if set, skips TLS validation.
|
||||
//
|
||||
func NewHTTPClient(cfg ClientConfig) (*http.Client, error) {
|
||||
func NewClient(cfg ClientConfig) (*http.Client, error) {
|
||||
if err := cfg.Validate(); err != nil {
|
||||
return nil, fmt.Errorf("validate: %w", err)
|
||||
}
|
||||
|
@ -50,13 +78,17 @@ func NewHTTPClient(cfg ClientConfig) (*http.Client, error) {
|
|||
}
|
||||
|
||||
if cfg.TLSClientCert != "" {
|
||||
if err := WithClientCertificate(cfg.TLSClientCert, cfg.TLSClientKey)(tlsConfig); err != nil {
|
||||
return nil, fmt.Errorf("with tls client certificate: %w", err)
|
||||
err := WithClientCertificate(
|
||||
cfg.TLSClientCert, cfg.TLSClientKey,
|
||||
)(tlsConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"with tls client certificate: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.TLSSkipVerify {
|
||||
_ = WithInsecureSkipVerify()(tlsConfig)
|
||||
WithInsecureSkipVerify()(tlsConfig)
|
||||
}
|
||||
|
||||
transport := http.DefaultTransport.(*http.Transport).Clone()
|
||||
|
|
|
@ -7,9 +7,7 @@ import (
|
|||
"os"
|
||||
)
|
||||
|
||||
type TLSOption func(*tls.Config) error
|
||||
|
||||
func WithCACert(fpath string) TLSOption {
|
||||
func WithCACert(fpath string) func(*tls.Config) error {
|
||||
return func(config *tls.Config) error {
|
||||
certBytes, err := os.ReadFile(fpath)
|
||||
if err != nil {
|
||||
|
@ -27,15 +25,13 @@ func WithCACert(fpath string) TLSOption {
|
|||
}
|
||||
}
|
||||
|
||||
func WithInsecureSkipVerify() TLSOption {
|
||||
return func(config *tls.Config) error {
|
||||
func WithInsecureSkipVerify() func(*tls.Config) {
|
||||
return func(config *tls.Config) {
|
||||
config.InsecureSkipVerify = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithClientCertificate(cert, key string) TLSOption {
|
||||
func WithClientCertificate(cert, key string) func(*tls.Config) error {
|
||||
return func(config *tls.Config) error {
|
||||
keypair, err := tls.LoadX509KeyPair(cert, key)
|
||||
if err != nil {
|
||||
|
|
|
@ -78,7 +78,7 @@ func NewClient(address string, opts ...ClientOption) (*Client, error) {
|
|||
}
|
||||
|
||||
if options.HTTPClient == nil {
|
||||
httpClient, err := mhttp.NewHTTPClient(mhttp.ClientConfig{})
|
||||
httpClient, err := mhttp.NewClient(mhttp.ClientConfig{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("new http client: %w", err)
|
||||
}
|
||||
|
|
|
@ -9,13 +9,20 @@ type Requester interface {
|
|||
// JSONRPC is used for callind methods under `/json_rpc` that follow
|
||||
// monero's `v2` response and error encapsulation.
|
||||
//
|
||||
JSONRPC(ctx context.Context, method string, params interface{}, result interface{}) error
|
||||
JSONRPC(
|
||||
ctx context.Context, method string, params, result interface{},
|
||||
) error
|
||||
|
||||
// RawRequest is used for making a request to an arbitrary endpoint
|
||||
// `endpoint` whose response (in JSON format) should be unmarshalled to
|
||||
// `response`.
|
||||
//
|
||||
RawRequest(ctx context.Context, endpoint string, params interface{}, response interface{}) error
|
||||
RawRequest(
|
||||
ctx context.Context,
|
||||
endpoint string,
|
||||
params interface{},
|
||||
response interface{},
|
||||
) error
|
||||
}
|
||||
|
||||
// Client provides access to the daemon's JSONRPC methods and regular
|
||||
|
|
|
@ -355,7 +355,8 @@ type GetBlockRequestParameters struct {
|
|||
Hash string `json:"hash,omitempty"`
|
||||
}
|
||||
|
||||
// GetBlock fetches full block information from a block at a particular hash OR height.
|
||||
// GetBlock fetches full block information from a block at a particular hash OR
|
||||
// height.
|
||||
//
|
||||
func (c *Client) GetBlock(
|
||||
ctx context.Context, params GetBlockRequestParameters,
|
||||
|
|
|
@ -25,13 +25,15 @@ type RPCResultFooter struct {
|
|||
TopHash string `json:"top_hash,omitempty"`
|
||||
}
|
||||
|
||||
// GetAlternateChainsResult is the result of a call to the GetAlternateChains RPC method.
|
||||
// GetAlternateChainsResult is the result of a call to the GetAlternateChains
|
||||
// RPC method.
|
||||
//
|
||||
type GetAlternateChainsResult struct {
|
||||
// Chains is the array of alternate chains seen by the node.
|
||||
//
|
||||
Chains []struct {
|
||||
// BlockHash is the hash of the first diverging block of this alternative chain.
|
||||
// BlockHash is the hash of the first diverging block of this
|
||||
// alternative chain.
|
||||
//
|
||||
BlockHash string `json:"block_hash"`
|
||||
|
||||
|
@ -39,7 +41,8 @@ type GetAlternateChainsResult struct {
|
|||
//
|
||||
BlockHashes []string `json:"block_hashes"`
|
||||
|
||||
// Difficulty is the cumulative difficulty of all blocks in the alternative chain.
|
||||
// Difficulty is the cumulative difficulty of all blocks in the
|
||||
// alternative chain.
|
||||
//
|
||||
Difficulty int64 `json:"difficulty"`
|
||||
|
||||
|
@ -48,11 +51,13 @@ type GetAlternateChainsResult struct {
|
|||
//
|
||||
DifficultyTop64 int `json:"difficulty_top64"`
|
||||
|
||||
// Height is the block height of the first diverging block of this alternative chain.
|
||||
// Height is the block height of the first diverging block of
|
||||
// this alternative chain.
|
||||
//
|
||||
Height uint64 `json:"height"`
|
||||
|
||||
// Length is the length in blocks of this alternative chain, after divergence.
|
||||
// Length is the length in blocks of this alternative chain,
|
||||
// after divergence.
|
||||
//
|
||||
Length uint64 `json:"length"`
|
||||
|
||||
|
@ -69,7 +74,8 @@ type GetAlternateChainsResult struct {
|
|||
RPCResultFooter `json:",inline"`
|
||||
}
|
||||
|
||||
// AccessTrackingResult is the result of a call to the RPCAccessTracking RPC method.
|
||||
// AccessTrackingResult is the result of a call to the RPCAccessTracking RPC
|
||||
// method.
|
||||
//
|
||||
type RPCAccessTrackingResult struct {
|
||||
Data []struct {
|
||||
|
@ -82,11 +88,13 @@ type RPCAccessTrackingResult struct {
|
|||
//
|
||||
RPC string `json:"rpc"`
|
||||
|
||||
// Time indicates how much time the daemon spent serving this procedure.
|
||||
// Time indicates how much time the daemon spent serving this
|
||||
// procedure.
|
||||
//
|
||||
Time uint64 `json:"time"`
|
||||
|
||||
// Credits indicates the number of credits consumed for this method.
|
||||
// Credits indicates the number of credits consumed for this
|
||||
// method.
|
||||
//
|
||||
Credits uint64 `json:"credits"`
|
||||
} `json:"data"`
|
||||
|
@ -152,7 +160,8 @@ type GetBansResult struct {
|
|||
// Bans contains the list of nodes banned by this node.
|
||||
//
|
||||
Bans []struct {
|
||||
// Host is the string representation of the node that is banned.
|
||||
// Host is the string representation of the node that is
|
||||
// banned.
|
||||
//
|
||||
Host string `json:"host"`
|
||||
|
||||
|
@ -225,7 +234,8 @@ type GetInfoResult struct {
|
|||
RPCResultFooter `json:",inline"`
|
||||
}
|
||||
|
||||
// GetBlockTemplateResult is the result of a call to the GetBlockTemplate RPC method.
|
||||
// GetBlockTemplateResult is the result of a call to the GetBlockTemplate RPC
|
||||
// method.
|
||||
//
|
||||
type GetBlockTemplateResult struct {
|
||||
// BlockhashingBlob is the blob on which to try to find a valid nonce.
|
||||
|
@ -248,7 +258,8 @@ type GetBlockTemplateResult struct {
|
|||
//
|
||||
Height int `json:"height"`
|
||||
|
||||
// PrevHash is the hash of the most recent block on which to mine the next block.
|
||||
// PrevHash is the hash of the most recent block on which to mine the
|
||||
// next block.
|
||||
//
|
||||
PrevHash string `json:"prev_hash"`
|
||||
|
||||
|
@ -278,7 +289,8 @@ type GetPeerListResult struct {
|
|||
RPCResultFooter `json:",inline"`
|
||||
}
|
||||
|
||||
// GetConnectionsResult is the result of a call to the GetConnections RPC method.
|
||||
// GetConnectionsResult is the result of a call to the GetConnections RPC
|
||||
// method.
|
||||
//
|
||||
type GetConnectionsResult struct {
|
||||
Connections []struct {
|
||||
|
@ -341,7 +353,8 @@ type GetNetStatsResult struct {
|
|||
RPCResultFooter `json:",inline"`
|
||||
}
|
||||
|
||||
// GetPublicNodesResult is the result of a call to the GetPublicNodes RPC method.
|
||||
// GetPublicNodesResult is the result of a call to the GetPublicNodes RPC
|
||||
// method.
|
||||
//
|
||||
type GetPublicNodesResult struct {
|
||||
WhiteList []Peer `json:"white"`
|
||||
|
@ -350,7 +363,8 @@ type GetPublicNodesResult struct {
|
|||
RPCResultFooter `json:",inline"`
|
||||
}
|
||||
|
||||
// GenerateBlocksResult is the result of a call to the GenerateBlocks RPC method.
|
||||
// GenerateBlocksResult is the result of a call to the GenerateBlocks RPC
|
||||
// method.
|
||||
//
|
||||
type GenerateBlocksResult struct {
|
||||
Blocks []string `json:"blocks"`
|
||||
|
@ -373,7 +387,8 @@ type RelayTxResult struct {
|
|||
RPCResultFooter `json:",inline"`
|
||||
}
|
||||
|
||||
// GetCoinbaseTxSumResult is the result of a call to the GetCoinbaseTxSum RPC method.
|
||||
// GetCoinbaseTxSumResult is the result of a call to the GetCoinbaseTxSum RPC
|
||||
// method.
|
||||
//
|
||||
type GetCoinbaseTxSumResult struct {
|
||||
EmissionAmount int64 `json:"emission_amount"`
|
||||
|
@ -424,7 +439,8 @@ type BlockHeader struct {
|
|||
//
|
||||
Hash string `json:"hash"`
|
||||
|
||||
// Height is the number of blocks preceding this block on the blockchain.
|
||||
// Height is the number of blocks preceding this block on the
|
||||
// blockchain.
|
||||
//
|
||||
Height uint64 `json:"height"`
|
||||
|
||||
|
@ -503,7 +519,8 @@ type GetBlockResult struct {
|
|||
//
|
||||
BlockHeader BlockHeader `json:"block_header"`
|
||||
|
||||
// JSON is a json representation of the block - see `GetBlockResultJSON`.
|
||||
// JSON is a json representation of the block - see
|
||||
// `GetBlockResultJSON`.
|
||||
//
|
||||
JSON string `json:"json"`
|
||||
|
||||
|
@ -544,7 +561,8 @@ type GetBlockResultJSON struct {
|
|||
//
|
||||
Version int `json:"version"`
|
||||
|
||||
// UnlockTime is the block height when the coinbase transaction becomes spendable.
|
||||
// UnlockTime is the block height when the coinbase transaction
|
||||
// becomes spendable.
|
||||
//
|
||||
UnlockTime int `json:"unlock_time"`
|
||||
|
||||
|
@ -639,7 +657,8 @@ type SyncInfoResult struct {
|
|||
RPCResultFooter `json:",inline"`
|
||||
}
|
||||
|
||||
// GetLastBlockHeaderResult is the result of a call to the GetLastBlockHeader RPC method.
|
||||
// GetLastBlockHeaderResult is the result of a call to the GetLastBlockHeader
|
||||
// RPC method.
|
||||
//
|
||||
type GetLastBlockHeaderResult struct {
|
||||
BlockHeader BlockHeader `json:"block_header"`
|
||||
|
@ -647,7 +666,8 @@ type GetLastBlockHeaderResult struct {
|
|||
RPCResultFooter `json:",inline"`
|
||||
}
|
||||
|
||||
// GetBlockHeaderByHeightResult is the result of a call to the GetBlockHeaderByHeight RPC method.
|
||||
// GetBlockHeaderByHeightResult is the result of a call to the
|
||||
// GetBlockHeaderByHeight RPC method.
|
||||
//
|
||||
type GetBlockHeaderByHeightResult struct {
|
||||
BlockHeader BlockHeader `json:"block_header"`
|
||||
|
@ -655,7 +675,8 @@ type GetBlockHeaderByHeightResult struct {
|
|||
RPCResultFooter `json:",inline"`
|
||||
}
|
||||
|
||||
// GetBlockHeaderByHashResult is the result of a call to the GetBlockHeaderByHash RPC method.
|
||||
// GetBlockHeaderByHashResult is the result of a call to the
|
||||
// GetBlockHeaderByHash RPC method.
|
||||
//
|
||||
type GetBlockHeaderByHashResult struct {
|
||||
BlockHeader BlockHeader `json:"block_header"`
|
||||
|
@ -664,7 +685,8 @@ type GetBlockHeaderByHashResult struct {
|
|||
RPCResultFooter `json:",inline"`
|
||||
}
|
||||
|
||||
// GetTransactionPoolStatsResult is the result of a call to the GetTransactionPoolStats RPC method.
|
||||
// GetTransactionPoolStatsResult is the result of a call to the
|
||||
// GetTransactionPoolStats RPC method.
|
||||
//
|
||||
type GetTransactionPoolStatsResult struct {
|
||||
PoolStats struct {
|
||||
|
|
|
@ -9,7 +9,9 @@ type Requester interface {
|
|||
// JSONRPC is used for callind methods under `/json_rpc` that follow
|
||||
// monero's `v2` response and error encapsulation.
|
||||
//
|
||||
JSONRPC(ctx context.Context, method string, params interface{}, result interface{}) error
|
||||
JSONRPC(
|
||||
ctx context.Context, method string, params, result interface{},
|
||||
) error
|
||||
}
|
||||
|
||||
// Client provides access to the daemon's JSONRPC methods and regular
|
||||
|
|
|
@ -9,7 +9,8 @@ const (
|
|||
methodGetBalance = "get_balance"
|
||||
)
|
||||
|
||||
// GetBalance gets the balance of the wallet configured for the wallet rpc server.
|
||||
// GetBalance gets the balance of the wallet configured for the wallet rpc
|
||||
// server.
|
||||
//
|
||||
func (c *Client) GetBalance(ctx context.Context) (*GetBalanceResult, error) {
|
||||
resp := &GetBalanceResult{}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package wallet
|
||||
|
||||
type GetBalanceResult struct {
|
||||
// Balance is the total balance of the current monero-wallet-rpc in session.
|
||||
// Balance is the total balance of the current monero-wallet-rpc in
|
||||
// session.
|
||||
//
|
||||
Balance uint64 `json:"balance"`
|
||||
|
||||
|
|
Reference in a new issue