import { BufferReader } from "@node-lightning/bufio" ; import { shortChannelIdFromBuffer } from "@node-lightning/core" ; import { expect } from "chai" ; import { readTlvs } from "../../lib/serialize/readTlvs" ; describe ( ".readTlvs()" , ( ) => { const n1tests = [ { 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" , 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" , failure : "less than encoding length for n1s tlv3" , } , { input : "0330023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb000000000000000100000000000001" , failure : "less than encoding length for n1s tlv3" , } , { input : "0332023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001000000000000000001" , 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" , 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 = { } ; function handler ( type , value ) { 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 = [ { 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" , 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 = { } ; function handler ( type , value ) { 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 ) ; } } ) ; } } ) ;