Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi: add getnetworkinfo rpc. #1536

Merged
merged 1 commit into from
Aug 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion addrmgr/addrmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ type localAddress struct {
score AddressPriority
}

// LocalAddr represents network address information for a local address.
type LocalAddr struct {
dnldd marked this conversation as resolved.
Show resolved Hide resolved
Address string
Port uint16
Score int32
}

// AddressPriority type is used to describe the hierarchy of local address
// discovery methods.
type AddressPriority int
Expand Down Expand Up @@ -536,7 +543,7 @@ func (a *AddrManager) deserializePeers(filePath string) error {

if v.refs > 0 && v.tried {
return fmt.Errorf("address %s after serialisation "+
"which is both new and tried!", k)
"which is both new and tried", k)
}
}

Expand Down Expand Up @@ -1022,6 +1029,25 @@ func (a *AddrManager) HasLocalAddress(na *wire.NetAddress) bool {
return ok
}

// FetchLocalAddresses fetches a summary of local addresses information for
// the getnetworkinfo rpc.
func (a *AddrManager) FetchLocalAddresses() []LocalAddr {
a.lamtx.Lock()
defer a.lamtx.Unlock()

addrs := make([]LocalAddr, 0, len(a.localAddresses))
for _, addr := range a.localAddresses {
la := LocalAddr{
Address: addr.na.IP.String(),
Port: addr.na.Port,
}

addrs = append(addrs, la)
}

return addrs
}

