add helpers to make routing records for Host

This commit is contained in:
Yusef Napora 2019-11-08 11:09:02 -05:00
parent 83260dfd12
commit b8de7fa7f3
2 changed files with 56 additions and 1 deletions

View File

@ -1,6 +1,11 @@
package host
import "github.com/libp2p/go-libp2p-core/peer"
import (
"errors"
"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/routing"
)
// InfoFromHost returns a peer.AddrInfo struct with the Host's ID and all of its Addrs.
func InfoFromHost(h Host) *peer.AddrInfo {
@ -9,3 +14,19 @@ func InfoFromHost(h Host) *peer.AddrInfo {
Addrs: h.Addrs(),
}
}
// RoutingStateFromHost returns a routing.RoutingState record that contains the Host's
// ID and all of its listen Addrs.
func RoutingStateFromHost(h Host) *routing.RoutingState {
return routing.RoutingStateFromAddrInfo(InfoFromHost(h))
}
// SignedRoutingStateFromHost
func SignedRoutingStateFromHost(h Host) (*crypto.SignedEnvelope, error) {
privKey := h.Peerstore().PrivKey(h.ID())
if privKey == nil {
return nil, errors.New("unable to find host's private key in peerstore")
}
return RoutingStateFromHost(h).ToSignedEnvelope(privKey)
}

View File

@ -7,11 +7,16 @@ import (
"github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
pb "github.com/libp2p/go-libp2p-core/routing/pb"
"time"
)
// The domain string used for routing state records contained in a SignedEnvelope.
const StateEnvelopeDomain = "libp2p-routing-record"
// The type hint used to identify routing state records in a SignedEnvelope.
// TODO: register multicodec
var StateEnvelopeTypeHint = []byte("/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.
@ -36,6 +41,18 @@ type RoutingState struct {
Addresses []*AnnotatedAddr
}
func RoutingStateFromAddrInfo(info *peer.AddrInfo) *RoutingState {
annotated := make([]*AnnotatedAddr, len(info.Addrs))
for i, a := range info.Addrs {
annotated[i] = &AnnotatedAddr{Multiaddr: a}
}
return &RoutingState{
PeerID: info.ID,
Seq: statelessSeqNo(),
Addresses: annotated,
}
}
// UnmarshalRoutingState unpacks a peer RoutingState record from a serialized protobuf representation.
func UnmarshalRoutingState(serialized []byte) (*RoutingState, error) {
msg := pb.RoutingStateRecord{}
@ -72,6 +89,16 @@ func RoutingStateFromEnvelope(envelope *crypto.SignedEnvelope) (*RoutingState, e
return state, nil
}
// ToSignedEnvelope wraps a Marshal'd RoutingState record in a SignedEnvelope using the
// given private signing key.
func (s *RoutingState) ToSignedEnvelope(key crypto.PrivKey) (*crypto.SignedEnvelope, error) {
payload, err := s.Marshal()
if err != nil {
return nil, err
}
return crypto.MakeEnvelope(key, StateEnvelopeDomain, StateEnvelopeTypeHint, payload)
}
// Marshal serializes a RoutingState record to protobuf and returns its byte representation.
func (s *RoutingState) Marshal() ([]byte, error) {
id, err := s.PeerID.MarshalBinary()
@ -95,6 +122,13 @@ func (s *RoutingState) Multiaddrs() []ma.Multiaddr {
return out
}
func statelessSeqNo() uint64 {
// use current time in milliseconds as seq number
// nanoseconds would overflow in 2262, but millis gives us
// a few hundred thousand years
return uint64(time.Now().UnixNano() / 1e6)
}
func addrsFromProtobuf(addrs []*pb.RoutingStateRecord_AddressInfo) []*AnnotatedAddr {
out := make([]*AnnotatedAddr, 0)
for _, addr := range addrs {