pytest: test that our closingd tx weight estimate is correct.

Compare against lightningd's, and the actual tx.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2022-01-12 14:22:43 +10:30
committed by Christian Decker
parent 59f1749967
commit 169c113d15
2 changed files with 35 additions and 5 deletions

View File

@@ -201,14 +201,15 @@ static bool closing_fee_is_acceptable(struct lightningd *ld,
fee = calc_tx_fee(channel->funding_sats, tx);
last_fee = calc_tx_fee(channel->funding_sats, channel->last_tx);
log_debug(channel->log, "Their actual closing tx fee is %s"
" vs previous %s",
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct amount_sat, &last_fee));
/* Weight once we add in sigs. */
weight = bitcoin_tx_weight(tx) + bitcoin_tx_input_sig_weight() * 2;
log_debug(channel->log, "Their actual closing tx fee is %s"
" vs previous %s: weight is %"PRIu64,
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct amount_sat, &last_fee),
weight);
/* If we don't have a feerate estimate, this gives feerate_floor */
min_feerate = feerate_min(ld, &feerate_unknown);

View File

@@ -3653,3 +3653,32 @@ def test_close_twice(node_factory, executor):
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
assert fut.result(TIMEOUT)['type'] == 'mutual'
assert fut2.result(TIMEOUT)['type'] == 'mutual'
@pytest.mark.xfail(strict=True)
def test_close_weight_estimate(node_factory, bitcoind):
"""closingd uses the expected closing tx weight to constrain fees; make sure that lightningd agrees
once it has the actual agreed tx"""
l1, l2 = node_factory.line_graph(2)
l1.rpc.close(l2.info['id'])
# Closingd gives this estimate before it begins
log = l1.daemon.wait_for_log('Expected closing weight = ')
expected_weight = int(re.match('.*Expected closing weight = ([0-9]*),.*', log).group(1))
# This is the actual weight: in theory this could use their
# actual sig, and thus vary, but we don't do that.
log = l1.daemon.wait_for_log('Their actual closing tx fee is')
actual_weight = int(re.match('.*: weight is ([0-9]*).*', log).group(1))
assert actual_weight == expected_weight
log = l1.daemon.wait_for_log('sendrawtransaction: ')
tx = re.match('.*sendrawtransaction: ([0-9a-f]*).*', log).group(1)
# This could actually be a bit shorter: 1 in 256 chance we get
# lucky with a sig and it's shorter. We have 2 sigs, so that's
# 1 in 128. Unlikely to do better than 2 bytes off though!
signed_weight = int(bitcoind.rpc.decoderawtransaction(tx)['weight'])
assert signed_weight <= actual_weight
assert signed_weight >= actual_weight - 2