mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-24 15:10:51 +01:00
135 lines
5.8 KiB
Python
135 lines
5.8 KiB
Python
|
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)
|