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.
In this commit, we add the missing logic to register for funding shims
when we're the taker of an executed order, and also to establish new
channels after we send OrderMatchAccept when we're the maker of an
executed order.
As a temporary work around, we'll also add a full lnd client, as we'll
need to do things like connect to peers, register for funding shims, and
also open channels. In the future we'll catch up lndclient to add these
new methods so we can use mocks in our unit tests.
The mapping in this function ensures that a given bid/ask pair will have
a unique deterministic pending channel ID to use when registering
funding shims and also making channels.
This commit aims to address another gap within the system to ensure
trader pending batch states are as accurate as possible. In a previous
commit, we addressed the case of a trader signing for a batch,
disconnecting and not receiving a Finalize message, and seeing a spend
for an account.
Here, we're interested in determining whether a batch a trader signed
for is actually still relevant to the trader. Since any trader can bail
from a batch, the batch may need to be re-done by the auctioneer, and if
a trader that previously signed for a previous version of the batch
remains disconnected, then they won't be aware of said new batch. At
this point, the trader has a lingering pending batch that's no longer
irrelevant, so we remove it. This logic is tied to the connection
establishment between the trader and auctioneer to ensure we handle the
disconnection and crash case of a trader after signing for a batch.
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.
This RPC exposes batch snapshots to traders. This is useful when the
trader wants to receive information about a batch they've participated
in for the relevant accounts.
Alternatively, this RPC can also be used by traders as a recovery
mechanism to determine whether they've made it into a finalized batch by
comparing their known batch transaction with the auctioneer's. This will
be expanded on in a later commit.
When traders create channels as part of a batch, the auctioneer provides
a guarantee to punish any traders who violate the lifetime of a channel
(also known as their maturity height). In order for the auctioneer to
carry out this duty, it'll need to retrieve a set of channel keys from
each trader to detect, in the event of a lifetime violation, who the
responsible trader was. This channel info is retrieved by the traders
from their encrypted SCBs.
We need this method for further synchronization: once this is sent we
expect the traders to respond with signatures for each of the accounts
involved in the batch. The addition of this message also means that the
responder of the channel funding has time to register their shim (done
before they send their Accept message) as we don't send the
OrderSignBegin message until all traders have accepted the batch. The
initiator can now use receipt of the OrderSignBegin as a signal to
initiate the channel funding.
We also fix an existing oversight in the `OrderMatchSign`: it expected a
fully valid witness, but the only thing the traders can produce by
themselves is a signature for their input.
If trader A provides a signature for a batch, disconnects, and trader B,
who is also in the auction, bails, then the auctioneer will re-attempt
matchmaking. If trader A hasn't reconnected by and a successful batch is
made without them, then the updates would need to be rolled back.
Previously, since we would overwrite the main account and order state,
we'd lack information in order to do so. By staging the update under a
distinct bucket, we can now do so properly by simply removing the state
within it.
Previously, if the connection between the trader and auctioneer was torn
down before the trader received a batch's finalize message, then the
trader would lose all context about the batch they participated in.
Committing the batch before providing our signatures to the auctioneer
ensures that this cannot happen. Follow-up work will allow the trader to
obtain the latest information regarding a pending batch upon
reconnections.
This commits serves as preparatory work for committing a pending batch
before providing signatures to the auctioneer. This is achieved by first
storing the batch as pending upon receiving a new batch and marking it
as complete upon receiving a finalize message.
This is done in preparation for future work in which we'll allow custom
inputs and outputs to be provided when crafting the spending transaction
of an account.
Some of the test cases relied on a map's keys always being in the
order they were defined, which is not guaranteed by the runtime.
A data race is also fixed by creating a new instance of the verifier
for each run.