2020-06-03 14:58:58 +02:00
|
|
|
'use strict'
|
|
|
|
|
|
|
|
const multiaddr = require('multiaddr')
|
|
|
|
const PeerId = require('peer-id')
|
2020-07-15 11:40:57 +02:00
|
|
|
const arrayEquals = require('libp2p-utils/src/array-equals')
|
2020-06-03 14:58:58 +02:00
|
|
|
|
|
|
|
const Protobuf = require('./peer-record.proto')
|
|
|
|
const {
|
|
|
|
ENVELOPE_DOMAIN_PEER_RECORD,
|
|
|
|
ENVELOPE_PAYLOAD_TYPE_PEER_RECORD
|
|
|
|
} = require('./consts')
|
|
|
|
|
|
|
|
/**
|
2020-12-10 14:48:14 +01:00
|
|
|
* @typedef {import('peer-id')} PeerId
|
|
|
|
* @typedef {import('multiaddr')} Multiaddr
|
|
|
|
* @typedef {import('libp2p-interfaces/src/record/types').Record} Record
|
2020-06-03 14:58:58 +02:00
|
|
|
*/
|
2020-12-10 14:48:14 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @implements {Record}
|
|
|
|
*/
|
|
|
|
class PeerRecord {
|
2020-06-03 14:58:58 +02:00
|
|
|
/**
|
2020-12-10 14:48:14 +01:00
|
|
|
* The PeerRecord is used for distributing peer routing records across the network.
|
|
|
|
* It contains the peer's reachable listen addresses.
|
|
|
|
*
|
2020-10-06 14:59:43 +02:00
|
|
|
* @class
|
2020-12-10 14:48:14 +01:00
|
|
|
* @param {Object} params
|
2020-06-03 14:58:58 +02:00
|
|
|
* @param {PeerId} params.peerId
|
2020-12-10 14:48:14 +01:00
|
|
|
* @param {Multiaddr[]} params.multiaddrs - addresses of the associated peer.
|
2020-10-06 14:59:43 +02:00
|
|
|
* @param {number} [params.seqNumber] - monotonically-increasing sequence counter that's used to order PeerRecords in time.
|
2020-06-03 14:58:58 +02:00
|
|
|
*/
|
|
|
|
constructor ({ peerId, multiaddrs = [], seqNumber = Date.now() }) {
|
2020-12-10 14:48:14 +01:00
|
|
|
this.domain = ENVELOPE_DOMAIN_PEER_RECORD
|
|
|
|
this.codec = ENVELOPE_PAYLOAD_TYPE_PEER_RECORD
|
2020-06-03 14:58:58 +02:00
|
|
|
|
|
|
|
this.peerId = peerId
|
|
|
|
this.multiaddrs = multiaddrs
|
|
|
|
this.seqNumber = seqNumber
|
|
|
|
|
|
|
|
// Cache
|
|
|
|
this._marshal = undefined
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Marshal a record to be used in an envelope.
|
2020-10-06 14:59:43 +02:00
|
|
|
*
|
|
|
|
* @returns {Uint8Array}
|
2020-06-03 14:58:58 +02:00
|
|
|
*/
|
|
|
|
marshal () {
|
|
|
|
if (this._marshal) {
|
|
|
|
return this._marshal
|
|
|
|
}
|
|
|
|
|
2020-12-10 14:48:14 +01:00
|
|
|
this._marshal = Protobuf.PeerRecord.encode({
|
2020-06-03 14:58:58 +02:00
|
|
|
peer_id: this.peerId.toBytes(),
|
|
|
|
seq: this.seqNumber,
|
|
|
|
addresses: this.multiaddrs.map((m) => ({
|
2020-08-24 11:58:02 +01:00
|
|
|
multiaddr: m.bytes
|
2020-06-03 14:58:58 +02:00
|
|
|
}))
|
|
|
|
})
|
|
|
|
|
|
|
|
return this._marshal
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-07-15 11:40:57 +02:00
|
|
|
* Returns true if `this` record equals the `other`.
|
2020-10-06 14:59:43 +02:00
|
|
|
*
|
2020-12-10 14:48:14 +01:00
|
|
|
* @param {unknown} other
|
2020-10-06 14:59:43 +02:00
|
|
|
* @returns {boolean}
|
2020-06-03 14:58:58 +02:00
|
|
|
*/
|
2020-07-15 11:40:57 +02:00
|
|
|
equals (other) {
|
2020-12-10 14:48:14 +01:00
|
|
|
if (!(other instanceof PeerRecord)) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-06-03 14:58:58 +02:00
|
|
|
// Validate PeerId
|
|
|
|
if (!this.peerId.equals(other.peerId)) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate seqNumber
|
|
|
|
if (this.seqNumber !== other.seqNumber) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate multiaddrs
|
2020-07-15 11:40:57 +02:00
|
|
|
if (!arrayEquals(this.multiaddrs, other.multiaddrs)) {
|
2020-06-03 14:58:58 +02:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unmarshal Peer Record Protobuf.
|
2020-10-06 14:59:43 +02:00
|
|
|
*
|
|
|
|
* @param {Uint8Array} buf - marshaled peer record.
|
|
|
|
* @returns {PeerRecord}
|
2020-06-03 14:58:58 +02:00
|
|
|
*/
|
2020-06-24 15:10:08 +02:00
|
|
|
PeerRecord.createFromProtobuf = (buf) => {
|
2020-06-03 14:58:58 +02:00
|
|
|
// Decode
|
2020-12-10 14:48:14 +01:00
|
|
|
const peerRecord = Protobuf.PeerRecord.decode(buf)
|
2020-06-03 14:58:58 +02:00
|
|
|
|
|
|
|
const peerId = PeerId.createFromBytes(peerRecord.peer_id)
|
|
|
|
const multiaddrs = (peerRecord.addresses || []).map((a) => multiaddr(a.multiaddr))
|
|
|
|
const seqNumber = peerRecord.seq
|
|
|
|
|
|
|
|
return new PeerRecord({ peerId, multiaddrs, seqNumber })
|
|
|
|
}
|
2020-06-24 15:10:08 +02:00
|
|
|
|
2020-06-20 19:32:39 +02:00
|
|
|
PeerRecord.DOMAIN = ENVELOPE_DOMAIN_PEER_RECORD
|
|
|
|
|
2020-06-24 15:10:08 +02:00
|
|
|
module.exports = PeerRecord
|