2014-05-07 18:14:39 +02:00
|
|
|
// Copyright (c) 2014 Conformal Systems LLC.
|
|
|
|
// Use of this source code is governed by an ISC
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package btcrpcclient
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"github.com/conformal/btcjson"
|
|
|
|
)
|
|
|
|
|
|
|
|
// AddNodeCommand enumerates the available commands that the AddNode function
|
|
|
|
// accepts.
|
|
|
|
type AddNodeCommand string
|
|
|
|
|
|
|
|
// Constants used to indicate the command for the AddNode function.
|
|
|
|
const (
|
|
|
|
// ANAdd indicates the specified host should be added as a persistent
|
|
|
|
// peer.
|
|
|
|
ANAdd AddNodeCommand = "add"
|
|
|
|
|
|
|
|
// ANRemove indicates the specified peer should be removed.
|
|
|
|
ANRemove AddNodeCommand = "remove"
|
|
|
|
|
|
|
|
// ANOneTry indicates the specified host should try to connect once,
|
|
|
|
// but it should not be made persistent.
|
|
|
|
ANOneTry AddNodeCommand = "onetry"
|
|
|
|
)
|
|
|
|
|
|
|
|
// String returns the AddNodeCommand in human-readable form.
|
|
|
|
func (cmd AddNodeCommand) String() string {
|
|
|
|
return string(cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
// FutureAddNodeResult is a future promise to deliver the result of an
|
|
|
|
// AddNodeAsync RPC invocation (or an applicable error).
|
|
|
|
type FutureAddNodeResult chan *futureResult
|
|
|
|
|
|
|
|
// Receive waits for the response promised by the future and returns an error if
|
|
|
|
// any occurred when performing the specified command.
|
|
|
|
func (r FutureAddNodeResult) Receive() error {
|
|
|
|
_, err := receiveFuture(r)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddNodeAsync returns an instance of a type that can be used to get the result
|
|
|
|
// of the RPC at some future time by invoking the Receive function on the
|
|
|
|
// returned instance.
|
|
|
|
//
|
|
|
|
// See AddNode for the blocking version and more details.
|
|
|
|
func (c *Client) AddNodeAsync(host string, command AddNodeCommand) FutureAddNodeResult {
|
|
|
|
id := c.NextID()
|
|
|
|
cmd, err := btcjson.NewAddNodeCmd(id, host, string(command))
|
|
|
|
if err != nil {
|
|
|
|
return newFutureError(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.sendCmd(cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddNode attempts to perform the passed command on the passed persistent peer.
|
|
|
|
// For example, it can be used to add or a remove a persistent peer, or to do
|
|
|
|
// a one time connection to a peer.
|
|
|
|
//
|
|
|
|
// It may not be used to remove non-persistent peers.
|
|
|
|
func (c *Client) AddNode(host string, command AddNodeCommand) error {
|
|
|
|
return c.AddNodeAsync(host, command).Receive()
|
|
|
|
}
|
|
|
|
|
|
|
|
// FutureGetAddedNodeInfoResult is a future promise to deliver the result of a
|
|
|
|
// GetAddedNodeInfoAsync RPC invocation (or an applicable error).
|
|
|
|
type FutureGetAddedNodeInfoResult chan *futureResult
|
|
|
|
|
|
|
|
// Receive waits for the response promised by the future and returns information
|
|
|
|
// about manually added (persistent) peers.
|
|
|
|
func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNodeInfoResult, error) {
|
|
|
|
reply, err := receiveFuture(r)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the returned data is the expected type.
|
|
|
|
nodeInfo, ok := reply.([]btcjson.GetAddedNodeInfoResult)
|
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("unexpected response type for "+
|
|
|
|
"getaddednodeinfo (dns=true): %T\n", reply)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nodeInfo, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAddedNodeInfoAsync returns an instance of a type that can be used to get
|
|
|
|
// the result of the RPC at some future time by invoking the Receive function on
|
|
|
|
// the returned instance.
|
|
|
|
//
|
|
|
|
// See GetAddedNodeInfo for the blocking version and more details.
|
|
|
|
func (c *Client) GetAddedNodeInfoAsync(peer string) FutureGetAddedNodeInfoResult {
|
|
|
|
id := c.NextID()
|
|
|
|
cmd, err := btcjson.NewGetAddedNodeInfoCmd(id, true, peer)
|
|
|
|
if err != nil {
|
|
|
|
return newFutureError(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.sendCmd(cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAddedNodeInfo returns information about manually added (persistent) peers.
|
|
|
|
//
|
|
|
|
// See GetAddedNodeInfoNoDNS to retrieve only a list of the added (persistent)
|
|
|
|
// peers.
|
|
|
|
func (c *Client) GetAddedNodeInfo(peer string) ([]btcjson.GetAddedNodeInfoResult, error) {
|
|
|
|
return c.GetAddedNodeInfoAsync(peer).Receive()
|
|
|
|
}
|
|
|
|
|
|
|
|
// FutureGetAddedNodeInfoNoDNSResult is a future promise to deliver the result
|
|
|
|
// of a GetAddedNodeInfoNoDNSAsync RPC invocation (or an applicable error).
|
|
|
|
type FutureGetAddedNodeInfoNoDNSResult chan *futureResult
|
|
|
|
|
|
|
|
// Receive waits for the response promised by the future and returns a list of
|
|
|
|
// manually added (persistent) peers.
|
|
|
|
func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) {
|
|
|
|
reply, err := receiveFuture(r)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the returned data is the expected type.
|
|
|
|
nodes, ok := reply.([]string)
|
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("unexpected response type for "+
|
|
|
|
"getaddednodeinfo (dns=false): %T\n", reply)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nodes, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAddedNodeInfoNoDNSAsync returns an instance of a type that can be used to
|
|
|
|
// get the result of the RPC at some future time by invoking the Receive
|
|
|
|
// function on the returned instance.
|
|
|
|
//
|
|
|
|
// See GetAddedNodeInfoNoDNS for the blocking version and more details.
|
|
|
|
func (c *Client) GetAddedNodeInfoNoDNSAsync(peer string) FutureGetAddedNodeInfoNoDNSResult {
|
|
|
|
id := c.NextID()
|
|
|
|
cmd, err := btcjson.NewGetAddedNodeInfoCmd(id, false, peer)
|
|
|
|
if err != nil {
|
|
|
|
return newFutureError(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.sendCmd(cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAddedNodeInfoNoDNS returns a list of manually added (persistent) peers.
|
|
|
|
// This works by setting the dns flag to false in the underlying RPC.
|
|
|
|
//
|
|
|
|
// See GetAddedNodeInfo to obtain more information about each added (persistent)
|
|
|
|
// peer.
|
|
|
|
func (c *Client) GetAddedNodeInfoNoDNS(peer string) ([]string, error) {
|
|
|
|
return c.GetAddedNodeInfoNoDNSAsync(peer).Receive()
|
|
|
|
}
|
|
|
|
|
|
|
|
// FutureGetConnectionCountResult is a future promise to deliver the result
|
|
|
|
// of a GetConnectionCountAsync RPC invocation (or an applicable error).
|
|
|
|
type FutureGetConnectionCountResult chan *futureResult
|
|
|
|
|
|
|
|
// Receive waits for the response promised by the future and returns the number
|
|
|
|
// of active connections to other peers.
|
|
|
|
func (r FutureGetConnectionCountResult) Receive() (int64, error) {
|
|
|
|
reply, err := receiveFuture(r)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the returned data is the expected type.
|
|
|
|
fcount, ok := reply.(float64)
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("unexpected response type for "+
|
|
|
|
"getconnectioncount: %T\n", reply)
|
|
|
|
}
|
|
|
|
|
|
|
|
return int64(fcount), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetConnectionCountAsync returns an instance of a type that can be used to get
|
|
|
|
// the result of the RPC at some future time by invoking the Receive function on
|
|
|
|
// the returned instance.
|
|
|
|
//
|
|
|
|
// See GetConnectionCount for the blocking version and more details.
|
|
|
|
func (c *Client) GetConnectionCountAsync() FutureGetConnectionCountResult {
|
|
|
|
id := c.NextID()
|
|
|
|
cmd, err := btcjson.NewGetConnectionCountCmd(id)
|
|
|
|
if err != nil {
|
|
|
|
return newFutureError(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.sendCmd(cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetConnectionCount returns the number of active connections to other peers.
|
|
|
|
func (c *Client) GetConnectionCount() (int64, error) {
|
|
|
|
return c.GetConnectionCountAsync().Receive()
|
|
|
|
}
|
|
|
|
|
|
|
|
// FuturePingResult is a future promise to deliver the result of a PingAsync RPC
|
|
|
|
// invocation (or an applicable error).
|
|
|
|
type FuturePingResult chan *futureResult
|
|
|
|
|
|
|
|
// Receive waits for the response promised by the future and returns the result
|
|
|
|
// of queueing a ping to be sent to each connected peer.
|
|
|
|
func (r FuturePingResult) Receive() error {
|
|
|
|
_, err := receiveFuture(r)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// PingAsync returns an instance of a type that can be used to get the result of
|
|
|
|
// the RPC at some future time by invoking the Receive function on the returned
|
|
|
|
// instance.
|
|
|
|
//
|
|
|
|
// See Ping for the blocking version and more details.
|
|
|
|
func (c *Client) PingAsync() FuturePingResult {
|
|
|
|
id := c.NextID()
|
|
|
|
cmd, err := btcjson.NewPingCmd(id)
|
|
|
|
if err != nil {
|
|
|
|
return newFutureError(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.sendCmd(cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ping queues a ping to be sent to each connected peer.
|
|
|
|
//
|
|
|
|
// Use the GetPeerInfo function and examine the PingTime and PingWait fields to
|
|
|
|
// access the ping times.
|
|
|
|
func (c *Client) Ping() error {
|
|
|
|
return c.PingAsync().Receive()
|
|
|
|
}
|
|
|
|
|
|
|
|
// FutureGetPeerInfoResult is a future promise to deliver the result of a
|
|
|
|
// GetPeerInfoAsync RPC invocation (or an applicable error).
|
|
|
|
type FutureGetPeerInfoResult chan *futureResult
|
|
|
|
|
|
|
|
// Receive waits for the response promised by the future and returns data about
|
|
|
|
// each connected network peer.
|
|
|
|
func (r FutureGetPeerInfoResult) Receive() ([]btcjson.GetPeerInfoResult, error) {
|
|
|
|
reply, err := receiveFuture(r)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the returned data is the expected type.
|
|
|
|
peerInfo, ok := reply.([]btcjson.GetPeerInfoResult)
|
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("unexpected response type for "+
|
|
|
|
"getpeerinfo: %T\n", reply)
|
|
|
|
}
|
|
|
|
|
|
|
|
return peerInfo, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetPeerInfoAsync returns an instance of a type that can be used to get the
|
|
|
|
// result of the RPC at some future time by invoking the Receive function on the
|
|
|
|
// returned instance.
|
|
|
|
//
|
|
|
|
// See GetPeerInfo for the blocking version and more details.
|
|
|
|
func (c *Client) GetPeerInfoAsync() FutureGetPeerInfoResult {
|
|
|
|
id := c.NextID()
|
|
|
|
cmd, err := btcjson.NewGetPeerInfoCmd(id)
|
|
|
|
if err != nil {
|
|
|
|
return newFutureError(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.sendCmd(cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetPeerInfo returns data about each connected network peer.
|
|
|
|
func (c *Client) GetPeerInfo() ([]btcjson.GetPeerInfoResult, error) {
|
|
|
|
return c.GetPeerInfoAsync().Receive()
|
|
|
|
}
|
|
|
|
|
|
|
|
// FutureGetNetTotalsResult is a future promise to deliver the result of a
|
|
|
|
// GetNetTotalsAsync RPC invocation (or an applicable error).
|
|
|
|
type FutureGetNetTotalsResult chan *futureResult
|
|
|
|
|
|
|
|
// Receive waits for the response promised by the future and returns network
|
|
|
|
// traffic statistics.
|
|
|
|
func (r FutureGetNetTotalsResult) Receive() (*btcjson.GetNetTotalsResult, error) {
|
|
|
|
reply, err := receiveFuture(r)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the returned data is the expected type.
|
2014-05-05 21:23:18 +02:00
|
|
|
totals, ok := reply.(*btcjson.GetNetTotalsResult)
|
2014-05-07 18:14:39 +02:00
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("unexpected response type for "+
|
|
|
|
"getnettotals: %T\n", reply)
|
|
|
|
}
|
|
|
|
|
2014-05-05 21:23:18 +02:00
|
|
|
return totals, nil
|
2014-05-07 18:14:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetNetTotalsAsync returns an instance of a type that can be used to get the
|
|
|
|
// result of the RPC at some future time by invoking the Receive function on the
|
|
|
|
// returned instance.
|
|
|
|
//
|
|
|
|
// See GetNetTotals for the blocking version and more details.
|
|
|
|
func (c *Client) GetNetTotalsAsync() FutureGetNetTotalsResult {
|
|
|
|
id := c.NextID()
|
|
|
|
cmd, err := btcjson.NewGetNetTotalsCmd(id)
|
|
|
|
if err != nil {
|
|
|
|
return newFutureError(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.sendCmd(cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNetTotals returns network traffic statistics.
|
|
|
|
func (c *Client) GetNetTotals() (*btcjson.GetNetTotalsResult, error) {
|
|
|
|
return c.GetNetTotalsAsync().Receive()
|
|
|
|
}
|