Exemple #1
0
    def test_n_decoding(self):
        # We flip the signature recovery bit, which would normally give a different
        # pubkey.
        _, hrp, data = bech32_decode(lnencode(
            LnAddr(paymenthash=RHASH, amount=24, tags=[('d', '')]), PRIVKEY),
                                     ignore_long_length=True)
        databits = u5_to_bitarray(data)
        databits.invert(-1)
        lnaddr = lndecode(bech32_encode(segwit_addr.Encoding.BECH32, hrp,
                                        bitarray_to_u5(databits)),
                          verbose=True)
        assert lnaddr.pubkey.serialize() != PUBKEY

        # But not if we supply expliciy `n` specifier!
        _, hrp, data = bech32_decode(lnencode(
            LnAddr(paymenthash=RHASH,
                   amount=24,
                   tags=[('d', ''), ('n', PUBKEY)]), PRIVKEY),
                                     ignore_long_length=True)
        databits = u5_to_bitarray(data)
        databits.invert(-1)
        lnaddr = lndecode(bech32_encode(segwit_addr.Encoding.BECH32, hrp,
                                        bitarray_to_u5(databits)),
                          verbose=True)
        assert lnaddr.pubkey.serialize() == PUBKEY
Exemple #2
0
 def test_min_final_cltv_expiry_roundtrip(self):
     for cltv in (1, 15, 16, 31, 32, 33, 150, 511, 512, 513, 1023, 1024,
                  1025):
         lnaddr = LnAddr(paymenthash=RHASH,
                         amount=Decimal('0.001'),
                         tags=[('d', '1 cup coffee'), ('x', 60),
                               ('c', cltv)])
         invoice = lnencode(lnaddr, PRIVKEY)
         self.assertEqual(cltv,
                          lndecode(invoice).get_min_final_cltv_expiry())
Exemple #3
0
class TestPeer(ElectrumTestCase):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        console_stderr_handler.setLevel(logging.DEBUG)

    def setUp(self):
        super().setUp()
        self.asyncio_loop, self._stop_loop, self._loop_thread = create_and_start_event_loop()

    def tearDown(self):
        super().tearDown()
        self.asyncio_loop.call_soon_threadsafe(self._stop_loop.set_result, 1)
        self._loop_thread.join(timeout=1)

    def prepare_peers(self, alice_channel, bob_channel):
        k1, k2 = keypair(), keypair()
        t1, t2 = transport_pair(alice_channel.name, bob_channel.name)
        q1, q2 = asyncio.Queue(), asyncio.Queue()
        w1 = MockLNWallet(k1, k2, alice_channel, tx_queue=q1)
        w2 = MockLNWallet(k2, k1, bob_channel, tx_queue=q2)
        p1 = Peer(w1, k1.pubkey, t1)
        p2 = Peer(w2, k2.pubkey, t2)
        w1.peer = p1
        w2.peer = p2
        # mark_open won't work if state is already OPEN.
        # so set it to FUNDED
        alice_channel._state = channel_states.FUNDED
        bob_channel._state = channel_states.FUNDED
        # this populates the channel graph:
        p1.mark_open(alice_channel)
        p2.mark_open(bob_channel)
        return p1, p2, w1, w2, q1, q2

    @staticmethod
    def prepare_invoice(
            w2,  # receiver
            *,
            amount_sat=100_000,
    ):
        amount_btc = amount_sat/Decimal(COIN)
        payment_preimage = os.urandom(32)
        RHASH = sha256(payment_preimage)
        info = PaymentInfo(RHASH, amount_sat, RECEIVED, PR_UNPAID)
        w2.save_preimage(RHASH, payment_preimage)
        w2.save_payment_info(info)
        lnaddr = LnAddr(
                    RHASH,
                    amount_btc,
                    tags=[('c', lnutil.MIN_FINAL_CLTV_EXPIRY_FOR_INVOICE),
                          ('d', 'coffee')
                         ])
        return lnencode(lnaddr, w2.node_keypair.privkey)
