All files / lib/messages QueryShortChannelIdsMessage.ts

21.15% Statements 11/52
0% Branches 0/5
20% Functions 1/5
21.15% Lines 11/52

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 108 109 110 1111x 1x   1x     1x 1x 1x 1x     1x                                                                                               15x                   15x         15x                                                                      
import { BufferReader, BufferWriter } from '@node-dlc/bufio';
import { BitField } from '@node-dlc/common';
import { ShortChannelId } from '@node-dlc/common';
import { shortChannelIdFromBuffer } from '@node-dlc/common';
 
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();
  }
}