mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 01:43:36 +01:00
xpay: make the xpay layer persistent.
As the first user of a persistent layer, this tripped tests which assumed the datastore would be empty! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
c93153ec37
commit
229fc3f2b4
@ -1582,6 +1582,7 @@ static const char *init(struct command *init_cmd,
|
|||||||
plugin_broken_cb,
|
plugin_broken_cb,
|
||||||
"askrene-create-layer");
|
"askrene-create-layer");
|
||||||
json_add_string(req->js, "layer", "xpay");
|
json_add_string(req->js, "layer", "xpay");
|
||||||
|
json_add_bool(req->js, "persistent", true);
|
||||||
send_outreq(req);
|
send_outreq(req);
|
||||||
|
|
||||||
start_aging_timer(plugin);
|
start_aging_timer(plugin);
|
||||||
|
@ -294,7 +294,8 @@ def test_layers(node_factory):
|
|||||||
|
|
||||||
def test_layer_persistence(node_factory):
|
def test_layer_persistence(node_factory):
|
||||||
"""Test persistence of layers across restart"""
|
"""Test persistence of layers across restart"""
|
||||||
l1, l2 = node_factory.line_graph(2, wait_for_announce=True)
|
l1, l2 = node_factory.line_graph(2, wait_for_announce=True,
|
||||||
|
opts={'disable-plugin': 'cln-xpay'})
|
||||||
|
|
||||||
assert l1.rpc.askrene_listlayers() == {'layers': []}
|
assert l1.rpc.askrene_listlayers() == {'layers': []}
|
||||||
with pytest.raises(RpcError, match="Unknown layer"):
|
with pytest.raises(RpcError, match="Unknown layer"):
|
||||||
|
@ -3509,7 +3509,8 @@ def test_datastore_escapeing(node_factory):
|
|||||||
|
|
||||||
|
|
||||||
def test_datastore(node_factory):
|
def test_datastore(node_factory):
|
||||||
l1 = node_factory.get_node()
|
# Suppress xpay, which makes a layer
|
||||||
|
l1 = node_factory.get_node(options={"disable-plugin": "cln-xpay"})
|
||||||
|
|
||||||
# Starts empty
|
# Starts empty
|
||||||
assert l1.rpc.listdatastore() == {'datastore': []}
|
assert l1.rpc.listdatastore() == {'datastore': []}
|
||||||
@ -3623,7 +3624,8 @@ def test_datastore(node_factory):
|
|||||||
|
|
||||||
|
|
||||||
def test_datastore_keylist(node_factory):
|
def test_datastore_keylist(node_factory):
|
||||||
l1 = node_factory.get_node()
|
# Suppress xpay, which makes a layer
|
||||||
|
l1 = node_factory.get_node(options={"disable-plugin": "cln-xpay"})
|
||||||
|
|
||||||
# Starts empty
|
# Starts empty
|
||||||
assert l1.rpc.listdatastore() == {'datastore': []}
|
assert l1.rpc.listdatastore() == {'datastore': []}
|
||||||
@ -3685,7 +3687,7 @@ def test_datastore_keylist(node_factory):
|
|||||||
|
|
||||||
|
|
||||||
def test_datastoreusage(node_factory):
|
def test_datastoreusage(node_factory):
|
||||||
l1: LightningNode = node_factory.get_node()
|
l1: LightningNode = node_factory.get_node(options={"disable-plugin": "cln-xpay"})
|
||||||
assert l1.rpc.datastoreusage() == {'datastoreusage': {'key': '[]', 'total_bytes': 0}}
|
assert l1.rpc.datastoreusage() == {'datastoreusage': {'key': '[]', 'total_bytes': 0}}
|
||||||
|
|
||||||
data = 'somedatatostoreinthedatastore' # len 29
|
data = 'somedatatostoreinthedatastore' # len 29
|
||||||
|
@ -576,6 +576,10 @@ def test_v2_rbf_liquidity_ad(node_factory, bitcoind, chainparams):
|
|||||||
|
|
||||||
l1, l2 = node_factory.get_nodes(2, opts=opts)
|
l1, l2 = node_factory.get_nodes(2, opts=opts)
|
||||||
|
|
||||||
|
# Other plugins use datastore, but we want to make sure our own
|
||||||
|
# data is cleared!
|
||||||
|
empty_datastore = l1.rpc.listdatastore()
|
||||||
|
|
||||||
# what happens when we RBF?
|
# what happens when we RBF?
|
||||||
feerate = 2000
|
feerate = 2000
|
||||||
amount = 500000
|
amount = 500000
|
||||||
@ -632,7 +636,7 @@ def test_v2_rbf_liquidity_ad(node_factory, bitcoind, chainparams):
|
|||||||
l1.rpc.openchannel_signed(chan_id, signed_psbt)
|
l1.rpc.openchannel_signed(chan_id, signed_psbt)
|
||||||
|
|
||||||
# There's data in the datastore now (l2 only)
|
# There's data in the datastore now (l2 only)
|
||||||
assert l1.rpc.listdatastore() == {'datastore': []}
|
assert l1.rpc.listdatastore() == empty_datastore
|
||||||
only_one(l2.rpc.listdatastore("funder/{}".format(chan_id))['datastore'])
|
only_one(l2.rpc.listdatastore("funder/{}".format(chan_id))['datastore'])
|
||||||
|
|
||||||
# what happens when the channel opens?
|
# what happens when the channel opens?
|
||||||
@ -640,8 +644,8 @@ def test_v2_rbf_liquidity_ad(node_factory, bitcoind, chainparams):
|
|||||||
l1.daemon.wait_for_log('to CHANNELD_NORMAL')
|
l1.daemon.wait_for_log('to CHANNELD_NORMAL')
|
||||||
|
|
||||||
# Datastore should be cleaned up!
|
# Datastore should be cleaned up!
|
||||||
assert l1.rpc.listdatastore() == {'datastore': []}
|
assert l1.rpc.listdatastore() == empty_datastore
|
||||||
wait_for(lambda: l2.rpc.listdatastore() == {'datastore': []})
|
wait_for(lambda: l2.rpc.listdatastore() == empty_datastore)
|
||||||
|
|
||||||
# This should be the accepter's amount
|
# This should be the accepter's amount
|
||||||
fundings = only_one(l1.rpc.listpeerchannels()['channels'])['funding']
|
fundings = only_one(l1.rpc.listpeerchannels()['channels'])['funding']
|
||||||
|
@ -229,6 +229,7 @@ def test_xpay_fake_channeld(node_factory, bitcoind, chainparams):
|
|||||||
shaseed = subprocess.check_output(["tools/hsmtool", "dumpcommitments", l1.info['id'], "1", "0", hsmfile]).decode('utf-8').strip().partition(": ")[2]
|
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)
|
l1.rpc.dev_peer_shachain(l2.info['id'], shaseed)
|
||||||
|
|
||||||
|
failed_parts = []
|
||||||
for n in range(0, 100):
|
for n in range(0, 100):
|
||||||
if n in (62, 76, 80, 97):
|
if n in (62, 76, 80, 97):
|
||||||
continue
|
continue
|
||||||
@ -246,7 +247,47 @@ def test_xpay_fake_channeld(node_factory, bitcoind, chainparams):
|
|||||||
f"d=Paying node {n}",
|
f"d=Paying node {n}",
|
||||||
f"amount={AMOUNT}msat"]).decode('utf-8').strip()
|
f"amount={AMOUNT}msat"]).decode('utf-8').strip()
|
||||||
assert l1.rpc.decode(inv)['payee'] == nodeids[n]
|
assert l1.rpc.decode(inv)['payee'] == nodeids[n]
|
||||||
l1.rpc.xpay(inv)
|
failed_parts.append(l1.rpc.xpay(inv)['failed_parts'])
|
||||||
|
|
||||||
|
# Should be no reservations left (clean up happens after return though)
|
||||||
|
wait_for(lambda: l1.rpc.askrene_listreservations() == {'reservations': []})
|
||||||
|
|
||||||
|
# It should remember the information it learned across restarts!
|
||||||
|
# FIXME: channeld_fakenet doesn't restart properly, so just redo xpay.
|
||||||
|
layers = l1.rpc.askrene_listlayers()
|
||||||
|
# Temporary layers should be gone.
|
||||||
|
assert len(layers['layers']) == 1
|
||||||
|
|
||||||
|
l1.rpc.plugin_stop("cln-askrene")
|
||||||
|
l1.rpc.plugin_start(os.path.join(os.getcwd(), 'plugins/cln-askrene'))
|
||||||
|
layers_after = l1.rpc.askrene_listlayers()
|
||||||
|
assert layers == layers_after
|
||||||
|
|
||||||
|
failed_parts_retry = []
|
||||||
|
for n in range(0, 100):
|
||||||
|
if n in (62, 76, 80, 97):
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(f"PAYING Node #{n}")
|
||||||
|
|
||||||
|
preimage_hex = bytes([n + 100]).hex() + '00' * 31
|
||||||
|
hash_hex = sha256(bytes.fromhex(preimage_hex)).hexdigest()
|
||||||
|
inv = subprocess.check_output(["devtools/bolt11-cli",
|
||||||
|
"encode",
|
||||||
|
n.to_bytes(length=8, byteorder=sys.byteorder).hex() + '01' * 24,
|
||||||
|
f"p={hash_hex}",
|
||||||
|
f"s={'00' * 32}",
|
||||||
|
f"d=Paying node {n}",
|
||||||
|
f"amount={AMOUNT}msat"]).decode('utf-8').strip()
|
||||||
|
assert l1.rpc.decode(inv)['payee'] == nodeids[n]
|
||||||
|
failed_parts_retry.append(l1.rpc.xpay(inv)['failed_parts'])
|
||||||
|
|
||||||
|
# At least some will have improved!
|
||||||
|
assert failed_parts_retry != failed_parts
|
||||||
|
|
||||||
|
# Now, we should be as good *or better* than the first time, since we remembered!
|
||||||
|
for p in zip(failed_parts_retry, failed_parts):
|
||||||
|
assert p[0] <= p[1]
|
||||||
|
|
||||||
|
|
||||||
def test_xpay_timeout(node_factory, executor):
|
def test_xpay_timeout(node_factory, executor):
|
||||||
|
Loading…
Reference in New Issue
Block a user