Skip to content

Commit f2291c4

Browse files
rustyrussellcdecker
authored andcommitted
onchaind: cap RBF penalty fee for testnet/regtest
On testnet I noticed if we can't reach bitcoind for some reason, we'll keep RBFing our penalty tx ("it didn't go in, RBF harder!!"). Makes no sense to grossly exceed the amount needed for next block, so simply cap penalty at 2x "estimatesmartfee 2 CONSERVATIVE". Signed-off-by: Rusty Russell <[email protected]>
1 parent 9e41754 commit f2291c4

File tree

6 files changed

+32
-15
lines changed

6 files changed

+32
-15
lines changed

lightningd/onchain_control.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ enum watch_result onchaind_funding_spent(struct channel *channel,
614614
struct lightningd *ld = channel->peer->ld;
615615
struct pubkey final_key;
616616
int hsmfd;
617-
u32 feerates[3];
617+
u32 feerates[4];
618618
enum state_change reason;
619619

620620
/* use REASON_ONCHAIN or closer's reason, if known */
@@ -730,6 +730,9 @@ enum watch_result onchaind_funding_spent(struct channel *channel,
730730
feerates[i] = feerate_floor();
731731
}
732732
}
733+
/* This is 10x highest bitcoind estimate (depending on dev-max-fee-multiplier),
734+
* so cap at 2x */
735+
feerates[3] = feerate_max(ld, NULL) / 5;
733736

734737
log_debug(channel->log, "channel->static_remotekey_start[LOCAL] %"PRIu64,
735738
channel->static_remotekey_start[LOCAL]);
@@ -749,8 +752,8 @@ enum watch_result onchaind_funding_spent(struct channel *channel,
749752
* we specify theirs. */
750753
channel->channel_info.their_config.to_self_delay,
751754
channel->our_config.to_self_delay,
752-
/* delayed_to_us, htlc, and penalty. */
753-
feerates[0], feerates[1], feerates[2],
755+
/* delayed_to_us, htlc, penalty, and penalty_max. */
756+
feerates[0], feerates[1], feerates[2], feerates[3],
754757
channel->our_config.dust_limit,
755758
&our_last_txid,
756759
channel->shutdown_scriptpubkey[LOCAL],

onchaind/onchaind.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static u32 delayed_to_us_feerate;
4343
static u32 htlc_feerate;
4444

4545
/* The feerate for transactions spending from revoked transactions. */
46-
static u32 penalty_feerate;
46+
static u32 penalty_feerate, max_penalty_feerate;
4747

4848
/* Min and max feerates we ever used */
4949
static u32 min_possible_feerate, max_possible_feerate;
@@ -878,10 +878,19 @@ compute_penalty_output_amount(struct amount_sat initial_amount,
878878
struct amount_sat max_output_amount;
879879
struct amount_sat output_amount;
880880
struct amount_sat deducted_amount;
881+
struct amount_sat min_output_amount, max_fee;
881882

882883
assert(depth <= max_depth);
883884
assert(depth > 0);
884885

886+
/* We never pay more than max_penalty_feerate; at some point,
887+
* it's clearly not working. */
888+
max_fee = amount_tx_fee(max_penalty_feerate, weight);
889+
if (!amount_sat_sub(&min_output_amount, initial_amount, max_fee))
890+
/* We may just donate the whole output as fee, meaning
891+
* we get zero amount. */
892+
min_output_amount = AMOUNT_SAT(0);
893+
885894
/* The difference between initial_amount, and the fee suggested
886895
* by min_rbf_bump, is the largest allowed output amount.
887896
*
@@ -892,11 +901,7 @@ compute_penalty_output_amount(struct amount_sat initial_amount,
892901
*/
893902
if (!amount_sat_sub(&max_output_amount,
894903
initial_amount, min_rbf_bump(weight, depth - 1)))
895-
/* If min_rbf_bump is larger than the initial_amount,
896-
* we should just donate the whole output as fee,
897-
* meaning we get 0 output amount.
898-
*/
899-
return AMOUNT_SAT(0);
904+
return min_output_amount;
900905

901906
/* Map the depth / max_depth into a number between 0->1. */
902907
double x = (double) depth / (double) max_depth;
@@ -910,9 +915,14 @@ compute_penalty_output_amount(struct amount_sat initial_amount,
910915

911916
/* output_amount = initial_amount - deducted_amount. */
912917
if (!amount_sat_sub(&output_amount,
913-
initial_amount, deducted_amount))
914-
/* If underflow, force to 0. */
915-
output_amount = AMOUNT_SAT(0);
918+
initial_amount, deducted_amount)) {
919+
/* If underflow, force to min. */
920+
output_amount = min_output_amount;
921+
}
922+
923+
/* If output below min, return min. */
924+
if (amount_sat_less(output_amount, min_output_amount))
925+
return min_output_amount;
916926

917927
/* If output exceeds max, return max. */
918928
if (amount_sat_less(max_output_amount, output_amount))
@@ -3908,6 +3918,7 @@ int main(int argc, char *argv[])
39083918
&delayed_to_us_feerate,
39093919
&htlc_feerate,
39103920
&penalty_feerate,
3921+
&max_penalty_feerate,
39113922
&dust_limit,
39123923
&our_broadcast_txid,
39133924
&scriptpubkey[LOCAL],

onchaind/onchaind_wire.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ msgdata,onchaind_init,remote_to_self_delay,u32,
2323
msgdata,onchaind_init,delayed_to_us_feerate,u32,
2424
msgdata,onchaind_init,htlc_feerate,u32,
2525
msgdata,onchaind_init,penalty_feerate,u32,
26+
msgdata,onchaind_init,max_penalty_feerate,u32,
2627
msgdata,onchaind_init,local_dust_limit_satoshi,amount_sat,
2728
# Gives an easy way to tell if it's our unilateral close or theirs...
2829
msgdata,onchaind_init,our_broadcast_txid,bitcoin_txid,

onchaind/test/run-grind_feerate-bug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ bool fromwire_onchaind_dev_memleak(const void *p UNNEEDED)
4949
bool fromwire_onchaind_htlcs(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct htlc_stub **htlc UNNEEDED, bool **tell_if_missing UNNEEDED, bool **tell_immediately UNNEEDED)
5050
{ fprintf(stderr, "fromwire_onchaind_htlcs called!\n"); abort(); }
5151
/* Generated stub for fromwire_onchaind_init */
52-
bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, u32 *ourwallet_index UNNEEDED, struct ext_key *ourwallet_ext_key UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, u32 *min_relay_feerate UNNEEDED)
52+
bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, u32 *max_penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, u32 *ourwallet_index UNNEEDED, struct ext_key *ourwallet_ext_key UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, u32 *min_relay_feerate UNNEEDED)
5353
{ fprintf(stderr, "fromwire_onchaind_init called!\n"); abort(); }
5454
/* Generated stub for fromwire_onchaind_known_preimage */
5555
bool fromwire_onchaind_known_preimage(const void *p UNNEEDED, struct preimage *preimage UNNEEDED)