Exemple #4
0
 def prepare_invoice(w2 # receiver
         ):
     amount_sat = 100000
     amount_btc = amount_sat/Decimal(COIN)
     payment_preimage = os.urandom(32)
     RHASH = sha256(payment_preimage)
     info = PaymentInfo(RHASH, amount_sat, RECEIVED, PR_UNPAID)
     w2.save_preimage(RHASH, payment_preimage)
     w2.save_payment_info(info)
     lnaddr = LnAddr(
                 RHASH,
                 amount_btc,
                 tags=[('c', lnutil.MIN_FINAL_CLTV_EXPIRY_FOR_INVOICE),
                       ('d', 'coffee')
                      ])
     return lnencode(lnaddr, w2.node_keypair.privkey)
Exemple #5
0
    def test_roundtrip(self):
        longdescription = ('One piece of chocolate cake, one icecream cone, one'
                          ' pickle, one slice of swiss cheese, one slice of salami,'
                          ' one lollypop, one piece of cherry pie, one sausage, one'
                          ' cupcake, and one slice of watermelon')


        tests = [
            LnAddr(RHASH, tags=[('d', '')]),
            LnAddr(RHASH, amount=Decimal('0.001'), tags=[('d', '1 cup coffee'), ('x', 60)]),
            LnAddr(RHASH, amount=Decimal('1'), tags=[('h', longdescription)]),
            LnAddr(RHASH, currency='tltc', tags=[('f', 'mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP'), ('h', longdescription)]),
            LnAddr(RHASH, amount=24, tags=[
                ('r', [(unhexlify('029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255'), unhexlify('0102030405060708'), 1, 20, 3), (unhexlify('039e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255'), unhexlify('030405060708090a'), 2, 30, 4)]), ('f', 'LKes97HFbh3dxrvhiMohYXyzYJPTK37n7u'), ('h', longdescription)]),
            LnAddr(RHASH, amount=24, tags=[('f', 'MLy36ApB4YZb2cBtTc1uYJhYsP2JkYokaf'), ('h', longdescription)]),
            LnAddr(RHASH, amount=24, tags=[('f', 'ltc1qw508d6qejxtdg4y5r3zarvary0c5xw7kgmn4n9'), ('h', longdescription)]),
            LnAddr(RHASH, amount=24, tags=[('f', 'ltc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qmu8tk5'), ('h', longdescription)]),
            LnAddr(RHASH, amount=24, tags=[('n', PUBKEY), ('h', longdescription)]),
        ]

        # Roundtrip
        for t in tests:
            o = lndecode(lnencode(t, PRIVKEY), expected_hrp=t.currency)
            self.compare(t, o)
Exemple #6
0
 def test_min_final_cltv_expiry_roundtrip(self):
     lnaddr = LnAddr(RHASH, amount=Decimal('0.001'), tags=[('d', '1 cup coffee'), ('x', 60), ('c', 150)])
     invoice = lnencode(lnaddr, PRIVKEY)
     self.assertEqual(150, lndecode(invoice).get_min_final_cltv_expiry())
Exemple #7
0
        amount_sat=100_000,
        include_routing_hints=False,
    ):
        amount_btc = amount_sat / Decimal(COIN)
        payment_preimage = os.urandom(32)
        RHASH = sha256(payment_preimage)
        info = PaymentInfo(RHASH, amount_sat, RECEIVED, PR_UNPAID)
        w2.save_preimage(RHASH, payment_preimage)
        w2.save_payment_info(info)
        if include_routing_hints:
            routing_hints = await w2._calc_routing_hints_for_invoice(amount_sat
                                                                     )
        else:
            routing_hints = []
        lnaddr = LnAddr(paymenthash=RHASH,
                        amount=amount_btc,
                        tags=[('c', lnutil.MIN_FINAL_CLTV_EXPIRY_FOR_INVOICE),
                              ('d', 'coffee')] + routing_hints)
        return lnencode(lnaddr, w2.node_keypair.privkey)

    def test_reestablish(self):
        alice_channel, bob_channel = create_test_channels()
        p1, p2, w1, w2, _q1, _q2 = self.prepare_peers(alice_channel,
                                                      bob_channel)
        for chan in (alice_channel, bob_channel):
            chan.peer_state = PeerState.DISCONNECTED

        async def reestablish():
            await asyncio.gather(p1.reestablish_channel(alice_channel),
                                 p2.reestablish_channel(bob_channel))
            self.assertEqual(alice_channel.peer_state, PeerState.GOOD)
            self.assertEqual(bob_channel.peer_state, PeerState.GOOD)
