UNPKG

@node-dlc/wire

Version:
406 lines (396 loc) 10.8 kB
import { BufferReader } from '@node-dlc/bufio'; import { shortChannelIdFromBuffer } from '@node-dlc/common'; import { expect } from 'chai'; import { readTlvs } from '../../lib/serialize/readTlvs'; describe('.readTlvs()', () => { const n1tests: Array<{ input: string; failure?: string; output?: any }> = [ { input: 'fd', failure: 'type truncated', }, { input: 'fd01', failure: 'type truncated', }, { input: 'fd000100', failure: 'not minimally encoded', }, { input: 'fd0101', failure: 'no length', }, { input: '0ffd', failure: 'length truncated', }, { input: '0ffd26', failure: 'length truncated', }, { input: '0ffd2602', failure: 'missing value', }, { input: '0ffd000100', failure: 'not minimally encoded', }, { input: "0ffd0201000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", // prettier-ignore failure: 'value truncated', }, { input: '1200', failure: 'unknown even type', }, { input: 'fd010200', failure: 'unknown even type', }, { input: 'fe0100000200', failure: 'unknow even type', }, { input: 'ff010000000000000200', failure: 'unknown even type', }, { input: '0109ffffffffffffffffff', failure: 'greater than encoding length for n1s tlv1', }, { input: '010100', failure: 'encoding for n1s tlv1s amount_msat is not minimal', }, { input: '01020001', failure: 'encoding for n1s tlv1s amount_msat is not minimal', }, { input: '0103000100', failure: 'encoding for n1s tlv1s amount_msat is not minimal', }, { input: '010400010000', failure: 'encoding for n1s tlv1s amount_msat is not minimal', }, { input: '01050001000000', failure: 'encoding for n1s tlv1s amount_msat is not minimal', }, { input: '0106000100000000', failure: 'encoding for n1s tlv1s amount_msat is not minimal', }, { input: '010700010000000000', failure: 'encoding for n1s tlv1s amount_msat is not minimal', }, { input: '01080001000000000000', failure: 'encoding for n1s tlv1s amount_msat is not minimal', }, { input: '020701010101010101', failure: 'less than encoding length for n1s tlv2', }, { input: '0209010101010101010101', failure: 'greater than encoding length for n1s tlv2', }, { input: '0321023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb', failure: 'less than encoding length for n1s tlv3', }, { input: "0329023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001", // prettier-ignore failure: 'less than encoding length for n1s tlv3', }, { input: '0330023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb000000000000000100000000000001', failure: 'less than encoding length for n1s tlv3', }, // { // input: "0331043da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb00000000000000010000000000000002", // prettier-ignore // failure: "n1s node_id is not a valid point", // }, { input: "0332023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001000000000000000001", // prettier-ignore failure: 'greater than encoding length for n1s tlv3', }, { input: 'fd00fe00', failure: 'less than encoding length for n1s tlv4', }, { input: 'fd00fe0101', failure: 'less than encoding length for n1s tlv4', }, { input: 'fd00fe03010101', failure: 'greater than encoding length for n1s tlv4', }, { input: '0000', failure: 'unknown even field for n1s namespace', }, { input: '', output: {}, }, { input: '2100', output: {}, }, { input: 'fd020100', output: {}, }, { input: 'fd00fd00', output: {}, }, { input: 'fd00ff00', output: {}, }, { input: 'fe0200000100', output: {}, }, { input: 'ff020000000000000100', output: {}, }, { input: '0100', output: { amount_msat: '0' }, }, { input: '010101', output: { amount_msat: '1' }, }, { input: '01020100', output: { amount_msat: '256' }, }, { input: '0103010000', output: { amount_msat: '65536' }, }, { input: '010401000000', output: { amount_msat: '16777216' }, }, { input: '01050100000000', output: { amount_msat: '4294967296' }, }, { input: '0106010000000000', output: { amount_msat: '1099511627776' }, }, { input: '010701000000000000', output: { amount_msat: '281474976710656' }, }, { input: '01080100000000000000', output: { amount_msat: '72057594037927936' }, }, { input: '02080000000000000226', output: { scid: '0x0x550' }, }, { input: "0331023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb00000000000000010000000000000002", // prettier-ignore output: { node_id: '023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb', amount_msat_1: '1', amount_msat_2: '2', }, }, { input: 'fd00fe020226', output: { cltv_delta: 550 }, }, { input: '01030100000 2080000000000000226', output: { amount_msat: '65536', scid: '0x0x550', }, }, { input: '02 08 0000000000000226 01 01 2a', failure: 'valid TLV records but invalid ordering', }, { input: '02 08 0000000000000231 02 08 0000000000000451', failure: 'duplicate TLV type', }, { input: '1f 00 0f 01 2a', failure: 'valid (ignored) TLV records but invalid ordering', }, { input: '1f 00 1f 01 2a', failure: 'duplicate TLV type (ignored)', }, ]; for (const test of n1tests) { it(`n1 ${test.input}`, () => { const instance: any = {}; function handler(type: bigint, value: BufferReader): boolean { switch (type) { case BigInt(1): { instance.amount_msat = value.readTUInt64().toString(); return true; } case BigInt(2): { const scid = shortChannelIdFromBuffer(value.readBytes(8)); instance.scid = scid.toString(); return true; } case BigInt(3): { const nodeId = value.readBytes(33); const amountMsat1 = value.readUInt64BE(); const amountMsat2 = value.readUInt64BE(); instance.node_id = nodeId.toString('hex'); instance.amount_msat_1 = amountMsat1.toString(); instance.amount_msat_2 = amountMsat2.toString(); return true; } case BigInt(254): { instance.cltv_delta = value.readUInt16BE(); return true; } } } const input = Buffer.from(test.input.replace(/ /g, ''), 'hex'); const reader = new BufferReader(input); if (test.failure) { expect(() => readTlvs(reader, handler)).to.throw(); } else { readTlvs(reader, handler); expect(instance).to.deep.equal(test.output); } }); } const n2tests: Array<{ input: string; failure?: string; output?: any }> = [ { input: 'fd', failure: 'type truncated', }, { input: 'fd01', failure: 'type truncated', }, { input: 'fd000100', failure: 'not minimally encoded', }, { input: 'fd0101', failure: 'no length', }, { input: '0ffd', failure: 'length truncated', }, { input: '0ffd26', failure: 'length truncated', }, { input: '0ffd2602', failure: 'missing value', }, { input: '0ffd000100', failure: 'not minimally encoded', }, { input: "0ffd0201000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", // prettier-ignore failure: 'value truncated', }, { input: '1200', failure: 'unknown even type', }, { input: 'fd010200', failure: 'unknown even type', }, { input: 'fe0100000200', failure: 'unknow even type', }, { input: 'ff010000000000000200', failure: 'unknown even type', }, { input: '', output: {}, }, { input: '2100', output: {}, }, { input: 'fd020100', output: {}, }, { input: 'fd00fd00', output: {}, }, { input: 'fd00ff00', output: {}, }, { input: 'fe0200000100', output: {}, }, { input: 'ff020000000000000100', output: {}, }, { input: 'ffffffffffffffffff 00 00 00', failure: 'valid TLV records but invalid ordering', }, ]; for (const test of n2tests) { it(`n2 ${test.input}`, () => { const instance: any = {}; function handler(type: bigint, value: BufferReader): boolean { switch (type) { case BigInt(0): { instance.amount_msat = value.readTUInt64().toString(); return true; } case BigInt(11): { instance.cltv_delta = value.readTUInt32(); return true; } } } const input = Buffer.from(test.input.replace(/ /g, ''), 'hex'); const reader = new BufferReader(input); if (test.failure) { expect(() => readTlvs(reader, handler)).to.throw(); } else { readTlvs(reader, handler); expect(instance).to.deep.equal(test.output); } }); } });