mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-01 17:55:20 +00:00
lnaddr: encode min_final_cltv into invoice
This commit is contained in:
parent
66cfcd9feb
commit
97d1438f5d
3 changed files with 21 additions and 7 deletions
|
@ -205,6 +205,12 @@ def lnencode(addr, privkey):
|
||||||
data += tagged_bytes('h', sha256(v.encode('utf-8')).digest())
|
data += tagged_bytes('h', sha256(v.encode('utf-8')).digest())
|
||||||
elif k == 'n':
|
elif k == 'n':
|
||||||
data += tagged_bytes('n', v)
|
data += tagged_bytes('n', v)
|
||||||
|
elif k == 'c':
|
||||||
|
# Get minimal length by trimming leading 5 bits at a time.
|
||||||
|
finalcltvbits = bitstring.pack('intbe:64', v)[4:64]
|
||||||
|
while finalcltvbits.startswith('0b00000'):
|
||||||
|
finalcltvbits = finalcltvbits[5:]
|
||||||
|
data += tagged('c', finalcltvbits)
|
||||||
else:
|
else:
|
||||||
# FIXME: Support unknown tags?
|
# FIXME: Support unknown tags?
|
||||||
raise ValueError("Unknown tag {}".format(k))
|
raise ValueError("Unknown tag {}".format(k))
|
||||||
|
@ -240,7 +246,7 @@ class LnAddr(object):
|
||||||
self.pubkey = None
|
self.pubkey = None
|
||||||
self.currency = constants.net.SEGWIT_HRP if currency is None else currency
|
self.currency = constants.net.SEGWIT_HRP if currency is None else currency
|
||||||
self.amount = amount
|
self.amount = amount
|
||||||
self.min_final_cltv_expiry = 9
|
self._min_final_cltv_expiry = 9
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "LnAddr[{}, amount={}{} tags=[{}]]".format(
|
return "LnAddr[{}, amount={}{} tags=[{}]]".format(
|
||||||
|
@ -249,6 +255,10 @@ class LnAddr(object):
|
||||||
", ".join([k + '=' + str(v) for k, v in self.tags])
|
", ".join([k + '=' + str(v) for k, v in self.tags])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_min_final_cltv_expiry(self) -> int:
|
||||||
|
return self._min_final_cltv_expiry
|
||||||
|
|
||||||
|
|
||||||
def lndecode(a, verbose=False, expected_hrp=None):
|
def lndecode(a, verbose=False, expected_hrp=None):
|
||||||
if expected_hrp is None:
|
if expected_hrp is None:
|
||||||
expected_hrp = constants.net.SEGWIT_HRP
|
expected_hrp = constants.net.SEGWIT_HRP
|
||||||
|
@ -354,7 +364,7 @@ def lndecode(a, verbose=False, expected_hrp=None):
|
||||||
pubkeybytes = trim_to_bytes(tagdata)
|
pubkeybytes = trim_to_bytes(tagdata)
|
||||||
addr.pubkey = pubkeybytes
|
addr.pubkey = pubkeybytes
|
||||||
elif tag == 'c':
|
elif tag == 'c':
|
||||||
addr.min_final_cltv_expiry = tagdata.int
|
addr._min_final_cltv_expiry = tagdata.int
|
||||||
else:
|
else:
|
||||||
addr.unknown_tags.append((tag, tagdata))
|
addr.unknown_tags.append((tag, tagdata))
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ class LNWorker(PrintError):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise Exception("ChannelDB returned path with short_channel_id {} that is not in channel list".format(bh2u(short_channel_id)))
|
raise Exception("ChannelDB returned path with short_channel_id {} that is not in channel list".format(bh2u(short_channel_id)))
|
||||||
coro = peer.pay(route, chan, amount_msat, payment_hash, addr.min_final_cltv_expiry)
|
coro = peer.pay(route, chan, amount_msat, payment_hash, addr.get_min_final_cltv_expiry())
|
||||||
return addr, peer, asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
|
return addr, peer, asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
|
||||||
|
|
||||||
def _create_route_from_invoice(self, decoded_invoice, amount_msat) -> List[RouteEdge]:
|
def _create_route_from_invoice(self, decoded_invoice, amount_msat) -> List[RouteEdge]:
|
||||||
|
|
|
@ -57,8 +57,7 @@ class TestBolt11(unittest.TestCase):
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
LnAddr(RHASH, tags=[('d', '')]),
|
LnAddr(RHASH, tags=[('d', '')]),
|
||||||
LnAddr(RHASH, amount=Decimal('0.001'),
|
LnAddr(RHASH, amount=Decimal('0.001'), tags=[('d', '1 cup coffee'), ('x', 60)]),
|
||||||
tags=[('d', '1 cup coffee'), ('x', 60)]),
|
|
||||||
LnAddr(RHASH, amount=Decimal('1'), tags=[('h', longdescription)]),
|
LnAddr(RHASH, amount=Decimal('1'), tags=[('h', longdescription)]),
|
||||||
LnAddr(RHASH, currency='tb', tags=[('f', 'mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP'), ('h', longdescription)]),
|
LnAddr(RHASH, currency='tb', tags=[('f', 'mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP'), ('h', longdescription)]),
|
||||||
LnAddr(RHASH, amount=24, tags=[
|
LnAddr(RHASH, amount=24, tags=[
|
||||||
|
@ -93,5 +92,10 @@ class TestBolt11(unittest.TestCase):
|
||||||
lnaddr = lndecode(bech32_encode(hrp, bitarray_to_u5(databits)), True)
|
lnaddr = lndecode(bech32_encode(hrp, bitarray_to_u5(databits)), True)
|
||||||
assert lnaddr.pubkey.serialize() == PUBKEY
|
assert lnaddr.pubkey.serialize() == PUBKEY
|
||||||
|
|
||||||
def test_min_final_cltv_expiry(self):
|
def test_min_final_cltv_expiry_decoding(self):
|
||||||
self.assertEquals(lndecode("lnsb500u1pdsgyf3pp5nmrqejdsdgs4n9ukgxcp2kcq265yhrxd4k5dyue58rxtp5y83s3qdqqcqzystrggccm9yvkr5yqx83jxll0qjpmgfg9ywmcd8g33msfgmqgyfyvqhku80qmqm8q6v35zvck2y5ccxsz5avtrauz8hgjj3uahppyq20qp6dvwxe", expected_hrp="sb").min_final_cltv_expiry, 144)
|
self.assertEquals(144, lndecode("lnsb500u1pdsgyf3pp5nmrqejdsdgs4n9ukgxcp2kcq265yhrxd4k5dyue58rxtp5y83s3qdqqcqzystrggccm9yvkr5yqx83jxll0qjpmgfg9ywmcd8g33msfgmqgyfyvqhku80qmqm8q6v35zvck2y5ccxsz5avtrauz8hgjj3uahppyq20qp6dvwxe", expected_hrp="sb").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)])
|
||||||
|
invoice = lnencode(lnaddr, PRIVKEY)
|
||||||
|
self.assertEquals(150, lndecode(invoice).get_min_final_cltv_expiry())
|
||||||
|
|
Loading…
Add table
Reference in a new issue