ln: implement option payment_secret
This commit is contained in:
@@ -6,7 +6,7 @@ import unittest
|
||||
|
||||
from electrum.lnaddr import shorten_amount, unshorten_amount, LnAddr, lnencode, lndecode, u5_to_bitarray, bitarray_to_u5
|
||||
from electrum.segwit_addr import bech32_encode, bech32_decode
|
||||
from electrum.lnutil import UnknownEvenFeatureBits
|
||||
from electrum.lnutil import UnknownEvenFeatureBits, derive_payment_secret_from_payment_preimage
|
||||
|
||||
from . import ElectrumTestCase
|
||||
|
||||
@@ -62,27 +62,28 @@ class TestBolt11(ElectrumTestCase):
|
||||
|
||||
|
||||
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='tb', tags=[('f', 'mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP'), ('h', longdescription)]),
|
||||
LnAddr(RHASH, amount=24, tags=[
|
||||
LnAddr(paymenthash=RHASH, tags=[('d', '')]),
|
||||
LnAddr(paymenthash=RHASH, amount=Decimal('0.001'), tags=[('d', '1 cup coffee'), ('x', 60)]),
|
||||
LnAddr(paymenthash=RHASH, amount=Decimal('1'), tags=[('h', longdescription)]),
|
||||
LnAddr(paymenthash=RHASH, currency='tb', tags=[('f', 'mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP'), ('h', longdescription)]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[
|
||||
('r', [(unhexlify('029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255'), unhexlify('0102030405060708'), 1, 20, 3),
|
||||
(unhexlify('039e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255'), unhexlify('030405060708090a'), 2, 30, 4)]),
|
||||
('f', '1RustyRX2oai4EYYDpQGWvEL62BBGqN9T'),
|
||||
('h', longdescription)]),
|
||||
LnAddr(RHASH, amount=24, tags=[('f', '3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX'), ('h', longdescription)]),
|
||||
LnAddr(RHASH, amount=24, tags=[('f', 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4'), ('h', longdescription)]),
|
||||
LnAddr(RHASH, amount=24, tags=[('f', 'bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3'), ('h', longdescription)]),
|
||||
LnAddr(RHASH, amount=24, tags=[('n', PUBKEY), ('h', longdescription)]),
|
||||
LnAddr(RHASH, amount=24, tags=[('h', longdescription), ('9', 514)]),
|
||||
LnAddr(RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 8))]),
|
||||
LnAddr(RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 9))]),
|
||||
LnAddr(RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 11))]),
|
||||
LnAddr(RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 12))]),
|
||||
LnAddr(RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 13))]),
|
||||
#LnAddr(RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 14))]),
|
||||
LnAddr(RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 15))]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('f', '3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX'), ('h', longdescription)]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('f', 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4'), ('h', longdescription)]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('f', 'bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3'), ('h', longdescription)]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('n', PUBKEY), ('h', longdescription)]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('h', longdescription), ('9', 514)]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 8))]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 9))]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 11))]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 12))]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 13))]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 14))]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('h', longdescription), ('9', 10 + (1 << 15))]),
|
||||
LnAddr(paymenthash=RHASH, amount=24, tags=[('h', longdescription), ('9', 33282)], payment_secret=b"\x11" * 32),
|
||||
]
|
||||
|
||||
# Roundtrip
|
||||
@@ -93,14 +94,14 @@ class TestBolt11(ElectrumTestCase):
|
||||
def test_n_decoding(self):
|
||||
# We flip the signature recovery bit, which would normally give a different
|
||||
# pubkey.
|
||||
hrp, data = bech32_decode(lnencode(LnAddr(RHASH, amount=24, tags=[('d', '')]), PRIVKEY), True)
|
||||
hrp, data = bech32_decode(lnencode(LnAddr(paymenthash=RHASH, amount=24, tags=[('d', '')]), PRIVKEY), True)
|
||||
databits = u5_to_bitarray(data)
|
||||
databits.invert(-1)
|
||||
lnaddr = lndecode(bech32_encode(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(RHASH, amount=24,
|
||||
hrp, data = bech32_decode(lnencode(LnAddr(paymenthash=RHASH, amount=24,
|
||||
tags=[('d', ''),
|
||||
('n', PUBKEY)]),
|
||||
PRIVKEY), True)
|
||||
@@ -115,7 +116,7 @@ class TestBolt11(ElectrumTestCase):
|
||||
self.assertEqual(144, lnaddr.get_min_final_cltv_expiry())
|
||||
|
||||
def test_min_final_cltv_expiry_roundtrip(self):
|
||||
lnaddr = LnAddr(RHASH, amount=Decimal('0.001'), tags=[('d', '1 cup coffee'), ('x', 60), ('c', 150)])
|
||||
lnaddr = LnAddr(paymenthash=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())
|
||||
|
||||
@@ -125,3 +126,13 @@ class TestBolt11(ElectrumTestCase):
|
||||
|
||||
with self.assertRaises(UnknownEvenFeatureBits):
|
||||
lndecode("lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdees9q4pqqqqqqqqqqqqqqqqqqszk3ed62snp73037h4py4gry05eltlp0uezm2w9ajnerhmxzhzhsu40g9mgyx5v3ad4aqwkmvyftzk4k9zenz90mhjcy9hcevc7r3lx2sphzfxz7")
|
||||
|
||||
def test_payment_secret(self):
|
||||
lnaddr = lndecode("lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqpqqq4u9s93jtgysm3mrwll70zr697y3mf902hvxwej0v7c62rsltw83ng0pu8w3j230sluc5gxkdmm9dvpy9y6ggtjd2w544mzdrcs42t7sqdkcy8h")
|
||||
self.assertEqual((1 << 15) + (1 << 99) , lnaddr.get_tag('9'))
|
||||
self.assertEqual(b"\x11" * 32, lnaddr.payment_secret)
|
||||
|
||||
def test_derive_payment_secret_from_payment_preimage(self):
|
||||
preimage = bytes.fromhex("cc3fc000bdeff545acee53ada12ff96060834be263f77d645abbebc3a8d53b92")
|
||||
self.assertEqual("bfd660b559b3f452c6bb05b8d2906f520c151c107b733863ed0cc53fc77021a8",
|
||||
derive_payment_secret_from_payment_preimage(preimage).hex())
|
||||
|
||||
@@ -235,8 +235,8 @@ class TestPeer(ElectrumTestCase):
|
||||
w2.save_preimage(RHASH, payment_preimage)
|
||||
w2.save_payment_info(info)
|
||||
lnaddr = LnAddr(
|
||||
RHASH,
|
||||
amount_btc,
|
||||
paymenthash=RHASH,
|
||||
amount=amount_btc,
|
||||
tags=[('c', lnutil.MIN_FINAL_CLTV_EXPIRY_FOR_INVOICE),
|
||||
('d', 'coffee')
|
||||
])
|
||||
@@ -355,7 +355,12 @@ class TestPeer(ElectrumTestCase):
|
||||
await asyncio.wait_for(p2.initialized, 1)
|
||||
# alice sends htlc
|
||||
route = w1._create_route_from_invoice(decoded_invoice=lnaddr)
|
||||
htlc = p1.pay(route, alice_channel, int(lnaddr.amount * COIN * 1000), lnaddr.paymenthash, lnaddr.get_min_final_cltv_expiry())
|
||||
htlc = p1.pay(route=route,
|
||||
chan=alice_channel,
|
||||
amount_msat=int(lnaddr.amount * COIN * 1000),
|
||||
payment_hash=lnaddr.paymenthash,
|
||||
min_final_cltv_expiry=lnaddr.get_min_final_cltv_expiry(),
|
||||
payment_secret=lnaddr.payment_secret)
|
||||
# alice closes
|
||||
await p1.close_channel(alice_channel.channel_id)
|
||||
gath.cancel()
|
||||
|
||||
Reference in New Issue
Block a user