All files / lib/messages QueryShortChannelIdsMessage.ts

98.08% Statements 51/52
60% Branches 3/5
100% Functions 5/5
98.04% Lines 50/51

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 1081x 1x   1x   1x 1x 1x 1x     1x   4x 4x   4x 4x         4x 4x 4x       4x 4x 27x 27x       4x 2x   2x 2x 2x 2x 4x 4x 4x   2x             4x           73x                   73x         73x     27x 4x   4x 4x 4x 4x 4x     4x   2x 2x 4x   2x     2x     2x 2x 2x     4x      
import { BufferReader, BufferWriter } from "@node-lightning/bufio";
import { BitField } from "@node-lightning/core";
import { ShortChannelId } from "@node-lightning/core";
import { shortChannelIdFromBuffer } from "@node-lightning/core";
import { QueryScidFlags } from "../flags/QueryScidFlags";
import { MessageType } from "../MessageType";
import { Encoder } from "../serialize/Encoder";
import { EncodingType } from "../serialize/EncodingType";
import { readTlvs } from "../serialize/readTlvs";
import { IWireMessage } from "./IWireMessage";
 
export class QueryShortChannelIdsMessage implements IWireMessage {
    public static deserialize(payload: Buffer): QueryShortChannelIdsMessage {
        const instance = new QueryShortChannelIdsMessage();
        const reader = new BufferReader(payload);
 
        reader.readUInt16BE(); // read off type
        instance.chainHash = reader.readBytes(32); // chain_hash
 
        // process the encoded short channel ids by reading the length of
        // encoded data, then using the decoder to get the raw buffer after
        // using the appropriate decoding scheme
        const encodedScidLen = reader.readUInt16BE();
        const encodedScidBuffer = reader.readBytes(encodedScidLen);
        const scidBuffer = new Encoder().decode(encodedScidBuffer);
 
        // After we have a raw buffer of scid values (each 8 bytes) we can read
        // the data from the buffer
        const scidReader = new BufferReader(scidBuffer);
        while (!scidReader.eof) {
            const scid = shortChannelIdFromBuffer(scidReader.readBytes(8));
            instance.shortChannelIds.push(scid);
        }
 
        // Process all TLVs available on the reader
        readTlvs(reader, (type: bigint, valueReader: BufferReader) => {
            switch (type) {
                case BigInt(1): {
                    const bytes = valueReader.readBytes();
                    const flagBytes = new Encoder().decode(bytes);
                    const flagReader = new BufferReader(flagBytes);
                    while (!flagReader.eof) {
                        const rawFlags = flagReader.readBigSize();
                        const flags = new BitField<QueryScidFlags>(rawFlags);
                        instance.flags.push(flags);
                    }
                    return true;
                }
                default:
                    return false;
            }
        });
 
        return instance;
    }
 
    /**
     * Type 261
     */
    public type: MessageType = MessageType.QueryShortChannelIds;
 
    /**
     * 32-byte chain hash
     */
    public chainHash: Buffer;
 
    /**
     * List of channels to query
     */
    public shortChannelIds: ShortChannelId[] = [];
 
    /**
     * Optional flags that can be set when gossip_queries_ex is enabled.
     */
    public flags: Array<BitField<QueryScidFlags>> = [];
 
    public serialize(encoding: EncodingType = EncodingType.ZlibDeflate): Buffer {
        const rawIdsBuffer = Buffer.concat(this.shortChannelIds.map(p => p.toBuffer()));
        const esids = new Encoder().encode(encoding, rawIdsBuffer);
 
        const writer = new BufferWriter();
        writer.writeUInt16BE(this.type);
        writer.writeBytes(this.chainHash);
        writer.writeUInt16BE(esids.length);
        writer.writeBytes(esids);
 
        // encode TLV 1
        if (this.flags.length) {
            // combine all BitFields into buffers
            const flagBufs: Buffer[] = [];
            for (const flag of this.flags) {
                flagBufs.push(flag.toBuffer());
            }
            const flagBytes = Buffer.concat(flagBufs);
 
            // encode the flag bytes according to the encoding strategy
            const encodedFlagBytes = new Encoder().encode(encoding, flagBytes);
 
            // write TLV data
            writer.writeBigSize(1);
            writer.writeBigSize(encodedFlagBytes.length);
            writer.writeBytes(encodedFlagBytes);
        }
 
        return writer.toBuffer();
    }
}