diff --git a/peer/addrinfo_serde.go b/peer/addrinfo_serde.go index 1df24e2b738d5fcaefbb610107de960bb9fd0a73..cef144fbe53c923ac53d557425419502999d7174 100644 --- a/peer/addrinfo_serde.go +++ b/peer/addrinfo_serde.go @@ -6,33 +6,38 @@ import ( ma "github.com/multiformats/go-multiaddr" ) +// Helper struct for decoding as we can't unmarshal into an interface (Multiaddr). +type addrInfoJson struct { + ID ID + Addrs []string +} + func (pi AddrInfo) MarshalJSON() ([]byte, error) { - out := make(map[string]interface{}) - out["ID"] = pi.ID.Pretty() - var addrs []string - for _, a := range pi.Addrs { - addrs = append(addrs, a.String()) + addrs := make([]string, len(pi.Addrs)) + for i, addr := range pi.Addrs { + addrs[i] = addr.String() } - out["Addrs"] = addrs - return json.Marshal(out) + return json.Marshal(&addrInfoJson{ + ID: pi.ID, + Addrs: addrs, + }) } func (pi *AddrInfo) UnmarshalJSON(b []byte) error { - var data map[string]interface{} - err := json.Unmarshal(b, &data) - if err != nil { + var data addrInfoJson + if err := json.Unmarshal(b, &data); err != nil { return err } - pid, err := IDB58Decode(data["ID"].(string)) - if err != nil { - return err - } - pi.ID = pid - addrs, ok := data["Addrs"].([]interface{}) - if ok { - for _, a := range addrs { - pi.Addrs = append(pi.Addrs, ma.StringCast(a.(string))) + addrs := make([]ma.Multiaddr, len(data.Addrs)) + for i, addr := range data.Addrs { + maddr, err := ma.NewMultiaddr(addr) + if err != nil { + return err } + addrs[i] = maddr } + + pi.ID = data.ID + pi.Addrs = addrs return nil } diff --git a/peer/addrinfo_test.go b/peer/addrinfo_test.go index b902fdf350ec7a52270c92c59beff1fdf352d877..5d1ce0a92e1ef39c488126f72969b4ea185ca3bf 100644 --- a/peer/addrinfo_test.go +++ b/peer/addrinfo_test.go @@ -133,3 +133,21 @@ func TestAddrInfosFromP2pAddrs(t *testing.T) { delete(expected, info.ID.Pretty()) } } + +func TestAddrInfoJSON(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) + } +}