From b840e5754ae7ba581c87611761b79f1ca0d1be57 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 28 Jun 2021 13:51:57 +0930 Subject: [PATCH 1/4] pytest: fix weird case in test_closing_different_fees We set amounts to a list, but then don't use the values except as a boolean. Make it a boolean, which should also speed the test up! Signed-off-by: Rusty Russell --- tests/test_closing.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_closing.py b/tests/test_closing.py index 127511a3ed87..18a916316e8b 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -236,8 +236,8 @@ def test_closing_different_fees(node_factory, bitcoind, executor): # Default feerate = 15000/11000/7500/1000 # It will start at the second number, accepting anything above the first. feerates = [[20000, 11000, 15000, 7400], [8000, 6000, 1001, 100]] - amounts = [0, 545999, 546000] - num_peers = len(feerates) * len(amounts) + balance = [False, True] + num_peers = len(feerates) * len(balance) addr = l1.rpc.newaddr()['bech32'] bitcoind.rpc.sendtoaddress(addr, 1) @@ -248,10 +248,10 @@ def test_closing_different_fees(node_factory, bitcoind, executor): # Create them in a batch, for speed! peers = [] for feerate in feerates: - for amount in amounts: + for b in balance: p = node_factory.get_node(feerates=feerate) p.feerate = feerate - p.amount = amount + p.balance = balance l1.rpc.connect(p.info['id'], 'localhost', p.port) peers.append(p) @@ -266,7 +266,7 @@ def test_closing_different_fees(node_factory, bitcoind, executor): l1.daemon.wait_for_logs(['update for channel .* now ACTIVE'] * num_peers + ['to CHANNELD_NORMAL'] * num_peers) for p in peers: - if p.amount != 0: + if p.balance: l1.pay(p, 100000000) # Now close all channels (not unilaterally!) From a665699c75a43febb7eae1b793598c8f29dbd4e1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 28 Jun 2021 13:52:03 +0930 Subject: [PATCH 2/4] lightningd: fix typo in debug statements. Show amount they were trying to pay with, not invoice amount. Also, show min fee in closing, not fee they offered. Signed-off-by: Rusty Russell --- lightningd/closing_control.c | 2 +- lightningd/invoice.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index d2070875715f..9768ae94ef68 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -79,7 +79,7 @@ static bool closing_fee_is_acceptable(struct lightningd *ld, if (amount_sat_less(fee, min_fee)) { log_debug(channel->log, "... That's below our min %s" " for weight %"PRIu64" at feerate %u", - type_to_string(tmpctx, struct amount_sat, &fee), + type_to_string(tmpctx, struct amount_sat, &min_fee), weight, min_feerate); return false; } diff --git a/lightningd/invoice.c b/lightningd/invoice.c index 4101853b030c..eb73a821410c 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -443,7 +443,7 @@ invoice_check_payment(const tal_t *ctx, log_debug(ld->log, "Attept to pay %s with amount %s > %s", type_to_string(tmpctx, struct sha256, &details->rhash), - type_to_string(tmpctx, struct amount_msat, details->msat), + type_to_string(tmpctx, struct amount_msat, &msat), type_to_string(tmpctx, struct amount_msat, &twice)); /* BOLT #4: * From 2be82a51b66bd262f0886f463fb56c78cf4379dc Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 28 Jun 2021 13:52:03 +0930 Subject: [PATCH 3/4] common: log at debug level when we update billboard. Makes for easier postmortem. Signed-off-by: Rusty Russell --- common/peer_billboard.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/peer_billboard.c b/common/peer_billboard.c index 183b9191c721..7ed816eb284d 100644 --- a/common/peer_billboard.c +++ b/common/peer_billboard.c @@ -12,6 +12,7 @@ void peer_billboard(bool perm, const char *fmt, ...) str = tal_vfmt(NULL, fmt, ap); va_end(ap); + status_debug("billboard%s: %s", perm ? " perm" : "", str); status_send(take(towire_status_peer_billboard(NULL, perm, str))); tal_free(str); } From 88616c74d99cc4c9848ef81239d8065d3a697c74 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 28 Jun 2021 14:38:10 +0930 Subject: [PATCH 4/4] 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 6c95ab92679d..106b7caa552d 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 4558c9a982d2..aa58ea18fa08 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 bb7d9d776d39..9c840a5a0a99 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 d39505198708..b948b737fc3c 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 9768ae94ef68..42d9909bf6aa 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 18a916316e8b..0bb6c170bc41 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -5,7 +5,7 @@ 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 @@ 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 feerate_for(target, minimum=0, maximum=10000000): """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 01f4760cd353..457334d9a1a1 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 de1a7060cf95..6f1d7842b86a 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]