UNPKG

@node-lightning/wire

Version:
160 lines (159 loc) 5.57 kB
/// <reference types="node" /> import { BitField } from "@node-lightning/core"; import { ILogger } from "@node-lightning/logger"; import { NoiseSocket } from "@node-lightning/noise"; import { Readable } from "stream"; import { InitFeatureFlags } from "./flags/InitFeatureFlags"; import { IWireMessage } from "./messages/IWireMessage"; import { PeerState } from "./PeerState"; import { PingPongState } from "./PingPongState"; export interface IMessageSender { send(buf: Buffer): void; sendMessage(msg: IWireMessage): void; } export interface IMessageReceiver { read(): IWireMessage; on(event: "readable", listener: () => void): this; off(event: "readable", listener: () => void): this; } export declare type IMessageSenderReceiver = IMessageSender & IMessageReceiver; export interface IPeer extends IMessageSenderReceiver { send(buf: Buffer): void; sendMessage(msg: IWireMessage): void; disconnect(): void; read(): IWireMessage; on(event: "readable", listener: () => void): this; on(event: "error", listener: (err: Error) => void): this; off(event: "readable", listener: () => void): this; off(event: "error", listener: (err: Error) => void): this; } /** * Peer is an EventEmitter that layers the Lightning Network wire * protocol ontop of an @node-lightning/noise NoiseSocket. * * Peer itself is a state-machine with three states: * 1. pending * 2. awaiting_peer_init * 3. ready * * The Peer instance starts in `pending` until the underlying NoiseSocket * has connected. * * It then immediately sends the InitMessage as specified in the Peer * constructor. * * At this point, the Peer transitions to `awaiting_peer_init`. * * Once the remote peer has sent its InitMessage, the state is * transitioned to `ready` and the Peer can be begin sending and * receiving messages. * * Once the peer is in the `ready` state it will begin emitting `message` * events when it receives new messages from the peer. * * The Peer will also start a PingPong state machine to manage sending * and receiving Pings and Pongs as defined in BOLT01 * * A choice (probably wrongly) was made to make Peer an EventEmitter * instead of a DuplexStream operating in object mode. We need to keep * the noise socket in flowing mode (instead of paused) because we will * not know the length of messages until after we have deserialized the * message. This makes it a challenge to implement a DuplexStream that * emits objects (such as messages). * * @emits ready the underlying socket has performed its handshake and * initialization message swap has occurred. * * @emits message a new message has been received. Only sent after the * `ready` event has fired. * * @emits rawmessage outputs the message as a raw buffer instead of * a deserialized message. * * @emits error emitted when there is an error processing a message. * The underlying socket will be closed after this event is emitted. * * @emits close emitted when the connection to the peer has completedly * closed. * * @emits open emmited when the connection to the peer has been established * after the handshake has been performed * * @emits end emitted when the connection to the peer is ending. */ export declare class Peer extends Readable implements IPeer { readonly ls: Buffer; readonly localFeatures: BitField<InitFeatureFlags>; readonly localChains: Buffer[]; readonly highWaterMark: number; static states: typeof PeerState; state: PeerState; socket: NoiseSocket; messageCounter: number; pingPongState: PingPongState; logger: ILogger; remoteFeatures: BitField<InitFeatureFlags>; remoteChains: Buffer[]; isInitiator: boolean; reconnectTimeoutMs: number; private _id; private _rpk; private _host; private _port; private _reconnectHandle; constructor(ls: Buffer, localFeatures: BitField<InitFeatureFlags>, localChains: Buffer[], logger: ILogger, highWaterMark?: number); get id(): string; get pubkey(): Buffer; get pubkeyHex(): string; /** * Connect to the remote peer and binds socket events into the Peer. */ connect(rpk: Buffer, host: string, port: number): void; /** * * @param socket */ attach(socket: NoiseSocket): void; /** * Writes data on the NoiseSocket. This method allows custom * serialization of methods. Use `sendMessage` to send a message * using the default message serialization. * @param buf */ send(buf: Buffer): boolean; /** * Writes the message on the NoiseSocket using the default * serialization properties */ sendMessage(m: IWireMessage): boolean; /** * Closes the socket */ disconnect(): void; /** * Reconnects the socket */ reconnect(): void; private _onSocketReady; private _onSocketClose; private _onSocketError; _onSocketReadable(): void; _read(): void; /** * Sends the initialization message to the peer. This message * does not matter if it is sent before or after the peer sends * there message. */ private _sendInitMessage; /** * Processes the initialization message sent by the remote peer. * Once this is successfully completed, the state is transitioned * to `active` */ private _processPeerInitMessage; /** * Process the raw message sent by the peer. These messages are * processed after the initialization message has been received. */ private _processMessage; }