From 8f33f46960736792a779dedfc2f6426bb48a2fd0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 28 Jun 2021 14:38:10 +0930 Subject: [PATCH] closingd: use a more accurate fee for closing fee negotiation. We were actually using the last commit tx's size, since we were setting it in lightningd. Instead, hand the min and desired feerates to closingd, and (as it knows the weight of the closing tx), and have it start negotiation from there. This can be significantly less when anchor outputs are enabled: for example in test_closing.py, the commit tx weight is 1124 Sipa, the close is 672 Sipa! Signed-off-by: Rusty Russell Changelog-Changed: Protocol: Use a more accurate fee for mutual close negotiation. --- closingd/closingd.c | 98 +++++++++++++++++++++++++++++++++--- closingd/closingd_wire.csv | 4 +- closingd/closingd_wiregen.c | 14 +++--- closingd/closingd_wiregen.h | 6 +-- lightningd/closing_control.c | 15 +----- tests/test_closing.py | 26 +++++----- tests/test_plugin.py | 18 +++---- tests/utils.py | 6 +++ 8 files changed, 134 insertions(+), 53 deletions(-) diff --git a/closingd/closingd.c b/closingd/closingd.c index 6c95ab926..106b7caa5 100644 --- a/closingd/closingd.c +++ b/closingd/closingd.c @@ -491,6 +491,84 @@ static void closing_dev_memleak(const tal_t *ctx, } #endif /* DEVELOPER */ +/* Figure out what weight we actually expect for this closing tx (using zero fees + * gives the largest possible tx: larger values might omit outputs). */ +static size_t closing_tx_weight_estimate(u8 *scriptpubkey[NUM_SIDES], + const u8 *funding_wscript, + const struct amount_sat *out, + struct amount_sat funding, + struct amount_sat dust_limit) +{ + /* We create a dummy close */ + struct bitcoin_tx *tx; + struct bitcoin_txid dummy_txid; + struct bitcoin_signature dummy_sig; + struct privkey dummy_privkey; + struct pubkey dummy_pubkey; + u8 **witness; + + memset(&dummy_txid, 0, sizeof(dummy_txid)); + tx = create_close_tx(tmpctx, chainparams, + scriptpubkey[LOCAL], scriptpubkey[REMOTE], + funding_wscript, + &dummy_txid, 0, + funding, + out[LOCAL], + out[REMOTE], + dust_limit); + + /* Create a signature, any signature, so we can weigh fully "signed" + * tx. */ + dummy_sig.sighash_type = SIGHASH_ALL; + memset(&dummy_privkey, 1, sizeof(dummy_privkey)); + sign_hash(&dummy_privkey, &dummy_txid.shad, &dummy_sig.s); + pubkey_from_privkey(&dummy_privkey, &dummy_pubkey); + witness = bitcoin_witness_2of2(NULL, &dummy_sig, &dummy_sig, + &dummy_pubkey, &dummy_pubkey); + bitcoin_tx_input_set_witness(tx, 0, take(witness)); + + return bitcoin_tx_weight(tx); +} + +/* Get the minimum and desired fees */ +static void calc_fee_bounds(size_t expected_weight, + u32 min_feerate, + u32 desired_feerate, + struct amount_sat maxfee, + struct amount_sat *minfee, + struct amount_sat *desiredfee) +{ + *minfee = amount_tx_fee(min_feerate, expected_weight); + *desiredfee = amount_tx_fee(desired_feerate, expected_weight); + + /* Can't exceed maxfee. */ + if (amount_sat_greater(*minfee, maxfee)) + *minfee = maxfee; + + if (amount_sat_less(*desiredfee, *minfee)) { + status_unusual("Our ideal fee is %s (%u sats/perkw)," + " but our minimum is %s: using that", + type_to_string(tmpctx, struct amount_sat, desiredfee), + desired_feerate, + type_to_string(tmpctx, struct amount_sat, minfee)); + *desiredfee = *minfee; + } + if (amount_sat_greater(*desiredfee, maxfee)) { + status_unusual("Our ideal fee is %s (%u sats/perkw)," + " but our maximum is %s: using that", + type_to_string(tmpctx, struct amount_sat, desiredfee), + desired_feerate, + type_to_string(tmpctx, struct amount_sat, &maxfee)); + *desiredfee = maxfee; + } + + status_debug("Expected closing weight = %zu, fee %s (min %s, max %s)", + expected_weight, + type_to_string(tmpctx, struct amount_sat, desiredfee), + type_to_string(tmpctx, struct amount_sat, minfee), + type_to_string(tmpctx, struct amount_sat, &maxfee)); +} + int main(int argc, char *argv[]) { setup_locale(); @@ -504,6 +582,7 @@ int main(int argc, char *argv[]) struct amount_sat funding, out[NUM_SIDES]; struct amount_sat our_dust_limit; struct amount_sat min_fee_to_accept, commitment_fee, offer[NUM_SIDES]; + u32 min_feerate, initial_feerate; struct feerange feerange; enum side opener; u8 *scriptpubkey[NUM_SIDES], *funding_wscript; @@ -531,8 +610,8 @@ int main(int argc, char *argv[]) &out[LOCAL], &out[REMOTE], &our_dust_limit, - &min_fee_to_accept, &commitment_fee, - &offer[LOCAL], + &min_feerate, &initial_feerate, + &commitment_fee, &scriptpubkey[LOCAL], &scriptpubkey[REMOTE], &fee_negotiation_step, @@ -544,6 +623,17 @@ int main(int argc, char *argv[]) /* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */ per_peer_state_set_fds(notleak(pps), 3, 4, 5); + funding_wscript = bitcoin_redeem_2of2(ctx, + &funding_pubkey[LOCAL], + &funding_pubkey[REMOTE]); + + /* Start at what we consider a reasonable feerate for this tx. */ + calc_fee_bounds(closing_tx_weight_estimate(scriptpubkey, + funding_wscript, + out, funding, our_dust_limit), + min_feerate, initial_feerate, commitment_fee, + &min_fee_to_accept, &offer[LOCAL]); + snprintf(fee_negotiation_step_str, sizeof(fee_negotiation_step_str), "%" PRIu64 "%s", fee_negotiation_step, fee_negotiation_step_unit == @@ -565,10 +655,6 @@ int main(int argc, char *argv[]) &wrong_funding->txid), wrong_funding->n); - funding_wscript = bitcoin_redeem_2of2(ctx, - &funding_pubkey[LOCAL], - &funding_pubkey[REMOTE]); - peer_billboard( true, "Negotiating closing fee between %s and %s satoshi (ideal %s) " diff --git a/closingd/closingd_wire.csv b/closingd/closingd_wire.csv index 4558c9a98..aa58ea18f 100644 --- a/closingd/closingd_wire.csv +++ b/closingd/closingd_wire.csv @@ -17,9 +17,9 @@ msgdata,closingd_init,opener,enum side, msgdata,closingd_init,local_sat,amount_sat, msgdata,closingd_init,remote_sat,amount_sat, msgdata,closingd_init,our_dust_limit,amount_sat, -msgdata,closingd_init,min_fee_satoshi,amount_sat, +msgdata,closingd_init,min_feerate_perksipa,u32, +msgdata,closingd_init,preferred_feerate_perksipa,u32, msgdata,closingd_init,fee_limit_satoshi,amount_sat, -msgdata,closingd_init,initial_fee_satoshi,amount_sat, msgdata,closingd_init,local_scriptpubkey_len,u16, msgdata,closingd_init,local_scriptpubkey,u8,local_scriptpubkey_len msgdata,closingd_init,remote_scriptpubkey_len,u16, diff --git a/closingd/closingd_wiregen.c b/closingd/closingd_wiregen.c index bb7d9d776..9c840a5a0 100644 --- a/closingd/closingd_wiregen.c +++ b/closingd/closingd_wiregen.c @@ -48,7 +48,7 @@ bool closingd_wire_is_defined(u16 type) /* WIRE: CLOSINGD_INIT */ /* Begin! (passes peer fd */ -u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, struct amount_sat min_fee_satoshi, struct amount_sat fee_limit_satoshi, struct amount_sat initial_fee_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding) +u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, u32 min_feerate_perksipa, u32 preferred_feerate_perksipa, struct amount_sat fee_limit_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding) { u16 local_scriptpubkey_len = tal_count(local_scriptpubkey); u16 remote_scriptpubkey_len = tal_count(remote_scriptpubkey); @@ -67,9 +67,9 @@ u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams towire_amount_sat(&p, local_sat); towire_amount_sat(&p, remote_sat); towire_amount_sat(&p, our_dust_limit); - towire_amount_sat(&p, min_fee_satoshi); + towire_u32(&p, min_feerate_perksipa); + towire_u32(&p, preferred_feerate_perksipa); towire_amount_sat(&p, fee_limit_satoshi); - towire_amount_sat(&p, initial_fee_satoshi); towire_u16(&p, local_scriptpubkey_len); towire_u8_array(&p, local_scriptpubkey, local_scriptpubkey_len); towire_u16(&p, remote_scriptpubkey_len); @@ -86,7 +86,7 @@ u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams return memcheck(p, tal_count(p)); } -bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, struct amount_sat *min_fee_satoshi, struct amount_sat *fee_limit_satoshi, struct amount_sat *initial_fee_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding) +bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, u32 *min_feerate_perksipa, u32 *preferred_feerate_perksipa, struct amount_sat *fee_limit_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding) { u16 local_scriptpubkey_len; u16 remote_scriptpubkey_len; @@ -108,9 +108,9 @@ bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainp *local_sat = fromwire_amount_sat(&cursor, &plen); *remote_sat = fromwire_amount_sat(&cursor, &plen); *our_dust_limit = fromwire_amount_sat(&cursor, &plen); - *min_fee_satoshi = fromwire_amount_sat(&cursor, &plen); + *min_feerate_perksipa = fromwire_u32(&cursor, &plen); + *preferred_feerate_perksipa = fromwire_u32(&cursor, &plen); *fee_limit_satoshi = fromwire_amount_sat(&cursor, &plen); - *initial_fee_satoshi = fromwire_amount_sat(&cursor, &plen); local_scriptpubkey_len = fromwire_u16(&cursor, &plen); // 2nd case local_scriptpubkey *local_scriptpubkey = local_scriptpubkey_len ? tal_arr(ctx, u8, local_scriptpubkey_len) : NULL; @@ -195,4 +195,4 @@ bool fromwire_closingd_complete(const void *p) return false; return cursor != NULL; } -// SHA256STAMP:cbcaa37f43a9705e657ef6905e276ac4b703171a3f9dcd6f6ca352e3d753a6f2 +// SHA256STAMP:a8b0af1ae87e71bc448585060b8d449c3e5f0d0f4f3ac195dcd4d84f8176ae17 diff --git a/closingd/closingd_wiregen.h b/closingd/closingd_wiregen.h index d39505198..b948b737f 100644 --- a/closingd/closingd_wiregen.h +++ b/closingd/closingd_wiregen.h @@ -37,8 +37,8 @@ bool closingd_wire_is_defined(u16 type); /* WIRE: CLOSINGD_INIT */ /* Begin! (passes peer fd */ -u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, struct amount_sat min_fee_satoshi, struct amount_sat fee_limit_satoshi, struct amount_sat initial_fee_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding); -bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, struct amount_sat *min_fee_satoshi, struct amount_sat *fee_limit_satoshi, struct amount_sat *initial_fee_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding); +u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, u32 min_feerate_perksipa, u32 preferred_feerate_perksipa, struct amount_sat fee_limit_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding); +bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, u32 *min_feerate_perksipa, u32 *preferred_feerate_perksipa, struct amount_sat *fee_limit_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding); /* WIRE: CLOSINGD_RECEIVED_SIGNATURE */ /* We received an offer */ @@ -56,4 +56,4 @@ bool fromwire_closingd_complete(const void *p); #endif /* LIGHTNING_CLOSINGD_CLOSINGD_WIREGEN_H */ -// SHA256STAMP:cbcaa37f43a9705e657ef6905e276ac4b703171a3f9dcd6f6ca352e3d753a6f2 +// SHA256STAMP:a8b0af1ae87e71bc448585060b8d449c3e5f0d0f4f3ac195dcd4d84f8176ae17 diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index 9768ae94e..42d9909bf 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -197,8 +197,8 @@ void peer_start_closingd(struct channel *channel, { u8 *initmsg; u32 feerate; - struct amount_sat minfee, startfee, feelimit; struct amount_msat their_msat; + struct amount_sat feelimit; int hsmfd; struct lightningd *ld = channel->peer->ld; u32 final_commit_feerate; @@ -247,10 +247,6 @@ void peer_start_closingd(struct channel *channel, feelimit = commit_tx_base_fee(final_commit_feerate, 0, channel->option_anchor_outputs); - /* Pick some value above slow feerate (or min possible if unknown) */ - minfee = commit_tx_base_fee(feerate_min(ld, NULL), 0, - channel->option_anchor_outputs); - /* If we can't determine feerate, start at half unilateral feerate. */ feerate = mutual_close_feerate(ld->topology); if (!feerate) { @@ -258,13 +254,6 @@ void peer_start_closingd(struct channel *channel, if (feerate < feerate_floor()) feerate = feerate_floor(); } - startfee = commit_tx_base_fee(feerate, 0, - channel->option_anchor_outputs); - - if (amount_sat_greater(startfee, feelimit)) - startfee = feelimit; - if (amount_sat_greater(minfee, feelimit)) - minfee = feelimit; /* BOLT #3: * @@ -298,7 +287,7 @@ void peer_start_closingd(struct channel *channel, amount_msat_to_sat_round_down(channel->our_msat), amount_msat_to_sat_round_down(their_msat), channel->our_config.dust_limit, - minfee, feelimit, startfee, + feerate_min(ld, NULL), feerate, feelimit, channel->shutdown_scriptpubkey[LOCAL], channel->shutdown_scriptpubkey[REMOTE], channel->closing_fee_negotiation_step, diff --git a/tests/test_closing.py b/tests/test_closing.py index 18a916316..0bb6c170b 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -5,7 +5,7 @@ from shutil import copyfile from pyln.testing.utils import SLOW_MACHINE from utils import ( only_one, sync_blockheight, wait_for, TIMEOUT, - account_balance, first_channel_id, basic_fee, TEST_NETWORK, + account_balance, first_channel_id, closing_fee, TEST_NETWORK, scriptpubkey_addr ) @@ -22,7 +22,7 @@ import unittest def test_closing(node_factory, bitcoind, chainparams): l1, l2 = node_factory.line_graph(2) chan = l1.get_channel_scid(l2) - fee = basic_fee(3750) if not chainparams['elements'] else 4477 + fee = closing_fee(3750, 2) if not chainparams['elements'] else 3603 l1.pay(l2, 200000000) @@ -377,7 +377,7 @@ def closing_negotiation_step(node_factory, bitcoind, chainparams, opts): """Binary search to find feerate""" assert minimum != maximum mid = (minimum + maximum) // 2 - mid_fee = basic_fee(mid) + mid_fee = closing_fee(mid, 1) if mid_fee > target: return feerate_for(target, minimum, mid) elif mid_fee < target: @@ -452,11 +452,11 @@ def test_closing_negotiation_step_30pct(node_factory, bitcoind, chainparams): opts['fee_negotiation_step'] = '30%' opts['close_initiated_by'] = 'opener' - opts['expected_close_fee'] = 20537 if not chainparams['elements'] else 33870 + opts['expected_close_fee'] = 20537 if not chainparams['elements'] else 26046 closing_negotiation_step(node_factory, bitcoind, chainparams, opts) opts['close_initiated_by'] = 'peer' - opts['expected_close_fee'] = 20233 if not chainparams['elements'] else 33366 + opts['expected_close_fee'] = 20233 if not chainparams['elements'] else 25657 closing_negotiation_step(node_factory, bitcoind, chainparams, opts) @@ -466,11 +466,11 @@ def test_closing_negotiation_step_50pct(node_factory, bitcoind, chainparams): opts['fee_negotiation_step'] = '50%' opts['close_initiated_by'] = 'opener' - opts['expected_close_fee'] = 20334 if not chainparams['elements'] else 33533 + opts['expected_close_fee'] = 20334 if not chainparams['elements'] else 25789 closing_negotiation_step(node_factory, bitcoind, chainparams, opts) opts['close_initiated_by'] = 'peer' - opts['expected_close_fee'] = 20334 if not chainparams['elements'] else 33533 + opts['expected_close_fee'] = 20334 if not chainparams['elements'] else 25789 closing_negotiation_step(node_factory, bitcoind, chainparams, opts) @@ -480,7 +480,7 @@ def test_closing_negotiation_step_100pct(node_factory, bitcoind, chainparams): opts['fee_negotiation_step'] = '100%' opts['close_initiated_by'] = 'opener' - opts['expected_close_fee'] = 20001 if not chainparams['elements'] else 32985 + opts['expected_close_fee'] = 20001 if not chainparams['elements'] else 25366 closing_negotiation_step(node_factory, bitcoind, chainparams, opts) # The close fee of 20499 looks strange in this case - one would expect @@ -489,7 +489,7 @@ def test_closing_negotiation_step_100pct(node_factory, bitcoind, chainparams): # * the opener is always first to propose, he uses 50% step, so he proposes 20500 # * the range is narrowed to [20001, 20499] and the peer proposes 20499 opts['close_initiated_by'] = 'peer' - opts['expected_close_fee'] = 20499 if not chainparams['elements'] else 33808 + opts['expected_close_fee'] = 20499 if not chainparams['elements'] else 25998 closing_negotiation_step(node_factory, bitcoind, chainparams, opts) @@ -499,11 +499,11 @@ def test_closing_negotiation_step_1sat(node_factory, bitcoind, chainparams): opts['fee_negotiation_step'] = '1' opts['close_initiated_by'] = 'opener' - opts['expected_close_fee'] = 20989 if not chainparams['elements'] else 34621 + opts['expected_close_fee'] = 20989 if not chainparams['elements'] else 26624 closing_negotiation_step(node_factory, bitcoind, chainparams, opts) opts['close_initiated_by'] = 'peer' - opts['expected_close_fee'] = 20010 if not chainparams['elements'] else 32995 + opts['expected_close_fee'] = 20010 if not chainparams['elements'] else 25373 closing_negotiation_step(node_factory, bitcoind, chainparams, opts) @@ -513,11 +513,11 @@ def test_closing_negotiation_step_700sat(node_factory, bitcoind, chainparams): opts['fee_negotiation_step'] = '700' opts['close_initiated_by'] = 'opener' - opts['expected_close_fee'] = 20151 if not chainparams['elements'] else 33459 + opts['expected_close_fee'] = 20151 if not chainparams['elements'] else 25650 closing_negotiation_step(node_factory, bitcoind, chainparams, opts) opts['close_initiated_by'] = 'peer' - opts['expected_close_fee'] = 20499 if not chainparams['elements'] else 33746 + opts['expected_close_fee'] = 20499 if not chainparams['elements'] else 25998 closing_negotiation_step(node_factory, bitcoind, chainparams, opts) diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 01f4760cd..457334d9a 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1884,8 +1884,8 @@ def test_coin_movement_notices(node_factory, bitcoind, chainparams): {'type': 'chain_mvt', 'credit': 1000000000, 'debit': 0, 'tag': 'deposit'}, {'type': 'channel_mvt', 'credit': 0, 'debit': 100000000, 'tag': 'routed'}, {'type': 'channel_mvt', 'credit': 50000501, 'debit': 0, 'tag': 'routed'}, - {'type': 'chain_mvt', 'credit': 0, 'debit': 4477501, 'tag': 'chain_fees'}, - {'type': 'chain_mvt', 'credit': 0, 'debit': 945523000, 'tag': 'withdrawal'}, + {'type': 'chain_mvt', 'credit': 0, 'debit': 4271501, 'tag': 'chain_fees'}, + {'type': 'chain_mvt', 'credit': 0, 'debit': 945729000, 'tag': 'withdrawal'}, ] l2_wallet_mvts = [ @@ -1898,7 +1898,7 @@ def test_coin_movement_notices(node_factory, bitcoind, chainparams): {'type': 'chain_mvt', 'credit': 0, 'debit': 8092000, 'tag': 'chain_fees'}, {'type': 'chain_mvt', 'credit': 991908000, 'debit': 0, 'tag': 'deposit'}, {'type': 'chain_mvt', 'credit': 100001000, 'debit': 0, 'tag': 'deposit'}, - {'type': 'chain_mvt', 'credit': 945523000, 'debit': 0, 'tag': 'deposit'}, + {'type': 'chain_mvt', 'credit': 945729000, 'debit': 0, 'tag': 'deposit'}, ] elif EXPERIMENTAL_FEATURES: # option_anchor_outputs @@ -1906,8 +1906,8 @@ def test_coin_movement_notices(node_factory, bitcoind, chainparams): {'type': 'chain_mvt', 'credit': 1000000000, 'debit': 0, 'tag': 'deposit'}, {'type': 'channel_mvt', 'credit': 0, 'debit': 100000000, 'tag': 'routed'}, {'type': 'channel_mvt', 'credit': 50000501, 'debit': 0, 'tag': 'routed'}, - {'type': 'chain_mvt', 'credit': 0, 'debit': 4215501, 'tag': 'chain_fees'}, - {'type': 'chain_mvt', 'credit': 0, 'debit': 945785000, 'tag': 'withdrawal'}, + {'type': 'chain_mvt', 'credit': 0, 'debit': 2520501, 'tag': 'chain_fees'}, + {'type': 'chain_mvt', 'credit': 0, 'debit': 947480000, 'tag': 'withdrawal'}, ] l2_wallet_mvts = [ @@ -1921,15 +1921,15 @@ def test_coin_movement_notices(node_factory, bitcoind, chainparams): {'type': 'chain_mvt', 'credit': 0, 'debit': 4567000, 'tag': 'chain_fees'}, {'type': 'chain_mvt', 'credit': 995433000, 'debit': 0, 'tag': 'deposit'}, {'type': 'chain_mvt', 'credit': 100001000, 'debit': 0, 'tag': 'deposit'}, - {'type': 'chain_mvt', 'credit': 945785000, 'debit': 0, 'tag': 'deposit'}, + {'type': 'chain_mvt', 'credit': 947480000, 'debit': 0, 'tag': 'deposit'}, ] else: l2_l3_mvts = [ {'type': 'chain_mvt', 'credit': 1000000000, 'debit': 0, 'tag': 'deposit'}, {'type': 'channel_mvt', 'credit': 0, 'debit': 100000000, 'tag': 'routed'}, {'type': 'channel_mvt', 'credit': 50000501, 'debit': 0, 'tag': 'routed'}, - {'type': 'chain_mvt', 'credit': 0, 'debit': 2715501, 'tag': 'chain_fees'}, - {'type': 'chain_mvt', 'credit': 0, 'debit': 947285000, 'tag': 'withdrawal'}, + {'type': 'chain_mvt', 'credit': 0, 'debit': 2520501, 'tag': 'chain_fees'}, + {'type': 'chain_mvt', 'credit': 0, 'debit': 947480000, 'tag': 'withdrawal'}, ] l2_wallet_mvts = [ @@ -1943,7 +1943,7 @@ def test_coin_movement_notices(node_factory, bitcoind, chainparams): {'type': 'chain_mvt', 'credit': 0, 'debit': 4567000, 'tag': 'chain_fees'}, {'type': 'chain_mvt', 'credit': 995433000, 'debit': 0, 'tag': 'deposit'}, {'type': 'chain_mvt', 'credit': 100001000, 'debit': 0, 'tag': 'deposit'}, - {'type': 'chain_mvt', 'credit': 947285000, 'debit': 0, 'tag': 'deposit'}, + {'type': 'chain_mvt', 'credit': 947480000, 'debit': 0, 'tag': 'deposit'}, ] l1, l2, l3 = node_factory.line_graph(3, opts=[ diff --git a/tests/utils.py b/tests/utils.py index de1a7060c..6f1d7842b 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -151,6 +151,12 @@ def basic_fee(feerate): return (weight * feerate) // 1000 +def closing_fee(feerate, num_outputs): + assert num_outputs == 1 or num_outputs == 2 + weight = 424 + 124 * num_outputs + return (weight * feerate) // 1000 + + def scriptpubkey_addr(scriptpubkey): if 'addresses' in scriptpubkey: return scriptpubkey['addresses'][0]