From a0cb7bd9b476538d8c3e5cd1314ce86088c0acbb Mon Sep 17 00:00:00 2001 From: niftynei Date: Wed, 3 Feb 2021 16:13:57 -0600 Subject: [PATCH] df: update reserve calculation We can use the funding amount to derive the reserve requirement. --- lightningd/dual_open_control.c | 51 +++++++++++++++++++++++++++++++++- openingd/dualopend.c | 34 +++++++++++------------ openingd/dualopend_wire.csv | 1 - openingd/dualopend_wiregen.c | 8 ++---- openingd/dualopend_wiregen.h | 6 ++-- 5 files changed, 73 insertions(+), 27 deletions(-) diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index 68da5dbd7..984c0bb5a 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -918,6 +918,46 @@ REGISTER_PLUGIN_HOOK(rbf_channel, rbf_channel_hook_serialize, struct rbf_channel_payload *); +static struct amount_sat calculate_reserve(struct channel_config *their_config, + struct amount_sat funding_total, + enum side opener) +{ + struct amount_sat reserve, dust_limit; + + /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 + * + * The channel reserve is fixed at 1% of the total channel balance + * rounded down (sum of `funding_satoshis` from `open_channel2` + * and `accept_channel2`) or the `dust_limit_satoshis` from + * `open_channel2`, whichever is greater. + */ + reserve = amount_sat_div(funding_total, 100); + dust_limit = opener == LOCAL ? + chainparams->dust_limit : + their_config->dust_limit; + + if (amount_sat_greater(dust_limit, reserve)) + return dust_limit; + + return reserve; +} + +static void channel_update_reserve(struct channel *channel, + struct channel_config *their_config, + struct amount_sat funding_total) +{ + struct amount_sat reserve; + + reserve = calculate_reserve(their_config, + funding_total, + channel->opener); + + /* Depending on path, these are disjoint */ + their_config->channel_reserve = reserve; + channel->channel_info.their_config.channel_reserve = reserve; + channel->our_config.channel_reserve = reserve; +} + /* Steals fields from uncommitted_channel: returns NULL if can't generate a * key for this channel (shouldn't happen!). */ static struct channel_inflight * @@ -1432,6 +1472,11 @@ void dualopen_tell_depth(struct subd *dualopend, channel->last_tx = tal_steal(channel, inf->last_tx); channel->last_sig = inf->last_sig; + /* Update the reserve */ + channel_update_reserve(channel, + &channel->channel_info.their_config, + inf->funding->total_funds); + wallet_channel_save(dualopend->ld->wallet, channel); /* FIXME: delete inflights */ } @@ -2230,7 +2275,6 @@ static void handle_commit_received(struct subd *dualopend, &channel->channel_flags, &feerate_funding, &feerate_commitment, - &channel->our_config.channel_reserve, &local_upfront_shutdown_script, &remote_upfront_shutdown_script)) { log_broken(channel->log, "bad WIRE_DUALOPEND_COMMIT_RCVD %s", @@ -2245,6 +2289,11 @@ static void handle_commit_received(struct subd *dualopend, unsaved_channel_disconnect(channel, LOG_BROKEN, err_reason); goto failed; } + /* We need to update the channel reserve on the config */ + channel_update_reserve(channel, + &channel_info.their_config, + total_funding); + if (!(inflight = wallet_commit_channel(ld, channel, remote_commit, diff --git a/openingd/dualopend.c b/openingd/dualopend.c index d5cd95985..931db0dcd 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -445,28 +445,30 @@ static void check_channel_id(struct state *state, } static void set_reserve(struct tx_state *tx_state, - struct amount_sat funding_total) + struct amount_sat funding_total, + enum tx_role our_role) { - struct amount_sat reserve; + struct amount_sat reserve, dust_limit; /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 * * The channel reserve is fixed at 1% of the total channel balance * rounded down (sum of `funding_satoshis` from `open_channel2` - * and `accept_channel2`) or the `dust_limit_satoshis`, whichever - * is greater. + * and `accept_channel2`) or the `dust_limit_satoshis` from + * `open_channel2`, whichever is greater. */ reserve = amount_sat_div(funding_total, 100); + dust_limit = our_role == TX_INITIATOR ? + tx_state->localconf.dust_limit : + tx_state->remoteconf.dust_limit; - if (amount_sat_greater(tx_state->remoteconf.dust_limit, reserve)) - tx_state->remoteconf.channel_reserve = tx_state->remoteconf.dust_limit; - else + if (amount_sat_greater(dust_limit, reserve)) { + tx_state->remoteconf.channel_reserve = dust_limit; + tx_state->localconf.channel_reserve = dust_limit; + } else { tx_state->remoteconf.channel_reserve = reserve; - - if (amount_sat_greater(tx_state->localconf.dust_limit, reserve)) - tx_state->localconf.channel_reserve = tx_state->localconf.dust_limit; - else tx_state->localconf.channel_reserve = reserve; + } } static bool is_openers(const struct wally_map *unknowns) @@ -1717,7 +1719,6 @@ static u8 *accepter_commits(struct state *state, state->channel_flags, tx_state->feerate_per_kw_funding, state->feerate_per_kw_commitment, - tx_state->localconf.channel_reserve, state->upfront_shutdown_script[LOCAL], state->upfront_shutdown_script[REMOTE]); @@ -1897,7 +1898,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) init_changeset(tx_state, tx_state->psbt); /* Now that we know the total of the channel, we can set the reserve */ - set_reserve(tx_state, total); + set_reserve(tx_state, total, state->our_role); if (!check_config_bounds(tmpctx, total, state->feerate_per_kw_commitment, @@ -2221,7 +2222,6 @@ static u8 *opener_commits(struct state *state, state->channel_flags, tx_state->feerate_per_kw_funding, state->feerate_per_kw_commitment, - tx_state->localconf.channel_reserve, state->upfront_shutdown_script[LOCAL], state->upfront_shutdown_script[REMOTE]); @@ -2431,7 +2431,7 @@ static void opener_start(struct state *state, u8 *msg) /* Now that we know the total of the channel, we can * set the reserve */ - set_reserve(tx_state, total); + set_reserve(tx_state, total, state->our_role); if (!check_config_bounds(tmpctx, total, state->feerate_per_kw_commitment, @@ -2698,7 +2698,7 @@ static void rbf_local_start(struct state *state, u8 *msg) } /* Now that we know the total of the channel, we can set the reserve */ - set_reserve(tx_state, total); + set_reserve(tx_state, total, state->our_role); if (!check_config_bounds(tmpctx, total, state->feerate_per_kw_commitment, @@ -2829,7 +2829,7 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg) } /* Now that we know the total of the channel, we can set the reserve */ - set_reserve(tx_state, total); + set_reserve(tx_state, total, state->our_role); if (!check_config_bounds(tmpctx, total, state->feerate_per_kw_commitment, diff --git a/openingd/dualopend_wire.csv b/openingd/dualopend_wire.csv index dea89715c..229220205 100644 --- a/openingd/dualopend_wire.csv +++ b/openingd/dualopend_wire.csv @@ -146,7 +146,6 @@ msgdata,dualopend_commit_rcvd,our_funding_sats,amount_sat, msgdata,dualopend_commit_rcvd,channel_flags,u8, msgdata,dualopend_commit_rcvd,feerate_per_kw_funding,u32, msgdata,dualopend_commit_rcvd,feerate_per_kw_commitment,u32, -msgdata,dualopend_commit_rcvd,our_channel_reserve_satoshis,amount_sat, msgdata,dualopend_commit_rcvd,local_shutdown_len,u16, msgdata,dualopend_commit_rcvd,local_shutdown_scriptpubkey,u8,local_shutdown_len msgdata,dualopend_commit_rcvd,remote_shutdown_len,u16, diff --git a/openingd/dualopend_wiregen.c b/openingd/dualopend_wiregen.c index 49accd054..c18d34b13 100644 --- a/openingd/dualopend_wiregen.c +++ b/openingd/dualopend_wiregen.c @@ -490,7 +490,7 @@ bool fromwire_dualopend_rbf_init(const tal_t *ctx, const void *p, struct amount_ /* WIRE: DUALOPEND_COMMIT_RCVD */ /* dualopend->master: ready to commit channel open to database and */ /* get some signatures for the funding_tx. */ -u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config *their_config, const struct bitcoin_tx *remote_first_commit, const struct penalty_base *pbase, const struct bitcoin_signature *first_commit_sig, const struct wally_psbt *psbt, const struct pubkey *revocation_basepoint, const struct pubkey *payment_basepoint, const struct pubkey *htlc_basepoint, const struct pubkey *delayed_payment_basepoint, const struct pubkey *their_per_commit_point, const struct pubkey *remote_fundingkey, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshis, struct amount_sat our_funding_sats, u8 channel_flags, u32 feerate_per_kw_funding, u32 feerate_per_kw_commitment, struct amount_sat our_channel_reserve_satoshis, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey) +u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config *their_config, const struct bitcoin_tx *remote_first_commit, const struct penalty_base *pbase, const struct bitcoin_signature *first_commit_sig, const struct wally_psbt *psbt, const struct pubkey *revocation_basepoint, const struct pubkey *payment_basepoint, const struct pubkey *htlc_basepoint, const struct pubkey *delayed_payment_basepoint, const struct pubkey *their_per_commit_point, const struct pubkey *remote_fundingkey, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshis, struct amount_sat our_funding_sats, u8 channel_flags, u32 feerate_per_kw_funding, u32 feerate_per_kw_commitment, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey) { u16 local_shutdown_len = tal_count(local_shutdown_scriptpubkey); u16 remote_shutdown_len = tal_count(remote_shutdown_scriptpubkey); @@ -520,7 +520,6 @@ u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config * towire_u8(&p, channel_flags); towire_u32(&p, feerate_per_kw_funding); towire_u32(&p, feerate_per_kw_commitment); - towire_amount_sat(&p, our_channel_reserve_satoshis); towire_u16(&p, local_shutdown_len); towire_u8_array(&p, local_shutdown_scriptpubkey, local_shutdown_len); towire_u16(&p, remote_shutdown_len); @@ -528,7 +527,7 @@ u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config * return memcheck(p, tal_count(p)); } -bool fromwire_dualopend_commit_rcvd(const tal_t *ctx, const void *p, struct channel_config *their_config, struct bitcoin_tx **remote_first_commit, struct penalty_base **pbase, struct bitcoin_signature *first_commit_sig, struct wally_psbt **psbt, struct pubkey *revocation_basepoint, struct pubkey *payment_basepoint, struct pubkey *htlc_basepoint, struct pubkey *delayed_payment_basepoint, struct pubkey *their_per_commit_point, struct pubkey *remote_fundingkey, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshis, struct amount_sat *our_funding_sats, u8 *channel_flags, u32 *feerate_per_kw_funding, u32 *feerate_per_kw_commitment, struct amount_sat *our_channel_reserve_satoshis, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey) +bool fromwire_dualopend_commit_rcvd(const tal_t *ctx, const void *p, struct channel_config *their_config, struct bitcoin_tx **remote_first_commit, struct penalty_base **pbase, struct bitcoin_signature *first_commit_sig, struct wally_psbt **psbt, struct pubkey *revocation_basepoint, struct pubkey *payment_basepoint, struct pubkey *htlc_basepoint, struct pubkey *delayed_payment_basepoint, struct pubkey *their_per_commit_point, struct pubkey *remote_fundingkey, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshis, struct amount_sat *our_funding_sats, u8 *channel_flags, u32 *feerate_per_kw_funding, u32 *feerate_per_kw_commitment, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey) { u16 local_shutdown_len; u16 remote_shutdown_len; @@ -561,7 +560,6 @@ bool fromwire_dualopend_commit_rcvd(const tal_t *ctx, const void *p, struct chan *channel_flags = fromwire_u8(&cursor, &plen); *feerate_per_kw_funding = fromwire_u32(&cursor, &plen); *feerate_per_kw_commitment = fromwire_u32(&cursor, &plen); - *our_channel_reserve_satoshis = fromwire_amount_sat(&cursor, &plen); local_shutdown_len = fromwire_u16(&cursor, &plen); // 2nd case local_shutdown_scriptpubkey *local_shutdown_scriptpubkey = local_shutdown_len ? tal_arr(ctx, u8, local_shutdown_len) : NULL; @@ -996,4 +994,4 @@ bool fromwire_dualopend_dev_memleak_reply(const void *p, bool *leak) *leak = fromwire_bool(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:ac2f996019c8461a99192330f4d2cc506fc8c6dcebf2f0ce56f7b53157ffffe4 +// SHA256STAMP:6212fc1bc5a22513c105ad2f18046e6e724ccd98aa5f94a9228fb3a1aa45e11f diff --git a/openingd/dualopend_wiregen.h b/openingd/dualopend_wiregen.h index eae54fb15..4982a8d6a 100644 --- a/openingd/dualopend_wiregen.h +++ b/openingd/dualopend_wiregen.h @@ -136,8 +136,8 @@ bool fromwire_dualopend_rbf_init(const tal_t *ctx, const void *p, struct amount_ /* WIRE: DUALOPEND_COMMIT_RCVD */ /* dualopend->master: ready to commit channel open to database and */ /* get some signatures for the funding_tx. */ -u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config *their_config, const struct bitcoin_tx *remote_first_commit, const struct penalty_base *pbase, const struct bitcoin_signature *first_commit_sig, const struct wally_psbt *psbt, const struct pubkey *revocation_basepoint, const struct pubkey *payment_basepoint, const struct pubkey *htlc_basepoint, const struct pubkey *delayed_payment_basepoint, const struct pubkey *their_per_commit_point, const struct pubkey *remote_fundingkey, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshis, struct amount_sat our_funding_sats, u8 channel_flags, u32 feerate_per_kw_funding, u32 feerate_per_kw_commitment, struct amount_sat our_channel_reserve_satoshis, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey); -bool fromwire_dualopend_commit_rcvd(const tal_t *ctx, const void *p, struct channel_config *their_config, struct bitcoin_tx **remote_first_commit, struct penalty_base **pbase, struct bitcoin_signature *first_commit_sig, struct wally_psbt **psbt, struct pubkey *revocation_basepoint, struct pubkey *payment_basepoint, struct pubkey *htlc_basepoint, struct pubkey *delayed_payment_basepoint, struct pubkey *their_per_commit_point, struct pubkey *remote_fundingkey, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshis, struct amount_sat *our_funding_sats, u8 *channel_flags, u32 *feerate_per_kw_funding, u32 *feerate_per_kw_commitment, struct amount_sat *our_channel_reserve_satoshis, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey); +u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config *their_config, const struct bitcoin_tx *remote_first_commit, const struct penalty_base *pbase, const struct bitcoin_signature *first_commit_sig, const struct wally_psbt *psbt, const struct pubkey *revocation_basepoint, const struct pubkey *payment_basepoint, const struct pubkey *htlc_basepoint, const struct pubkey *delayed_payment_basepoint, const struct pubkey *their_per_commit_point, const struct pubkey *remote_fundingkey, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshis, struct amount_sat our_funding_sats, u8 channel_flags, u32 feerate_per_kw_funding, u32 feerate_per_kw_commitment, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey); +bool fromwire_dualopend_commit_rcvd(const tal_t *ctx, const void *p, struct channel_config *their_config, struct bitcoin_tx **remote_first_commit, struct penalty_base **pbase, struct bitcoin_signature *first_commit_sig, struct wally_psbt **psbt, struct pubkey *revocation_basepoint, struct pubkey *payment_basepoint, struct pubkey *htlc_basepoint, struct pubkey *delayed_payment_basepoint, struct pubkey *their_per_commit_point, struct pubkey *remote_fundingkey, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshis, struct amount_sat *our_funding_sats, u8 *channel_flags, u32 *feerate_per_kw_funding, u32 *feerate_per_kw_commitment, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey); /* WIRE: DUALOPEND_PSBT_CHANGED */ /* dualopend->master: peer updated the psbt */ @@ -230,4 +230,4 @@ bool fromwire_dualopend_dev_memleak_reply(const void *p, bool *leak); #endif /* LIGHTNING_OPENINGD_DUALOPEND_WIREGEN_H */ -// SHA256STAMP:ac2f996019c8461a99192330f4d2cc506fc8c6dcebf2f0ce56f7b53157ffffe4 +// SHA256STAMP:6212fc1bc5a22513c105ad2f18046e6e724ccd98aa5f94a9228fb3a1aa45e11f