2021-04-07 09:39:48 +02:00

138 lines
2.8 KiB
JavaScript

'use strict'
// @ts-ignore libp2p crypto has no types
const randomBytes = require('libp2p-crypto/src/random-bytes')
const uint8ArrayToString = require('uint8arrays/to-string')
const uint8ArrayFromString = require('uint8arrays/from-string')
const PeerId = require('peer-id')
const multihash = require('multihashes')
/**
* Generatea random sequence number.
*
* @returns {Uint8Array}
* @private
*/
const randomSeqno = () => {
return randomBytes(8)
}
/**
* Generate a message id, based on the `from` and `seqno`.
*
* @param {string} from
* @param {Uint8Array} seqno
* @returns {Uint8Array}
* @private
*/
const msgId = (from, seqno) => {
const fromBytes = PeerId.createFromB58String(from).id
const msgId = new Uint8Array(fromBytes.length + seqno.length)
msgId.set(fromBytes, 0)
msgId.set(seqno, fromBytes.length)
return msgId
}
/**
* Generate a message id, based on message `data`.
*
* @param {Uint8Array} data
* @returns {Uint8Array}
* @private
*/
const noSignMsgId = (data) => multihash.encode(data, 'sha2-256')
/**
* Check if any member of the first set is also a member
* of the second set.
*
* @param {Set<number>|Array<number>} a
* @param {Set<number>|Array<number>} b
* @returns {boolean}
* @private
*/
const anyMatch = (a, b) => {
let bHas
if (Array.isArray(b)) {
/**
* @param {number} val
*/
bHas = (val) => b.indexOf(val) > -1
} else {
/**
* @param {number} val
*/
bHas = (val) => b.has(val)
}
for (const val of a) {
if (bHas(val)) {
return true
}
}
return false
}
/**
* Make everything an array.
*
* @template T
* @param {T|T[]} maybeArray
* @returns {T[]}
* @private
*/
const ensureArray = (maybeArray) => {
if (!Array.isArray(maybeArray)) {
return [maybeArray]
}
return maybeArray
}
/**
* Ensures `message.from` is base58 encoded
*
* @template {{from?:any}} T
* @param {T & {from?:string, receivedFrom:string}} message
* @param {string} [peerId]
* @returns {T & {from?: string, peerId?: string }}
*/
const normalizeInRpcMessage = (message, peerId) => {
const m = Object.assign({}, message)
if (message.from instanceof Uint8Array) {
m.from = uint8ArrayToString(message.from, 'base58btc')
}
if (peerId) {
m.receivedFrom = peerId
}
return m
}
/**
* @template {{from?:any, data?:any}} T
*
* @param {T} message
* @returns {T & {from?: Uint8Array, data?: Uint8Array}}
*/
const normalizeOutRpcMessage = (message) => {
const m = Object.assign({}, message)
if (typeof message.from === 'string') {
m.from = uint8ArrayFromString(message.from, 'base58btc')
}
if (typeof message.data === 'string') {
m.data = uint8ArrayFromString(message.data)
}
return m
}
module.exports = {
randomSeqno,
msgId,
noSignMsgId,
anyMatch,
ensureArray,
normalizeInRpcMessage,
normalizeOutRpcMessage
}