@node-lightning/wire
Version:
Lightning Network Wire Protocol
141 lines (140 loc) • 5.48 kB
TypeScript
/// <reference types="node" />
import { ShortChannelId } from "@node-lightning/core";
import { ILogger } from "@node-lightning/logger";
import { ReplyChannelRangeMessage } from "../../messages/ReplyChannelRangeMessage";
import { IMessageSender } from "../../Peer";
import { GossipError } from "../GossipError";
export declare enum ChannelRangeQueryState {
Idle = 0,
Active = 1,
Complete = 2,
Failed = 3
}
/**
* Performs a single query_channel_range operation and encapsulates the state
* machine performed during the query operations.
*
* A single query_channel_range may be too large to fit in a single
* reply_channel_range response. When this happens, there will be multiple
* reply_channel_range responses to address the query_channel_range message.
*
* There are two modes of replies: Legacy LND and Standard.
*
* Standard was defined in changes to BOLT7 that were merged in with #730. These
* changes clarified the meaning of the reply fields to ensure the recipient
* of replies knows when the query has successfully completed. This includes:
*
* - a node must not submit a new query_channel_range until the full set of
* reply_channel_range messages covering the range are received.
*
* - clarified the meaning of full_information (previously complete) to
* indicate that the responding node contains complete information for the
* chain_hash, not that the reply is complete.
*
* - enforces that when there are multiple reply_channel_range msgs, the
* range of blocks must be strictly increasing until the full query range is
* covered. This range may exceed (both below and above) the request range.
* This means:
* - the first reply first_blocknum must be <= requests first_blocknum
* - subsequent first_blocknum will be strictly increasing from the
* previous reply's first_blocknum+number_of_blocks
* - the final first_blocknum+number_of_blocks must be >= the query's
* first_blocknum+number_of_blocks
*
* This is functionality is a clarification from Legacy LND mode where
* gossip_queries was implemented in a different manner.
*
* - full_information indicated a multipart message that was incomplete
* - lack of short_channel_ids and full_information=false can be treated
* as a failure condition
*/
export declare class ChannelRangeQuery {
readonly chainHash: Buffer;
readonly messageSender: IMessageSender;
readonly logger: ILogger;
private _state;
private _isLegacy;
private _query;
private _results;
private _error;
private _resolve;
private _reject;
constructor(chainHash: Buffer, messageSender: IMessageSender, logger: ILogger, isLegacy?: boolean);
/**
* Returns true if we detect this is using the legacy querying gossip_queries
* mechanism that was originally implemented in LND. This code may be able to
* be removed eventually.
*/
get isLegacy(): boolean;
/**
* Gets the current state of the Query object
*/
get state(): ChannelRangeQueryState;
/**
* Results found
*/
get results(): ShortChannelId[];
/**
* Gets the error that was encountered during processing
*/
get error(): GossipError;
/**
* Handles a reply_channel_range message. May initiate a message
* broadcast.
*/
handleReplyChannelRange(msg: ReplyChannelRangeMessage): void;
/**
* Resolves when the query has completed, otherwise it will reject on an
* error.
*/
queryRange(firstBlock?: number, numBlocks?: number): Promise<ShortChannelId[]>;
/**
* Idempotent method that marks the state machine failed
* @param error
*/
private _transitionFailed;
/**
* Idempotent method that marks the state machine complete
*/
private _transitionComplete;
/**
* Constructs and sends the query message the remote peer.
* @param firstBlock
* @param numBlocks
*/
private _sendQuery;
/**
* Check if this has the signature of a legacy reply. We can detect this by
* looking at a complete=false and that scids exist.
* @param msg
*/
private _isLegacyReply;
/**
* Handles a reply_channel_range message which ensures that the entire queried
* range has been received. The responder can reply with pre-sized ranges
* which means the reply range may not be the EXACT range requested but will
* include the queried range.
*
* For a query range with first_blocknum and number_of_blocks arguments,
* we can expect messages to have the following:
*
* - first reply first_blocknum <= requested first_blocknum
* - intermediate replies sequentially ordered so that first_blocknum is the
* first_blocknum + number_of_blocks from previous reply (strictly ordered)
* - last reply has fist_blocknum + number_of_blocks >= the queries
* first_blocknum + number_of_blocks
*
* This ordering allows us to know when a message is complete. If a reply has
* full_information=false, then the remote peer does not maintain a
* up-to-date information for the supplied chain_hash.
* @param msg
*/
private _handleReply;
/**
* Handles a reply_channel_range message using the legacy strategy. This
* code will error if fullInformation=0 scids=[] and will be considered
* complete when fullInformation=1.
* @param msg
*/
private _handleLegacyReply;
}