lease-rates: calculate the fee owed to peer for the funds lease

This commit is contained in:
niftynei 2021-06-14 17:49:57 -05:00 committed by neil saitug
parent 9dd0a2c2e5
commit 63e2ce01e7
5 changed files with 117 additions and 5 deletions

View File

@ -45,6 +45,41 @@ void lease_rates_get_commitment(struct pubkey *pubkey,
sha256_done(&sctx, sha); sha256_done(&sctx, sha);
} }
bool lease_rates_calc_fee(struct lease_rates *rates,
struct amount_sat accept_funding_sats,
struct amount_sat requested_sats,
u32 onchain_feerate,
struct amount_sat *fee)
{
struct amount_sat lease_fee, basis_sat, tx_fee;
/* BOLT- #2:
* The lease fee is calculated as:
* `lease_fee_base_sat` +
* min(`accept_channel2`.`funding_satoshis`, `open_channel2`.`requested_sats`) * `lease_fee_basis` / 10_000 +
* `funding_weight` * `funding_feerate_perkw` / 1000
*/
lease_fee = amount_sat(rates->lease_fee_base_sat);
basis_sat = amount_sat_less(accept_funding_sats, requested_sats)
? accept_funding_sats : requested_sats;
if (!amount_sat_scale(&basis_sat, basis_sat,
rates->lease_fee_basis))
return false;
basis_sat = amount_sat_div(basis_sat, 10000);
if (!amount_sat_add(&lease_fee, lease_fee, basis_sat))
return false;
tx_fee = amount_tx_fee(onchain_feerate, rates->funding_weight);
if (!amount_sat_add(&lease_fee, lease_fee, tx_fee))
return false;
*fee = lease_fee;
return true;
}
bool lease_rates_set_chan_fee_base_msat(struct lease_rates *rates, bool lease_rates_set_chan_fee_base_msat(struct lease_rates *rates,
struct amount_msat amt) struct amount_msat amt)
{ {

View File

@ -19,6 +19,12 @@ void lease_rates_get_commitment(struct pubkey *pubkey,
u16 chan_fee_ppt, u16 chan_fee_ppt,
struct sha256 *sha); struct sha256 *sha);
bool lease_rates_calc_fee(struct lease_rates *rates,
struct amount_sat accept_funding_sats,
struct amount_sat requested_sats,
u32 onchain_feerate,
struct amount_sat *fee);
WARN_UNUSED_RESULT bool lease_rates_set_chan_fee_base_msat(struct lease_rates *rates, struct amount_msat amt); WARN_UNUSED_RESULT bool lease_rates_set_chan_fee_base_msat(struct lease_rates *rates, struct amount_msat amt);
WARN_UNUSED_RESULT bool lease_rates_set_lease_fee_sat(struct lease_rates *rates, struct amount_sat amt); WARN_UNUSED_RESULT bool lease_rates_set_lease_fee_sat(struct lease_rates *rates, struct amount_sat amt);

View File

@ -95,11 +95,42 @@ static void check_lease_rate_commitment_hash(void)
} }
static void check_lease_rate_fees(void)
{
/* BOLT- #2:
* E.g.
* An node requests 1_000_000sats at a feerate of 2500perkw. They
* are contributing 500_000sats. Their weight contribution to the
* funding transaction will be 720.
*
* The accepter adds 1,100,000sats and charges a base funding fee of
* 233sats with a lease fee basis of 22. Their funding weight is 444.
* The lease fee is as follows:
* 233 + min(1_000_000,1_100_000) * 22 / 10_000 + 444 * 2500 / 1000
* The total lease fee for this open is 3543sats.
*/
struct amount_sat request_sats = amount_sat(1000000);
struct amount_sat accepter_contrib = amount_sat(1100000);
struct amount_sat fee;
struct lease_rates rates;
u32 feerate = 2500;
rates.lease_fee_basis = 22;
rates.lease_fee_base_sat = 233;
rates.funding_weight = 444;
assert(lease_rates_calc_fee(&rates, accepter_contrib,
request_sats, feerate,
&fee));
assert(amount_sat_eq(fee, amount_sat(3543)));
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
common_setup(argv[0]); common_setup(argv[0]);
check_lease_rate_commitment_hash(); check_lease_rate_commitment_hash();
check_lease_rate_fees();
common_shutdown(); common_shutdown();
} }

