electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

test_lnutil.py (54929B)


      1 import unittest
      2 import json
      3 
      4 from electrum import bitcoin
      5 from electrum.json_db import StoredDict
      6 from electrum.lnutil import (RevocationStore, get_per_commitment_secret_from_seed, make_offered_htlc,
      7                              make_received_htlc, make_commitment, make_htlc_tx_witness, make_htlc_tx_output,
      8                              make_htlc_tx_inputs, secret_to_pubkey, derive_blinded_pubkey, derive_privkey,
      9                              derive_pubkey, make_htlc_tx, extract_ctn_from_tx, UnableToDeriveSecret,
     10                              get_compressed_pubkey_from_bech32, split_host_port, ConnStringFormatError,
     11                              ScriptHtlc, extract_nodeid, calc_fees_for_commitment_tx, UpdateAddHtlc, LnFeatures,
     12                              ln_compare_features, IncompatibleLightningFeatures)
     13 from electrum.util import bh2u, bfh, MyEncoder
     14 from electrum.transaction import Transaction, PartialTransaction
     15 from electrum.lnworker import LNWallet
     16 
     17 from . import ElectrumTestCase
     18 
     19 
     20 funding_tx_id = '8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be'
     21 funding_output_index = 0
     22 funding_amount_satoshi = 10000000
     23 commitment_number = 42
     24 local_delay = 144
     25 local_dust_limit_satoshi = 546
     26 
     27 local_payment_basepoint = bytes.fromhex('034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa')
     28 remote_payment_basepoint = bytes.fromhex('032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991')
     29 # obs = get_obscured_ctn(42, local_payment_basepoint, remote_payment_basepoint)
     30 local_funding_privkey = bytes.fromhex('30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f374901')
     31 local_funding_pubkey = bytes.fromhex('023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb')
     32 remote_funding_pubkey = bytes.fromhex('030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1')
     33 local_privkey = bytes.fromhex('bb13b121cdc357cd2e608b0aea294afca36e2b34cf958e2e6451a2f27469449101')
     34 localpubkey = bytes.fromhex('030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e7')
     35 remotepubkey = bytes.fromhex('0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b')
     36 local_delayedpubkey = bytes.fromhex('03fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c')
     37 local_revocation_pubkey = bytes.fromhex('0212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b19')
     38 # funding wscript = 5221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae
     39 
     40 
     41 class TestLNUtil(ElectrumTestCase):
     42     def test_shachain_store(self):
     43         tests = [
     44             {
     45                 "name": "insert_secret correct sequence",
     46                 "inserts": [
     47                     {
     48                         "index": 281474976710655,
     49                         "secret": "7cc854b54e3e0dcdb010d7a3fee464a9687b" +\
     50                             "e6e8db3be6854c475621e007a5dc",
     51                         "successful": True
     52                     },
     53                     {
     54                         "index": 281474976710654,
     55                         "secret": "c7518c8ae4660ed02894df8976fa1a3659c1" +\
     56                             "a8b4b5bec0c4b872abeba4cb8964",
     57                         "successful": True
     58                     },
     59                     {
     60                         "index": 281474976710653,
     61                         "secret": "2273e227a5b7449b6e70f1fb4652864038b1" +\
     62                             "cbf9cd7c043a7d6456b7fc275ad8",
     63                         "successful": True
     64                     },
     65                     {
     66                         "index": 281474976710652,
     67                         "secret": "27cddaa5624534cb6cb9d7da077cf2b22ab2" +\
     68                             "1e9b506fd4998a51d54502e99116",
     69                         "successful": True
     70                     },
     71                     {
     72                         "index": 281474976710651,
     73                         "secret": "c65716add7aa98ba7acb236352d665cab173" +\
     74                             "45fe45b55fb879ff80e6bd0c41dd",
     75                         "successful": True
     76                     },
     77                     {
     78                         "index": 281474976710650,
     79                         "secret": "969660042a28f32d9be17344e09374b37996" +\
     80                             "2d03db1574df5a8a5a47e19ce3f2",
     81                         "successful": True
     82                     },
     83                     {
     84                         "index": 281474976710649,
     85                         "secret": "a5a64476122ca0925fb344bdc1854c1c0a59" +\
     86                             "fc614298e50a33e331980a220f32",
     87                         "successful": True
     88                     },
     89                     {
     90                         "index": 281474976710648,
     91                         "secret": "05cde6323d949933f7f7b78776bcc1ea6d9b" +\
     92                             "31447732e3802e1f7ac44b650e17",
     93                         "successful": True
     94                     }
     95                 ]
     96             },
     97             {
     98                 "name": "insert_secret #1 incorrect",
     99                 "inserts": [
    100                     {
    101                         "index": 281474976710655,
    102                         "secret": "02a40c85b6f28da08dfdbe0926c53fab2d" +\
    103                             "e6d28c10301f8f7c4073d5e42e3148",
    104                         "successful": True
    105                     },
    106                     {
    107                         "index": 281474976710654,
    108                         "secret": "c7518c8ae4660ed02894df8976fa1a3659" +\
    109                             "c1a8b4b5bec0c4b872abeba4cb8964",
    110                         "successful": False
    111                     }
    112                 ]
    113             },
    114             {
    115                 "name": "insert_secret #2 incorrect (#1 derived from incorrect)",
    116                 "inserts": [
    117                     {
    118                         "index": 281474976710655,
    119                         "secret": "02a40c85b6f28da08dfdbe0926c53fab2de6" +\
    120                             "d28c10301f8f7c4073d5e42e3148",
    121                         "successful": True
    122                     },
    123                     {
    124                         "index": 281474976710654,
    125                         "secret": "dddc3a8d14fddf2b68fa8c7fbad274827493" +\
    126                             "7479dd0f8930d5ebb4ab6bd866a3",
    127                         "successful": True
    128                     },
    129                     {
    130                         "index": 281474976710653,
    131                         "secret": "2273e227a5b7449b6e70f1fb4652864038b1" +\
    132                             "cbf9cd7c043a7d6456b7fc275ad8",
    133                         "successful": True
    134                     },
    135                     {
    136                         "index": 281474976710652,
    137                         "secret": "27cddaa5624534cb6cb9d7da077cf2b22a" +\
    138                             "b21e9b506fd4998a51d54502e99116",
    139                         "successful": False
    140                     }
    141                 ]
    142             },
    143             {
    144                 "name": "insert_secret #3 incorrect",
    145                 "inserts": [
    146                     {
    147                         "index": 281474976710655,
    148                         "secret": "7cc854b54e3e0dcdb010d7a3fee464a9687b" +\
    149                             "e6e8db3be6854c475621e007a5dc",
    150                         "successful": True
    151                     },
    152                     {
    153                         "index": 281474976710654,
    154                         "secret": "c7518c8ae4660ed02894df8976fa1a3659c1" +\
    155                             "a8b4b5bec0c4b872abeba4cb8964",
    156                         "successful": True
    157                     },
    158                     {
    159                         "index": 281474976710653,
    160                         "secret": "c51a18b13e8527e579ec56365482c62f180b" +\
    161                             "7d5760b46e9477dae59e87ed423a",
    162                         "successful": True
    163                     },
    164                     {
    165                         "index": 281474976710652,
    166                         "secret": "27cddaa5624534cb6cb9d7da077cf2b22ab2" +\
    167                             "1e9b506fd4998a51d54502e99116",
    168                         "successful": False
    169                     }
    170                 ]
    171             },
    172             {
    173                 "name": "insert_secret #4 incorrect (1,2,3 derived from incorrect)",
    174                 "inserts": [
    175                     {
    176                         "index": 281474976710655,
    177                         "secret": "02a40c85b6f28da08dfdbe0926c53fab2de6" +\
    178                             "d28c10301f8f7c4073d5e42e3148",
    179                         "successful": True
    180                     },
    181                     {
    182                         "index": 281474976710654,
    183                         "secret": "dddc3a8d14fddf2b68fa8c7fbad274827493" +\
    184                             "7479dd0f8930d5ebb4ab6bd866a3",
    185                         "successful": True
    186                     },
    187                     {
    188                         "index": 281474976710653,
    189                         "secret": "c51a18b13e8527e579ec56365482c62f18" +\
    190                             "0b7d5760b46e9477dae59e87ed423a",
    191                         "successful": True
    192                     },
    193                     {
    194                         "index": 281474976710652,
    195                         "secret": "ba65d7b0ef55a3ba300d4e87af29868f39" +\
    196                             "4f8f138d78a7011669c79b37b936f4",
    197                         "successful": True
    198                     },
    199                     {
    200                         "index": 281474976710651,
    201                         "secret": "c65716add7aa98ba7acb236352d665cab1" +\
    202                             "7345fe45b55fb879ff80e6bd0c41dd",
    203                         "successful": True
    204                     },
    205                     {
    206                         "index": 281474976710650,
    207                         "secret": "969660042a28f32d9be17344e09374b379" +\
    208                             "962d03db1574df5a8a5a47e19ce3f2",
    209                         "successful": True
    210                     },
    211                     {
    212                         "index": 281474976710649,
    213                         "secret": "a5a64476122ca0925fb344bdc1854c1c0a" +\
    214                             "59fc614298e50a33e331980a220f32",
    215                         "successful": True
    216                     },
    217                     {
    218                         "index": 281474976710649,
    219                         "secret": "05cde6323d949933f7f7b78776bcc1ea6d9b" +\
    220                             "31447732e3802e1f7ac44b650e17",
    221                         "successful": False
    222                     }
    223                 ]
    224             },
    225             {
    226                 "name": "insert_secret #5 incorrect",
    227                 "inserts": [
    228                     {
    229                         "index": 281474976710655,
    230                         "secret": "7cc854b54e3e0dcdb010d7a3fee464a9687b" +\
    231                             "e6e8db3be6854c475621e007a5dc",
    232                         "successful": True
    233                     },
    234                     {
    235                         "index": 281474976710654,
    236                         "secret": "c7518c8ae4660ed02894df8976fa1a3659c1a" +\
    237                             "8b4b5bec0c4b872abeba4cb8964",
    238                         "successful": True
    239                     },
    240                     {
    241                         "index": 281474976710653,
    242                         "secret": "2273e227a5b7449b6e70f1fb4652864038b1" +\
    243                             "cbf9cd7c043a7d6456b7fc275ad8",
    244                         "successful": True
    245                     },
    246                     {
    247                         "index": 281474976710652,
    248                         "secret": "27cddaa5624534cb6cb9d7da077cf2b22ab21" +\
    249                             "e9b506fd4998a51d54502e99116",
    250                         "successful": True
    251                     },
    252                     {
    253                         "index": 281474976710651,
    254                         "secret": "631373ad5f9ef654bb3dade742d09504c567" +\
    255                             "edd24320d2fcd68e3cc47e2ff6a6",
    256                         "successful": True
    257                     },
    258                     {
    259                         "index": 281474976710650,
    260                         "secret": "969660042a28f32d9be17344e09374b37996" +\
    261                             "2d03db1574df5a8a5a47e19ce3f2",
    262                         "successful": False
    263                     }
    264                 ]
    265             },
    266             {
    267                 "name": "insert_secret #6 incorrect (5 derived from incorrect)",
    268                 "inserts": [
    269                     {
    270                         "index": 281474976710655,
    271                         "secret": "7cc854b54e3e0dcdb010d7a3fee464a9687b" +\
    272                             "e6e8db3be6854c475621e007a5dc",
    273                         "successful": True
    274                     },
    275                     {
    276                         "index": 281474976710654,
    277                         "secret": "c7518c8ae4660ed02894df8976fa1a3659c1a" +\
    278                             "8b4b5bec0c4b872abeba4cb8964",
    279                         "successful": True
    280                     },
    281                     {
    282                         "index": 281474976710653,
    283                         "secret": "2273e227a5b7449b6e70f1fb4652864038b1" +\
    284                             "cbf9cd7c043a7d6456b7fc275ad8",
    285                         "successful": True
    286                     },
    287                     {
    288                         "index": 281474976710652,
    289                         "secret": "27cddaa5624534cb6cb9d7da077cf2b22ab21" +\
    290                             "e9b506fd4998a51d54502e99116",
    291                         "successful": True
    292                     },
    293                     {
    294                         "index": 281474976710651,
    295                         "secret": "631373ad5f9ef654bb3dade742d09504c567" +\
    296                             "edd24320d2fcd68e3cc47e2ff6a6",
    297                         "successful": True
    298                     },
    299                     {
    300                         "index": 281474976710650,
    301                         "secret": "b7e76a83668bde38b373970155c868a65330" +\
    302                             "4308f9896692f904a23731224bb1",
    303                         "successful": True
    304                     },
    305                     {
    306                         "index": 281474976710649,
    307                         "secret": "a5a64476122ca0925fb344bdc1854c1c0a59f" +\
    308                             "c614298e50a33e331980a220f32",
    309                         "successful": True
    310                     },
    311                     {
    312                         "index": 281474976710648,
    313                         "secret": "05cde6323d949933f7f7b78776bcc1ea6d9b" +\
    314                             "31447732e3802e1f7ac44b650e17",
    315                         "successful": False
    316                     }
    317                 ]
    318             },
    319             {
    320                 "name": "insert_secret #7 incorrect",
    321                 "inserts": [
    322                     {
    323                         "index": 281474976710655,
    324                         "secret": "7cc854b54e3e0dcdb010d7a3fee464a9687b" +\
    325                             "e6e8db3be6854c475621e007a5dc",
    326                         "successful": True
    327                     },
    328                     {
    329                         "index": 281474976710654,
    330                         "secret": "c7518c8ae4660ed02894df8976fa1a3659c1a" +\
    331                             "8b4b5bec0c4b872abeba4cb8964",
    332                         "successful": True
    333                     },
    334                     {
    335                         "index": 281474976710653,
    336                         "secret": "2273e227a5b7449b6e70f1fb4652864038b1" +\
    337                             "cbf9cd7c043a7d6456b7fc275ad8",
    338                         "successful": True
    339                     },
    340                     {
    341                         "index": 281474976710652,
    342                         "secret": "27cddaa5624534cb6cb9d7da077cf2b22ab21" +\
    343                             "e9b506fd4998a51d54502e99116",
    344                         "successful": True
    345                     },
    346                     {
    347                         "index": 281474976710651,
    348                         "secret": "c65716add7aa98ba7acb236352d665cab173" +\
    349                             "45fe45b55fb879ff80e6bd0c41dd",
    350                         "successful": True
    351                     },
    352                     {
    353                         "index": 281474976710650,
    354                         "secret": "969660042a28f32d9be17344e09374b37996" +\
    355                             "2d03db1574df5a8a5a47e19ce3f2",
    356                         "successful": True
    357                     },
    358                     {
    359                         "index": 281474976710649,
    360                         "secret": "e7971de736e01da8ed58b94c2fc216cb1d" +\
    361                             "ca9e326f3a96e7194fe8ea8af6c0a3",
    362                         "successful": True
    363                     },
    364                     {
    365                         "index": 281474976710648,
    366                         "secret": "05cde6323d949933f7f7b78776bcc1ea6d" +\
    367                             "9b31447732e3802e1f7ac44b650e17",
    368                         "successful": False
    369                     }
    370                 ]
    371             },
    372             {
    373                 "name": "insert_secret #8 incorrect",
    374                 "inserts": [
    375                     {
    376                         "index": 281474976710655,
    377                         "secret": "7cc854b54e3e0dcdb010d7a3fee464a9687b" +\
    378                             "e6e8db3be6854c475621e007a5dc",
    379                         "successful": True
    380                     },
    381                     {
    382                         "index": 281474976710654,
    383                         "secret": "c7518c8ae4660ed02894df8976fa1a3659c1a" +\
    384                             "8b4b5bec0c4b872abeba4cb8964",
    385                         "successful": True
    386                     },
    387                     {
    388                         "index": 281474976710653,
    389                         "secret": "2273e227a5b7449b6e70f1fb4652864038b1" +\
    390                             "cbf9cd7c043a7d6456b7fc275ad8",
    391                         "successful": True
    392                     },
    393                     {
    394                         "index": 281474976710652,
    395                         "secret": "27cddaa5624534cb6cb9d7da077cf2b22ab21" +\
    396                             "e9b506fd4998a51d54502e99116",
    397                         "successful": True
    398                     },
    399                     {
    400                         "index": 281474976710651,
    401                         "secret": "c65716add7aa98ba7acb236352d665cab173" +\
    402                             "45fe45b55fb879ff80e6bd0c41dd",
    403                         "successful": True
    404                     },
    405                     {
    406                         "index": 281474976710650,
    407                         "secret": "969660042a28f32d9be17344e09374b37996" +\
    408                             "2d03db1574df5a8a5a47e19ce3f2",
    409                         "successful": True
    410                     },
    411                     {
    412                         "index": 281474976710649,
    413                         "secret": "a5a64476122ca0925fb344bdc1854c1c0a" +\
    414                             "59fc614298e50a33e331980a220f32",
    415                         "successful": True
    416                     },
    417                     {
    418                         "index": 281474976710648,
    419                         "secret": "a7efbc61aac46d34f77778bac22c8a20c6" +\
    420                             "a46ca460addc49009bda875ec88fa4",
    421                         "successful": False
    422                     }
    423                 ]
    424             }
    425         ]
    426 
    427         for test in tests:
    428             receiver = RevocationStore(StoredDict({}, None, []))
    429             for insert in test["inserts"]:
    430                 secret = bytes.fromhex(insert["secret"])
    431 
    432                 try:
    433                     receiver.add_next_entry(secret)
    434                 except Exception as e:
    435                     if insert["successful"]:
    436                         raise Exception("Failed ({}): error was received but it shouldn't: {}".format(test["name"], e))
    437                 else:
    438                     if not insert["successful"]:
    439                         raise Exception("Failed ({}): error wasn't received".format(test["name"]))
    440 
    441             for insert in test["inserts"]:
    442                 secret = bytes.fromhex(insert["secret"])
    443                 index = insert["index"]
    444                 if insert["successful"]:
    445                     self.assertEqual(secret, receiver.retrieve_secret(index))
    446 
    447             print("Passed ({})".format(test["name"]))
    448 
    449     def test_shachain_produce_consume(self):
    450         seed = bitcoin.sha256(b"shachaintest")
    451         consumer = RevocationStore(StoredDict({}, None, []))
    452         for i in range(10000):
    453             secret = get_per_commitment_secret_from_seed(seed, RevocationStore.START_INDEX - i)
    454             try:
    455                 consumer.add_next_entry(secret)
    456             except Exception as e:
    457                 raise Exception("iteration " + str(i) + ": " + str(e))
    458             if i % 1000 == 0:
    459                 c1 = consumer
    460                 s1 = json.dumps(c1.storage, cls=MyEncoder)
    461                 c2 = RevocationStore(StoredDict(json.loads(s1), None, []))
    462                 s2 = json.dumps(c2.storage, cls=MyEncoder)
    463                 self.assertEqual(s1, s2)
    464 
    465     def test_commitment_tx_with_all_five_HTLCs_untrimmed_minimum_feerate(self):
    466         to_local_msat = 6988000000
    467         to_remote_msat = 3000000000
    468         local_feerate_per_kw = 0
    469         # base commitment transaction fee = 0
    470         # actual commitment transaction fee = 0
    471 
    472         per_commitment_secret = 0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100
    473         per_commitment_point = secret_to_pubkey(per_commitment_secret)
    474 
    475         remote_htlcpubkey = remotepubkey
    476         local_htlcpubkey = localpubkey
    477 
    478         htlc_cltv_timeout = {}
    479         htlc_payment_preimage = {}
    480         htlc = {}
    481 
    482         htlc_cltv_timeout[2] = 502
    483         htlc_payment_preimage[2] = b"\x02" * 32
    484         htlc[2] = make_offered_htlc(local_revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, bitcoin.sha256(htlc_payment_preimage[2]))
    485 
    486         htlc_cltv_timeout[3] = 503
    487         htlc_payment_preimage[3] = b"\x03" * 32
    488         htlc[3] = make_offered_htlc(local_revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, bitcoin.sha256(htlc_payment_preimage[3]))
    489 
    490         htlc_cltv_timeout[0] = 500
    491         htlc_payment_preimage[0] = b"\x00" * 32
    492         htlc[0] = make_received_htlc(local_revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, bitcoin.sha256(htlc_payment_preimage[0]), htlc_cltv_timeout[0])
    493 
    494         htlc_cltv_timeout[1] = 501
    495         htlc_payment_preimage[1] = b"\x01" * 32
    496         htlc[1] = make_received_htlc(local_revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, bitcoin.sha256(htlc_payment_preimage[1]), htlc_cltv_timeout[1])
    497 
    498         htlc_cltv_timeout[4] = 504
    499         htlc_payment_preimage[4] = b"\x04" * 32
    500         htlc[4] = make_received_htlc(local_revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, bitcoin.sha256(htlc_payment_preimage[4]), htlc_cltv_timeout[4])
    501 
    502         remote_signature = "304402204fd4928835db1ccdfc40f5c78ce9bd65249b16348df81f0c44328dcdefc97d630220194d3869c38bc732dd87d13d2958015e2fc16829e74cd4377f84d215c0b70606"
    503         output_commit_tx = "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8007e80300000000000022002052bfef0479d7b293c27e0f1eb294bea154c63a3294ef092c19af51409bce0e2ad007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110e0a06a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e04004730440220275b0c325a5e9355650dc30c0eccfbc7efb23987c24b556b9dfdd40effca18d202206caceb2c067836c51f296740c7ae807ffcbfbf1dd3a0d56b6de9a5b247985f060147304402204fd4928835db1ccdfc40f5c78ce9bd65249b16348df81f0c44328dcdefc97d630220194d3869c38bc732dd87d13d2958015e2fc16829e74cd4377f84d215c0b7060601475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"
    504 
    505         htlc_obj = {}
    506         for num, msat in [(0, 1000 * 1000),
    507             (2, 2000 * 1000),
    508             (1, 2000 * 1000),
    509             (3, 3000 * 1000),
    510             (4, 4000 * 1000)]:
    511             htlc_obj[num] = UpdateAddHtlc(amount_msat=msat, payment_hash=bitcoin.sha256(htlc_payment_preimage[num]), cltv_expiry=0, htlc_id=None, timestamp=0)
    512         htlcs = [ScriptHtlc(htlc[x], htlc_obj[x]) for x in range(5)]
    513 
    514         our_commit_tx = make_commitment(
    515             ctn=commitment_number,
    516             local_funding_pubkey=local_funding_pubkey,
    517             remote_funding_pubkey=remote_funding_pubkey,
    518             remote_payment_pubkey=remotepubkey,
    519             funder_payment_basepoint=local_payment_basepoint,
    520             fundee_payment_basepoint=remote_payment_basepoint,
    521             revocation_pubkey=local_revocation_pubkey,
    522             delayed_pubkey=local_delayedpubkey,
    523             to_self_delay=local_delay,
    524             funding_txid=funding_tx_id,
    525             funding_pos=funding_output_index,
    526             funding_sat=funding_amount_satoshi,
    527             local_amount=to_local_msat,
    528             remote_amount=to_remote_msat,
    529             dust_limit_sat=local_dust_limit_satoshi,
    530             fees_per_participant=calc_fees_for_commitment_tx(num_htlcs=len(htlcs), feerate=local_feerate_per_kw, is_local_initiator=True),
    531             htlcs=htlcs)
    532         self.sign_and_insert_remote_sig(our_commit_tx, remote_funding_pubkey, remote_signature, local_funding_pubkey, local_funding_privkey)
    533         self.assertEqual(str(our_commit_tx), output_commit_tx)
    534 
    535         signature_for_output_remote_htlc = {}
    536         signature_for_output_remote_htlc[0] = "304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a6"
    537         signature_for_output_remote_htlc[2] = "3045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b"
    538         signature_for_output_remote_htlc[1] = "304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f202"
    539         signature_for_output_remote_htlc[3] = "3045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554"
    540         signature_for_output_remote_htlc[4] = "304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d"
    541 
    542         output_htlc_tx = {}
    543         SUCCESS = True
    544         TIMEOUT = False
    545         output_htlc_tx[0] = (SUCCESS, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219700000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a60147304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000")
    546 
    547         output_htlc_tx[2] = (TIMEOUT, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b0147304402205735e9f335dfd123f730ac5bf184fd7d5b672e4d84c51a3f0478cc229bb44936022018b1cec3e3b29e5cc335d7e326bc29d75a7e063216427d081cb83ebdbd828b4d01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000")
    548 
    549         output_htlc_tx[1] = (SUCCESS, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219702000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f202014730440220481a48f83c358ae0f220e37f88e56b3d434cefaded82065b8e7a9fd78fee7a26022022674ab37a4c39e6efba302f760ca05931d8add8d65231c5bf34a6c2a76b15bf012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000")
    550 
    551         output_htlc_tx[3] = (TIMEOUT, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219703000000000000000001b80b0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554014730440220643aacb19bbb72bd2b635bc3f7375481f5981bace78cdd8319b2988ffcc6704202203d27784ec8ad51ed3bd517a05525a5139bb0b755dd719e0054332d186ac0872701008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000")
    552 
    553         output_htlc_tx[4] = (SUCCESS, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219704000000000000000001a00f0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d014730440220549e80b4496803cbc4a1d09d46df50109f546d43fbbf86cd90b174b1484acd5402205f12a4f995cb9bded597eabfee195a285986aa6d93ae5bb72507ebc6a4e2349e012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000")
    554 
    555         htlc_output_index = {0: 0, 1: 2, 2: 1, 3: 3, 4: 4}
    556 
    557         for i in range(5):
    558             self.assertEqual(output_htlc_tx[i][1], self.htlc_tx(htlc[i], htlc_output_index[i],
    559                 htlcs[i].htlc.amount_msat,
    560                 htlc_payment_preimage[i],
    561                 signature_for_output_remote_htlc[i],
    562                 output_htlc_tx[i][0], htlc_cltv_timeout[i] if not output_htlc_tx[i][0] else 0,
    563                 local_feerate_per_kw,
    564                 our_commit_tx))
    565 
    566     def htlc_tx(self, htlc, htlc_output_index, amount_msat, htlc_payment_preimage, remote_htlc_sig, success, cltv_timeout, local_feerate_per_kw, our_commit_tx):
    567         _script, our_htlc_tx_output = make_htlc_tx_output(
    568             amount_msat=amount_msat,
    569             local_feerate=local_feerate_per_kw,
    570             revocationpubkey=local_revocation_pubkey,
    571             local_delayedpubkey=local_delayedpubkey,
    572             success=success,
    573             to_self_delay=local_delay)
    574         our_htlc_tx_inputs = make_htlc_tx_inputs(
    575             htlc_output_txid=our_commit_tx.txid(),
    576             htlc_output_index=htlc_output_index,
    577             amount_msat=amount_msat,
    578             witness_script=bh2u(htlc))
    579         our_htlc_tx = make_htlc_tx(
    580             cltv_expiry=cltv_timeout,
    581             inputs=our_htlc_tx_inputs,
    582             output=our_htlc_tx_output)
    583 
    584         local_sig = our_htlc_tx.sign_txin(0, local_privkey[:-1])
    585 
    586         our_htlc_tx_witness = make_htlc_tx_witness(
    587             remotehtlcsig=bfh(remote_htlc_sig) + b"\x01",  # 0x01 is SIGHASH_ALL
    588             localhtlcsig=bfh(local_sig),
    589             payment_preimage=htlc_payment_preimage if success else b'',  # will put 00 on witness if timeout
    590             witness_script=htlc)
    591         our_htlc_tx._inputs[0].witness = our_htlc_tx_witness
    592         return str(our_htlc_tx)
    593 
    594     def test_commitment_tx_with_one_output(self):
    595         to_local_msat= 6988000000
    596         to_remote_msat= 3000000000
    597         local_feerate_per_kw= 9651181
    598         remote_signature = "3044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e"
    599         output_commit_tx= "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8001c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431100400473044022031a82b51bd014915fe68928d1abf4b9885353fb896cac10c3fdd88d7f9c7f2e00220716bda819641d2c63e65d3549b6120112e1aeaf1742eed94a471488e79e206b101473044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"
    600 
    601         our_commit_tx = make_commitment(
    602             ctn=commitment_number,
    603             local_funding_pubkey=local_funding_pubkey,
    604             remote_funding_pubkey=remote_funding_pubkey,
    605             remote_payment_pubkey=remotepubkey,
    606             funder_payment_basepoint=local_payment_basepoint,
    607             fundee_payment_basepoint=remote_payment_basepoint,
    608             revocation_pubkey=local_revocation_pubkey,
    609             delayed_pubkey=local_delayedpubkey,
    610             to_self_delay=local_delay,
    611             funding_txid=funding_tx_id,
    612             funding_pos=funding_output_index,
    613             funding_sat=funding_amount_satoshi,
    614             local_amount=to_local_msat,
    615             remote_amount=to_remote_msat,
    616             dust_limit_sat=local_dust_limit_satoshi,
    617             fees_per_participant=calc_fees_for_commitment_tx(num_htlcs=0, feerate=local_feerate_per_kw, is_local_initiator=True),
    618             htlcs=[])
    619         self.sign_and_insert_remote_sig(our_commit_tx, remote_funding_pubkey, remote_signature, local_funding_pubkey, local_funding_privkey)
    620 
    621         self.assertEqual(str(our_commit_tx), output_commit_tx)
    622 
    623     def test_commitment_tx_with_fee_greater_than_funder_amount(self):
    624         to_local_msat= 6988000000
    625         to_remote_msat= 3000000000
    626         local_feerate_per_kw= 9651936
    627         remote_signature = "3044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e"
    628         output_commit_tx= "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8001c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431100400473044022031a82b51bd014915fe68928d1abf4b9885353fb896cac10c3fdd88d7f9c7f2e00220716bda819641d2c63e65d3549b6120112e1aeaf1742eed94a471488e79e206b101473044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"
    629 
    630         our_commit_tx = make_commitment(
    631             ctn=commitment_number,
    632             local_funding_pubkey=local_funding_pubkey,
    633             remote_funding_pubkey=remote_funding_pubkey,
    634             remote_payment_pubkey=remotepubkey,
    635             funder_payment_basepoint=local_payment_basepoint,
    636             fundee_payment_basepoint=remote_payment_basepoint,
    637             revocation_pubkey=local_revocation_pubkey,
    638             delayed_pubkey=local_delayedpubkey,
    639             to_self_delay=local_delay,
    640             funding_txid=funding_tx_id,
    641             funding_pos=funding_output_index,
    642             funding_sat=funding_amount_satoshi,
    643             local_amount=to_local_msat,
    644             remote_amount=to_remote_msat,
    645             dust_limit_sat=local_dust_limit_satoshi,
    646             fees_per_participant=calc_fees_for_commitment_tx(num_htlcs=0, feerate=local_feerate_per_kw, is_local_initiator=True),
    647             htlcs=[])
    648         self.sign_and_insert_remote_sig(our_commit_tx, remote_funding_pubkey, remote_signature, local_funding_pubkey, local_funding_privkey)
    649 
    650         self.assertEqual(str(our_commit_tx), output_commit_tx)
    651 
    652     def test_extract_commitment_number_from_tx(self):
    653         raw_tx = "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8007e80300000000000022002052bfef0479d7b293c27e0f1eb294bea154c63a3294ef092c19af51409bce0e2ad007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110e0a06a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e04004730440220275b0c325a5e9355650dc30c0eccfbc7efb23987c24b556b9dfdd40effca18d202206caceb2c067836c51f296740c7ae807ffcbfbf1dd3a0d56b6de9a5b247985f060147304402204fd4928835db1ccdfc40f5c78ce9bd65249b16348df81f0c44328dcdefc97d630220194d3869c38bc732dd87d13d2958015e2fc16829e74cd4377f84d215c0b7060601475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"
    654         tx = Transaction(raw_tx)
    655         self.assertEqual(commitment_number, extract_ctn_from_tx(tx, 0, local_payment_basepoint, remote_payment_basepoint))
    656 
    657     def test_per_commitment_secret_from_seed(self):
    658         self.assertEqual(0x02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148.to_bytes(byteorder="big", length=32),
    659                          get_per_commitment_secret_from_seed(0x0000000000000000000000000000000000000000000000000000000000000000.to_bytes(byteorder="big", length=32), 281474976710655))
    660         self.assertEqual(0x7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc.to_bytes(byteorder="big", length=32),
    661                          get_per_commitment_secret_from_seed(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.to_bytes(byteorder="big", length=32), 281474976710655))
    662         self.assertEqual(0x56f4008fb007ca9acf0e15b054d5c9fd12ee06cea347914ddbaed70d1c13a528.to_bytes(byteorder="big", length=32),
    663                          get_per_commitment_secret_from_seed(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.to_bytes(byteorder="big", length=32), 0xaaaaaaaaaaa))
    664         self.assertEqual(0x9015daaeb06dba4ccc05b91b2f73bd54405f2be9f217fbacd3c5ac2e62327d31.to_bytes(byteorder="big", length=32),
    665                          get_per_commitment_secret_from_seed(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.to_bytes(byteorder="big", length=32), 0x555555555555))
    666         self.assertEqual(0x915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c.to_bytes(byteorder="big", length=32),
    667                          get_per_commitment_secret_from_seed(0x0101010101010101010101010101010101010101010101010101010101010101.to_bytes(byteorder="big", length=32), 1))
    668 
    669     def test_key_derivation(self):
    670         # BOLT3, Appendix E
    671         base_secret = 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
    672         per_commitment_secret = 0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100
    673         revocation_basepoint_secret = 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
    674         base_point = secret_to_pubkey(base_secret)
    675         self.assertEqual(base_point, bfh('036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2'))
    676         per_commitment_point = secret_to_pubkey(per_commitment_secret)
    677         self.assertEqual(per_commitment_point, bfh('025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486'))
    678         localpubkey = derive_pubkey(base_point, per_commitment_point)
    679         self.assertEqual(localpubkey, bfh('0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5'))
    680         localprivkey = derive_privkey(base_secret, per_commitment_point)
    681         self.assertEqual(localprivkey, 0xcbced912d3b21bf196a766651e436aff192362621ce317704ea2f75d87e7be0f)
    682         revocation_basepoint = secret_to_pubkey(revocation_basepoint_secret)
    683         self.assertEqual(revocation_basepoint, bfh('036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2'))
    684         revocationpubkey = derive_blinded_pubkey(revocation_basepoint, per_commitment_point)
    685         self.assertEqual(revocationpubkey, bfh('02916e326636d19c33f13e8c0c3a03dd157f332f3e99c317c141dd865eb01f8ff0'))
    686 
    687     def test_simple_commitment_tx_with_no_HTLCs(self):
    688         to_local_msat = 7000000000
    689         to_remote_msat = 3000000000
    690         local_feerate_per_kw = 15000
    691         # base commitment transaction fee = 10860
    692         # actual commitment transaction fee = 10860
    693         # to_local amount 6989140 wscript 63210212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b1967029000b2752103fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c68ac
    694         # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b)
    695         remote_signature = "3045022100f51d2e566a70ba740fc5d8c0f07b9b93d2ed741c3c0860c613173de7d39e7968022041376d520e9c0e1ad52248ddf4b22e12be8763007df977253ef45a4ca3bdb7c0"
    696         # local_signature = 3044022051b75c73198c6deee1a875871c3961832909acd297c6b908d59e3319e5185a46022055c419379c5051a78d00dbbce11b5b664a0c22815fbcc6fcef6b1937c3836939
    697         our_commit_tx = make_commitment(
    698             ctn=commitment_number,
    699             local_funding_pubkey=local_funding_pubkey,
    700             remote_funding_pubkey=remote_funding_pubkey,
    701             remote_payment_pubkey=remotepubkey,
    702             funder_payment_basepoint=local_payment_basepoint,
    703             fundee_payment_basepoint=remote_payment_basepoint,
    704             revocation_pubkey=local_revocation_pubkey,
    705             delayed_pubkey=local_delayedpubkey,
    706             to_self_delay=local_delay,
    707             funding_txid=funding_tx_id,
    708             funding_pos=funding_output_index,
    709             funding_sat=funding_amount_satoshi,
    710             local_amount=to_local_msat,
    711             remote_amount=to_remote_msat,
    712             dust_limit_sat=local_dust_limit_satoshi,
    713             fees_per_participant=calc_fees_for_commitment_tx(num_htlcs=0, feerate=local_feerate_per_kw, is_local_initiator=True),
    714             htlcs=[])
    715         self.sign_and_insert_remote_sig(our_commit_tx, remote_funding_pubkey, remote_signature, local_funding_pubkey, local_funding_privkey)
    716         ref_commit_tx_str = '02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8002c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311054a56a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400473044022051b75c73198c6deee1a875871c3961832909acd297c6b908d59e3319e5185a46022055c419379c5051a78d00dbbce11b5b664a0c22815fbcc6fcef6b1937c383693901483045022100f51d2e566a70ba740fc5d8c0f07b9b93d2ed741c3c0860c613173de7d39e7968022041376d520e9c0e1ad52248ddf4b22e12be8763007df977253ef45a4ca3bdb7c001475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220'
    717         self.assertEqual(str(our_commit_tx), ref_commit_tx_str)
    718 
    719     def sign_and_insert_remote_sig(self, tx: PartialTransaction, remote_pubkey, remote_signature, pubkey, privkey):
    720         assert type(remote_pubkey) is bytes
    721         assert len(remote_pubkey) == 33
    722         assert type(remote_signature) is str
    723         assert type(pubkey) is bytes
    724         assert type(privkey) is bytes
    725         assert len(pubkey) == 33
    726         assert len(privkey) == 33
    727         tx.sign({bh2u(pubkey): (privkey[:-1], True)})
    728         tx.add_signature_to_txin(txin_idx=0, signing_pubkey=remote_pubkey.hex(), sig=remote_signature + "01")
    729 
    730     def test_get_compressed_pubkey_from_bech32(self):
    731         self.assertEqual(b'\x03\x84\xef\x87\xd9d\xa2\xaaa7=\xff\xb8\xfe=t8[}>;\n\x13\xa8e\x8eo:\xf5Mi\xb5H',
    732                          get_compressed_pubkey_from_bech32('ln1qwzwlp7evj325cfh8hlm3l3awsu9klf78v9p82r93ehn4a2ddx65s66awg5'))
    733 
    734     def test_split_host_port(self):
    735         self.assertEqual(split_host_port("[::1]:8000"), ("::1", "8000"))
    736         self.assertEqual(split_host_port("[::1]"), ("::1", "9735"))
    737         self.assertEqual(split_host_port("[2601:602:8800:9a:dc59:a4ff:fede:24a9]:9735"), ("2601:602:8800:9a:dc59:a4ff:fede:24a9", "9735"))
    738         self.assertEqual(split_host_port("[2601:602:8800::a4ff:fede:24a9]:9735"), ("2601:602:8800::a4ff:fede:24a9", "9735"))
    739         self.assertEqual(split_host_port("kæn.guru:8000"), ("kæn.guru", "8000"))
    740         self.assertEqual(split_host_port("kæn.guru"), ("kæn.guru", "9735"))
    741         self.assertEqual(split_host_port("127.0.0.1:8000"), ("127.0.0.1", "8000"))
    742         self.assertEqual(split_host_port("127.0.0.1"), ("127.0.0.1", "9735"))
    743         # accepted by getaddrinfo but not ipaddress.ip_address
    744         self.assertEqual(split_host_port("127.0.0:8000"), ("127.0.0", "8000"))
    745         self.assertEqual(split_host_port("127.0.0"), ("127.0.0", "9735"))
    746         self.assertEqual(split_host_port("electrum.org:8000"), ("electrum.org", "8000"))
    747         self.assertEqual(split_host_port("electrum.org"), ("electrum.org", "9735"))
    748 
    749         with self.assertRaises(ConnStringFormatError):
    750             split_host_port("electrum.org:8000:")
    751         with self.assertRaises(ConnStringFormatError):
    752             split_host_port("electrum.org:")
    753 
    754     def test_extract_nodeid(self):
    755         with self.assertRaises(ConnStringFormatError):
    756             extract_nodeid("00" * 32 + "@localhost")
    757         with self.assertRaises(ConnStringFormatError):
    758             extract_nodeid("00" * 33 + "@")
    759         self.assertEqual(extract_nodeid("00" * 33 + "@localhost"), (b"\x00" * 33, "localhost"))
    760 
    761     def test_ln_features_validate_transitive_dependencies(self):
    762         features = LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ
    763         self.assertTrue(features.validate_transitive_dependencies())
    764         features = LnFeatures.PAYMENT_SECRET_OPT
    765         self.assertFalse(features.validate_transitive_dependencies())
    766         features = LnFeatures.PAYMENT_SECRET_REQ
    767         self.assertFalse(features.validate_transitive_dependencies())
    768         features = LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_REQ
    769         self.assertTrue(features.validate_transitive_dependencies())
    770         features = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ
    771         self.assertFalse(features.validate_transitive_dependencies())
    772         features = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_OPT
    773         self.assertTrue(features.validate_transitive_dependencies())
    774         features = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_REQ
    775         self.assertTrue(features.validate_transitive_dependencies())
    776 
    777     def test_ln_features_for_init_message(self):
    778         features = LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ
    779         self.assertEqual(features, features.for_init_message())
    780         features = LnFeatures.PAYMENT_SECRET_OPT
    781         self.assertEqual(features, features.for_init_message())
    782         features = LnFeatures.PAYMENT_SECRET_REQ
    783         self.assertEqual(features, features.for_init_message())
    784         features = LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_REQ
    785         self.assertEqual(features, features.for_init_message())
    786         features = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ
    787         self.assertEqual(features, features.for_init_message())
    788         features = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_OPT
    789         self.assertEqual(features, features.for_init_message())
    790         features = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_REQ
    791         self.assertEqual(features, features.for_init_message())
    792 
    793     def test_ln_features_for_invoice(self):
    794         features = LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ
    795         self.assertEqual(LnFeatures(0), features.for_invoice())
    796         features = LnFeatures.PAYMENT_SECRET_OPT
    797         self.assertEqual(features, features.for_invoice())
    798         features = LnFeatures.PAYMENT_SECRET_REQ
    799         self.assertEqual(features, features.for_invoice())
    800         features = LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_REQ
    801         self.assertEqual(features, features.for_invoice())
    802         features = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ
    803         self.assertEqual(LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ,
    804                          features.for_invoice())
    805         features = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_OPT | LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ
    806         self.assertEqual(LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_OPT,
    807                          features.for_invoice())
    808         features = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_REQ
    809         self.assertEqual(features, features.for_invoice())
    810 
    811     def test_ln_compare_features(self):
    812         f1 = LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ | LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT
    813         f2 = LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ
    814         self.assertEqual(LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ | LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT,
    815                          ln_compare_features(f1, f2))
    816         self.assertEqual(LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ | LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT,
    817                          ln_compare_features(f2, f1))
    818         # note that the args are not commutative; if we (first arg) REQ a feature, OPT will get auto-set
    819         f1 = LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT
    820         f2 = LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ
    821         self.assertEqual(LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT,
    822                          ln_compare_features(f1, f2))
    823         self.assertEqual(LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ | LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT,
    824                          ln_compare_features(f2, f1))
    825 
    826         f1 = LnFeatures(0)
    827         f2 = LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT
    828         self.assertEqual(LnFeatures(0), ln_compare_features(f1, f2))
    829         self.assertEqual(LnFeatures(0), ln_compare_features(f2, f1))
    830 
    831         f1 = LnFeatures(0)
    832         f2 = LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ
    833         with self.assertRaises(IncompatibleLightningFeatures):
    834             ln_compare_features(f1, f2)
    835         with self.assertRaises(IncompatibleLightningFeatures):
    836             ln_compare_features(f2, f1)
    837 
    838         f1 = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT | LnFeatures.VAR_ONION_OPT
    839         f2 = LnFeatures.PAYMENT_SECRET_OPT | LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ | LnFeatures.VAR_ONION_OPT
    840         self.assertEqual(LnFeatures.PAYMENT_SECRET_OPT |
    841                          LnFeatures.PAYMENT_SECRET_REQ |
    842                          LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT |
    843                          LnFeatures.VAR_ONION_OPT,
    844                          ln_compare_features(f1, f2))
    845         self.assertEqual(LnFeatures.PAYMENT_SECRET_OPT |
    846                          LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT |
    847                          LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ |
    848                          LnFeatures.VAR_ONION_OPT,
    849                          ln_compare_features(f2, f1))
    850 
    851     def test_ln_features_supports(self):
    852         f_null = LnFeatures(0)
    853         f_opt = LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT
    854         f_req = LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ
    855         f_optreq = LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ | LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT
    856         self.assertFalse(f_null.supports(LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT))
    857         self.assertFalse(f_null.supports(LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ))
    858         self.assertTrue(f_opt.supports(LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT))
    859         self.assertTrue(f_opt.supports(LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ))
    860         self.assertTrue(f_req.supports(LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT))
    861         self.assertTrue(f_req.supports(LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ))
    862         self.assertTrue(f_optreq.supports(LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT))
    863         self.assertTrue(f_optreq.supports(LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ))
    864         with self.assertRaises(ValueError):
    865             f_opt.supports(f_optreq)
    866         with self.assertRaises(ValueError):
    867             f_optreq.supports(f_optreq)
    868         f1 = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT | LnFeatures.VAR_ONION_OPT
    869         self.assertTrue(f1.supports(LnFeatures.PAYMENT_SECRET_OPT))
    870         self.assertTrue(f1.supports(LnFeatures.BASIC_MPP_REQ))
    871         self.assertFalse(f1.supports(LnFeatures.OPTION_STATIC_REMOTEKEY_OPT))
    872         self.assertFalse(f1.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_REQ))
    873 
    874     def test_lnworker_decode_channel_update_msg(self):
    875         msg_without_prefix = bytes.fromhex("439b71c8ddeff63004e4ff1f9764a57dcf20232b79d9d669aef0e31c42be8e44208f7d868d0133acb334047f30e9399dece226ccd98e5df5330adf7f356290516fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000008762700054a00005ef2cf9c0101009000000000000003e80000000000000001000000002367b880")
    876         # good messages
    877         self.assertNotEqual(
    878             None,
    879             LNWallet._decode_channel_update_msg(msg_without_prefix))
    880         self.assertNotEqual(
    881             None,
    882             LNWallet._decode_channel_update_msg(bytes.fromhex("0102") + msg_without_prefix))
    883         # bad messages
    884         self.assertEqual(
    885             None,
    886             LNWallet._decode_channel_update_msg(bytes.fromhex("0102030405")))
    887         self.assertEqual(
    888             None,
    889             LNWallet._decode_channel_update_msg(bytes.fromhex("ffff") + msg_without_prefix))
    890         self.assertEqual(
    891             None,
    892             LNWallet._decode_channel_update_msg(bytes.fromhex("0101") + msg_without_prefix))