mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-04-29 04:22:14 +00:00
100 lines
2.5 KiB
JavaScript
100 lines
2.5 KiB
JavaScript
|
'use strict'
|
||
|
|
||
|
const multiaddr = require('multiaddr')
|
||
|
const PeerId = require('peer-id')
|
||
|
const Record = require('libp2p-interfaces/src/record')
|
||
|
|
||
|
const Protobuf = require('./peer-record.proto')
|
||
|
const {
|
||
|
ENVELOPE_DOMAIN_PEER_RECORD,
|
||
|
ENVELOPE_PAYLOAD_TYPE_PEER_RECORD
|
||
|
} = require('./consts')
|
||
|
|
||
|
const arraysAreEqual = (a, b) => a.length === b.length && a.sort().every((item, index) => b[index].equals(item))
|
||
|
|
||
|
/**
|
||
|
* The PeerRecord is responsible for TODOTODOTRDO
|
||
|
*/
|
||
|
class PeerRecord extends Record {
|
||
|
/**
|
||
|
* @constructor
|
||
|
* @param {object} params
|
||
|
* @param {PeerId} params.peerId
|
||
|
* @param {Array<multiaddr>} params.multiaddrs public addresses of the peer this record pertains to.
|
||
|
* @param {number} [params.seqNumber] monotonically-increasing sequence counter that's used to order PeerRecords in time.
|
||
|
*/
|
||
|
constructor ({ peerId, multiaddrs = [], seqNumber = Date.now() }) {
|
||
|
// TODO: verify domain/payload type
|
||
|
super(ENVELOPE_DOMAIN_PEER_RECORD, ENVELOPE_PAYLOAD_TYPE_PEER_RECORD)
|
||
|
|
||
|
this.peerId = peerId
|
||
|
this.multiaddrs = multiaddrs
|
||
|
this.seqNumber = seqNumber
|
||
|
|
||
|
// Cache
|
||
|
this._marshal = undefined
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Marshal a record to be used in an envelope.
|
||
|
* @return {Buffer}
|
||
|
*/
|
||
|
marshal () {
|
||
|
if (this._marshal) {
|
||
|
return this._marshal
|
||
|
}
|
||
|
|
||
|
this._marshal = Protobuf.encode({
|
||
|
peer_id: this.peerId.toBytes(),
|
||
|
seq: this.seqNumber,
|
||
|
addresses: this.multiaddrs.map((m) => ({
|
||
|
multiaddr: m.buffer
|
||
|
}))
|
||
|
})
|
||
|
|
||
|
return this._marshal
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Verifies if the other PeerRecord is identical to this one.
|
||
|
* @param {Record} other
|
||
|
* @return {boolean}
|
||
|
*/
|
||
|
isEqual (other) {
|
||
|
// Validate PeerId
|
||
|
if (!this.peerId.equals(other.peerId)) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
// Validate seqNumber
|
||
|
if (this.seqNumber !== other.seqNumber) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
// Validate multiaddrs
|
||
|
if (this.multiaddrs.length !== other.multiaddrs.length || !arraysAreEqual(this.multiaddrs, other.multiaddrs)) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exports = module.exports = PeerRecord
|
||
|
|
||
|
/**
|
||
|
* Unmarshal Peer Record Protobuf.
|
||
|
* @param {Buffer} buf marshaled peer record.
|
||
|
* @return {PeerRecord}
|
||
|
*/
|
||
|
exports.createFromProtobuf = (buf) => {
|
||
|
// Decode
|
||
|
const peerRecord = Protobuf.decode(buf)
|
||
|
|
||
|
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 })
|
||
|
}
|