core-lightning/tests/test_xpay.py

135 lines
5.8 KiB
Python
Raw Normal View History

from fixtures import * # noqa: F401,F403
from fixtures import TEST_NETWORK
from pyln.client import RpcError
from utils import (
TIMEOUT, first_scid, GenChannel, generate_gossip_store
)
import os
import pytest
import subprocess
from hashlib import sha256
def test_pay_fakenet(node_factory):
hash1 = sha256(bytes.fromhex('00' + '00' * 31)).hexdigest()
hash2 = sha256(bytes.fromhex('01' + '00' * 31)).hexdigest()
failhash = '00' * 32
# Create gossip map of channels from l2 (aka nodemap[0])
gsfile, nodemap = generate_gossip_store([GenChannel(0, 1, capacity_sats=100_000),
GenChannel(1, 2, capacity_sats=100_000),
GenChannel(2, 3, capacity_sats=200_000)],
nodemap={0: '022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59'})
# l2 will warn l1 about its invalid gossip: ignore.
l1, l2 = node_factory.line_graph(2,
opts=[{'gossip_store_file': gsfile.name,
'subdaemon': 'channeld:../tests/plugins/channeld_fakenet',
'allow_warning': True}, {}])
# l1 needs to know l2's shaseed for the channel so it can make revocations
hsmfile = os.path.join(l2.daemon.lightning_dir, TEST_NETWORK, "hsm_secret")
# Needs peer node id and channel dbid (1, it's the first channel), prints out:
# "shaseed: xxxxxxx\n"
shaseed = subprocess.check_output(["tools/hsmtool", "dumpcommitments", l1.info['id'], "1", "0", hsmfile]).decode('utf-8').strip().partition(": ")[2]
l1.rpc.dev_peer_shachain(l2.info['id'], shaseed)
# Failure from final (unknown payment hash)
l1.rpc.sendpay(route=[{'id': l2.info['id'],
'channel': first_scid(l1, l2),
'delay': 18 + 6,
'amount_msat': 1000001},
{'id': nodemap[1],
'channel': '0x1x0',
'delay': 18,
'amount_msat': 100000}],
payment_hash=failhash)
with pytest.raises(RpcError, match="WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS") as err:
l1.rpc.waitsendpay(payment_hash=failhash, timeout=TIMEOUT)
assert err.value.error['data']['erring_node'] == nodemap[1]
# Success from final (known payment hash)
l1.rpc.sendpay(route=[{'id': l2.info['id'],
'channel': first_scid(l1, l2),
'delay': 18 + 6,
'amount_msat': 1000001},
{'id': nodemap[1],
'channel': '0x1x0',
'delay': 18,
'amount_msat': 100000}],
payment_hash=hash1)
l1.rpc.waitsendpay(payment_hash=hash1, timeout=TIMEOUT)
# Failure from node 2 (unknown scid)
l1.rpc.sendpay(route=[{'id': l2.info['id'],
'channel': first_scid(l1, l2),
'delay': 18 + 6 + 6,
'amount_msat': 1000002},
{'id': nodemap[1],
'channel': '0x1x0',
'delay': 18 + 6,
'amount_msat': 1000001},
{'id': nodemap[2],
'channel': '1x1x0',
'delay': 18,
'amount_msat': 1000000},
{'id': nodemap[3],
'channel': '0x1x0',
'delay': 18,
'amount_msat': 100000}],
payment_hash=failhash)
with pytest.raises(RpcError, match="WIRE_UNKNOWN_NEXT_PEER"):
l1.rpc.waitsendpay(payment_hash=failhash, timeout=TIMEOUT)
# MPP test
l1.rpc.sendpay(partid=1,
amount_msat=200000,
route=[{'id': l2.info['id'],
'channel': first_scid(l1, l2),
'delay': 18 + 6,
'amount_msat': 1000001},
{'id': nodemap[1],
'channel': '0x1x0',
'delay': 18,
'amount_msat': 100000}],
payment_hash=hash2,
payment_secret=hash2)
with pytest.raises(RpcError, match="WIRE_MPP_TIMEOUT"):
l1.rpc.waitsendpay(payment_hash=hash2, timeout=60 + TIMEOUT, partid=1)
# This one will actually work.
l1.rpc.sendpay(partid=2,
groupid=2,
amount_msat=200000,
route=[{'id': l2.info['id'],
'channel': first_scid(l1, l2),
'delay': 18 + 6,
'amount_msat': 1000001},
{'id': nodemap[1],
'channel': '0x1x0',
'delay': 18,
'amount_msat': 100000}],
payment_hash=hash2,
payment_secret=hash2)
l1.rpc.sendpay(partid=3,
groupid=2,
amount_msat=200000,
route=[{'id': l2.info['id'],
'channel': first_scid(l1, l2),
'delay': 18 + 6,
'amount_msat': 1000001},
{'id': nodemap[1],
'channel': '0x1x0',
'delay': 18,
'amount_msat': 100000}],
payment_hash=hash2,
payment_secret=hash2)
l1.rpc.waitsendpay(payment_hash=hash2, timeout=TIMEOUT, partid=2)
l1.rpc.waitsendpay(payment_hash=hash2, timeout=TIMEOUT, partid=3)