test_lnmsg.py (32845B)
1 import io 2 3 from electrum.lnmsg import (read_bigsize_int, write_bigsize_int, FieldEncodingNotMinimal, 4 UnexpectedEndOfStream, LNSerializer, UnknownMandatoryTLVRecordType, 5 MalformedMsg, MsgTrailingGarbage, MsgInvalidFieldOrder, encode_msg, 6 decode_msg, UnexpectedFieldSizeForEncoder) 7 from electrum.util import bfh 8 from electrum.lnutil import ShortChannelID, LnFeatures 9 from electrum import constants 10 11 from . import TestCaseForTestnet 12 13 14 class TestLNMsg(TestCaseForTestnet): 15 16 def test_write_bigsize_int(self): 17 self.assertEqual(bfh("00"), write_bigsize_int(0)) 18 self.assertEqual(bfh("fc"), write_bigsize_int(252)) 19 self.assertEqual(bfh("fd00fd"), write_bigsize_int(253)) 20 self.assertEqual(bfh("fdffff"), write_bigsize_int(65535)) 21 self.assertEqual(bfh("fe00010000"), write_bigsize_int(65536)) 22 self.assertEqual(bfh("feffffffff"), write_bigsize_int(4294967295)) 23 self.assertEqual(bfh("ff0000000100000000"), write_bigsize_int(4294967296)) 24 self.assertEqual(bfh("ffffffffffffffffff"), write_bigsize_int(18446744073709551615)) 25 26 def test_read_bigsize_int(self): 27 self.assertEqual(0, read_bigsize_int(io.BytesIO(bfh("00")))) 28 self.assertEqual(252, read_bigsize_int(io.BytesIO(bfh("fc")))) 29 self.assertEqual(253, read_bigsize_int(io.BytesIO(bfh("fd00fd")))) 30 self.assertEqual(65535, read_bigsize_int(io.BytesIO(bfh("fdffff")))) 31 self.assertEqual(65536, read_bigsize_int(io.BytesIO(bfh("fe00010000")))) 32 self.assertEqual(4294967295, read_bigsize_int(io.BytesIO(bfh("feffffffff")))) 33 self.assertEqual(4294967296, read_bigsize_int(io.BytesIO(bfh("ff0000000100000000")))) 34 self.assertEqual(18446744073709551615, read_bigsize_int(io.BytesIO(bfh("ffffffffffffffffff")))) 35 36 with self.assertRaises(FieldEncodingNotMinimal): 37 read_bigsize_int(io.BytesIO(bfh("fd00fc"))) 38 with self.assertRaises(FieldEncodingNotMinimal): 39 read_bigsize_int(io.BytesIO(bfh("fe0000ffff"))) 40 with self.assertRaises(FieldEncodingNotMinimal): 41 read_bigsize_int(io.BytesIO(bfh("ff00000000ffffffff"))) 42 with self.assertRaises(UnexpectedEndOfStream): 43 read_bigsize_int(io.BytesIO(bfh("fd00"))) 44 with self.assertRaises(UnexpectedEndOfStream): 45 read_bigsize_int(io.BytesIO(bfh("feffff"))) 46 with self.assertRaises(UnexpectedEndOfStream): 47 read_bigsize_int(io.BytesIO(bfh("ffffffffff"))) 48 self.assertEqual(None, read_bigsize_int(io.BytesIO(bfh("")))) 49 with self.assertRaises(UnexpectedEndOfStream): 50 read_bigsize_int(io.BytesIO(bfh("fd"))) 51 with self.assertRaises(UnexpectedEndOfStream): 52 read_bigsize_int(io.BytesIO(bfh("fe"))) 53 with self.assertRaises(UnexpectedEndOfStream): 54 read_bigsize_int(io.BytesIO(bfh("ff"))) 55 56 def test_read_tlv_stream_tests1(self): 57 # from https://github.com/lightningnetwork/lightning-rfc/blob/452a0eb916fedf4c954137b4fd0b61b5002b34ad/01-messaging.md#tlv-decoding-failures 58 lnser = LNSerializer() 59 for tlv_stream_name in ("n1", "n2"): 60 with self.subTest(tlv_stream_name=tlv_stream_name): 61 with self.assertRaises(UnexpectedEndOfStream): 62 lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd")), tlv_stream_name=tlv_stream_name) 63 with self.assertRaises(UnexpectedEndOfStream): 64 lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd01")), tlv_stream_name=tlv_stream_name) 65 with self.assertRaises(FieldEncodingNotMinimal): 66 lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd000100")), tlv_stream_name=tlv_stream_name) 67 with self.assertRaises(UnexpectedEndOfStream): 68 lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd0101")), tlv_stream_name=tlv_stream_name) 69 with self.assertRaises(UnexpectedEndOfStream): 70 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0ffd")), tlv_stream_name=tlv_stream_name) 71 with self.assertRaises(UnexpectedEndOfStream): 72 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0ffd26")), tlv_stream_name=tlv_stream_name) 73 with self.assertRaises(UnexpectedEndOfStream): 74 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0ffd2602")), tlv_stream_name=tlv_stream_name) 75 with self.assertRaises(FieldEncodingNotMinimal): 76 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0ffd000100")), tlv_stream_name=tlv_stream_name) 77 with self.assertRaises(UnexpectedEndOfStream): 78 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0ffd0201000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")), tlv_stream_name="n1") 79 with self.assertRaises(UnknownMandatoryTLVRecordType): 80 lnser.read_tlv_stream(fd=io.BytesIO(bfh("1200")), tlv_stream_name=tlv_stream_name) 81 with self.assertRaises(UnknownMandatoryTLVRecordType): 82 lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd010200")), tlv_stream_name=tlv_stream_name) 83 with self.assertRaises(UnknownMandatoryTLVRecordType): 84 lnser.read_tlv_stream(fd=io.BytesIO(bfh("fe0100000200")), tlv_stream_name=tlv_stream_name) 85 with self.assertRaises(UnknownMandatoryTLVRecordType): 86 lnser.read_tlv_stream(fd=io.BytesIO(bfh("ff010000000000000200")), tlv_stream_name=tlv_stream_name) 87 with self.assertRaises(MsgTrailingGarbage): 88 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0109ffffffffffffffffff")), tlv_stream_name="n1") 89 with self.assertRaises(FieldEncodingNotMinimal): 90 lnser.read_tlv_stream(fd=io.BytesIO(bfh("010100")), tlv_stream_name="n1") 91 with self.assertRaises(FieldEncodingNotMinimal): 92 lnser.read_tlv_stream(fd=io.BytesIO(bfh("01020001")), tlv_stream_name="n1") 93 with self.assertRaises(FieldEncodingNotMinimal): 94 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0103000100")), tlv_stream_name="n1") 95 with self.assertRaises(FieldEncodingNotMinimal): 96 lnser.read_tlv_stream(fd=io.BytesIO(bfh("010400010000")), tlv_stream_name="n1") 97 with self.assertRaises(FieldEncodingNotMinimal): 98 lnser.read_tlv_stream(fd=io.BytesIO(bfh("01050001000000")), tlv_stream_name="n1") 99 with self.assertRaises(FieldEncodingNotMinimal): 100 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0106000100000000")), tlv_stream_name="n1") 101 with self.assertRaises(FieldEncodingNotMinimal): 102 lnser.read_tlv_stream(fd=io.BytesIO(bfh("010700010000000000")), tlv_stream_name="n1") 103 with self.assertRaises(FieldEncodingNotMinimal): 104 lnser.read_tlv_stream(fd=io.BytesIO(bfh("01080001000000000000")), tlv_stream_name="n1") 105 with self.assertRaises(UnexpectedEndOfStream): 106 lnser.read_tlv_stream(fd=io.BytesIO(bfh("020701010101010101")), tlv_stream_name="n1") 107 with self.assertRaises(MsgTrailingGarbage): 108 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0209010101010101010101")), tlv_stream_name="n1") 109 with self.assertRaises(UnexpectedEndOfStream): 110 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0321023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb")), tlv_stream_name="n1") 111 with self.assertRaises(UnexpectedEndOfStream): 112 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0329023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001")), tlv_stream_name="n1") 113 with self.assertRaises(UnexpectedEndOfStream): 114 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0330023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb000000000000000100000000000001")), tlv_stream_name="n1") 115 # check if ECC point is valid?... skip for now. 116 #with self.assertRaises(Exception): 117 # lnser.read_tlv_stream(fd=io.BytesIO(bfh("0331043da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb00000000000000010000000000000002")), tlv_stream_name="n1") 118 with self.assertRaises(MsgTrailingGarbage): 119 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0332023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001000000000000000001")), tlv_stream_name="n1") 120 with self.assertRaises(UnexpectedEndOfStream): 121 lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd00fe00")), tlv_stream_name="n1") 122 with self.assertRaises(UnexpectedEndOfStream): 123 lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd00fe0101")), tlv_stream_name="n1") 124 with self.assertRaises(MsgTrailingGarbage): 125 lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd00fe03010101")), tlv_stream_name="n1") 126 with self.assertRaises(UnknownMandatoryTLVRecordType): 127 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0000")), tlv_stream_name="n1") 128 129 def test_read_tlv_stream_tests2(self): 130 # from https://github.com/lightningnetwork/lightning-rfc/blob/452a0eb916fedf4c954137b4fd0b61b5002b34ad/01-messaging.md#tlv-decoding-successes 131 lnser = LNSerializer() 132 for tlv_stream_name in ("n1", "n2"): 133 with self.subTest(tlv_stream_name=tlv_stream_name): 134 self.assertEqual({}, lnser.read_tlv_stream(fd=io.BytesIO(bfh("")), tlv_stream_name=tlv_stream_name)) 135 self.assertEqual({}, lnser.read_tlv_stream(fd=io.BytesIO(bfh("2100")), tlv_stream_name=tlv_stream_name)) 136 self.assertEqual({}, lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd020100")), tlv_stream_name=tlv_stream_name)) 137 self.assertEqual({}, lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd00fd00")), tlv_stream_name=tlv_stream_name)) 138 self.assertEqual({}, lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd00ff00")), tlv_stream_name=tlv_stream_name)) 139 self.assertEqual({}, lnser.read_tlv_stream(fd=io.BytesIO(bfh("fe0200000100")), tlv_stream_name=tlv_stream_name)) 140 self.assertEqual({}, lnser.read_tlv_stream(fd=io.BytesIO(bfh("ff020000000000000100")), tlv_stream_name=tlv_stream_name)) 141 142 self.assertEqual({"tlv1": {"amount_msat": 0}}, 143 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0100")), tlv_stream_name="n1")) 144 self.assertEqual({"tlv1": {"amount_msat": 1}}, 145 lnser.read_tlv_stream(fd=io.BytesIO(bfh("010101")), tlv_stream_name="n1")) 146 self.assertEqual({"tlv1": {"amount_msat": 256}}, 147 lnser.read_tlv_stream(fd=io.BytesIO(bfh("01020100")), tlv_stream_name="n1")) 148 self.assertEqual({"tlv1": {"amount_msat": 65536}}, 149 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0103010000")), tlv_stream_name="n1")) 150 self.assertEqual({"tlv1": {"amount_msat": 16777216}}, 151 lnser.read_tlv_stream(fd=io.BytesIO(bfh("010401000000")), tlv_stream_name="n1")) 152 self.assertEqual({"tlv1": {"amount_msat": 4294967296}}, 153 lnser.read_tlv_stream(fd=io.BytesIO(bfh("01050100000000")), tlv_stream_name="n1")) 154 self.assertEqual({"tlv1": {"amount_msat": 1099511627776}}, 155 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0106010000000000")), tlv_stream_name="n1")) 156 self.assertEqual({"tlv1": {"amount_msat": 281474976710656}}, 157 lnser.read_tlv_stream(fd=io.BytesIO(bfh("010701000000000000")), tlv_stream_name="n1")) 158 self.assertEqual({"tlv1": {"amount_msat": 72057594037927936}}, 159 lnser.read_tlv_stream(fd=io.BytesIO(bfh("01080100000000000000")), tlv_stream_name="n1")) 160 self.assertEqual({"tlv2": {"scid": ShortChannelID.from_components(0, 0, 550)}}, 161 lnser.read_tlv_stream(fd=io.BytesIO(bfh("02080000000000000226")), tlv_stream_name="n1")) 162 self.assertEqual({"tlv3": {"node_id": bfh("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb"), 163 "amount_msat_1": 1, 164 "amount_msat_2": 2}}, 165 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0331023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb00000000000000010000000000000002")), tlv_stream_name="n1")) 166 self.assertEqual({"tlv4": {"cltv_delta": 550}}, 167 lnser.read_tlv_stream(fd=io.BytesIO(bfh("fd00fe020226")), tlv_stream_name="n1")) 168 169 def test_read_tlv_stream_tests3(self): 170 # from https://github.com/lightningnetwork/lightning-rfc/blob/452a0eb916fedf4c954137b4fd0b61b5002b34ad/01-messaging.md#tlv-stream-decoding-failure 171 lnser = LNSerializer() 172 with self.assertRaises(MsgInvalidFieldOrder): 173 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0208000000000000022601012a")), tlv_stream_name="n1") 174 with self.assertRaises(MsgInvalidFieldOrder): 175 lnser.read_tlv_stream(fd=io.BytesIO(bfh("0208000000000000023102080000000000000451")), tlv_stream_name="n1") 176 with self.assertRaises(MsgInvalidFieldOrder): 177 lnser.read_tlv_stream(fd=io.BytesIO(bfh("1f000f012a")), tlv_stream_name="n1") 178 with self.assertRaises(MsgInvalidFieldOrder): 179 lnser.read_tlv_stream(fd=io.BytesIO(bfh("1f001f012a")), tlv_stream_name="n1") 180 with self.assertRaises(MsgInvalidFieldOrder): 181 lnser.read_tlv_stream(fd=io.BytesIO(bfh("ffffffffffffffffff000000")), tlv_stream_name="n2") 182 183 def test_encode_decode_msg__missing_mandatory_field_gets_set_to_zeroes(self): 184 # "channel_update": "signature" missing -> gets set to zeroes 185 self.assertEqual(bfh("01020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000000d43100006f00025e6ed0830100009000000000000000c8000001f400000023000000003b9aca00"), 186 encode_msg( 187 "channel_update", 188 short_channel_id=ShortChannelID.from_components(54321, 111, 2), 189 channel_flags=b'\x00', 190 message_flags=b'\x01', 191 cltv_expiry_delta=144, 192 htlc_minimum_msat=200, 193 htlc_maximum_msat=1_000_000_000, 194 fee_base_msat=500, 195 fee_proportional_millionths=35, 196 chain_hash=constants.net.rev_genesis_bytes(), 197 timestamp=1584320643, 198 )) 199 self.assertEqual(('channel_update', 200 {'chain_hash': b'CI\x7f\xd7\xf8&\x95q\x08\xf4\xa3\x0f\xd9\xce\xc3\xae\xbay\x97 \x84\xe9\x0e\xad\x01\xea3\t\x00\x00\x00\x00', 201 'channel_flags': b'\x00', 202 'cltv_expiry_delta': 144, 203 'fee_base_msat': 500, 204 'fee_proportional_millionths': 35, 205 'htlc_maximum_msat': 1000000000, 206 'htlc_minimum_msat': 200, 207 'message_flags': b'\x01', 208 'short_channel_id': b'\x00\xd41\x00\x00o\x00\x02', 209 'signature': bytes(64), 210 'timestamp': 1584320643} 211 ), 212 decode_msg(bfh("01020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000000d43100006f00025e6ed0830100009000000000000000c8000001f400000023000000003b9aca00"))) 213 214 def test_encode_decode_msg__missing_optional_field_will_not_appear_in_decoded_dict(self): 215 # "channel_update": optional field "htlc_maximum_msat" missing -> does not get put into dict 216 self.assertEqual(bfh("01020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000000d43100006f00025e6ed0830100009000000000000000c8000001f400000023"), 217 encode_msg( 218 "channel_update", 219 short_channel_id=ShortChannelID.from_components(54321, 111, 2), 220 channel_flags=b'\x00', 221 message_flags=b'\x01', 222 cltv_expiry_delta=144, 223 htlc_minimum_msat=200, 224 fee_base_msat=500, 225 fee_proportional_millionths=35, 226 chain_hash=constants.net.rev_genesis_bytes(), 227 timestamp=1584320643, 228 )) 229 self.assertEqual(('channel_update', 230 {'chain_hash': b'CI\x7f\xd7\xf8&\x95q\x08\xf4\xa3\x0f\xd9\xce\xc3\xae\xbay\x97 \x84\xe9\x0e\xad\x01\xea3\t\x00\x00\x00\x00', 231 'channel_flags': b'\x00', 232 'cltv_expiry_delta': 144, 233 'fee_base_msat': 500, 234 'fee_proportional_millionths': 35, 235 'htlc_minimum_msat': 200, 236 'message_flags': b'\x01', 237 'short_channel_id': b'\x00\xd41\x00\x00o\x00\x02', 238 'signature': bytes(64), 239 'timestamp': 1584320643} 240 ), 241 decode_msg(bfh("01020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000000d43100006f00025e6ed0830100009000000000000000c8000001f400000023"))) 242 243 def test_encode_decode_msg__ints_can_be_passed_as_bytes(self): 244 self.assertEqual(bfh("01020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000000d43100006f00025e6ed0830100009000000000000000c8000001f400000023000000003b9aca00"), 245 encode_msg( 246 "channel_update", 247 short_channel_id=ShortChannelID.from_components(54321, 111, 2), 248 channel_flags=b'\x00', 249 message_flags=b'\x01', 250 cltv_expiry_delta=int.to_bytes(144, length=2, byteorder="big", signed=False), 251 htlc_minimum_msat=int.to_bytes(200, length=8, byteorder="big", signed=False), 252 htlc_maximum_msat=int.to_bytes(1_000_000_000, length=8, byteorder="big", signed=False), 253 fee_base_msat=int.to_bytes(500, length=4, byteorder="big", signed=False), 254 fee_proportional_millionths=int.to_bytes(35, length=4, byteorder="big", signed=False), 255 chain_hash=constants.net.rev_genesis_bytes(), 256 timestamp=int.to_bytes(1584320643, length=4, byteorder="big", signed=False), 257 )) 258 self.assertEqual(('channel_update', 259 {'chain_hash': b'CI\x7f\xd7\xf8&\x95q\x08\xf4\xa3\x0f\xd9\xce\xc3\xae\xbay\x97 \x84\xe9\x0e\xad\x01\xea3\t\x00\x00\x00\x00', 260 'channel_flags': b'\x00', 261 'cltv_expiry_delta': 144, 262 'fee_base_msat': 500, 263 'fee_proportional_millionths': 35, 264 'htlc_maximum_msat': 1000000000, 265 'htlc_minimum_msat': 200, 266 'message_flags': b'\x01', 267 'short_channel_id': b'\x00\xd41\x00\x00o\x00\x02', 268 'signature': bytes(64), 269 'timestamp': 1584320643} 270 ), 271 decode_msg(bfh("01020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000000d43100006f00025e6ed0830100009000000000000000c8000001f400000023000000003b9aca00"))) 272 # "htlc_minimum_msat" is passed as bytes but with incorrect length 273 with self.assertRaises(UnexpectedFieldSizeForEncoder): 274 encode_msg( 275 "channel_update", 276 short_channel_id=ShortChannelID.from_components(54321, 111, 2), 277 channel_flags=b'\x00', 278 message_flags=b'\x01', 279 cltv_expiry_delta=int.to_bytes(144, length=2, byteorder="big", signed=False), 280 htlc_minimum_msat=int.to_bytes(200, length=4, byteorder="big", signed=False), 281 htlc_maximum_msat=int.to_bytes(1_000_000_000, length=8, byteorder="big", signed=False), 282 fee_base_msat=int.to_bytes(500, length=4, byteorder="big", signed=False), 283 fee_proportional_millionths=int.to_bytes(35, length=4, byteorder="big", signed=False), 284 chain_hash=constants.net.rev_genesis_bytes(), 285 timestamp=int.to_bytes(1584320643, length=4, byteorder="big", signed=False), 286 ) 287 288 def test_encode_decode_msg__commitment_signed(self): 289 # "commitment_signed" is interesting because of the "htlc_signature" field, 290 # which is a concatenation of multiple ("num_htlcs") signatures. 291 # 5 htlcs 292 self.assertEqual(bfh("0084010101010101010101010101010101010101010101010101010101010101010106112951d0a6d7fc1dbca3bd1cdbda9acfee7f668b3c0a36bd944f7e2f305b274ba46a61279e15163b2d376c664bb3481d7c5e107a5b268301e39aebbda27d2d00056548bd093a2bd2f4f053f0c6eb2c5f541d55eb8a2ede4d35fe974e5d3cd0eec3138bfd4115f4483c3b14e7988b48811d2da75f29f5e6eee691251fb4fba5a2610ba8fe7007117fe1c9fa1a6b01805c84cfffbb0eba674b64342c7cac567dea50728c1bb1aadc6d23fc2f4145027eafca82d6072cc9ce6529542099f728a0521e4b2044df5d02f7f2cdf84404762b1979528aa689a3e060a2a90ba8ef9a83d24d31ffb0d95c71d9fb9049b24ecf2c949c1486e7eb3ae160d70d54e441dc785dc57f7f3c9901b9537398c66f546cfc1d65e0748895d14699342c407fe119ac17db079b103720124a5ba22d4ba14c12832324dea9cb60c61ee74376ee7dcffdd1836e354aa8838ce3b37854fa91465cc40c73b702915e3580bfebaace805d52373b57ac755ebe4a8fe97e5fc21669bea124b809c79968479148f7174f39b8014542"), 293 encode_msg( 294 "commitment_signed", 295 channel_id=b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01', 296 signature=b"\x06\x11)Q\xd0\xa6\xd7\xfc\x1d\xbc\xa3\xbd\x1c\xdb\xda\x9a\xcf\xee\x7ff\x8b<\n6\xbd\x94O~/0['K\xa4ja'\x9e\x15\x16;-7lfK\xb3H\x1d|^\x10z[&\x83\x01\xe3\x9a\xeb\xbd\xa2}-", 297 num_htlcs=5, 298 htlc_signature=bfh("6548bd093a2bd2f4f053f0c6eb2c5f541d55eb8a2ede4d35fe974e5d3cd0eec3138bfd4115f4483c3b14e7988b48811d2da75f29f5e6eee691251fb4fba5a2610ba8fe7007117fe1c9fa1a6b01805c84cfffbb0eba674b64342c7cac567dea50728c1bb1aadc6d23fc2f4145027eafca82d6072cc9ce6529542099f728a0521e4b2044df5d02f7f2cdf84404762b1979528aa689a3e060a2a90ba8ef9a83d24d31ffb0d95c71d9fb9049b24ecf2c949c1486e7eb3ae160d70d54e441dc785dc57f7f3c9901b9537398c66f546cfc1d65e0748895d14699342c407fe119ac17db079b103720124a5ba22d4ba14c12832324dea9cb60c61ee74376ee7dcffdd1836e354aa8838ce3b37854fa91465cc40c73b702915e3580bfebaace805d52373b57ac755ebe4a8fe97e5fc21669bea124b809c79968479148f7174f39b8014542"), 299 )) 300 self.assertEqual(('commitment_signed', 301 {'channel_id': b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01', 302 'signature': b"\x06\x11)Q\xd0\xa6\xd7\xfc\x1d\xbc\xa3\xbd\x1c\xdb\xda\x9a\xcf\xee\x7ff\x8b<\n6\xbd\x94O~/0['K\xa4ja'\x9e\x15\x16;-7lfK\xb3H\x1d|^\x10z[&\x83\x01\xe3\x9a\xeb\xbd\xa2}-", 303 'num_htlcs': 5, 304 'htlc_signature': bfh("6548bd093a2bd2f4f053f0c6eb2c5f541d55eb8a2ede4d35fe974e5d3cd0eec3138bfd4115f4483c3b14e7988b48811d2da75f29f5e6eee691251fb4fba5a2610ba8fe7007117fe1c9fa1a6b01805c84cfffbb0eba674b64342c7cac567dea50728c1bb1aadc6d23fc2f4145027eafca82d6072cc9ce6529542099f728a0521e4b2044df5d02f7f2cdf84404762b1979528aa689a3e060a2a90ba8ef9a83d24d31ffb0d95c71d9fb9049b24ecf2c949c1486e7eb3ae160d70d54e441dc785dc57f7f3c9901b9537398c66f546cfc1d65e0748895d14699342c407fe119ac17db079b103720124a5ba22d4ba14c12832324dea9cb60c61ee74376ee7dcffdd1836e354aa8838ce3b37854fa91465cc40c73b702915e3580bfebaace805d52373b57ac755ebe4a8fe97e5fc21669bea124b809c79968479148f7174f39b8014542")} 305 ), 306 decode_msg(bfh("0084010101010101010101010101010101010101010101010101010101010101010106112951d0a6d7fc1dbca3bd1cdbda9acfee7f668b3c0a36bd944f7e2f305b274ba46a61279e15163b2d376c664bb3481d7c5e107a5b268301e39aebbda27d2d00056548bd093a2bd2f4f053f0c6eb2c5f541d55eb8a2ede4d35fe974e5d3cd0eec3138bfd4115f4483c3b14e7988b48811d2da75f29f5e6eee691251fb4fba5a2610ba8fe7007117fe1c9fa1a6b01805c84cfffbb0eba674b64342c7cac567dea50728c1bb1aadc6d23fc2f4145027eafca82d6072cc9ce6529542099f728a0521e4b2044df5d02f7f2cdf84404762b1979528aa689a3e060a2a90ba8ef9a83d24d31ffb0d95c71d9fb9049b24ecf2c949c1486e7eb3ae160d70d54e441dc785dc57f7f3c9901b9537398c66f546cfc1d65e0748895d14699342c407fe119ac17db079b103720124a5ba22d4ba14c12832324dea9cb60c61ee74376ee7dcffdd1836e354aa8838ce3b37854fa91465cc40c73b702915e3580bfebaace805d52373b57ac755ebe4a8fe97e5fc21669bea124b809c79968479148f7174f39b8014542"))) 307 # single htlc 308 self.assertEqual(bfh("008401010101010101010101010101010101010101010101010101010101010101013b14af0c549dfb1fb287ff57c012371b3932996db5929eda5f251704751fb49d0dc2dcb88e5021575cb572fb71693758543f97d89e9165f913bfb7488d7cc26500012d31103b9f6e71131e4fee86fdfbdeba90e52b43fcfd11e8e53811cd4d59b2575ae6c3c82f85bea144c88cc35e568f1e6bdd0c57337e86de0b5da7cd9994067a"), 309 encode_msg( 310 "commitment_signed", 311 channel_id=b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01', 312 signature=b';\x14\xaf\x0cT\x9d\xfb\x1f\xb2\x87\xffW\xc0\x127\x1b92\x99m\xb5\x92\x9e\xda_%\x17\x04u\x1f\xb4\x9d\r\xc2\xdc\xb8\x8eP!W\\\xb5r\xfbqi7XT?\x97\xd8\x9e\x91e\xf9\x13\xbf\xb7H\x8d|\xc2e', 313 num_htlcs=1, 314 htlc_signature=bfh("2d31103b9f6e71131e4fee86fdfbdeba90e52b43fcfd11e8e53811cd4d59b2575ae6c3c82f85bea144c88cc35e568f1e6bdd0c57337e86de0b5da7cd9994067a"), 315 )) 316 self.assertEqual(('commitment_signed', 317 {'channel_id': b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01', 318 'signature': b';\x14\xaf\x0cT\x9d\xfb\x1f\xb2\x87\xffW\xc0\x127\x1b92\x99m\xb5\x92\x9e\xda_%\x17\x04u\x1f\xb4\x9d\r\xc2\xdc\xb8\x8eP!W\\\xb5r\xfbqi7XT?\x97\xd8\x9e\x91e\xf9\x13\xbf\xb7H\x8d|\xc2e', 319 'num_htlcs': 1, 320 'htlc_signature': bfh("2d31103b9f6e71131e4fee86fdfbdeba90e52b43fcfd11e8e53811cd4d59b2575ae6c3c82f85bea144c88cc35e568f1e6bdd0c57337e86de0b5da7cd9994067a")} 321 ), 322 decode_msg(bfh("008401010101010101010101010101010101010101010101010101010101010101013b14af0c549dfb1fb287ff57c012371b3932996db5929eda5f251704751fb49d0dc2dcb88e5021575cb572fb71693758543f97d89e9165f913bfb7488d7cc26500012d31103b9f6e71131e4fee86fdfbdeba90e52b43fcfd11e8e53811cd4d59b2575ae6c3c82f85bea144c88cc35e568f1e6bdd0c57337e86de0b5da7cd9994067a"))) 323 # zero htlcs 324 self.assertEqual(bfh("008401010101010101010101010101010101010101010101010101010101010101014e206ecf904d9237b1c5b4e08513555e9a5932c45b5f68be8764ce998df635ae04f6ce7bbcd3b4fd08e2daab7f9059b287ecab4155367b834682633497173f450000"), 325 encode_msg( 326 "commitment_signed", 327 channel_id=b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01', 328 signature=b'N n\xcf\x90M\x927\xb1\xc5\xb4\xe0\x85\x13U^\x9aY2\xc4[_h\xbe\x87d\xce\x99\x8d\xf65\xae\x04\xf6\xce{\xbc\xd3\xb4\xfd\x08\xe2\xda\xab\x7f\x90Y\xb2\x87\xec\xabAU6{\x83F\x82c4\x97\x17?E', 329 num_htlcs=0, 330 htlc_signature=bfh(""), 331 )) 332 self.assertEqual(('commitment_signed', 333 {'channel_id': b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01', 334 'signature': b'N n\xcf\x90M\x927\xb1\xc5\xb4\xe0\x85\x13U^\x9aY2\xc4[_h\xbe\x87d\xce\x99\x8d\xf65\xae\x04\xf6\xce{\xbc\xd3\xb4\xfd\x08\xe2\xda\xab\x7f\x90Y\xb2\x87\xec\xabAU6{\x83F\x82c4\x97\x17?E', 335 'num_htlcs': 0, 336 'htlc_signature': bfh("")} 337 ), 338 decode_msg(bfh("008401010101010101010101010101010101010101010101010101010101010101014e206ecf904d9237b1c5b4e08513555e9a5932c45b5f68be8764ce998df635ae04f6ce7bbcd3b4fd08e2daab7f9059b287ecab4155367b834682633497173f450000"))) 339 340 def test_encode_decode_msg__init(self): 341 # "init" is interesting because it has TLVs optionally 342 self.assertEqual(bfh("00100000000220c2"), 343 encode_msg( 344 "init", 345 gflen=0, 346 flen=2, 347 features=(LnFeatures.OPTION_STATIC_REMOTEKEY_OPT | 348 LnFeatures.GOSSIP_QUERIES_OPT | 349 LnFeatures.GOSSIP_QUERIES_REQ | 350 LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT), 351 )) 352 self.assertEqual(bfh("00100000000220c2"), 353 encode_msg("init", gflen=0, flen=2, features=bfh("20c2"))) 354 self.assertEqual(bfh("00100000000220c2012043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000"), 355 encode_msg( 356 "init", 357 gflen=0, 358 flen=2, 359 features=(LnFeatures.OPTION_STATIC_REMOTEKEY_OPT | 360 LnFeatures.GOSSIP_QUERIES_OPT | 361 LnFeatures.GOSSIP_QUERIES_REQ | 362 LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT), 363 init_tlvs={ 364 'networks': 365 {'chains': b'CI\x7f\xd7\xf8&\x95q\x08\xf4\xa3\x0f\xd9\xce\xc3\xae\xbay\x97 \x84\xe9\x0e\xad\x01\xea3\t\x00\x00\x00\x00'} 366 } 367 )) 368 self.assertEqual(('init', 369 {'gflen': 2, 370 'globalfeatures': b'"\x00', 371 'flen': 3, 372 'features': b'\x02\xa2\xa1', 373 'init_tlvs': {}} 374 ), 375 decode_msg(bfh("001000022200000302a2a1"))) 376 self.assertEqual(('init', 377 {'gflen': 2, 378 'globalfeatures': b'"\x00', 379 'flen': 3, 380 'features': b'\x02\xaa\xa2', 381 'init_tlvs': { 382 'networks': 383 {'chains': b'CI\x7f\xd7\xf8&\x95q\x08\xf4\xa3\x0f\xd9\xce\xc3\xae\xbay\x97 \x84\xe9\x0e\xad\x01\xea3\t\x00\x00\x00\x00'} 384 }}), 385 decode_msg(bfh("001000022200000302aaa2012043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000")))