add routing state records, extend peerstore API

This commit is contained in:
Yusef Napora 2019-12-20 16:13:11 -05:00
parent 10ff6fca32
commit 83260dfd12
7 changed files with 772 additions and 1 deletions

1
go.mod
View File

@ -4,6 +4,7 @@ require (
github.com/btcsuite/btcd v0.20.1-beta
github.com/coreos/go-semver v0.3.0
github.com/gogo/protobuf v1.3.1
github.com/golang/protobuf v1.3.1
github.com/ipfs/go-cid v0.0.4
github.com/jbenet/goprocess v0.1.3
github.com/libp2p/go-flow-metrics v0.0.3

1
go.sum
View File

@ -34,6 +34,7 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=

View File

@ -96,6 +96,10 @@ type AddrBook interface {
// If the manager has a longer TTL, the operation is a no-op for that address
AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration)
// AddCertifiedAddrs adds addresses from a PeerStateRecord contained
// in the given SignedEnvelope.
AddCertifiedAddrs(envelope *ic.SignedEnvelope, ttl time.Duration) error
// SetAddr calls mgr.SetAddrs(p, addr, ttl)
SetAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration)
@ -107,9 +111,14 @@ type AddrBook interface {
// the given oldTTL to have the given newTTL.
UpdateAddrs(p peer.ID, oldTTL time.Duration, newTTL time.Duration)
// Addresses returns all known (and valid) addresses for a given peer
// Addrs returns all known (and valid) addresses for a given peer
Addrs(p peer.ID) []ma.Multiaddr
// CertifiedAddrs returns all known addresses for a peer that have
// been certified by that peer. CertifiedAddrs are contained in
// a SignedEnvelope and added to the Peerstore using AddCertifiedAddrs.
CertifiedAddrs(p peer.ID) []ma.Multiaddr
// AddrStream returns a channel that gets all addresses for a given
// peer sent on it. If new addresses are added after the call is made
// they will be sent along through the channel as well.

11
routing/pb/Makefile Normal file
View File

@ -0,0 +1,11 @@
PB = $(wildcard *.proto)
GO = $(PB:.proto=.pb.go)
all: $(GO)
%.pb.go: %.proto
protoc --proto_path=$(GOPATH)/src:. --gogofaster_out=. $<
clean:
rm -f *.pb.go
rm -f *.go

View File

@ -0,0 +1,621 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: routing_state.proto
package routing_pb
import (
fmt "fmt"
github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type RoutingStateRecord struct {
PeerId []byte `protobuf:"bytes,1,req,name=peerId" json:"peerId"`
Seq uint64 `protobuf:"varint,2,req,name=seq" json:"seq"`
Addresses []*RoutingStateRecord_AddressInfo `protobuf:"bytes,3,rep,name=addresses" json:"addresses,omitempty"`
}
func (m *RoutingStateRecord) Reset() { *m = RoutingStateRecord{} }
func (m *RoutingStateRecord) String() string { return proto.CompactTextString(m) }
func (*RoutingStateRecord) ProtoMessage() {}
func (*RoutingStateRecord) Descriptor() ([]byte, []int) {
return fileDescriptor_2bc7f62bc26d3acc, []int{0}
}
func (m *RoutingStateRecord) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *RoutingStateRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_RoutingStateRecord.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *RoutingStateRecord) XXX_Merge(src proto.Message) {
xxx_messageInfo_RoutingStateRecord.Merge(m, src)
}
func (m *RoutingStateRecord) XXX_Size() int {
return m.Size()
}
func (m *RoutingStateRecord) XXX_DiscardUnknown() {
xxx_messageInfo_RoutingStateRecord.DiscardUnknown(m)
}
var xxx_messageInfo_RoutingStateRecord proto.InternalMessageInfo
func (m *RoutingStateRecord) GetPeerId() []byte {
if m != nil {
return m.PeerId
}
return nil
}
func (m *RoutingStateRecord) GetSeq() uint64 {
if m != nil {
return m.Seq
}
return 0
}
func (m *RoutingStateRecord) GetAddresses() []*RoutingStateRecord_AddressInfo {
if m != nil {
return m.Addresses
}
return nil
}
type RoutingStateRecord_AddressInfo struct {
Multiaddr []byte `protobuf:"bytes,1,req,name=multiaddr" json:"multiaddr"`
}
func (m *RoutingStateRecord_AddressInfo) Reset() { *m = RoutingStateRecord_AddressInfo{} }
func (m *RoutingStateRecord_AddressInfo) String() string { return proto.CompactTextString(m) }
func (*RoutingStateRecord_AddressInfo) ProtoMessage() {}
func (*RoutingStateRecord_AddressInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_2bc7f62bc26d3acc, []int{0, 0}
}
func (m *RoutingStateRecord_AddressInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *RoutingStateRecord_AddressInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_RoutingStateRecord_AddressInfo.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *RoutingStateRecord_AddressInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_RoutingStateRecord_AddressInfo.Merge(m, src)
}
func (m *RoutingStateRecord_AddressInfo) XXX_Size() int {
return m.Size()
}
func (m *RoutingStateRecord_AddressInfo) XXX_DiscardUnknown() {
xxx_messageInfo_RoutingStateRecord_AddressInfo.DiscardUnknown(m)
}
var xxx_messageInfo_RoutingStateRecord_AddressInfo proto.InternalMessageInfo
func (m *RoutingStateRecord_AddressInfo) GetMultiaddr() []byte {
if m != nil {
return m.Multiaddr
}
return nil
}
func init() {
proto.RegisterType((*RoutingStateRecord)(nil), "routing.pb.RoutingStateRecord")
proto.RegisterType((*RoutingStateRecord_AddressInfo)(nil), "routing.pb.RoutingStateRecord.AddressInfo")
}
func init() { proto.RegisterFile("routing_state.proto", fileDescriptor_2bc7f62bc26d3acc) }
var fileDescriptor_2bc7f62bc26d3acc = []byte{
// 198 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2e, 0xca, 0x2f, 0x2d,
0xc9, 0xcc, 0x4b, 0x8f, 0x2f, 0x2e, 0x49, 0x2c, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17,
0xe2, 0x82, 0x0a, 0xea, 0x15, 0x24, 0x29, 0x1d, 0x67, 0xe4, 0x12, 0x0a, 0x82, 0x70, 0x83, 0x41,
0x4a, 0x82, 0x52, 0x93, 0xf3, 0x8b, 0x52, 0x84, 0x64, 0xb8, 0xd8, 0x0a, 0x52, 0x53, 0x8b, 0x3c,
0x53, 0x24, 0x18, 0x15, 0x98, 0x34, 0x78, 0x9c, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x82, 0x8a,
0x09, 0x89, 0x71, 0x31, 0x17, 0xa7, 0x16, 0x4a, 0x30, 0x29, 0x30, 0x69, 0xb0, 0x40, 0xa5, 0x40,
0x02, 0x42, 0x1e, 0x5c, 0x9c, 0x89, 0x29, 0x29, 0x45, 0xa9, 0xc5, 0xc5, 0xa9, 0xc5, 0x12, 0xcc,
0x0a, 0xcc, 0x1a, 0xdc, 0x46, 0x5a, 0x7a, 0x08, 0xcb, 0xf4, 0x30, 0x2d, 0xd2, 0x73, 0x84, 0xa8,
0xf7, 0xcc, 0x4b, 0xcb, 0x0f, 0x42, 0x68, 0x96, 0x32, 0xe4, 0xe2, 0x46, 0x92, 0x11, 0x52, 0xe2,
0xe2, 0xcc, 0x2d, 0xcd, 0x29, 0xc9, 0x04, 0x29, 0x40, 0x71, 0x11, 0x42, 0xd8, 0x49, 0xe2, 0xc4,
0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1,
0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0x00, 0x01, 0x00, 0x00, 0xff, 0xff, 0x13, 0x14,
0xbe, 0xc4, 0x05, 0x01, 0x00, 0x00,
}
func (m *RoutingStateRecord) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *RoutingStateRecord) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.PeerId != nil {
dAtA[i] = 0xa
i++
i = encodeVarintRoutingState(dAtA, i, uint64(len(m.PeerId)))
i += copy(dAtA[i:], m.PeerId)
}
dAtA[i] = 0x10
i++
i = encodeVarintRoutingState(dAtA, i, uint64(m.Seq))
if len(m.Addresses) > 0 {
for _, msg := range m.Addresses {
dAtA[i] = 0x1a
i++
i = encodeVarintRoutingState(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n
}
}
return i, nil
}
func (m *RoutingStateRecord_AddressInfo) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *RoutingStateRecord_AddressInfo) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Multiaddr != nil {
dAtA[i] = 0xa
i++
i = encodeVarintRoutingState(dAtA, i, uint64(len(m.Multiaddr)))
i += copy(dAtA[i:], m.Multiaddr)
}
return i, nil
}
func encodeVarintRoutingState(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func (m *RoutingStateRecord) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.PeerId != nil {
l = len(m.PeerId)
n += 1 + l + sovRoutingState(uint64(l))
}
n += 1 + sovRoutingState(uint64(m.Seq))
if len(m.Addresses) > 0 {
for _, e := range m.Addresses {
l = e.Size()
n += 1 + l + sovRoutingState(uint64(l))
}
}
return n
}
func (m *RoutingStateRecord_AddressInfo) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Multiaddr != nil {
l = len(m.Multiaddr)
n += 1 + l + sovRoutingState(uint64(l))
}
return n
}
func sovRoutingState(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozRoutingState(x uint64) (n int) {
return sovRoutingState(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *RoutingStateRecord) Unmarshal(dAtA []byte) error {
var hasFields [1]uint64
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRoutingState
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: RoutingStateRecord: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: RoutingStateRecord: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PeerId", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRoutingState
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthRoutingState
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthRoutingState
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.PeerId = append(m.PeerId[:0], dAtA[iNdEx:postIndex]...)
if m.PeerId == nil {
m.PeerId = []byte{}
}
iNdEx = postIndex
hasFields[0] |= uint64(0x00000001)
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Seq", wireType)
}
m.Seq = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRoutingState
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Seq |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
hasFields[0] |= uint64(0x00000002)
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRoutingState
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthRoutingState
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthRoutingState
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Addresses = append(m.Addresses, &RoutingStateRecord_AddressInfo{})
if err := m.Addresses[len(m.Addresses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRoutingState(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthRoutingState
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthRoutingState
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if hasFields[0]&uint64(0x00000001) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("peerId")
}
if hasFields[0]&uint64(0x00000002) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("seq")
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *RoutingStateRecord_AddressInfo) Unmarshal(dAtA []byte) error {
var hasFields [1]uint64
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRoutingState
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: AddressInfo: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: AddressInfo: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Multiaddr", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRoutingState
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthRoutingState
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthRoutingState
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Multiaddr = append(m.Multiaddr[:0], dAtA[iNdEx:postIndex]...)
if m.Multiaddr == nil {
m.Multiaddr = []byte{}
}
iNdEx = postIndex
hasFields[0] |= uint64(0x00000001)
default:
iNdEx = preIndex
skippy, err := skipRoutingState(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthRoutingState
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthRoutingState
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if hasFields[0]&uint64(0x00000001) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("multiaddr")
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipRoutingState(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRoutingState
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRoutingState
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRoutingState
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthRoutingState
}
iNdEx += length
if iNdEx < 0 {
return 0, ErrInvalidLengthRoutingState
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRoutingState
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipRoutingState(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
if iNdEx < 0 {
return 0, ErrInvalidLengthRoutingState
}
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthRoutingState = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowRoutingState = fmt.Errorf("proto: integer overflow")
)

View File

@ -0,0 +1,12 @@
syntax = "proto2";
package routing.pb;
message RoutingStateRecord {
message AddressInfo {
required bytes multiaddr = 1;
}
required bytes peerId = 1;
required uint64 seq = 2;
repeated AddressInfo addresses = 3;
}

116
routing/state.go Normal file
View File

@ -0,0 +1,116 @@
package routing
import (
"errors"
"github.com/gogo/protobuf/proto"
"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
pb "github.com/libp2p/go-libp2p-core/routing/pb"
)
// The domain string used for routing state records contained in a SignedEnvelope.
const StateEnvelopeDomain = "libp2p-routing-record"
// AnnotatedAddr will extend the Multiaddr type with additional metadata, as
// extensions are added to the routing state record spec. It's defined now to
// make refactoring simpler in the future.
type AnnotatedAddr struct {
ma.Multiaddr
}
// RoutingState contains a snapshot of public, transient state (e.g. addresses, supported protocols)
// for a peer at a given point in time, where "time" is defined by the sequence counter
// field Seq. Greater Seq values are later in time than lesser values, but there are no
// guarantees about the wall-clock time between any two Seq values.
//
// Note that Seq values are peer-specific and can only be compared for records with equal PeerIDs.
type RoutingState struct {
// PeerID is the ID of the peer this record pertains to.
PeerID peer.ID
// Seq is an increment-only sequence counter used to order RoutingState records in time.
Seq uint64
// Addresses contains the public addresses of the peer this record pertains to.
Addresses []*AnnotatedAddr
}
// UnmarshalRoutingState unpacks a peer RoutingState record from a serialized protobuf representation.
func UnmarshalRoutingState(serialized []byte) (*RoutingState, error) {
msg := pb.RoutingStateRecord{}
err := proto.Unmarshal(serialized, &msg)
if err != nil {
return nil, err
}
id, err := peer.IDFromBytes(msg.PeerId)
if err != nil {
return nil, err
}
return &RoutingState{
PeerID: id,
Seq: msg.Seq,
Addresses: addrsFromProtobuf(msg.Addresses),
}, nil
}
// RoutingStateFromEnvelope unwraps a peer RoutingState record from a SignedEnvelope.
// This method will fail if the signature is invalid, or if the record
// belongs to a peer other than the one that signed the envelope.
func RoutingStateFromEnvelope(envelope *crypto.SignedEnvelope) (*RoutingState, error) {
msgBytes, err := envelope.Open(StateEnvelopeDomain)
if err != nil {
return nil, err
}
state, err := UnmarshalRoutingState(msgBytes)
if err != nil {
return nil, err
}
if !state.PeerID.MatchesPublicKey(envelope.PublicKey) {
return nil, errors.New("peer id in routing state record does not match signing key")
}
return state, nil
}
// Marshal serializes a RoutingState record to protobuf and returns its byte representation.
func (s *RoutingState) Marshal() ([]byte, error) {
id, err := s.PeerID.MarshalBinary()
if err != nil {
return nil, err
}
msg := pb.RoutingStateRecord{
PeerId: id,
Seq: s.Seq,
Addresses: addrsToProtobuf(s.Addresses),
}
return proto.Marshal(&msg)
}
// Multiaddrs returns the addresses from a RoutingState record without any metadata annotations.
func (s *RoutingState) Multiaddrs() []ma.Multiaddr {
out := make([]ma.Multiaddr, len(s.Addresses))
for i, addr := range s.Addresses {
out[i] = addr.Multiaddr
}
return out
}
func addrsFromProtobuf(addrs []*pb.RoutingStateRecord_AddressInfo) []*AnnotatedAddr {
out := make([]*AnnotatedAddr, 0)
for _, addr := range addrs {
a, err := ma.NewMultiaddrBytes(addr.Multiaddr)
if err != nil {
continue
}
out = append(out, &AnnotatedAddr{Multiaddr: a})
}
return out
}
func addrsToProtobuf(addrs []*AnnotatedAddr) []*pb.RoutingStateRecord_AddressInfo {
out := make([]*pb.RoutingStateRecord_AddressInfo, 0)
for _, addr := range addrs {
out = append(out, &pb.RoutingStateRecord_AddressInfo{Multiaddr: addr.Bytes()})
}
return out
}