mirror of
https://github.com/accumulator/charge-lnd.git
synced 2026-08-13 12:33:01 +02:00
Introducing: inbound_level_ppm and min_inbound_fee_ppm_delta
1) `min_inbound_fee_ppm_delta` is the necessary minimum change in the inbound_fee_ppm. The parameter uses `min_fee_ppm_delta` as the default. 2) We also ensure that the inbound fee rates are only changed if the change is sufficiently large. 3) If `inbound_level_ppm` is set, `inbound_fee_ppm` is calculated with `min(inbound_level_ppm - fee_ppm; 0)`.
This commit is contained in:
parent
fd1a164acf
commit
7f651450a9
3 changed files with 41 additions and 17 deletions
|
|
@ -213,11 +213,11 @@ Available strategies:
|
|||
|:--|:--|:--|
|
||||
|**ignore** | ignores the channel completely||
|
||||
|**ignore_fees** | don't make any fee changes, only update htlc size limits and time_lock_delta||
|
||||
|**static** | sets fixed base fee and fee rate values for the outbound and inbound side.| **fee_ppm**<br>**base_fee_msat**<br>**inbound_fee_ppm**<br>**inbound_base_fee_msat**|
|
||||
|**static** | sets fixed base fee and fee rate values for the outbound and inbound side.| **fee_ppm**<br>**base_fee_msat**<br>**inbound_fee_ppm**<br>**inbound_base_fee_msat**<br>**inbound_level_ppm** if set we calculate `inbound_fee_ppm = min(0,inbound_level_ppm - fee_ppm)`|
|
||||
|**match_peer** | sets the same base fee and fee rate values as the peer for the outbound and inbound side.|if **base_fee_msat**, **fee_ppm**, **inbound_base_fee_msat** or **inbound_fee_ppm** are set the override the peer values|
|
||||
|**cost** | calculate cost for opening channel, and set ppm to cover cost when channel depletes.|**cost_factor**|
|
||||
|**onchain_fee** | sets the fees to a % equivalent of a standard onchain payment. We use lnd's internal fee estimate, which is usually based on bitcoind's fee estimate.| **onchain_fee_btc** BTC<br>within **onchain_fee_numblocks** blocks.|
|
||||
|**proportional** | sets outbound fee ppm according to balancedness. Inbound fee ppm keeps unchanged.|**min_fee_ppm**<br>**max_fee_ppm**<br>**sum_peer_chans** consider all channels with peer for balance calculations|
|
||||
|**proportional** | sets outbound fee ppm according to balancedness. Inbound Fees are set like using strategy **static**.|**min_fee_ppm**<br>**max_fee_ppm**<br>**sum_peer_chans** consider all channels with peer for balance calculations|
|
||||
|**disable** | disables the channel in the outgoing direction. Channel will be re-enabled again if it matches another policy (except when that policy uses an 'ignore' strategy).||
|
||||
|**use_config** | process channel according to rules defined in another config file.|**config_file**|
|
||||
|
||||
|
|
@ -230,7 +230,8 @@ All strategies (except the ignore strategy) will apply the following properties
|
|||
| **max_htlc_msat** | Maximum size (in msat) of HTLC to allow | # msat |
|
||||
| **max_htlc_msat_ratio** | Maximum size of HTLC to allow as a fraction of total channel capacity | 0..1 |
|
||||
| **time_lock_delta** | Time Lock Delta | # blocks |
|
||||
| **min_fee_ppm_delta** | Minimum change in fees (ppm) before updating channel | ppm delta |
|
||||
| **min_fee_ppm_delta** | Minimum change in fees (ppm) before updating channel (default: 0) | ppm delta |
|
||||
| **min_inbound_fee_ppm_delta** | Minimum change in inbound fees (ppm) before updating channel (default: min_fee_ppm_delta) | ppm delta |
|
||||
| **cb_max_hourly_rate** | Circuitbreaker: maximum number of incoming htlcs per hour | # hourly rate |
|
||||
| **cb_max_pending** | Circuitbreaker: maximum number of incoming htlcs at the same time | # incoming pending htlcs |
|
||||
| **cb_mode** | Circuitbreaker: mode (0 - FAIL; 1 - QUEUE; 2 - QUEUE_PEER_INITIATED; 3 - BLOCK) | 0..3 |
|
||||
|
|
|
|||
|
|
@ -79,14 +79,32 @@ def main():
|
|||
fee_ppm_changed = is_defined(chp.fee_ppm) and current_fee_ppm != chp.fee_ppm and abs(current_fee_ppm - chp.fee_ppm) >= min_fee_ppm_delta
|
||||
base_fee_changed = is_defined(chp.base_fee_msat) and current_base_fee_msat != chp.base_fee_msat
|
||||
|
||||
inbound_fee_ppm_changed = lnd.supports_inbound_fees() \
|
||||
and is_defined(chp.inbound_fee_ppm) \
|
||||
and my_policy.inbound_fee_rate_milli_msat != chp.inbound_fee_ppm \
|
||||
and abs(my_policy.inbound_fee_rate_milli_msat - chp.inbound_fee_ppm) >= min_fee_ppm_delta
|
||||
min_inbound_fee_ppm_delta = policy.getint('min_inbound_fee_ppm_delta', min_fee_ppm_delta)
|
||||
inbound_fee_ppm_changed = inbound_base_fee_changed = False
|
||||
if lnd.supports_inbound_fees():
|
||||
# If there is any definied inbound_level we recalculate the inbound fee rate.
|
||||
if is_defined(chp.inbound_level_ppm):
|
||||
chp.inbound_fee_ppm = min(0,
|
||||
chp.inbound_level_ppm - (chp.fee_ppm if fee_ppm_changed else current_fee_ppm))
|
||||
|
||||
inbound_base_fee_changed = lnd.supports_inbound_fees() \
|
||||
and is_defined(chp.inbound_base_fee_msat) \
|
||||
and my_policy.inbound_fee_base_msat != chp.inbound_base_fee_msat
|
||||
# We'd like to avoid updating the inbound fee rate if the change is lower than the min delta,
|
||||
# even in the case other outbound properties have changed.
|
||||
# The goal is to minimize the gossip around the inbound fees, because at the moment there
|
||||
# are no updates for the incoming channel in the case of a FeeInsuffient error.
|
||||
# (https://github.com/lightningnetwork/lnd/pull/6967)
|
||||
# First we check if the base fee changed. In this case we will advance the inbound
|
||||
# fee anyway.
|
||||
inbound_base_fee_changed = is_defined(chp.inbound_base_fee_msat) \
|
||||
and my_policy.inbound_fee_base_msat != chp.inbound_base_fee_msat
|
||||
|
||||
if is_defined(chp.inbound_fee_ppm) \
|
||||
and not inbound_base_fee_changed \
|
||||
and abs(my_policy.inbound_fee_rate_milli_msat - chp.inbound_fee_ppm) < min_inbound_fee_ppm_delta:
|
||||
|
||||
chp.inbound_fee_ppm = my_policy.inbound_fee_rate_milli_msat
|
||||
|
||||
inbound_fee_ppm_changed = is_defined(chp.inbound_fee_ppm) \
|
||||
and my_policy.inbound_fee_rate_milli_msat != chp.inbound_fee_ppm
|
||||
|
||||
# We are using the local constraints as a floor for min_htlc and as a cap for max_htlc.
|
||||
# Otherwise, e.g. if min_htlc is too low, lnd cannot perform the whole policy update.
|
||||
|
|
@ -94,7 +112,7 @@ def main():
|
|||
chp.min_htlc_msat = max(chp.min_htlc_msat, channel.local_constraints.min_htlc_msat)
|
||||
if is_defined(chp.max_htlc_msat):
|
||||
chp.max_htlc_msat = min(chp.max_htlc_msat, channel.local_constraints.max_pending_amt_msat)
|
||||
|
||||
|
||||
min_htlc_changed = is_defined(chp.min_htlc_msat) and my_policy.min_htlc != chp.min_htlc_msat
|
||||
max_htlc_changed = is_defined(chp.max_htlc_msat) and my_policy.max_htlc_msat != chp.max_htlc_msat
|
||||
time_lock_delta_changed = is_defined(chp.time_lock_delta) and my_policy.time_lock_delta != chp.time_lock_delta
|
||||
|
|
@ -146,8 +164,8 @@ def main():
|
|||
s = ''
|
||||
if inbound_fee_ppm_changed:
|
||||
s = ' ➜ ' + fmt.col_hi(chp.inbound_fee_ppm)
|
||||
if min_fee_ppm_delta > abs(chp.inbound_fee_ppm - my_policy.inbound_fee_rate_milli_msat):
|
||||
s = s + ' (min_fee_ppm_delta=%d)' % min_fee_ppm_delta
|
||||
if min_inbound_fee_ppm_delta > abs(chp.inbound_fee_ppm - my_policy.inbound_fee_rate_milli_msat):
|
||||
s = s + ' (min_inbound_fee_ppm_delta=%d)' % min_inbound_fee_ppm_delta
|
||||
print(" inbound_fee_ppm: %s%s" % (fmt.col_hi(my_policy.inbound_fee_rate_milli_msat), s) )
|
||||
if is_defined(chp.min_htlc_msat) or arguments.verbose:
|
||||
s = ''
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class ChanParams(SimpleNamespace):
|
|||
time_lock_delta: Optional[Union[str, int]] = DONTCARE
|
||||
inbound_base_fee_msat: Optional[Union[str, int]] = DONTCARE
|
||||
inbound_fee_ppm: Optional[Union[str, int]] = DONTCARE
|
||||
inbound_level_ppm: Optional[Union[str, int]] = DONTCARE
|
||||
disabled: Optional[Union[str, bool]] = DONTCARE
|
||||
circuitbreaker_params: Optional[Union[str, CircuitbreakerParams]] = DONTCARE
|
||||
|
||||
|
|
@ -115,7 +116,8 @@ def strategy_static(channel, policy, **kwargs):
|
|||
base_fee_msat=policy.getint('base_fee_msat'),
|
||||
fee_ppm=policy.getint('fee_ppm'),
|
||||
inbound_base_fee_msat=policy.getint('inbound_base_fee_msat'),
|
||||
inbound_fee_ppm=policy.getint('inbound_fee_ppm')
|
||||
inbound_fee_ppm=policy.getint('inbound_fee_ppm'),
|
||||
inbound_level_ppm=policy.getint('inbound_level_ppm'),
|
||||
)
|
||||
|
||||
@strategy(name = 'proportional')
|
||||
|
|
@ -158,7 +160,8 @@ def strategy_proportional(channel, policy, **kwargs):
|
|||
base_fee_msat=policy.getint('base_fee_msat'),
|
||||
fee_ppm=ppm,
|
||||
inbound_base_fee_msat=policy.getint('inbound_base_fee_msat'),
|
||||
inbound_fee_ppm=policy.getint('inbound_fee_ppm')
|
||||
inbound_fee_ppm=policy.getint('inbound_fee_ppm'),
|
||||
inbound_level_ppm=policy.getint('inbound_level_ppm'),
|
||||
)
|
||||
|
||||
@strategy(name = 'match_peer')
|
||||
|
|
@ -197,7 +200,8 @@ def strategy_cost(channel, policy, **kwargs):
|
|||
base_fee_msat=policy.getint('base_fee_msat'),
|
||||
fee_ppm=ppm,
|
||||
inbound_base_fee_msat=policy.getint('inbound_base_fee_msat'),
|
||||
inbound_fee_ppm=policy.getint('inbound_fee_ppm')
|
||||
inbound_fee_ppm=policy.getint('inbound_fee_ppm'),
|
||||
inbound_level_ppm=policy.getint('inbound_level_ppm'),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -218,7 +222,8 @@ def strategy_onchain_fee(channel, policy, **kwargs):
|
|||
base_fee_msat=policy.getint('base_fee_msat'),
|
||||
fee_ppm=fee_ppm,
|
||||
inbound_base_fee_msat=policy.getint('inbound_base_fee_msat'),
|
||||
inbound_fee_ppm=policy.getint('inbound_fee_ppm')
|
||||
inbound_fee_ppm=policy.getint('inbound_fee_ppm'),
|
||||
inbound_level_ppm=policy.getint('inbound_level_ppm'),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue