niftynei
4 years ago
committed by
Rusty Russell
5 changed files with 246 additions and 189 deletions
@ -0,0 +1,197 @@ |
|||
#include <ccan/ccan/tal/str/str.h> |
|||
#include <common/amount.h> |
|||
#include <common/channel_config.h> |
|||
#include <common/initial_commit_tx.h> |
|||
#include <common/type_to_string.h> |
|||
#include <openingd/common.h> |
|||
|
|||
/*~ This is the key function that checks that their configuration is reasonable:
|
|||
* it applied for both the case where they're trying to open a channel, and when |
|||
* they've accepted our open. */ |
|||
bool check_config_bounds(const tal_t *ctx, |
|||
struct amount_sat funding, |
|||
u32 feerate_per_kw, |
|||
u32 max_to_self_delay, |
|||
struct amount_msat min_effective_htlc_capacity, |
|||
const struct channel_config *remoteconf, |
|||
const struct channel_config *localconf, |
|||
bool am_opener, |
|||
bool option_anchor_outputs, |
|||
char **err_reason) |
|||
{ |
|||
struct amount_sat capacity; |
|||
struct amount_sat reserve; |
|||
struct amount_sat fee; |
|||
|
|||
/* BOLT #2:
|
|||
* |
|||
* The receiving node MUST fail the channel if: |
|||
*... |
|||
* - `to_self_delay` is unreasonably large. |
|||
*/ |
|||
if (remoteconf->to_self_delay > max_to_self_delay) { |
|||
*err_reason = tal_fmt(ctx, |
|||
"to_self_delay %u larger than %u", |
|||
remoteconf->to_self_delay, |
|||
max_to_self_delay); |
|||
return false; |
|||
} |
|||
|
|||
/* BOLT #2:
|
|||
* |
|||
* The receiving node MAY fail the channel if: |
|||
*... |
|||
* - `funding_satoshis` is too small. |
|||
* - it considers `htlc_minimum_msat` too large. |
|||
* - it considers `max_htlc_value_in_flight_msat` too small. |
|||
* - it considers `channel_reserve_satoshis` too large. |
|||
* - it considers `max_accepted_htlcs` too small. |
|||
*/ |
|||
/* We accumulate this into an effective bandwidth minimum. */ |
|||
|
|||
/* Add both reserves to deduct from capacity. */ |
|||
if (!amount_sat_add(&reserve, |
|||
remoteconf->channel_reserve, |
|||
localconf->channel_reserve)) { |
|||
*err_reason = tal_fmt(ctx, |
|||
"channel_reserve_satoshis %s" |
|||
" too large", |
|||
type_to_string(ctx, struct amount_sat, |
|||
&remoteconf->channel_reserve)); |
|||
return false; |
|||
} |
|||
|
|||
/* BOLT-a12da24dd0102c170365124782b46d9710950ac1 #2:
|
|||
* - if `option_anchor_outputs` applies to this commitment |
|||
* transaction and the sending node is the funder: |
|||
* - MUST be able to additionally pay for `to_local_anchor` and |
|||
* `to_remote_anchor` above its reserve. |
|||
*/ |
|||
/* (We simply include in "reserve" here if they opened). */ |
|||
if (option_anchor_outputs |
|||
&& !am_opener |
|||
&& !amount_sat_add(&reserve, reserve, AMOUNT_SAT(660))) { |
|||
*err_reason = tal_fmt(ctx, |
|||
"cannot add anchors to reserve %s", |
|||
type_to_string(ctx, struct amount_sat, |
|||
&reserve)); |
|||
return false; |
|||
} |
|||
|
|||
/* If reserves are larger than total sat, we fail. */ |
|||
if (!amount_sat_sub(&capacity, funding, reserve)) { |
|||
*err_reason = tal_fmt(ctx, "channel_reserve_satoshis %s" |
|||
" and %s too large for funding %s", |
|||
type_to_string(ctx, struct amount_sat, |
|||
&remoteconf->channel_reserve), |
|||
type_to_string(ctx, struct amount_sat, |
|||
&localconf->channel_reserve), |
|||
type_to_string(ctx, struct amount_sat, |
|||
&funding)); |
|||
return false; |
|||
} |
|||
|
|||
/* They have to pay for fees, too. Assuming HTLC is dust, though,
|
|||
* we don't account for an HTLC output. */ |
|||
fee = commit_tx_base_fee(feerate_per_kw, 0, option_anchor_outputs); |
|||
if (!amount_sat_sub(&capacity, capacity, fee)) { |
|||
*err_reason = tal_fmt(ctx, "channel_reserve_satoshis %s" |
|||
" and %s plus fee %s too large for " |
|||
"funding %s", |
|||
type_to_string(tmpctx, struct amount_sat, |
|||
&remoteconf->channel_reserve), |
|||
type_to_string(tmpctx, struct amount_sat, |
|||
&localconf->channel_reserve), |
|||
type_to_string(tmpctx, struct amount_sat, |
|||
&fee), |
|||
type_to_string(tmpctx, struct amount_sat, |
|||
&funding)); |
|||
return false; |
|||
} |
|||
|
|||
/* If they set the max HTLC value to less than that number, it caps
|
|||
* the channel capacity. */ |
|||
if (amount_sat_greater(capacity, |
|||
amount_msat_to_sat_round_down(remoteconf->max_htlc_value_in_flight))) |
|||
capacity = amount_msat_to_sat_round_down(remoteconf->max_htlc_value_in_flight); |
|||
|
|||
/* If the minimum htlc is greater than the capacity, the channel is
|
|||
* useless. */ |
|||
if (amount_msat_greater_sat(remoteconf->htlc_minimum, capacity)) { |
|||
*err_reason = tal_fmt(ctx, "htlc_minimum_msat %s" |
|||
" too large for funding %s" |
|||
" capacity_msat %s", |
|||
type_to_string(ctx, struct amount_msat, |
|||
&remoteconf->htlc_minimum), |
|||
type_to_string(ctx, struct amount_sat, |
|||
&funding), |
|||
type_to_string(ctx, struct amount_sat, |
|||
&capacity)); |
|||
return false; |
|||
} |
|||
|
|||
/* If the resulting channel doesn't meet our minimum "effective capacity"
|
|||
* set by lightningd, don't bother opening it. */ |
|||
if (amount_msat_greater_sat(min_effective_htlc_capacity, |
|||
capacity)) { |
|||
*err_reason = tal_fmt(ctx, |
|||
"channel capacity with funding %s," |
|||
" reserves %s/%s," |
|||
" max_htlc_value_in_flight_msat is %s," |
|||
" channel capacity is %s, which is below %s", |
|||
type_to_string(ctx, struct amount_sat, |
|||
&funding), |
|||
type_to_string(ctx, struct amount_sat, |
|||
&remoteconf->channel_reserve), |
|||
type_to_string(ctx, struct amount_sat, |
|||
&localconf->channel_reserve), |
|||
type_to_string(ctx, struct amount_msat, |
|||
&remoteconf->max_htlc_value_in_flight), |
|||
type_to_string(ctx, struct amount_sat, |
|||
&capacity), |
|||
type_to_string(ctx, struct amount_msat, |
|||
&min_effective_htlc_capacity)); |
|||
return false; |
|||
} |
|||
|
|||
/* We don't worry about how many HTLCs they accept, as long as > 0! */ |
|||
if (remoteconf->max_accepted_htlcs == 0) { |
|||
*err_reason = tal_fmt(ctx, |
|||
"max_accepted_htlcs %u invalid", |
|||
remoteconf->max_accepted_htlcs); |
|||
return false; |
|||
} |
|||
|
|||
/* BOLT #2:
|
|||
* |
|||
* The receiving node MUST fail the channel if: |
|||
*... |
|||
* - `max_accepted_htlcs` is greater than 483. |
|||
*/ |
|||
if (remoteconf->max_accepted_htlcs > 483) { |
|||
*err_reason = tal_fmt(ctx, |
|||
"max_accepted_htlcs %u too large", |
|||
remoteconf->max_accepted_htlcs); |
|||
return false; |
|||
} |
|||
|
|||
/* BOLT #2:
|
|||
* |
|||
* The receiving node MUST fail the channel if: |
|||
*... |
|||
* - `dust_limit_satoshis` is greater than `channel_reserve_satoshis`. |
|||
*/ |
|||
if (amount_sat_greater(remoteconf->dust_limit, |
|||
remoteconf->channel_reserve)) { |
|||
*err_reason = tal_fmt(ctx, |
|||
"dust_limit_satoshis %s" |
|||
" too large for channel_reserve_satoshis %s", |
|||
type_to_string(ctx, struct amount_sat, |
|||
&remoteconf->dust_limit), |
|||
type_to_string(ctx, struct amount_sat, |
|||
&remoteconf->channel_reserve)); |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
@ -0,0 +1,21 @@ |
|||
#ifndef LIGHTNING_OPENINGD_COMMON_H |
|||
#define LIGHTNING_OPENINGD_COMMON_H |
|||
|
|||
#include "config.h" |
|||
|
|||
struct amount_sat; |
|||
struct channel_config; |
|||
|
|||
|
|||
bool check_config_bounds(const tal_t *ctx, |
|||
struct amount_sat funding, |
|||
u32 feerate_per_kw, |
|||
u32 max_to_self_delay, |
|||
struct amount_msat min_effective_htlc_capacity, |
|||
const struct channel_config *remoteconf, |
|||
const struct channel_config *localconf, |
|||
bool am_opener, |
|||
bool option_anchor_outputs, |
|||
char **err_reason); |
|||
|
|||
#endif /* LIGHTNING_OPENINGD_COMMON_H */ |
Loading…
Reference in new issue