const (
// Unreachable represents a publicly unreachable connection state
// between two addresses.
Expand Down
43 changes: 43 additions & 0 deletions docs/json_rpc_api.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ the method name for further details such as parameter and return information.
|Y
|Returns the estimated network hashes per second for the block heights provided by the parameters.
|-
|[[#getnetworkinfo|getnetworkinfo]]
|Y
|Returns a JSON object containing network-related information.
|-
|[[#getpeerinfo|getpeerinfo]]
|N
|Returns information about each connected network peer as an array of json objects.
Expand Down Expand Up @@ -950,6 +954,45 @@ the method name for further details such as parameter and return information.

----

====getnetworkinfo====
{|
!Method
|getnetworkinfo
|-
!Parameters
|None
|-
!Description
|Returns a JSON object containing network-related information.
|-
!Returns
|<code>(json object)</code>
: <code>address</code>: <code>(string)</code> The local address being listened on.
: <code>port</code>: <code>(numeric)</code> The port being listened on for the associated local address.
: <code>score</code>: <code>(numeric)</code> Reserved.
: <code>name</code>: <code>(string)</code> The name of the network interface.
: <code>limited</code>: <code>(boolean)</code> True if only connections to the network are allowed.
: <code>proxy</code>: <code>(string)</code> The proxy set for the network.
: <code>proxyrandomizecredentials</code>: <code>(boolean)</code> True if randomized credentials are set for the proxy.
: <code>reachable</code>: <code>(boolean)</code> True if connections can be made to or from the network.
: <code>version</code>: <code>(numeric)</code> The version of the node as a numeric.
: <code>subversion</code>: <code>(string)</code> The subversion of the node, as advertised to peers.
: <code>protocolversion</code>: <code>(numeric)</code> The protocol version of the node.
: <code>timeoffset</code>: <code>(numeric)</code> The node clock offset in seconds.
: <code>connections</code>: <code>(numeric)</code> The total number of open connections for the node.
: <code>networks</code>: <code>(json array)</code> An array of objects describing IPV4, IPV6 and Onion network interface states.
: <code>relayfee</code>: <code>(numeric)</code> The minimum required transaction fee for the node.
: <code>localaddresses</code>: <code>(json array)</code> An array of objects describing local addresses being listened on by the node.
: <code>localservices</code>: <code>(string)</code> The services supported by the node, as advertised in its version message.

<code>{"version": n, "subversion": "major.minor.patch", "protocolversion": n, "timeoffset": n, "connections": n, "networks": [{"name": "network", "limited": true or false, "reachable": true or false, "proxy": "host:port","proxyrandomizecredentials": true or false }, ...], "relayfee": n.nn., "localaddresses": [{ "address": "ip", "port": n, "score": n }, ...], "localservices": "services"}</code>
|-
!Example Return
|<code>{"version": 1050000, "subversion": "1.5.0", "protocolversion": 6, "timeoffset": 0, "connections": 4, "networks": [{"name": "IPV4", "limited": true, "reachable": true, "proxy": "127.0.0.1:9050", "proxyrandomizecredentials": false}, {"name": "IPV6", "limited": false, "reachable": false, "proxy": "", "proxyrandomizecredentials": false}, {"name": "Onion", "limited": false, "reachable": false, "proxy": "", "proxyrandomizecredentials": false}], "relayfee": 0.0001, "localaddresses": [{"address": "fd87:d87e:eb43:d208:593b:4305:c8e5:2e77", "port": 9108, "score": 0}], "localservices": "0000000000000005"}</code>
|}

----

====getpeerinfo====
{|
!Method
Expand Down
2 changes: 2 additions & 0 deletions rpc/jsonrpc/types/chainsvrresults.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,14 @@ type NetworksResult struct {
// command.
type GetNetworkInfoResult struct {
Version int32 `json:"version"`
SubVersion string `json:"subversion"`
ProtocolVersion int32 `json:"protocolversion"`
TimeOffset int64 `json:"timeoffset"`
Connections int32 `json:"connections"`
Networks []NetworksResult `json:"networks"`
RelayFee float64 `json:"relayfee"`
LocalAddresses []LocalAddressesResult `json:"localaddresses"`
LocalServices string `json:"localservices"`
}

// GetNetTotalsResult models the data returned from the getnettotals command.
Expand Down
32 changes: 31 additions & 1 deletion rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ var rpcHandlersBeforeInit = map[types.Method]commandHandler{
"getmininginfo": handleGetMiningInfo,
"getnettotals": handleGetNetTotals,
"getnetworkhashps": handleGetNetworkHashPS,
"getnetworkinfo": handleGetNetworkInfo,
"getpeerinfo": handleGetPeerInfo,
"getrawmempool": handleGetRawMempool,
"getrawtransaction": handleGetRawTransaction,
Expand Down Expand Up @@ -299,7 +300,6 @@ var rpcAskWallet = map[string]struct{}{
var rpcUnimplemented = map[string]struct{}{
"estimatepriority": {},
"getblocktemplate": {},
"getnetworkinfo": {},
}

// Commands that are available to a limited user
Expand Down Expand Up @@ -331,6 +331,7 @@ var rpcLimited = map[string]struct{}{
"getinfo": {},
"getnettotals": {},
"getnetworkhashps": {},
"getnetworkinfo": {},
"getrawmempool": {},
"getrawtransaction": {},
"gettxout": {},
Expand Down Expand Up @@ -3359,6 +3360,35 @@ func handleGetNetworkHashPS(s *rpcServer, cmd interface{}, closeChan <-chan stru
return hashesPerSec.Int64(), nil
}

// handleGetNetworkInfo implements the getnetworkinfo command.
func handleGetNetworkInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
networks := cfg.generateNetworkInfo()
lAddrs := s.server.addrManager.FetchLocalAddresses()
localAddrs := make([]types.LocalAddressesResult, len(lAddrs))
for idx, entry := range lAddrs {
addr := types.LocalAddressesResult{
Address: entry.Address,
Port: entry.Port,
}
localAddrs[idx] = addr
}

info := types.GetNetworkInfoResult{
Version: int32(1000000*version.Major + 10000*version.Minor +
100*version.Patch),
SubVersion: userAgentVersion,
ProtocolVersion: int32(maxProtocolVersion),
TimeOffset: int64(s.server.timeSource.Offset().Seconds()),
Connections: s.server.ConnectedCount(),
RelayFee: cfg.minRelayTxFee.ToCoin(),
Networks: networks,
LocalAddresses: localAddrs,
LocalServices: fmt.Sprintf("%016x", uint64(s.server.services)),
}

return info, nil
}

// handleGetPeerInfo implements the getpeerinfo command.
func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
peers := s.server.Peers()
Expand Down
27 changes: 27 additions & 0 deletions rpcserverhelp.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,32 @@ var helpDescsEnUS = map[string]string{
"getnetworkhashps-height": "Perform estimate ending with this height or -1 for current best chain block height",
"getnetworkhashps--result0": "Estimated hashes per second",

// GetNetworkInfoCmd help.
"getnetworkinfo--synopsis": "Returns a JSON object containing network-related information.",

// LocalAddressesResult help.
"localaddressesresult-address": "The local address being listened on",
"localaddressesresult-port": "The port being listened on for the associated local address",
"localaddressesresult-score": "Reserved",

// NetworksResult help.
"networksresult-name": "The name of the network interface",
"networksresult-limited": "True if only connections to the network are allowed",
"networksresult-proxy": "The proxy set for the network",
"networksresult-proxyrandomizecredentials": "True if randomized credentials are set for the proxy",
"networksresult-reachable": "True if connections can be made to or from the network",

// GetNetworkInfoResult help.
"getnetworkinforesult-version": "The version of the node as a numeric",
"getnetworkinforesult-subversion": "The subversion of the node, as advertised to peers",
"getnetworkinforesult-protocolversion": "The protocol version of the node",
"getnetworkinforesult-timeoffset": "The node clock offset in seconds",
"getnetworkinforesult-connections": "The total number of open connections for the node",
"getnetworkinforesult-networks": "An array of objects describing IPV4, IPV6 and Onion network interface states",
"getnetworkinforesult-relayfee": "The minimum required transaction fee for the node.",
"getnetworkinforesult-localaddresses": "An array of objects describing local addresses being listened on by the node",
"getnetworkinforesult-localservices": "The services supported by the node, as advertised in its version message",

// GetNetTotalsCmd help.
"getnettotals--synopsis": "Returns a JSON object containing network traffic statistics.",

Expand Down Expand Up @@ -990,6 +1016,7 @@ var rpcResultTypes = map[types.Method][]interface{}{
"getmininginfo": {(*types.GetMiningInfoResult)(nil)},
"getnettotals": {(*types.GetNetTotalsResult)(nil)},
"getnetworkhashps": {(*int64)(nil)},
"getnetworkinfo": {(*[]types.GetNetworkInfoResult)(nil)},
"getpeerinfo": {(*[]types.GetPeerInfoResult)(nil)},
"getrawmempool": {(*[]string)(nil), (*types.GetRawMempoolVerboseResult)(nil)},
"getrawtransaction": {(*string)(nil), (*types.TxRawResult)(nil)},
Expand Down