Catch exceptions happening to callbacks to continue calling the
remaining callbacks. Otherwise if the first callback throws an exception
the remaining callbacks aren't going to be called.
- 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
- was added when functions in lnsweep returned already signed tx, and signing is expensive
- get_ctx_sweep_info does not presign anymore
- cache invalidation is difficult here
- e.g. not only on new blocks, but we should e.g. also invalidate the cache when learning new preimages
The class TxBatcher handles the creation, broadcast and replacement
of replaceable transactions. Callers (LNWatcher, SwapManager) use
methods add_payment_output and add_sweep_info. Transactions
created by TxBatcher may combine sweeps and outgoing payments.
Transactions created by TxBatcher will have their fee bumped
automatically (this was only the case for sweeps before).
TxBatcher manages several TxBatches. TxBatches are created
dynamically when needed.
The GUI does not touch txbatcher transactions:
- wallet.get_candidates_for_batching excludes txbatcher
transactions
- RBF dialogs do not work with txbatcher transactions
wallet:
- instead of reading config variables, make_unsigned_transaction
takes new parameters: base_tx, send_change_to_lighting
tests:
- unit tests in test_txbatcher.py (replaces test_sswaps.py)
- force all regtests to use MPP, so that we sweep transactions
with several HTLCs. This forces the payment manager to aggregate
first-stage HTLC tx inputs. second-stage are not batched for now.
- Wallet.make_unsigned_transaction takes a FeePolicy parameter
- fee sliders act on a FeePolicy instead of config
- different fee policies may be used for different purposes
- do not detect dust outputs in lnsweep, delegate that to lnwatcher
Ideally, given an on-chain backup, after the remote force-closes, we should be able to spend our anchor output,
to CPFP the remote commitment tx (assuming the channel used OPTION_ANCHORS).
To spend the anchor output, we need to be able to sign with the local funding_privkey.
Previously we derived the funding_key from the channel_seed (which comes from os.urandom).
Prior to anchors, there was no use case for signing with the funding_key given a channel backup.
Now with anchors, we should make its derivation deterministic somehow, in a way so that it can
be derived given just an on-chain backup.
- one way would be to put some more data into the existing OP_RETURN
- uses block space
- the OP_RETURNs can be disabled via "use_recoverable_channels"
- only the initiator can use OP_RETURNs (so what if channel is in incoming dir?)
- instead, new scheme for our funding_key:
- we derive the funding_privkey from the lnworker root secret (derived from our bip32 seed)
- for outgoing channels:
- lnworker_root_secret + remote_node_id + funding_tx_nlocktime
- for incoming channels:
- lnworker_root_secret + remote_node_id + remote_funding_pubkey
- a check is added to avoid reusing the same key between channels:
not letting to user open more than one channel with the same peer in a single block
- only the first 16 bytes of the remote_node_id are used, as the onchain backup OP_RETURNs only contain that
- as the funding_privkey cannot be derived from the channel_seed anymore, it is included in the
imported channel backups, which in turn need a new version defined
- a wallet db upgrade is used to update already stored imported cbs
- alternatively we could keep the imported cbs as-is, so no new version, no new funding_privkey field, as it is clearly somewhat redundant given on-chain backups can reconstruct it
- however adding the field seems easier
- otherwise the existing code would try to derive the funding_privkey from the channel_seed
- also note: atm there is no field in the imported backups to distinguish anchor channels vs static-remotekey channels
- txins have an optional make_witness method
- instead of gen_tx, SweepInfo has a txin and
an optional txout, for 1st stage HTLCs
- sweep transactions are created by lnwatcher
The purpose of this change is to allow combining several
inputs in the same sweep transaction.
inspect_tx_candidate assumes that htlc transactions have
only one input, which is not true for anchor channels.
inspect_tx_candidate is still used by the watchtower, because
it does not have access to channel information.
Due to anchor channel's sighash.SINGLE and sighash.ANYONECANPAY,
several HTLC-transactions can be combined. This means we must watch for
revoked outputs in the HTLC transaction not only at index 0 but at any
index.
local_watchtower.adb.start_network was getting called twice.
follow-up 6ac3f84095
```
20230418T014725.636141Z | ERROR | __main__ |
Traceback (most recent call last):
File "/home/user/wspace/electrum/./run_electrum", line 435, in main
handle_cmd(
File "/home/user/wspace/electrum/./run_electrum", line 469, in handle_cmd
d = daemon.Daemon(config, fd)
File "/home/user/wspace/electrum/electrum/util.py", line 462, in <lambda>
return lambda *args, **kw_args: do_profile(args, kw_args)
File "/home/user/wspace/electrum/electrum/util.py", line 458, in do_profile
o = func(*args, **kw_args)
File "/home/user/wspace/electrum/electrum/daemon.py", line 404, in __init__
self.network = Network(config, daemon=self)
File "/home/user/wspace/electrum/electrum/network.py", line 348, in __init__
self.local_watchtower.adb.start_network(self)
File "/home/user/wspace/electrum/electrum/address_synchronizer.py", line 185, in start_network
assert self.network is None, "already started"
AssertionError: already started
```
The qt, qml, and kivy GUIs have a first-start network-setup screen
that allows the user customising the network settings before creating a wallet.
Previously the daemon used to create the network and start it, before this screen,
before the GUI even starts. If the user changed network settings, those would
be set on the already running network, potentially including restarting the network.
Now it becomes the responsibility of the GUI to start the network, allowing this
first-start customisation to take place before starting the network at all.
The qt and the qml GUIs are adapted to make use of this. Kivy, and the other
prototype GUIs are not adapted and just start the network right away, as before.