View File

@ -57,6 +57,7 @@ OPENINGD_COMMON_OBJS := \
common/initial_commit_tx.o \ common/initial_commit_tx.o \
common/key_derive.o \ common/key_derive.o \
common/keyset.o \ common/keyset.o \
common/lease_rates.o \
common/memleak.o \ common/memleak.o \
common/msg_queue.o \ common/msg_queue.o \
common/node_id.o \ common/node_id.o \

View File

@ -192,6 +192,9 @@ struct state {
/* State of inflight funding transaction attempt */ /* State of inflight funding transaction attempt */
struct tx_state *tx_state; struct tx_state *tx_state;
/* If delay til the channel funds lease expires */
u32 lease_expiry;
}; };
/* psbt_changeset_get_next - Get next message to send /* psbt_changeset_get_next - Get next message to send
@ -2491,7 +2494,7 @@ static void opener_start(struct state *state, u8 *msg)
struct channel_id cid; struct channel_id cid;
char *err_reason; char *err_reason;
struct amount_sat total, requested_sats; struct amount_sat total, requested_sats;
u32 current_blockheight, lease_expiry; u32 current_blockheight;
bool dry_run; bool dry_run;
struct tx_state *tx_state = state->tx_state; struct tx_state *tx_state = state->tx_state;
@ -2642,16 +2645,21 @@ static void opener_start(struct state *state, u8 *msg)
open_err_warn(state, "%s", "Abort requested"); open_err_warn(state, "%s", "Abort requested");
} }
/* FIXME: BOLT QUOTE */ /* BOLT- #2:
* The accepting node: ...
* - if they decide to accept the offer:
* - MUST include a `will_fund` tlv
*/
if (open_tlv->request_funds && a_tlv->will_fund) { if (open_tlv->request_funds && a_tlv->will_fund) {
char *err_msg; char *err_msg;
struct lease_rates *rates = &a_tlv->will_fund->lease_rates; struct lease_rates *rates = &a_tlv->will_fund->lease_rates;
struct amount_sat lease_fee;
lease_expiry = current_blockheight + LEASE_RATE_DURATION; state->lease_expiry = current_blockheight + LEASE_RATE_DURATION;
msg = towire_dualopend_validate_lease(NULL, msg = towire_dualopend_validate_lease(NULL,
&a_tlv->will_fund->signature, &a_tlv->will_fund->signature,
lease_expiry, state->lease_expiry,
rates->channel_fee_max_base_msat, rates->channel_fee_max_base_msat,
rates->channel_fee_max_proportional_thousandths, rates->channel_fee_max_proportional_thousandths,
&state->their_funding_pubkey); &state->their_funding_pubkey);
@ -2666,8 +2674,39 @@ static void opener_start(struct state *state, u8 *msg)
if (err_msg) if (err_msg)
open_err_warn(state, "%s", err_msg); open_err_warn(state, "%s", err_msg);
/* BOLT- #2:
* The lease fee is added to the accepter's balance
* in a channel, in addition to the `funding_satoshi`
* that they are contributing. The channel initiator
* must contribute enough funds to cover
* `open_channel2`.`funding_satoshis`, the lease fee,
* and their tx weight * `funding_feerate_perkw` / 1000.
*/
if (!lease_rates_calc_fee(rates, tx_state->accepter_funding,
requested_sats,
tx_state->feerate_per_kw_funding,
&lease_fee))
negotiation_failed(state,
"Unable to calculate lease fee");
/* Add it to the accepter's total */
if (!amount_sat_add(&tx_state->accepter_funding,
tx_state->accepter_funding, lease_fee)) {
negotiation_failed(state,
"Unable to add accepter's funding"
" and channel lease fee (%s + %s)",
type_to_string(tmpctx,
struct amount_sat,
&tx_state->accepter_funding),
type_to_string(tmpctx,
struct amount_sat,
&lease_fee));
return;
}
} else } else
lease_expiry = 0; state->lease_expiry = 0;
/* Check that total funding doesn't overflow */ /* Check that total funding doesn't overflow */
if (!amount_sat_add(&total, tx_state->opener_funding, if (!amount_sat_add(&total, tx_state->opener_funding,