mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-21 23:29:38 +00:00
neorpc: extend getpeers method
Signed-off-by: edgedlt <edgedlt@protonmail.com>
This commit is contained in:
parent
cf4d4a2611
commit
aab2620548
6 changed files with 77 additions and 18 deletions
|
@ -207,6 +207,15 @@ the error-free C# response that provides a default result.
|
|||
NeoGo can generate an error in response to an invalid proof, unlike
|
||||
the error-free C# implementation.
|
||||
|
||||
##### `getPeers`
|
||||
|
||||
NeoGo extends the `getpeers` RPC call to return the user agent
|
||||
(`useragent` JSON field) and last known block height
|
||||
(`lastknownheight` JSON field) for each connected peer where available.
|
||||
The last known block height field may be stale depending on the
|
||||
PingInterval node config and the time since the last ping.
|
||||
Ping behavior may also differ between node implementations.
|
||||
|
||||
### Unsupported methods
|
||||
|
||||
Methods listed below are not going to be supported for various reasons
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"encoding/json"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/network"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -19,8 +21,10 @@ type (
|
|||
|
||||
// Peer represents a peer.
|
||||
Peer struct {
|
||||
Address string `json:"address"`
|
||||
Port uint16 `json:"port"`
|
||||
Address string `json:"address"`
|
||||
Port uint16 `json:"port"`
|
||||
UserAgent string `json:"useragent,omitempty"`
|
||||
LastKnownHeight uint32 `json:"lastknownheight,omitempty"`
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -38,9 +42,9 @@ func (g *GetPeers) AddUnconnected(addrs []string) {
|
|||
g.Unconnected.addPeers(addrs)
|
||||
}
|
||||
|
||||
// AddConnected adds a set of peers to the connected peers slice.
|
||||
func (g *GetPeers) AddConnected(addrs []string) {
|
||||
g.Connected.addPeers(addrs)
|
||||
// AddConnected adds a set of connected peers to the connected peers slice.
|
||||
func (g *GetPeers) AddConnected(connectedPeers []network.PeerInfo) {
|
||||
g.Connected.addConnectedPeers(connectedPeers)
|
||||
}
|
||||
|
||||
// AddBad adds a set of peers to the bad peers slice.
|
||||
|
@ -51,17 +55,31 @@ func (g *GetPeers) AddBad(addrs []string) {
|
|||
// addPeers adds a set of peers to the given peer slice.
|
||||
func (p *Peers) addPeers(addrs []string) {
|
||||
for i := range addrs {
|
||||
host, portStr, err := net.SplitHostPort(addrs[i])
|
||||
host, port, err := parseHostPort(addrs[i])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
port, err := strconv.ParseUint(portStr, 10, 16)
|
||||
if err != nil {
|
||||
port = 0
|
||||
}
|
||||
peer := Peer{
|
||||
Address: host,
|
||||
Port: uint16(port),
|
||||
Port: port,
|
||||
}
|
||||
|
||||
*p = append(*p, peer)
|
||||
}
|
||||
}
|
||||
|
||||
// addConnectedPeers adds a set of connected peers to the given peer slice.
|
||||
func (p *Peers) addConnectedPeers(connectedPeers []network.PeerInfo) {
|
||||
for i := range connectedPeers {
|
||||
host, port, err := parseHostPort(connectedPeers[i].Address)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
peer := Peer{
|
||||
Address: host,
|
||||
Port: port,
|
||||
UserAgent: connectedPeers[i].UserAgent,
|
||||
LastKnownHeight: connectedPeers[i].Height,
|
||||
}
|
||||
|
||||
*p = append(*p, peer)
|
||||
|
@ -98,3 +116,14 @@ func (p *Peer) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// parseHostPort parses host and port from the given address.
|
||||
// An improperly formatted port string will return zero port.
|
||||
func parseHostPort(addr string) (string, uint16, error) {
|
||||
host, portStr, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
port, _ := strconv.ParseUint(portStr, 10, 16)
|
||||
return host, uint16(port), nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/network"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -15,7 +16,11 @@ func TestGetPeers(t *testing.T) {
|
|||
|
||||
gp.AddUnconnected([]string{"1.1.1.1:53", "8.8.8.8:53", "9.9.9.9:53"})
|
||||
unsupportedFormat := "2001:DB0:0:123A:::30"
|
||||
gp.AddConnected([]string{"192.168.0.1:10333", unsupportedFormat, "[2001:DB0:0:123A::]:30"})
|
||||
gp.AddConnected([]network.PeerInfo{
|
||||
{Address: "192.168.0.1:10333", UserAgent: "/NEO-GO:0.106.2/", Height: 100},
|
||||
{Address: unsupportedFormat, UserAgent: "", Height: 0},
|
||||
{Address: "[2001:DB0:0:123A::]:30", UserAgent: "/NEO-GO:0.106.2/", Height: 200},
|
||||
})
|
||||
gp.AddBad([]string{"127.0.0.1:20333", "127.0.0.1:65536"})
|
||||
|
||||
require.Equal(t, 3, len(gp.Unconnected))
|
||||
|
@ -23,10 +28,13 @@ func TestGetPeers(t *testing.T) {
|
|||
require.Equal(t, 2, len(gp.Bad))
|
||||
require.Equal(t, "192.168.0.1", gp.Connected[0].Address)
|
||||
require.Equal(t, uint16(10333), gp.Connected[0].Port)
|
||||
require.Equal(t, "/NEO-GO:0.106.2/", gp.Connected[0].UserAgent)
|
||||
require.Equal(t, uint32(100), gp.Connected[0].LastKnownHeight)
|
||||
require.Equal(t, uint16(30), gp.Connected[1].Port)
|
||||
require.Equal(t, "/NEO-GO:0.106.2/", gp.Connected[1].UserAgent)
|
||||
require.Equal(t, uint32(200), gp.Connected[1].LastKnownHeight)
|
||||
require.Equal(t, "127.0.0.1", gp.Bad[0].Address)
|
||||
require.Equal(t, uint16(20333), gp.Bad[0].Port)
|
||||
require.Equal(t, uint16(0), gp.Bad[1].Port)
|
||||
|
||||
gps := GetPeers{}
|
||||
oldPeerFormat := `{"unconnected": [{"address": "20.109.188.128","port": "10333"},{"address": "27.188.182.47","port": "10333"}],"connected": [{"address": "54.227.43.72","port": "10333"},{"address": "157.90.177.38","port": "10333"}],"bad": [{"address": "5.226.142.226","port": "10333"}]}`
|
||||
|
|
|
@ -7,6 +7,13 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
||||
)
|
||||
|
||||
// PeerInfo represents the info for a connected peer.
|
||||
type PeerInfo struct {
|
||||
Address string
|
||||
UserAgent string
|
||||
Height uint32
|
||||
}
|
||||
|
||||
type AddressablePeer interface {
|
||||
// ConnectionAddr returns an address-like identifier of this connection
|
||||
// before we have a proper one (after the handshake). It's either the
|
||||
|
|
|
@ -427,13 +427,17 @@ func (s *Server) BadPeers() []string {
|
|||
}
|
||||
|
||||
// ConnectedPeers returns a list of currently connected peers.
|
||||
func (s *Server) ConnectedPeers() []string {
|
||||
func (s *Server) ConnectedPeers() []PeerInfo {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
|
||||
peers := make([]string, 0, len(s.peers))
|
||||
peers := make([]PeerInfo, 0, len(s.peers))
|
||||
for k := range s.peers {
|
||||
peers = append(peers, k.PeerAddr().String())
|
||||
peers = append(peers, PeerInfo{
|
||||
Address: k.PeerAddr().String(),
|
||||
UserAgent: string(k.Version().UserAgent),
|
||||
Height: k.LastBlockIndex(),
|
||||
})
|
||||
}
|
||||
|
||||
return peers
|
||||
|
|
|
@ -580,8 +580,10 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
},
|
||||
Connected: result.Peers{
|
||||
{
|
||||
Address: "127.0.0.1",
|
||||
Port: 20335,
|
||||
Address: "127.0.0.1",
|
||||
Port: 20335,
|
||||
UserAgent: "/NEO-GO:0.106.2/",
|
||||
LastKnownHeight: 1000,
|
||||
},
|
||||
},
|
||||
Bad: result.Peers{
|
||||
|
|
Loading…
Reference in a new issue