rpc: Add getnodeaddresses JSON-RPC support
Add NodeAddresses function to rpcserverConnManager interface for fetching known node addresses.
This commit is contained in:
parent
9ef973c282
commit
fff96610aa
7 changed files with 150 additions and 0 deletions
|
@ -557,6 +557,22 @@ func NewGetNetworkHashPSCmd(numBlocks, height *int) *GetNetworkHashPSCmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetNodeAddressesCmd defines the getnodeaddresses JSON-RPC command.
|
||||||
|
type GetNodeAddressesCmd struct {
|
||||||
|
Count *int32 `jsonrpcdefault:"1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetNodeAddressesCmd returns a new instance which can be used to issue a
|
||||||
|
// getnodeaddresses JSON-RPC command.
|
||||||
|
//
|
||||||
|
// The parameters which are pointers indicate they are optional. Passing nil
|
||||||
|
// for optional parameters will use the default value.
|
||||||
|
func NewGetNodeAddressesCmd(count *int32) *GetNodeAddressesCmd {
|
||||||
|
return &GetNodeAddressesCmd{
|
||||||
|
Count: count,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetPeerInfoCmd defines the getpeerinfo JSON-RPC command.
|
// GetPeerInfoCmd defines the getpeerinfo JSON-RPC command.
|
||||||
type GetPeerInfoCmd struct{}
|
type GetPeerInfoCmd struct{}
|
||||||
|
|
||||||
|
@ -974,6 +990,7 @@ func init() {
|
||||||
MustRegisterCmd("getnetworkinfo", (*GetNetworkInfoCmd)(nil), flags)
|
MustRegisterCmd("getnetworkinfo", (*GetNetworkInfoCmd)(nil), flags)
|
||||||
MustRegisterCmd("getnettotals", (*GetNetTotalsCmd)(nil), flags)
|
MustRegisterCmd("getnettotals", (*GetNetTotalsCmd)(nil), flags)
|
||||||
MustRegisterCmd("getnetworkhashps", (*GetNetworkHashPSCmd)(nil), flags)
|
MustRegisterCmd("getnetworkhashps", (*GetNetworkHashPSCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("getnodeaddresses", (*GetNodeAddressesCmd)(nil), flags)
|
||||||
MustRegisterCmd("getpeerinfo", (*GetPeerInfoCmd)(nil), flags)
|
MustRegisterCmd("getpeerinfo", (*GetPeerInfoCmd)(nil), flags)
|
||||||
MustRegisterCmd("getrawmempool", (*GetRawMempoolCmd)(nil), flags)
|
MustRegisterCmd("getrawmempool", (*GetRawMempoolCmd)(nil), flags)
|
||||||
MustRegisterCmd("getrawtransaction", (*GetRawTransactionCmd)(nil), flags)
|
MustRegisterCmd("getrawtransaction", (*GetRawTransactionCmd)(nil), flags)
|
||||||
|
|
|
@ -753,6 +753,32 @@ func TestChainSvrCmds(t *testing.T) {
|
||||||
Height: btcjson.Int(123),
|
Height: btcjson.Int(123),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "getnodeaddresses",
|
||||||
|
newCmd: func() (interface{}, error) {
|
||||||
|
return btcjson.NewCmd("getnodeaddresses")
|
||||||
|
},
|
||||||
|
staticCmd: func() interface{} {
|
||||||
|
return btcjson.NewGetNodeAddressesCmd(nil)
|
||||||
|
},
|
||||||
|
marshalled: `{"jsonrpc":"1.0","method":"getnodeaddresses","params":[],"id":1}`,
|
||||||
|
unmarshalled: &btcjson.GetNodeAddressesCmd{
|
||||||
|
Count: btcjson.Int32(1),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "getnodeaddresses optional",
|
||||||
|
newCmd: func() (interface{}, error) {
|
||||||
|
return btcjson.NewCmd("getnodeaddresses", 10)
|
||||||
|
},
|
||||||
|
staticCmd: func() interface{} {
|
||||||
|
return btcjson.NewGetNodeAddressesCmd(btcjson.Int32(10))
|
||||||
|
},
|
||||||
|
marshalled: `{"jsonrpc":"1.0","method":"getnodeaddresses","params":[10],"id":1}`,
|
||||||
|
unmarshalled: &btcjson.GetNodeAddressesCmd{
|
||||||
|
Count: btcjson.Int32(10),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "getpeerinfo",
|
name: "getpeerinfo",
|
||||||
newCmd: func() (interface{}, error) {
|
newCmd: func() (interface{}, error) {
|
||||||
|
|
|
@ -365,6 +365,16 @@ type GetNetworkInfoResult struct {
|
||||||
Warnings string `json:"warnings"`
|
Warnings string `json:"warnings"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetNodeAddressesResult models the data returned from the getnodeaddresses
|
||||||
|
// command.
|
||||||
|
type GetNodeAddressesResult struct {
|
||||||
|
// Timestamp in seconds since epoch (Jan 1 1970 GMT) keeping track of when the node was last seen
|
||||||
|
Time int64 `json:"time"`
|
||||||
|
Services uint64 `json:"services"` // The services offered
|
||||||
|
Address string `json:"address"` // The address of the node
|
||||||
|
Port uint16 `json:"port"` // The port of the node
|
||||||
|
}
|
||||||
|
|
||||||
// GetPeerInfoResult models the data returned from the getpeerinfo command.
|
// GetPeerInfoResult models the data returned from the getpeerinfo command.
|
||||||
type GetPeerInfoResult struct {
|
type GetPeerInfoResult struct {
|
||||||
ID int32 `json:"id"`
|
ID int32 `json:"id"`
|
||||||
|
|
|
@ -223,6 +223,15 @@ func (cm *rpcConnManager) RelayTransactions(txns []*mempool.TxDesc) {
|
||||||
cm.server.relayTransactions(txns)
|
cm.server.relayTransactions(txns)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NodeAddresses returns an array consisting node addresses which can
|
||||||
|
// potentially be used to find new nodes in the network.
|
||||||
|
//
|
||||||
|
// This function is safe for concurrent access and is part of the
|
||||||
|
// rpcserverConnManager interface implementation.
|
||||||
|
func (cm *rpcConnManager) NodeAddresses() []*wire.NetAddress {
|
||||||
|
return cm.server.addrManager.AddressCache()
|
||||||
|
}
|
||||||
|
|
||||||
// rpcSyncMgr provides a block manager for use with the RPC server and
|
// rpcSyncMgr provides a block manager for use with the RPC server and
|
||||||
// implements the rpcserverSyncManager interface.
|
// implements the rpcserverSyncManager interface.
|
||||||
type rpcSyncMgr struct {
|
type rpcSyncMgr struct {
|
||||||
|
|
|
@ -281,6 +281,43 @@ func (c *Client) GetNetworkInfo() (*btcjson.GetNetworkInfoResult, error) {
|
||||||
return c.GetNetworkInfoAsync().Receive()
|
return c.GetNetworkInfoAsync().Receive()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FutureGetNodeAddressesResult is a future promise to deliver the result of a
|
||||||
|
// GetNodeAddressesAsync RPC invocation (or an applicable error).
|
||||||
|
type FutureGetNodeAddressesResult chan *response
|
||||||
|
|
||||||
|
// Receive waits for the response promised by the future and returns data about
|
||||||
|
// known node addresses.
|
||||||
|
func (r FutureGetNodeAddressesResult) Receive() ([]btcjson.GetNodeAddressesResult, error) {
|
||||||
|
res, err := receiveFuture(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal result as an array of getnodeaddresses result objects.
|
||||||
|
var nodeAddresses []btcjson.GetNodeAddressesResult
|
||||||
|
err = json.Unmarshal(res, &nodeAddresses)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeAddresses, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNodeAddressesAsync 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 GetNodeAddresses for the blocking version and more details.
|
||||||
|
func (c *Client) GetNodeAddressesAsync(count *int32) FutureGetNodeAddressesResult {
|
||||||
|
cmd := btcjson.NewGetNodeAddressesCmd(count)
|
||||||
|
return c.sendCmd(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNodeAddresses returns data about known node addresses.
|
||||||
|
func (c *Client) GetNodeAddresses(count *int32) ([]btcjson.GetNodeAddressesResult, error) {
|
||||||
|
return c.GetNodeAddressesAsync(count).Receive()
|
||||||
|
}
|
||||||
|
|
||||||
// FutureGetPeerInfoResult is a future promise to deliver the result of a
|
// FutureGetPeerInfoResult is a future promise to deliver the result of a
|
||||||
// GetPeerInfoAsync RPC invocation (or an applicable error).
|
// GetPeerInfoAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetPeerInfoResult chan *response
|
type FutureGetPeerInfoResult chan *response
|
||||||
|
|
39
rpcserver.go
39
rpcserver.go
|
@ -156,6 +156,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
||||||
"getmininginfo": handleGetMiningInfo,
|
"getmininginfo": handleGetMiningInfo,
|
||||||
"getnettotals": handleGetNetTotals,
|
"getnettotals": handleGetNetTotals,
|
||||||
"getnetworkhashps": handleGetNetworkHashPS,
|
"getnetworkhashps": handleGetNetworkHashPS,
|
||||||
|
"getnodeaddresses": handleGetNodeAddresses,
|
||||||
"getpeerinfo": handleGetPeerInfo,
|
"getpeerinfo": handleGetPeerInfo,
|
||||||
"getrawmempool": handleGetRawMempool,
|
"getrawmempool": handleGetRawMempool,
|
||||||
"getrawtransaction": handleGetRawTransaction,
|
"getrawtransaction": handleGetRawTransaction,
|
||||||
|
@ -2477,6 +2478,40 @@ func handleGetNetworkHashPS(s *rpcServer, cmd interface{}, closeChan <-chan stru
|
||||||
return hashesPerSec.Int64(), nil
|
return hashesPerSec.Int64(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleGetNodeAddresses implements the getnodeaddresses command.
|
||||||
|
func handleGetNodeAddresses(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
|
c := cmd.(*btcjson.GetNodeAddressesCmd)
|
||||||
|
|
||||||
|
count := int32(1)
|
||||||
|
if c.Count != nil {
|
||||||
|
count = *c.Count
|
||||||
|
if count <= 0 {
|
||||||
|
return nil, &btcjson.RPCError{
|
||||||
|
Code: btcjson.ErrRPCInvalidParameter,
|
||||||
|
Message: "Address count out of range",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes := s.cfg.ConnMgr.NodeAddresses()
|
||||||
|
if n := int32(len(nodes)); n < count {
|
||||||
|
count = n
|
||||||
|
}
|
||||||
|
|
||||||
|
addresses := make([]*btcjson.GetNodeAddressesResult, 0, count)
|
||||||
|
for _, node := range nodes[:count] {
|
||||||
|
address := &btcjson.GetNodeAddressesResult{
|
||||||
|
Time: node.Timestamp.Unix(),
|
||||||
|
Services: uint64(node.Services),
|
||||||
|
Address: node.IP.String(),
|
||||||
|
Port: node.Port,
|
||||||
|
}
|
||||||
|
addresses = append(addresses, address)
|
||||||
|
}
|
||||||
|
|
||||||
|
return addresses, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleGetPeerInfo implements the getpeerinfo command.
|
// handleGetPeerInfo implements the getpeerinfo command.
|
||||||
func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
peers := s.cfg.ConnMgr.ConnectedPeers()
|
peers := s.cfg.ConnMgr.ConnectedPeers()
|
||||||
|
@ -4298,6 +4333,10 @@ type rpcserverConnManager interface {
|
||||||
// RelayTransactions generates and relays inventory vectors for all of
|
// RelayTransactions generates and relays inventory vectors for all of
|
||||||
// the passed transactions to all connected peers.
|
// the passed transactions to all connected peers.
|
||||||
RelayTransactions(txns []*mempool.TxDesc)
|
RelayTransactions(txns []*mempool.TxDesc)
|
||||||
|
|
||||||
|
// NodeAddresses returns an array consisting node addresses which can
|
||||||
|
// potentially be used to find new nodes in the network.
|
||||||
|
NodeAddresses() []*wire.NetAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
// rpcserverSyncManager represents a sync manager for use with the RPC server.
|
// rpcserverSyncManager represents a sync manager for use with the RPC server.
|
||||||
|
|
|
@ -452,6 +452,17 @@ var helpDescsEnUS = map[string]string{
|
||||||
"getnettotalsresult-totalbytessent": "Total bytes sent",
|
"getnettotalsresult-totalbytessent": "Total bytes sent",
|
||||||
"getnettotalsresult-timemillis": "Number of milliseconds since 1 Jan 1970 GMT",
|
"getnettotalsresult-timemillis": "Number of milliseconds since 1 Jan 1970 GMT",
|
||||||
|
|
||||||
|
// GetNodeAddressesResult help.
|
||||||
|
"getnodeaddressesresult-time": "Timestamp in seconds since epoch (Jan 1 1970 GMT) keeping track of when the node was last seen",
|
||||||
|
"getnodeaddressesresult-services": "The services offered",
|
||||||
|
"getnodeaddressesresult-address": "The address of the node",
|
||||||
|
"getnodeaddressesresult-port": "The port of the node",
|
||||||
|
|
||||||
|
// GetNodeAddressesCmd help.
|
||||||
|
"getnodeaddresses--synopsis": "Return known addresses which can potentially be used to find new nodes in the network",
|
||||||
|
"getnodeaddresses-count": "How many addresses to return. Limited to the smaller of 2500 or 23% of all known addresses",
|
||||||
|
"getnodeaddresses--result0": "List of node addresses",
|
||||||
|
|
||||||
// GetPeerInfoResult help.
|
// GetPeerInfoResult help.
|
||||||
"getpeerinforesult-id": "A unique node ID",
|
"getpeerinforesult-id": "A unique node ID",
|
||||||
"getpeerinforesult-addr": "The ip address and port of the peer",
|
"getpeerinforesult-addr": "The ip address and port of the peer",
|
||||||
|
@ -726,6 +737,7 @@ var rpcResultTypes = map[string][]interface{}{
|
||||||
"getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)},
|
"getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)},
|
||||||
"getnettotals": {(*btcjson.GetNetTotalsResult)(nil)},
|
"getnettotals": {(*btcjson.GetNetTotalsResult)(nil)},
|
||||||
"getnetworkhashps": {(*int64)(nil)},
|
"getnetworkhashps": {(*int64)(nil)},
|
||||||
|
"getnodeaddresses": {(*[]btcjson.GetNodeAddressesResult)(nil)},
|
||||||
"getpeerinfo": {(*[]btcjson.GetPeerInfoResult)(nil)},
|
"getpeerinfo": {(*[]btcjson.GetPeerInfoResult)(nil)},
|
||||||
"getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)},
|
"getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)},
|
||||||
"getrawtransaction": {(*string)(nil), (*btcjson.TxRawResult)(nil)},
|
"getrawtransaction": {(*string)(nil), (*btcjson.TxRawResult)(nil)},
|
||||||
|
|
Loading…
Reference in a new issue