Source File
record.go
Belonging Package
github.com/libp2p/go-libp2p/core/peer
package peerimport (ma)var _ record.Record = (*PeerRecord)(nil)func init() {record.RegisterType(&PeerRecord{})}// PeerRecordEnvelopeDomain is the domain string used for peer records contained in an Envelope.const PeerRecordEnvelopeDomain = "libp2p-peer-record"// PeerRecordEnvelopePayloadType is the type hint used to identify peer records in an Envelope.// Defined in https://github.com/multiformats/multicodec/blob/master/table.csv// with name "libp2p-peer-record".var PeerRecordEnvelopePayloadType = []byte{0x03, 0x01}// PeerRecord contains information that is broadly useful to share with other peers,// either through a direct exchange (as in the libp2p identify protocol), or through// a Peer Routing provider, such as a DHT.//// Currently, a PeerRecord contains the public listen addresses for a peer, but this// is expected to expand to include other information in the future.//// PeerRecords are ordered in time by their Seq field. Newer PeerRecords must have// greater Seq values than older records. The NewPeerRecord function will create// a PeerRecord with a timestamp-based Seq value. The other PeerRecord fields should// be set by the caller://// rec := peer.NewPeerRecord()// rec.PeerID = aPeerID// rec.Addrs = someAddrs//// Alternatively, you can construct a PeerRecord struct directly and use the TimestampSeq// helper to set the Seq field://// rec := peer.PeerRecord{PeerID: aPeerID, Addrs: someAddrs, Seq: peer.TimestampSeq()}//// Failing to set the Seq field will not result in an error, however, a PeerRecord with a// Seq value of zero may be ignored or rejected by other peers.//// PeerRecords are intended to be shared with other peers inside a signed// routing.Envelope, and PeerRecord implements the routing.Record interface// to facilitate this.//// To share a PeerRecord, first call Sign to wrap the record in an Envelope// and sign it with the local peer's private key://// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs}// envelope, err := rec.Sign(myPrivateKey)//// The resulting record.Envelope can be marshalled to a []byte and shared// publicly. As a convenience, the MarshalSigned method will produce the// Envelope and marshal it to a []byte in one go://// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs}// recordBytes, err := rec.MarshalSigned(myPrivateKey)//// To validate and unmarshal a signed PeerRecord from a remote peer,// "consume" the containing envelope, which will return both the// routing.Envelope and the inner Record. The Record must be cast to// a PeerRecord pointer before use://// envelope, untypedRecord, err := ConsumeEnvelope(envelopeBytes, PeerRecordEnvelopeDomain)// if err != nil {// handleError(err)// return// }// peerRec := untypedRecord.(*PeerRecord)type PeerRecord struct {// PeerID is the ID of the peer this record pertains to.PeerID ID// Addrs contains the public addresses of the peer this record pertains to.Addrs []ma.Multiaddr// Seq is a monotonically-increasing sequence counter that's used to order// PeerRecords in time. The interval between Seq values is unspecified,// but newer PeerRecords MUST have a greater Seq value than older records// for the same peer.Seq uint64}// NewPeerRecord returns a PeerRecord with a timestamp-based sequence number.// The returned record is otherwise empty and should be populated by the caller.func () *PeerRecord {return &PeerRecord{Seq: TimestampSeq()}}// PeerRecordFromAddrInfo creates a PeerRecord from an AddrInfo struct.// The returned record will have a timestamp-based sequence number.func ( AddrInfo) *PeerRecord {:= NewPeerRecord().PeerID = .ID.Addrs = .Addrsreturn}// PeerRecordFromProtobuf creates a PeerRecord from a protobuf PeerRecord// struct.func ( *pb.PeerRecord) (*PeerRecord, error) {:= &PeerRecord{}var IDif := .UnmarshalBinary(.PeerId); != nil {return nil,}.PeerID =.Addrs = addrsFromProtobuf(.Addresses).Seq = .Seqreturn , nil}var (lastTimestampMu sync.MutexlastTimestamp uint64)// TimestampSeq is a helper to generate a timestamp-based sequence number for a PeerRecord.func () uint64 {:= uint64(time.Now().UnixNano())lastTimestampMu.Lock()defer lastTimestampMu.Unlock()// Not all clocks are strictly increasing, but we need these sequence numbers to be strictly// increasing.if <= lastTimestamp {= lastTimestamp + 1}lastTimestamp =return}// Domain is used when signing and validating PeerRecords contained in Envelopes.// It is constant for all PeerRecord instances.func ( *PeerRecord) () string {return PeerRecordEnvelopeDomain}// Codec is a binary identifier for the PeerRecord type. It is constant for all PeerRecord instances.func ( *PeerRecord) () []byte {return PeerRecordEnvelopePayloadType}// UnmarshalRecord parses a PeerRecord from a byte slice.// This method is called automatically when consuming a record.Envelope// whose PayloadType indicates that it contains a PeerRecord.// It is generally not necessary or recommended to call this method directly.func ( *PeerRecord) ( []byte) ( error) {if == nil {return fmt.Errorf("cannot unmarshal PeerRecord to nil receiver")}defer func() { catch.HandlePanic(recover(), &, "libp2p peer record unmarshal") }()var pb.PeerRecord= proto.Unmarshal(, &)if != nil {return}, := PeerRecordFromProtobuf(&)if != nil {return}* = *return nil}// MarshalRecord serializes a PeerRecord to a byte slice.// This method is called automatically when constructing a routing.Envelope// using Seal or PeerRecord.Sign.func ( *PeerRecord) () ( []byte, error) {defer func() { catch.HandlePanic(recover(), &, "libp2p peer record marshal") }(), := .ToProtobuf()if != nil {return nil,}return proto.Marshal()}// Equal returns true if the other PeerRecord is identical to this one.func ( *PeerRecord) ( *PeerRecord) bool {if == nil {return == nil}if .PeerID != .PeerID {return false}if .Seq != .Seq {return false}if len(.Addrs) != len(.Addrs) {return false}for := range .Addrs {if !.Addrs[].Equal(.Addrs[]) {return false}}return true}// ToProtobuf returns the equivalent Protocol Buffer struct object of a PeerRecord.func ( *PeerRecord) () (*pb.PeerRecord, error) {, := .PeerID.MarshalBinary()if != nil {return nil,}return &pb.PeerRecord{PeerId: ,Addresses: addrsToProtobuf(.Addrs),Seq: .Seq,}, nil}func addrsFromProtobuf( []*pb.PeerRecord_AddressInfo) []ma.Multiaddr {:= make([]ma.Multiaddr, 0, len())for , := range {, := ma.NewMultiaddrBytes(.Multiaddr)if != nil {continue}= append(, )}return}func addrsToProtobuf( []ma.Multiaddr) []*pb.PeerRecord_AddressInfo {:= make([]*pb.PeerRecord_AddressInfo, 0, len())for , := range {= append(, &pb.PeerRecord_AddressInfo{Multiaddr: .Bytes()})}return}
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |