mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
test: refactor lockup_drain add helpers drain and force_feerates
This commit is contained in:
committed by
Christian Decker
parent
e1ba42f139
commit
80ff9c5b63
@@ -1,4 +1,5 @@
|
|||||||
from bitcoin.rpc import RawProxy as BitcoinProxy
|
from bitcoin.rpc import RawProxy as BitcoinProxy
|
||||||
|
from pyln.client import RpcError
|
||||||
from pyln.testing.btcproxy import BitcoinRpcProxy
|
from pyln.testing.btcproxy import BitcoinRpcProxy
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
@@ -811,6 +812,7 @@ class LightningNode(object):
|
|||||||
if 'htlcs' in channel:
|
if 'htlcs' in channel:
|
||||||
wait_for(lambda: len(self.rpc.listpeers()['peers'][p]['channels'][c]['htlcs']) == 0)
|
wait_for(lambda: len(self.rpc.listpeers()['peers'][p]['channels'][c]['htlcs']) == 0)
|
||||||
|
|
||||||
|
# This sends money to a directly connected peer
|
||||||
def pay(self, dst, amt, label=None):
|
def pay(self, dst, amt, label=None):
|
||||||
if not label:
|
if not label:
|
||||||
label = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(20))
|
label = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(20))
|
||||||
@@ -839,6 +841,18 @@ class LightningNode(object):
|
|||||||
result = self.rpc.waitsendpay(rhash)
|
result = self.rpc.waitsendpay(rhash)
|
||||||
assert(result.get('status') == 'complete')
|
assert(result.get('status') == 'complete')
|
||||||
|
|
||||||
|
# This helper sends all money to a peer until even 1 msat can't get through.
|
||||||
|
def drain(self, peer):
|
||||||
|
total = 0
|
||||||
|
msat = 16**9
|
||||||
|
while msat != 0:
|
||||||
|
try:
|
||||||
|
self.pay(peer, msat)
|
||||||
|
total += msat
|
||||||
|
except RpcError:
|
||||||
|
msat //= 2
|
||||||
|
return total
|
||||||
|
|
||||||
# Note: this feeds through the smoother in update_feerate, so changing
|
# Note: this feeds through the smoother in update_feerate, so changing
|
||||||
# it on a running daemon may not give expected result!
|
# it on a running daemon may not give expected result!
|
||||||
def set_feerates(self, feerates, wait_for_effect=True):
|
def set_feerates(self, feerates, wait_for_effect=True):
|
||||||
@@ -868,6 +882,15 @@ class LightningNode(object):
|
|||||||
if wait_for_effect:
|
if wait_for_effect:
|
||||||
wait_for(lambda: self.daemon.rpcproxy.mock_counts['estimatesmartfee'] >= 3)
|
wait_for(lambda: self.daemon.rpcproxy.mock_counts['estimatesmartfee'] >= 3)
|
||||||
|
|
||||||
|
# force new feerates by restarting and thus skipping slow smoothed process
|
||||||
|
# Note: testnode must be created with: opts={'may_reconnect': True}
|
||||||
|
def force_feerates(self, rate):
|
||||||
|
assert(self.may_reconnect)
|
||||||
|
self.set_feerates([rate] * 3, False)
|
||||||
|
self.restart()
|
||||||
|
self.daemon.wait_for_log('peer_out WIRE_UPDATE_FEE')
|
||||||
|
assert(self.rpc.feerates('perkw')['perkw']['normal'] == rate)
|
||||||
|
|
||||||
def wait_for_onchaind_broadcast(self, name, resolve=None):
|
def wait_for_onchaind_broadcast(self, name, resolve=None):
|
||||||
"""Wait for onchaind to drop tx name to resolve (if any)"""
|
"""Wait for onchaind to drop tx name to resolve (if any)"""
|
||||||
if resolve:
|
if resolve:
|
||||||
|
|||||||
@@ -2275,34 +2275,20 @@ def test_lockup_drain(node_factory, bitcoind):
|
|||||||
l1, l2 = node_factory.line_graph(2, opts={'may_reconnect': True})
|
l1, l2 = node_factory.line_graph(2, opts={'may_reconnect': True})
|
||||||
|
|
||||||
# l1 sends all the money to l2 until even 1 msat can't get through.
|
# l1 sends all the money to l2 until even 1 msat can't get through.
|
||||||
total = 0
|
total = l1.drain(l2)
|
||||||
msat = 16**9
|
|
||||||
while msat != 0:
|
|
||||||
try:
|
|
||||||
l1.pay(l2, msat)
|
|
||||||
print("l1->l2: {}".format(msat))
|
|
||||||
total += msat
|
|
||||||
except RpcError:
|
|
||||||
msat //= 2
|
|
||||||
|
|
||||||
# Even if feerate now increases 2x (30000), l2 should be able to send
|
# Even if feerate now increases 2x (30000), l2 should be able to send
|
||||||
# non-dust HTLC to l1.
|
# non-dust HTLC to l1.
|
||||||
l1.set_feerates([30000] * 3, False)
|
l1.force_feerates(30000)
|
||||||
# Restart forces fast fee adjustment (otherwise it's smoothed and takes
|
|
||||||
# a very long time!).
|
|
||||||
l1.restart()
|
|
||||||
wait_for(lambda: only_one(l1.rpc.listpeers()['peers'])['connected'])
|
|
||||||
assert(l1.rpc.feerates('perkw')['perkw']['normal'] == 30000)
|
|
||||||
|
|
||||||
l2.pay(l1, total // 2)
|
l2.pay(l1, total // 2)
|
||||||
|
|
||||||
# But if feerate increase just a little more, l2 should not be able to send
|
# reset fees and send all back again
|
||||||
# non-dust HTLC to l1
|
l1.force_feerates(15000)
|
||||||
l1.set_feerates([30002] * 3, False) # TODO: why does 30001 fail, off by one in C code?
|
l1.drain(l2)
|
||||||
l1.restart()
|
|
||||||
wait_for(lambda: only_one(l1.rpc.listpeers()['peers'])['connected'])
|
|
||||||
assert(l1.rpc.feerates('perkw')['perkw']['normal'] == 30002)
|
|
||||||
|
|
||||||
|
# But if feerate increase just a little more, l2 should not be able to send
|
||||||
|
# non-fust HTLC to l1
|
||||||
|
l1.force_feerates(30002) # TODO: Why does 30001 fail? off by one in C code?
|
||||||
with pytest.raises(RpcError, match=r".*Capacity exceeded.*"):
|
with pytest.raises(RpcError, match=r".*Capacity exceeded.*"):
|
||||||
l2.pay(l1, total // 2)
|
l2.pay(l1, total // 2)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user