@node-dlc/wire
Version:
Lightning Network Wire Protocol
98 lines • 3.73 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChannelsQuery = exports.ChannelsQueryState = void 0;
const QueryShortChannelIdsMessage_1 = require("../messages/QueryShortChannelIdsMessage");
const GossipError_1 = require("./GossipError");
var ChannelsQueryState;
(function (ChannelsQueryState) {
ChannelsQueryState[ChannelsQueryState["Idle"] = 0] = "Idle";
ChannelsQueryState[ChannelsQueryState["Active"] = 1] = "Active";
ChannelsQueryState[ChannelsQueryState["Complete"] = 2] = "Complete";
ChannelsQueryState[ChannelsQueryState["Failed"] = 3] = "Failed";
})(ChannelsQueryState = exports.ChannelsQueryState || (exports.ChannelsQueryState = {}));
/**
* This class manages the state machine for executing query_short_channel_ids
* and will resolve as either complete or with an error. This class can accept
* an arbitrarily large number of short channel ids and will chunk the requests
* appropriately.
*/
class ChannelsQuery {
constructor(chainHash, peer, logger) {
this.chainHash = chainHash;
this.peer = peer;
this.logger = logger;
this.chunkSize = 2000;
this._queue = [];
this._state = ChannelsQueryState.Idle;
}
get state() {
return this._state;
}
get error() {
return this._error;
}
handleReplyShortChannelIdsEnd(msg) {
this.logger.debug('received reply_short_channel_ids_end - complete: %d', msg.complete);
// If we receive a reply with complete=false, the remote peer
// does not maintain up-to-date channel information for the
// requested chain_hash
if (!msg.complete) {
const error = new GossipError_1.GossipError(GossipError_1.GossipErrorCode.ReplyChannelsNoInfo, msg);
this._transitionFailed(error);
return;
}
// This occurs when the last batch of information has been received
// but there is still more short_channel_ids to request. This scenario
// requires sending another QueryShortIds message
if (this._queue.length > 0) {
this._sendQuery();
}
else {
this._transitionSuccess();
return;
}
}
/**
*
* @param scids
*/
query(...scids) {
return new Promise((resolve, reject) => {
// enqueue the short ids
for (const scid of scids) {
this._queue.push(scid);
}
// Ensure we are in the active state
this._state = ChannelsQueryState.Active;
// send our query to the peer
this._sendQuery();
// capture the promise method for use when complete
this._resolve = resolve;
this._reject = reject;
});
}
_transitionSuccess() {
if (this._state !== ChannelsQueryState.Active)
return;
this._state = ChannelsQueryState.Complete;
this._resolve();
}
_transitionFailed(error) {
if (this._state !== ChannelsQueryState.Active)
return;
this._state = ChannelsQueryState.Failed;
this._error = error;
this._reject(error);
}
_sendQuery() {
// splice a chunk of work to do from the suqery
const scids = this._queue.splice(0, this.chunkSize);
const msg = new QueryShortChannelIdsMessage_1.QueryShortChannelIdsMessage();
msg.chainHash = this.chainHash;
msg.shortChannelIds = scids;
this.logger.debug('sending query_short_channel_ids - scid_count:', scids.length);
this.peer.sendMessage(msg);
}
}
exports.ChannelsQuery = ChannelsQuery;
//# sourceMappingURL=ChannelsQuery.js.map