|
| 1 | +// Taken from lodestar: https://github.com/ChainSafe/lodestar |
| 2 | +import { sha256 } from '@aztec/foundation/crypto'; |
| 3 | + |
| 4 | +import { type RPC } from '@chainsafe/libp2p-gossipsub/message'; |
| 5 | +import { type Message } from '@libp2p/interface'; |
| 6 | +import xxhashFactory from 'xxhash-wasm'; |
| 7 | + |
| 8 | +// Load WASM |
| 9 | +const xxhash = await xxhashFactory(); |
| 10 | + |
| 11 | +// Use salt to prevent msgId from being mined for collisions |
| 12 | +const h64Seed = BigInt(Math.floor(Math.random() * 1e9)); |
| 13 | + |
| 14 | +// Shared buffer to convert msgId to string |
| 15 | +const sharedMsgIdBuf = Buffer.alloc(20); |
| 16 | + |
| 17 | +/** |
| 18 | + * The function used to generate a gossipsub message id |
| 19 | + * We use the first 8 bytes of SHA256(data) for content addressing |
| 20 | + */ |
| 21 | +export function fastMsgIdFn(rpcMsg: RPC.Message): string { |
| 22 | + if (rpcMsg.data) { |
| 23 | + return xxhash.h64Raw(rpcMsg.data, h64Seed).toString(16); |
| 24 | + } |
| 25 | + return '0000000000000000'; |
| 26 | +} |
| 27 | + |
| 28 | +export function msgIdToStrFn(msgId: Uint8Array): string { |
| 29 | + // This happens serially, no need to reallocate the buffer |
| 30 | + sharedMsgIdBuf.set(msgId); |
| 31 | + return `0x${sharedMsgIdBuf.toString('hex')}`; |
| 32 | +} |
| 33 | + |
| 34 | +/** |
| 35 | + * Get the message identifier from a libp2p message |
| 36 | + * |
| 37 | + * Follows similarly to: |
| 38 | + * https://github.com/ethereum/consensus-specs/blob/v1.1.0-alpha.7/specs/altair/p2p-interface.md#topics-and-messages |
| 39 | + * |
| 40 | + * @param message - The libp2p message |
| 41 | + * @returns The message identifier |
| 42 | + */ |
| 43 | +export function getMsgIdFn(message: Message) { |
| 44 | + const { topic } = message; |
| 45 | + |
| 46 | + const vec = [Buffer.from(topic), message.data]; |
| 47 | + return sha256(Buffer.concat(vec)).subarray(0, 20); |
| 48 | +} |
0 commit comments