UNPKG

@node-lightning/wire

Version:
215 lines 8.46 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChannelUpdateMessage = void 0; const bufio_1 = require("@node-lightning/bufio"); const core_1 = require("@node-lightning/core"); const core_2 = require("@node-lightning/core"); const crypto = __importStar(require("@node-lightning/crypto")); const Checksum_1 = require("../domain/Checksum"); const MessageType_1 = require("../MessageType"); /** * After a channel has been announced, each side independently announces the fees * and minimum expiry delta it requires to relay HTLCs through this channel. A * node can broadcast this message multiple times in order to change fees. */ class ChannelUpdateMessage { constructor() { /** * Message type is 258 */ this.type = MessageType_1.MessageType.ChannelUpdate; /** * Indicate the presence of optional fields in the channel_update message. * bit, field * 0, htlc_maximum_msat */ this.messageFlags = new core_1.BitField(); /** * Indicates the direction of the channel: it identifies the node that this * update originated from and signals various options concerning the channel * such as whether it is disabled. * bit, name * 0, direction * 1, disabled */ this.channelFlags = new core_1.BitField(); } /** * Deserializes the message from a Buffer. The message * is not validated in this function. */ static deserialize(payload) { const instance = new ChannelUpdateMessage(); const reader = new bufio_1.BufferReader(payload); reader.readUInt16BE(); // read off type instance.signature = reader.readBytes(64); instance.chainHash = reader.readBytes(32); instance.shortChannelId = core_2.shortChannelIdFromBuffer(reader.readBytes(8)); instance.timestamp = reader.readUInt32BE(); instance.messageFlags = core_1.BitField.fromNumber(reader.readUInt8()); instance.channelFlags = core_1.BitField.fromNumber(reader.readUInt8()); instance.cltvExpiryDelta = reader.readUInt16BE(); instance.htlcMinimumMsat = core_1.Value.fromMilliSats(reader.readUInt64BE()); instance.feeBaseMsat = core_1.Value.fromMilliSats(reader.readUInt32BE()); instance.feeProportionalMillionths = core_1.Value.fromMicroSats(reader.readUInt32BE()); // has optional_channel_htlc_max if (instance.hasHtlcMaximumMsatFlag) { instance.htlcMaximumMsat = core_1.Value.fromMilliSats(reader.readUInt64BE()); } return instance; } /** * Performs a double SHA-256 hash of the message with all * data excluding the signature data */ static hashForSignature(message) { const raw = message.serialize().slice(66); return crypto.hash256(raw); } /** * Performs signature validation for the message by * hashing the data post signature. A passing signature * indicates that the message was submitted by the node * that owns the channel. Becuase the nodeId is not included * in the message, we need to obtain the nodeId by accessing * the ChannelAnnouncementMessage and determining the public key * @param message * @param pubkey 33-byte ECDSA public key */ static validateSignature(message, pubkey) { const sigmsg = ChannelUpdateMessage.hashForSignature(message); return crypto.verifySig(sigmsg, message.signature, pubkey); } /** * Returns true when message flags have the optional * maximum HTLC msat value available */ get hasHtlcMaximumMsatFlag() { return this.messageFlags.isSet(0); } /** * Direction is determined by channel_flags bit 0. * When set to 0, node_1 is the sender. When set to 1 * node_2 is the sender */ get direction() { return this.channelFlags.isSet(0) ? 1 : 0; } set direction(val) { if (val === 0) { this.channelFlags.unset(0); } else if (val === 1) { this.channelFlags.set(0); } else { throw new Error("Invlid direction"); } } /** * Disabled flag is determined by channel_flags bit 1. * When set to 0, the channel is active. When set to 1 * the channel is disabled. */ get disabled() { return this.channelFlags.isSet(1); } set disabled(val) { if (val) { this.channelFlags.set(1); } else { this.channelFlags.unset(1); } } /** * Serializes the instance into a Buffer that can be * transmitted over the wire */ serialize() { const len = 2 + // type 64 + // signature 32 + // chain_hash 8 + // short_channel_id 4 + // timestamp 1 + // message_flags 1 + // channel_flags 2 + // cltv_expiry_delta 8 + // htlc_minimum_msat 4 + // fee_base_msat 4 + // fee_proportional_millionths (this.hasHtlcMaximumMsatFlag ? 8 : 0); const writer = new bufio_1.BufferWriter(Buffer.alloc(len)); writer.writeUInt16BE(this.type); writer.writeBytes(this.signature); writer.writeBytes(this.chainHash); writer.writeBytes(this.shortChannelId.toBuffer()); writer.writeUInt32BE(this.timestamp); writer.writeUInt8(this.messageFlags.toNumber()); writer.writeUInt8(this.channelFlags.toNumber()); writer.writeUInt16BE(this.cltvExpiryDelta); writer.writeUInt64BE(this.htlcMinimumMsat.msats); writer.writeUInt32BE(Number(this.feeBaseMsat.msats)); writer.writeUInt32BE(Number(this.feeProportionalMillionths.microsats)); if (this.hasHtlcMaximumMsatFlag) { writer.writeUInt64BE(this.htlcMaximumMsat.msats); } return writer.toBuffer(); } /** * CRC32C checksum is calculated from the raw channel_update * message and excludes the signature and timestamp. * * @remarks * Defined in BOLT 07 gossip queries section: * https://github.com/lightningnetwork/lightning-rfc/blob/master/07-routing-gossip.md#query-messages * */ checksum() { const len = 2 + // type 32 + // chain_hash 8 + // short_channel_id 1 + // message_flags 1 + // channel_flags 2 + // cltv_expiry_delta 8 + // htlc_minimum_msat 4 + // fee_base_msat 4 + // fee_proportional_millionths (this.hasHtlcMaximumMsatFlag ? 8 : 0); const writer = new bufio_1.BufferWriter(Buffer.alloc(len)); writer.writeUInt16BE(this.type); writer.writeBytes(this.chainHash); writer.writeBytes(this.shortChannelId.toBuffer()); writer.writeUInt8(Number(this.messageFlags)); writer.writeUInt8(Number(this.channelFlags)); writer.writeUInt16BE(this.cltvExpiryDelta); writer.writeUInt64BE(this.htlcMinimumMsat.msats); writer.writeUInt32BE(Number(this.feeBaseMsat.msats)); writer.writeUInt32BE(Number(this.feeProportionalMillionths.microsats)); if (this.hasHtlcMaximumMsatFlag) { writer.writeUInt64BE(this.htlcMaximumMsat.msats); } return Checksum_1.Checksum.fromBuffer(writer.toBuffer()); } } exports.ChannelUpdateMessage = ChannelUpdateMessage; //# sourceMappingURL=ChannelUpdateMessage.js.map