Skip to content

Commit

Permalink
pytest: test that our closingd tx weight estimate is correct.
Browse files Browse the repository at this point in the history
Compare against lightningd's, and the actual tx.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell authored and cdecker committed Jan 27, 2022
1 parent 59f1749 commit 169c113
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
11 changes: 6 additions & 5 deletions lightningd/closing_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
29 changes: 29 additions & 0 deletions tests/test_closing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 169c113

Please sign in to comment.