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 ) { 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 ) { this . _channelUpd . set ( getChanUpdKey ( getChanKey ( msg . shortChannelId ) , msg . direction ) , msg ) ; } public async saveNodeAnnouncement ( msg ) { this . _nodeAnn . set ( getNodeKey ( msg . nodeId ) , msg ) ; } public async findChannelsForNode ( nodeId ) { const scidInts = this . _nodeChannels . get ( getNodeKey ( nodeId ) ) ; const results = [ ] ; if ( ! scidInts ) return results ; for ( const scidInt of scidInts ) { results . push ( shortChannelIdFromNumber ( scidInt ) ) ; } return results ; } public async findNodeAnnouncement ( nodeId ) { return this . _nodeAnn . get ( getNodeKey ( nodeId ) ) ; } public async findNodeAnnouncements ( ) { return Array . from ( this . _nodeAnn . values ( ) ) ; } public async findChannelAnnouncemnts ( ) { return Array . from ( this . _channelAnn . values ( ) ) ; } public async findChannelAnnouncement ( scid ) { return this . _channelAnn . get ( getChanKey ( scid ) ) ; } public async findChannelAnnouncementByOutpoint ( outpoint ) { const scidNum = this . _channelByOutPoint . get ( outpoint . toString ( ) ) ; return this . _channelAnn . get ( scidNum ) ; } public async findChannelUpdate ( scid , dir ) { return this . _channelUpd . get ( getChanUpdKey ( getChanKey ( scid ) , dir ) ) ; } public async deleteChannelAnnouncement ( scid ) { const msg = await this . findChannelAnnouncement ( scid ) ; if ( ! msg ) return ; const chanKey = getChanKey ( scid ) ; this . _channelAnn . delete ( getChanKey ( scid ) ) ; if ( msg instanceof ExtendedChannelAnnouncementMessage ) { this . _channelByOutPoint . delete ( msg . outpoint . toString ( ) ) ; } this . _channelUpd . delete ( getChanUpdKey ( scid . toNumber ( ) , 0 ) ) ; this . _channelUpd . delete ( getChanUpdKey ( scid . toNumber ( ) , 0 ) ) ; this . _nodeChannels . get ( getNodeKey ( msg . nodeId1 ) ) . delete ( chanKey ) ; this . _nodeChannels . get ( getNodeKey ( msg . nodeId2 ) ) . delete ( chanKey ) ; } public async deleteChannelUpdate ( scid , dir ) { this . _channelUpd . delete ( getChanUpdKey ( getChanKey ( scid ) , dir ) ) ; } public async deleteNodeAnnouncement ( nodeId ) { this . _nodeAnn . delete ( getNodeKey ( nodeId ) ) ; this . _nodeChannels . get ( getNodeKey ( nodeId ) ) ; } private async _saveNodeChannel ( nodeId , chanKey ) { const nodeKey = getNodeKey ( nodeId ) ; this . _nodeChannels . set ( nodeKey , this . _nodeChannels . get ( nodeKey ) || new Set < bigint > ( ) ) ; this . _nodeChannels . get ( nodeKey ) . add ( chanKey ) ; } } function getNodeKey ( nodeId ) { return nodeId . toString ( "hex" ) ; } function getChanKey ( scid ) { return scid . toNumber ( ) ; } function getChanUpdKey ( chanKey , direction ) { return ( chanKey << BigInt ( 8 ) ) | BigInt ( direction ) ; }