onchaind/test/run-grind_feerate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ bool fromwire_onchaind_dev_memleak(const void *p UNNEEDED)
5454
bool fromwire_onchaind_htlcs(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct htlc_stub **htlc UNNEEDED, bool **tell_if_missing UNNEEDED, bool **tell_immediately UNNEEDED)
5555
{ fprintf(stderr, "fromwire_onchaind_htlcs called!\n"); abort(); }
5656
/* Generated stub for fromwire_onchaind_init */
57-
bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, u32 *ourwallet_index UNNEEDED, struct ext_key *ourwallet_ext_key UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, u32 *min_relay_feerate UNNEEDED)
57+
bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, u32 *max_penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, u32 *ourwallet_index UNNEEDED, struct ext_key *ourwallet_ext_key UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, u32 *min_relay_feerate UNNEEDED)
5858
{ fprintf(stderr, "fromwire_onchaind_init called!\n"); abort(); }
5959
/* Generated stub for fromwire_onchaind_known_preimage */
6060
bool fromwire_onchaind_known_preimage(const void *p UNNEEDED, struct preimage *preimage UNNEEDED)

tests/test_closing.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1668,7 +1668,9 @@ def test_penalty_rbf_burn(node_factory, bitcoind, executor, chainparams):
16681668
may_fail=True, allow_broken_log=True)
16691669
l2 = node_factory.get_node(options={'dev-disable-commit-after': 1,
16701670
'watchtime-blocks': to_self_delay,
1671-
'plugin': coin_mvt_plugin})
1671+
'plugin': coin_mvt_plugin},
1672+
# Exporbitant feerates mean we don't have cap on RBF!
1673+
feerates=(15000000, 11000, 7500, 3750))
16721674

16731675
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
16741676
l1.fundchannel(l2, 10**7)

0 commit comments

Comments
 (0)