Skip to content
This repository has been archived by the owner on Sep 6, 2022. It is now read-only.

fix JSON deserialization of peer.AddrInfo #177

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 17 additions & 10 deletions peer/addrinfo_serde.go
Expand Up @@ -2,6 +2,7 @@ package peer

import (
"encoding/json"
"errors"

ma "github.com/multiformats/go-multiaddr"
)
Expand All @@ -19,19 +20,25 @@ func (pi AddrInfo) MarshalJSON() ([]byte, error) {

func (pi *AddrInfo) UnmarshalJSON(b []byte) error {
var data map[string]interface{}
err := json.Unmarshal(b, &data)
if err != nil {
if err := json.Unmarshal(b, &data); err != nil {
return err
}
pid, err := IDB58Decode(data["ID"].(string))
if err != nil {
return err
id, ok := data["ID"]
if !ok {
return errors.New("no peer ID")
}
if idString, ok := id.(string); ok {
pid, err := IDB58Decode(idString)
if err != nil {
return err
}
pi.ID = pid
}
pi.ID = pid
addrs, ok := data["Addrs"].([]interface{})
if ok {
for _, a := range addrs {
pi.Addrs = append(pi.Addrs, ma.StringCast(a.(string)))
if addrsEntry, ok := data["Addrs"]; ok {
if addrs, ok := addrsEntry.([]interface{}); ok {
for _, a := range addrs {
pi.Addrs = append(pi.Addrs, ma.StringCast(a.(string)))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR looks good, the only outstanding issue I see is that ma.StringCast will panic if the multiaddr is malformed or we don't know one of the codecs in the multiaddr. Given this might contain an unknown codec perhaps we should just ignore the particular addr and continue trying to unmarshal the others?

}
}
}
return nil
Expand Down
27 changes: 27 additions & 0 deletions peer/addrinfo_test.go
Expand Up @@ -133,3 +133,30 @@ func TestAddrInfosFromP2pAddrs(t *testing.T) {
delete(expected, info.ID.Pretty())
}
}

func TestAddrInfoJSON(t *testing.T) {
t.Run("valid AddrInfo", func(t *testing.T) {
ai := AddrInfo{ID: testID, Addrs: []ma.Multiaddr{maddrFull}}
out, err := ai.MarshalJSON()
if err != nil {
t.Fatal(err)
}
var addrInfo AddrInfo
if err := addrInfo.UnmarshalJSON(out); err != nil {
t.Fatal(err)
}
if addrInfo.ID != testID {
t.Fatalf("expected ID to equal %s, got %s", testID.Pretty(), addrInfo.ID.Pretty())
}
if len(addrInfo.Addrs) != 1 || !addrInfo.Addrs[0].Equal(maddrFull) {
t.Fatalf("expected addrs to match %v, got %v", maddrFull, addrInfo.Addrs)
}
})
t.Run("missing ID", func(t *testing.T) {
s := []byte(`{"Addrs":["/ip4/127.0.0.1/tcp/1234/p2p/QmS3zcG7LhYZYSJMhyRZvTddvbNUqtt8BJpaSs6mi1K5Va"]}`)
var addrInfo AddrInfo
if err := addrInfo.UnmarshalJSON(s); err == nil || err.Error() != "no peer ID" {
t.Fatalf("expected no peer ID error, got %v", err)
}
})
}