Exemple #8
0
    def test_roundtrip(self):
        longdescription = (
            'One piece of chocolate cake, one icecream cone, one'
            ' pickle, one slice of swiss cheese, one slice of salami,'
            ' one lollypop, one piece of cherry pie, one sausage, one'
            ' cupcake, and one slice of watermelon')

        timestamp = 1615922274
        tests = [
            (LnAddr(date=timestamp, paymenthash=RHASH, tags=[('d', '')]),
             "lnltc1ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdqqtxf4xmgwm6d57t2u47xcknw8mcmxgnx24c4vq3uxft5f0sgx4kv478rt4j350n2hjlq0qqwgkwqv54ujrjtmw2gahwyrzfqq572r64qpsrpjy4"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=Decimal('0.001'),
                    tags=[('d', '1 cup coffee'), ('x', 60)]),
             "lnltc1m1ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuve3yl8e96v8ccdy5lgf4z8vdpmkzj228v2qxknwws2r00cwvqwhp2agvlqw4eklf8sjnvkeama0ke8nrlrc6nd4twspv5zhuy7hzqxgqd8tsep"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=Decimal('1'),
                    tags=[('h', longdescription)]),
             "lnltc11ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsz9dyzv7qgv60vrvj6hu8cyhj4epls6hwtgzgew82sqyhv0cjhnmjrr627cdjp4ejce0fps0q83505fjrh43enpwje3hty4kpu244trqp8snnu3"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    currency='tltc',
                    tags=[('f', 'mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP'),
                          ('h', longdescription)]),
             "lntltc1ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfpp3x9et2e20v6pu37c5d9vax37wxq72un98hp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9pqjahusc5f4737qr4ke4tf6mnswpt689y07jhw8usmus07q2pd43f7ya5t82d9aq8ay2e7kwuat0wzp7hhfla9ghg9ytt38r8pynrgqdt4rpe"
             ),
            (LnAddr(
                date=timestamp,
                paymenthash=RHASH,
                amount=24,
                tags=
                [('r',
                  [(unhexlify(
                      '029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255'
                  ), unhexlify('0102030405060708'), 1, 20, 3),
                   (unhexlify(
                       '039e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255'
                   ), unhexlify('030405060708090a'), 2, 30, 4)]),
                 ('f', 'LKes97HFbh3dxrvhiMohYXyzYJPTK37n7u'),
                 ('h', longdescription)]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzqfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsgrh5ds6jq65tly9q0rm43r09gpt7u7z56rksadhzrz66jqauxgvqffqmkwytlxvdamkfhvsy9p52zfum9ae6g3twas5euq75yz2wnugpwm2dm6"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('f', 'MLy36ApB4YZb2cBtTc1uYJhYsP2JkYokaf'),
                          ('h', longdescription)]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppj3a24vwu6r8ejrss3axul8rxldph2q7z9hp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfdpk2gswds3zw9jud4drk8auayp2rrar2vj9ku2u90jy53s3s9cnnd8ulqe5z6989amdkf6q2sdun0zxuuej65rj0zgdum9kewl6xvgqls5kcn"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('f', 'ltc1qw508d6qejxtdg4y5r3zarvary0c5xw7kgmn4n9'),
                          ('h', longdescription)]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppqw508d6qejxtdg4y5r3zarvary0c5xw7khp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsx62fjmp3a3alh6wz6jvdnnhgn22r39c6y05y6z994wyr24x9h3tkpmncc0w5e7xkskx5ce70zyeue5jvhst5ra4sfu6xffcaqumnvdsp3ushrl"
             ),
            (LnAddr(
                date=timestamp,
                paymenthash=RHASH,
                amount=24,
                tags=
                [('f',
                  'ltc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qmu8tk5'
                  ), ('h', longdescription)]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfp4qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsppnxg8agzaze483el3cay2c3vkw44qn7js06234yn6xw2z006f3jxhqqwelf7r6vq35hpnws9t99lkkzrhnnpaq0yaqz298d4zxvcrqqawfwf9"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('n', PUBKEY), ('h', longdescription)]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqnp4q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhv66hp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfypgxsuxk3fau4ukql3d4xv8a5m7rj4rnhv74qwm04t5tzmvdf6hfkqywdg6xxam6xq9ugn789exnhvzrh8skt2c3wahr0u6raqjw3spcdsjmp"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('h', longdescription), ('9', 514)]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qzszpr8mych58cqnmntv99ydz0x82llruk6uq56vc03xhrantv3sq5hhhtuevn34ygfxqwrgnfw84psukufz2py5s8p8pczlzxpk9cx4twqpznf9x5"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('h', longdescription), ('9', 10 + (1 << 8))]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qzg2tqw82hj5vjmyjzmr3235ff9a8xvxgvw70gj8nfa7ld2ukukmxet4d7nhgmxs4rl6fuvdlq0q35sq3ahqz6dl4akufdsnalvzrvzjh2qp8kxwnx"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('h', longdescription), ('9', 10 + (1 << 9))]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qzs2qlljt3pj65yflxr6rn3u04kd3dd0hq7javh9dp3d5cdly6ktr08spxnxnrdpgg008ddn2e85k4740fwlth60ccz7r004hep97rrpptqq0ex938"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('h', longdescription),
                          ('9', 10 + (1 << 7) + (1 << 11))]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qrzy2fv7yushe94fn00a0pz9wwmhcqhlnjjwnlf7wvev899jajmjq3qlqcvea0kcl6mr7v3fhf5yyhc6xg0f5l6zcwndeh5rcdw4pq28c5eqqg95ywn"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('h', longdescription), ('9', 10 + (1 << 12))]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qryq2p49wj470xych6a9qhzlgmhuyf6hntj3tznj3netm5c3c7nzytdjj2cafly9wrkmccqfnenknydfhaxzualdp5490k70y6u5amzmfwdsqa7yuu2"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('h', longdescription), ('9', 10 + (1 << 13))]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qrgq2gxz07cm2v66xftk0wyey0cgddn9j6kxxr8tfx6p0nmzs7p3ypwxxa78m5ez4gf4lzjusnflfkhfa8s9hzelrgx5h3t6s8562g6xgwpqqsx7rh4"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('h', longdescription),
                          ('9', 10 + (1 << 9) + (1 << 14))]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qrss2fr9507w72ylxmngwkxdeexm2utfjvl5z0lz28jap7c5p32k4kt9pl727gz0df93h9d2c83w6wl7wz28lv52psmgmyjc6qklkuvx7a6qqd8qs4s"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('h', longdescription),
                          ('9', 10 + (1 << 9) + (1 << 15))]),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qypqs2qp2e0nuq5a7llrdc7ftqczzkfajkazjzmn20dg2qucmghnwuhutpa6tk6dfdjukanzngzvzhnzhmucujfpu7fv5ekvwx2jh2mkwne9gq02clpv"
             ),
            (LnAddr(date=timestamp,
                    paymenthash=RHASH,
                    amount=24,
                    tags=[('h', longdescription), ('9', 33282)],
                    payment_secret=b"\x11" * 32),
             "lnltc241ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygshp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs9qypqszxkdza3c2a8mx7htenxyj28tl9uhs6zd8pz8nec3n2s7k0zzas4cn6jcgnk4j49zu552kwlg6nz4lcl847d8g26nf6lxn4c0y7jmkkjsqt2wsey"
             ),
        ]

        # Roundtrip
        for lnaddr1, invoice_str1 in tests:
            invoice_str2 = lnencode(lnaddr1, PRIVKEY)
            self.assertEqual(invoice_str1, invoice_str2)
            lnaddr2 = lndecode(invoice_str2, expected_hrp=lnaddr1.currency)
            self.compare(lnaddr1, lnaddr2)