Skip to content

Commit

Permalink
Merge pull request #2914 from ixje/fix-getpeers
Browse files Browse the repository at this point in the history
neorpc: change peer port to int type (fixes #2910)
  • Loading branch information
roman-khimov authored Apr 7, 2023
2 parents ce7658e + f479b2b commit 601c26b
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 15 deletions.
9 changes: 9 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,12 @@ for security reasons.

Removal of these options from ProtocolConfiguration is scheduled for May-June
2023 (~0.103.0 release).

## GetPeers RPC server response type changes and RPC client support

GetPeers RPC command returns a list of Peers where the port type has changed from
string to uint16 to match C#. The RPC client currently supports unmarshalling both
formats.

Removal of Peer unmarshalling with string based ports is scheduled for ~September 2023
(~0.105.0 release).
50 changes: 45 additions & 5 deletions pkg/neorpc/result/peers.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package result

import (
"strings"
"encoding/json"
"net"
"strconv"
)

type (
Expand All @@ -18,7 +20,7 @@ type (
// Peer represents a peer.
Peer struct {
Address string `json:"address"`
Port string `json:"port"`
Port uint16 `json:"port"`
}
)

Expand Down Expand Up @@ -49,12 +51,50 @@ 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 {
addressParts := strings.Split(addrs[i], ":")
host, portStr, err := net.SplitHostPort(addrs[i])
if err != nil {
continue
}
port, err := strconv.ParseUint(portStr, 10, 16)
if err != nil {
port = 0
}
peer := Peer{
Address: addressParts[0],
Port: addressParts[1],
Address: host,
Port: uint16(port),
}

*p = append(*p, peer)
}
}

func (p *Peer) UnmarshalJSON(data []byte) error {
type NewPeer Peer
var np NewPeer

err := json.Unmarshal(data, &np)
if err == nil {
*p = Peer(np)
return nil
}

type OldPeer struct {
Address string `json:"address"`
Port string `json:"port"`
}
var op OldPeer

err = json.Unmarshal(data, &op)
if err == nil {
port, err := strconv.ParseUint(op.Port, 10, 16)
if err != nil {
return err
}

*p = Peer{
Address: op.Address,
Port: uint16(port),
}
}
return err
}
30 changes: 24 additions & 6 deletions pkg/neorpc/result/peers_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package result

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -13,14 +14,31 @@ func TestGetPeers(t *testing.T) {
require.Equal(t, 0, len(gp.Bad))

gp.AddUnconnected([]string{"1.1.1.1:53", "8.8.8.8:53", "9.9.9.9:53"})
gp.AddConnected([]string{"192.168.0.1:10333"})
gp.AddBad([]string{"127.0.0.1:20333"})
unsupportedFormat := "2001:DB0:0:123A:::30"
gp.AddConnected([]string{"192.168.0.1:10333", unsupportedFormat, "[2001:DB0:0:123A::]:30"})
gp.AddBad([]string{"127.0.0.1:20333", "127.0.0.1:65536"})

require.Equal(t, 3, len(gp.Unconnected))
require.Equal(t, 1, len(gp.Connected))
require.Equal(t, 1, len(gp.Bad))
require.Equal(t, 2, len(gp.Connected))
require.Equal(t, 2, len(gp.Bad))
require.Equal(t, "192.168.0.1", gp.Connected[0].Address)
require.Equal(t, "10333", gp.Connected[0].Port)
require.Equal(t, uint16(10333), gp.Connected[0].Port)
require.Equal(t, uint16(30), gp.Connected[1].Port)
require.Equal(t, "127.0.0.1", gp.Bad[0].Address)
require.Equal(t, "20333", gp.Bad[0].Port)
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"}]}`
err := json.Unmarshal([]byte(oldPeerFormat), &gps)
require.NoError(t, err)
newPeerFormat := `{"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},{"address": "54.208.117.178","port": 10333}]}`
err = json.Unmarshal([]byte(newPeerFormat), &gps)
require.NoError(t, err)
badIntFormat := `{"unconnected": [{"address": "20.109.188.128","port": 65536}],"connected": [],"bad": []}`
err = json.Unmarshal([]byte(badIntFormat), &gps)
require.Error(t, err)
badStringFormat := `{"unconnected": [{"address": "20.109.188.128","port": "badport"}],"connected": [],"bad": []}`
err = json.Unmarshal([]byte(badStringFormat), &gps)
require.Error(t, err)
}
9 changes: 5 additions & 4 deletions pkg/rpcclient/rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -700,25 +700,26 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
invoke: func(c *Client) (any, error) {
return c.GetPeers()
},
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"unconnected":[{"address":"172.200.0.1","port":"20333"}],"connected":[{"address":"127.0.0.1","port":"20335"}],"bad":[{"address":"172.200.0.254","port":"20332"}]}}`,
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"unconnected":[{"address":"172.200.0.1","port":20333}],"connected":[{"address":"127.0.0.1","port":20335}],"bad":[{"address":"172.200.0.254","port":20332}]}}`,
result: func(c *Client) any {

return &result.GetPeers{
Unconnected: result.Peers{
{
Address: "172.200.0.1",
Port: "20333",
Port: 20333,
},
},
Connected: result.Peers{
{
Address: "127.0.0.1",
Port: "20335",
Port: 20335,
},
},
Bad: result.Peers{
{
Address: "172.200.0.254",
Port: "20332",
Port: 20332,
},
},
}
Expand Down

0 comments on commit 601c26b

Please sign in to comment.