In this commit, in order to make accounting for account
modification/creation transactions a bit easier, we'll now always add a
label describing the transaction within the account manager. The user is
also able to set their own prefix to the label as well to allow
insertion of custom meta data.
In case the auctioneer is offline or restarting during the initial boot
up of the trader server, we get a hard failure directly if we try to
query the terms when the server connection isn't ready yet. This isn't
really nice as we'd never come into the auto-retry of the account
subscription that way.
To optimize this, we only query the terms when we actually need them.
This makes it possible for confirmed, open accounts to go into the
subscription connection re-try logic. We'd only hard fail on startup if
there are any pending accounts and the auctioneer is offline exactly
during the trader boot up.
We introduce two distinct ways traders can express their closing
transaction fees: a single address/output script along with a fee rate,
or a list of outputs (script and value) which implicitly expresses the
transaction fees. This provides traders with greater coin control
flexibility, allowing them to directly send their account funds to their
desired destinations efficiently without needing multiple transactions.
This commit allows the account manager to handle the situation where
an account participates in multiple consecutive batches that might still
be in the mempool. Once the first batch confirms, the database state of
the account might differ from the batch key used in that earlier batch.
We need to cancel old spend and conf watches and only watch the latest
batch for confirmation. While an account is in this pending batch state, no
user modification like deposits or withdrawals are allowed so it's safe
to just jump to the latest batch and wait for confirmations on that one.
To track whether or not an account was recently involved in one or more
batches, we need to add a new pending state. This pending state is
different from the normal pending update from a balance modification as
the auctioneer allows an account in this state to participate in a
batch. A scenario is possible where an account was involved in two or
more consecutive batches that both aren't confirmed on chain yet. To
handle that special case we need to also track the special account state
on the trader side.
In the future we might want to have the possibility to add additional
fields to a database object (like orders or accounts) without the need
for a migration. We add the code for that already, even if it's not
being used currently.
To make sure we don't run into an error when actually sending the
desired amount to an account output, we invoke lnd's fee estimation RPC
to make sure we can construct a transaction that also respects the new
fee parameter.
If we encounter an account in the state initiated when performing the
account recovery, we certainly don't want to send funds to it again. If
lnd finds the transaction that funded the account, great. We can try to
recover it. If the transaction isn't found, it is very likely that it
was never broadcast. We update the account's state to
StateRecoveryFailed in that case.
Most of the code is heavily borrowed from the chanfunding package in
lnd, except for some minor changes to account for the difference in
weights. Ideally, that package is refactored and abstracted such that it
doesn't only apply for channel funding.
The account subscription doesn't need access to the full account,
only its key descriptor. This is a preparation for the account
recovery where we want to subscribe to the auctioneer but don't have
the full account anymore.
This commit introduces support for trader account withdrawals to
arbitrary outputs. Traders are able to withdraw their accounts through
either spending paths, multi-sig or expiry, with the latter requiring a
new expiration (to be done as a follow-up). When spending through the
multi-sig path, traders submit their outputs to the auctioneer,
excluding the new account output as that can be reconstructed by the
auctioneer. The auctioneer then creates a transaction adhering to the
trader's constraints and provides a signature back.
This is essential as otherwise if the trader has an unexpected shutdown
between receiving the auctioneer's signature and committing the
modifications to disk, then there would be no context of said
modifications from the PoV of the trader after a restart.
While the method is yet to be used, this lays down the groundwork for
allowing account modifications in which we're required to recreate the
account output.
This commit aims to address a current gap within the system where trader
account states can become desynchronized if they participated in a batch
and they never received a Finalize message from the auctioneer.
From now on, if an account spend arrives while a trader has a pending
batch, then we assume they weren't able to receive its Finalize message,
and use the spend as an indication that the batch has been finalized.
This works because if a trader signs for a batch and disconnects, the
batch should have already been persisted, and if the batch was actually
finalized (i.e., broadcast without any changes), then the account should
have been spent.