mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
lease-rates: calculate the fee owed to peer for the funds lease
This commit is contained in:
parent
9dd0a2c2e5
commit
63e2ce01e7
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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 \
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user