@node-lightning/wire
Version:
Lightning Network Wire Protocol
160 lines (159 loc) • 5.57 kB
TypeScript
/// <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;
}