lnwatcher: keep watching sweep TXOs that are dust due to high fees
- if fee estimates are high atm, some outputs are not worth to sweep
- however, fee estimates might be only-temporarily very high
- previously in such a case lnwatcher would just discard outputs as dust,
and mark the channel REDEEMED (and hence never watch it or try again)
- now, instead, if the outputs would not be dust if fee estimates were lower,
lnwatcher will keep watching the channel
- and if estimates go down, lnwatcher will sweep them then
- relatedly, previously txbatcher.is_dust() used allow_fallback_to_static_rates=True,
and it erroneously almost always fell back to the static rates (150 s/b) during
startup (race: lnwatcher was faster than the network managed to get estimates)
- now, instead, txbatcher.is_dust() does not fallback to static rates,
and the callers are supposed to handle NoDynamicFeeEstimates.
- I think this makes much more sense. The previous meaning of "is_dust"
with the fallback was weird. Now it means: "is dust at current feerates".
fixes https://github.com/spesmilo/electrum/issues/9980
This commit is contained in:
@@ -99,6 +99,7 @@ class TxBatcher(Logger):
|
||||
|
||||
@locked
|
||||
def add_sweep_input(self, key: str, sweep_info: 'SweepInfo') -> None:
|
||||
"""Can raise BelowDustLimit or NoDynamicFeeEstimates."""
|
||||
if sweep_info.txin and sweep_info.txout:
|
||||
# detect legacy htlc using name and csv delay
|
||||
if sweep_info.name in ['received-htlc', 'offered-htlc'] and sweep_info.csv_delay == 0:
|
||||
@@ -263,20 +264,25 @@ class TxBatch(Logger):
|
||||
self.batch_payments.append(output)
|
||||
|
||||
def is_dust(self, sweep_info: SweepInfo) -> bool:
|
||||
"""Can raise NoDynamicFeeEstimates."""
|
||||
if sweep_info.is_anchor():
|
||||
return False
|
||||
if sweep_info.txout is not None:
|
||||
return False
|
||||
value = sweep_info.txin._trusted_value_sats
|
||||
value = sweep_info.txin.value_sats()
|
||||
witness_size = len(sweep_info.txin.make_witness(71*b'\x00'))
|
||||
tx_size_vbytes = 84 + witness_size//4 # assumes no batching, sweep to p2wpkh
|
||||
self.logger.info(f'{sweep_info.name} size = {tx_size_vbytes}')
|
||||
fee = self.fee_policy.estimate_fee(tx_size_vbytes, network=self.wallet.network, allow_fallback_to_static_rates=True)
|
||||
fee = self.fee_policy.estimate_fee(tx_size_vbytes, network=self.wallet.network)
|
||||
return value - fee <= dust_threshold()
|
||||
|
||||
@locked
|
||||
def add_sweep_input(self, sweep_info: 'SweepInfo') -> None:
|
||||
"""Can raise BelowDustLimit or NoDynamicFeeEstimates."""
|
||||
if self.is_dust(sweep_info):
|
||||
# note: this uses the current fee estimates. Just because something is dust
|
||||
# at the current fee levels, if fees go down, it might still become
|
||||
# worthwhile to sweep. So callers might want to retry later.
|
||||
raise BelowDustLimit
|
||||
txin = sweep_info.txin
|
||||
if txin.prevout in self._unconfirmed_sweeps:
|
||||
|
||||
Reference in New Issue
Block a user