UNPKG

@node-lightning/wire

Version:
142 lines (116 loc) 5.28 kB
/* eslint-disable @typescript-eslint/require-await */ import { ShortChannelId } from "@node-lightning/core"; import { shortChannelIdFromNumber } from "@node-lightning/core"; import { OutPoint } from "@node-lightning/core"; import { ChannelAnnouncementMessage } from "../messages/ChannelAnnouncementMessage"; import { ChannelUpdateMessage } from "../messages/ChannelUpdateMessage"; import { ExtendedChannelAnnouncementMessage } from "../messages/ExtendedChannelAnnouncementMessage"; import { NodeAnnouncementMessage } from "../messages/NodeAnnouncementMessage"; import { IGossipStore } from "./GossipStore"; /** * In-memory implementation of the IGossipStore. */ export class GossipMemoryStore implements IGossipStore { private _channelAnn = new Map<bigint, ChannelAnnouncementMessage>(); private _channelByOutPoint = new Map<string, bigint>(); private _channelUpd = new Map<bigint, ChannelUpdateMessage>(); private _nodeAnn = new Map<string, NodeAnnouncementMessage>(); private _nodeChannels = new Map<string, Set<bigint>>(); public get channelAnnouncementCount() { return this._channelAnn.size; } public get channelUpdateCount() { return this._channelUpd.size; } public get nodeAnnouncementCount() { return this._nodeAnn.size; } public async saveChannelAnnouncement(msg: ChannelAnnouncementMessage): Promise<void> { const chanKey = getChanKey(msg.shortChannelId); this._channelAnn.set(chanKey, msg); if (msg instanceof ExtendedChannelAnnouncementMessage) { this._channelByOutPoint.set(msg.outpoint.toString(), msg.shortChannelId.toNumber()); } await this._saveNodeChannel(msg.nodeId1, chanKey); await this._saveNodeChannel(msg.nodeId2, chanKey); } public async saveChannelUpdate(msg: ChannelUpdateMessage): Promise<void> { this._channelUpd.set(getChanUpdKey(getChanKey(msg.shortChannelId), msg.direction), msg); } public async saveNodeAnnouncement(msg: NodeAnnouncementMessage): Promise<void> { this._nodeAnn.set(getNodeKey(msg.nodeId), msg); } public async findChannelsForNode(nodeId: Buffer): Promise<ShortChannelId[]> { const scidInts = this._nodeChannels.get(getNodeKey(nodeId)); const results: ShortChannelId[] = []; if (!scidInts) return results; for (const scidInt of scidInts) { results.push(shortChannelIdFromNumber(scidInt)); } return results; } public async findNodeAnnouncement(nodeId: Buffer): Promise<NodeAnnouncementMessage> { return this._nodeAnn.get(getNodeKey(nodeId)); } public async findNodeAnnouncements(): Promise<NodeAnnouncementMessage[]> { return Array.from(this._nodeAnn.values()); } public async findChannelAnnouncemnts(): Promise<ChannelAnnouncementMessage[]> { return Array.from(this._channelAnn.values()); } public async findChannelAnnouncement( scid: ShortChannelId, ): Promise<ChannelAnnouncementMessage> { return this._channelAnn.get(getChanKey(scid)); } public async findChannelAnnouncementByOutpoint( outpoint: OutPoint, ): Promise<ChannelAnnouncementMessage> { const scidNum = this._channelByOutPoint.get(outpoint.toString()); return this._channelAnn.get(scidNum); } public async findChannelUpdate( scid: ShortChannelId, dir: number, ): Promise<ChannelUpdateMessage> { return this._channelUpd.get(getChanUpdKey(getChanKey(scid), dir)); } public async deleteChannelAnnouncement(scid: ShortChannelId): Promise<void> { const msg = await this.findChannelAnnouncement(scid); if (!msg) return; const chanKey = getChanKey(scid); // delete channel this._channelAnn.delete(getChanKey(scid)); // delete outpoint link if (msg instanceof ExtendedChannelAnnouncementMessage) { this._channelByOutPoint.delete(msg.outpoint.toString()); } // delete channel_updates this._channelUpd.delete(getChanUpdKey(scid.toNumber(), 0)); this._channelUpd.delete(getChanUpdKey(scid.toNumber(), 0)); // delete node links this._nodeChannels.get(getNodeKey(msg.nodeId1)).delete(chanKey); this._nodeChannels.get(getNodeKey(msg.nodeId2)).delete(chanKey); } public async deleteChannelUpdate(scid: ShortChannelId, dir: number) { this._channelUpd.delete(getChanUpdKey(getChanKey(scid), dir)); } public async deleteNodeAnnouncement(nodeId: Buffer) { this._nodeAnn.delete(getNodeKey(nodeId)); this._nodeChannels.get(getNodeKey(nodeId)); } private async _saveNodeChannel(nodeId: Buffer, chanKey: bigint) { const nodeKey = getNodeKey(nodeId); this._nodeChannels.set(nodeKey, this._nodeChannels.get(nodeKey) || new Set<bigint>()); this._nodeChannels.get(nodeKey).add(chanKey); } } function getNodeKey(nodeId: Buffer): string { return nodeId.toString("hex"); } function getChanKey(scid: ShortChannelId): bigint { return scid.toNumber(); } function getChanUpdKey(chanKey: bigint, direction: number): bigint { return (chanKey << BigInt(8)) | BigInt(direction); }