The wallet is an instance of a wallet that has a name.
When we use `CreateWalletForOutputThenReloadWallet` we actually unload the wallet.
It would be cleaner to create a new instance that does that swap, but I did not go that far.
Instead of instantiating the `EventLoop` within the builder, we only
pass in the necessary arguments (which is the `EventLoopHandle`) to
the Builder upon `new`.
This is work towards #255 which will require us to perform network
communication (which implies having the `EventLoop`) before starting
a swap.
If our expression directly evaluates to a future, we don't need to
create an async block.
This requires us to have `EventLoopRun::run` consume the instance
instead of just taking a mutable reference (otherwise we run into
lifetime issues). However, that is better anyway because `run` is
an endless loop so you never get to use the handle afterwards
anyway.
Previously we were ignoring if the monero wallet rpc was not found and
unpacked from archive leading to a failure down the line when trying to
run a non-existent executable. Bail when the executable is no found in
the archive.
1. We can generalize the signing interface by passing a PSBT in
instead of the `TxLock` transaction.
2. Knowing the transaction ID of a transaction that we are about
to sign is not very useful. Instead, it is much more useful to know
what failed. Hence we add a `.context` to the call of `sign_and_finalize`.
3. In case the signing succeeds, we will immediately broadcast it
afterwards. The new broadcasting interface will tell us that we broadcasted
the "lock" transaction.
We eliminate unnecessary layers of indirection for broadcasting logic
and force our callers to provide us with the `kind` of transaction
that we are publishing.
Eventually, we can replace this string with some type-system magic
we can derive the name from the actual transaction. For now, we just
require the caller to duplicate this information because it is faster
and good enough TM.
This struct is a wallet. The only thing it can meaningfully broadcast
are transactions. The fact that they have to be signed for that is
implied. You cannot broadcast unsigned transactions.
Abstracting over the individual bits of functionality of the wallet
does have its place, especially if one wants to keep a separation
of an abstract protocol library that other people can use with their
own wallets.
However, at the moment, the traits only cause unnecessary friction.
We can always add such abstraction layers again once we need them.
If the user doesn't pass `--debug`, we only show `INFO` logs but
without time and level to make it clearer that it is meant to be
read by the user.
Without `--debug`, the user sees:
Still got 0.00009235 BTC left in wallet, swapping ...
With `--debug`, they see:
2021-03-01 12:21:07 DEBUG Database and seed will be stored in /home/thomas/.local/share/xmr-btc-swap
2021-03-01 12:21:07 DEBUG Starting monero-wallet-rpc on port 40779
2021-03-01 12:21:11 INFO Still got 0.00009235 BTC left in wallet, swapping ...
2021-03-01 12:21:11 DEBUG Dialing alice at 12D3KooWCdMKjesXMJz1SiZ7HgotrxuqhQJbP5sgBm2BwP1cqThi
2021-03-01 12:21:12 DEBUG Requesting quote for 0.00008795 BTC
Previously, the time was formatted as ISO8601 timestamps which is
barely readable by humans. Activating the `chrono` feature allows
us to format with a different format string. The output now looks
like this:
2021-03-01 11:59:52 DEBUG Database and seed will be stored in /home/thomas/.local/share/xmr-btc-swap
2021-03-01 11:59:52 DEBUG Starting monero-wallet-rpc on port 40673
2021-03-01 11:59:59 DEBUG Still got 0.00009235 BTC left in wallet, swapping ...
2021-03-01 11:59:59 DEBUG Dialing alice at 12D3KooWCdMKjesXMJz1SiZ7HgotrxuqhQJbP5sgBm2BwP1cqThi
2021-03-01 11:59:59 DEBUG Requesting quote for 0.00008795 BTC
There is a double space after the time which is already fixed in
tracing-subscriber but not yet released.
See https://github.com/tokio-rs/tracing/issues/1271.
Log messages are ideally as close to the functionality they are talking about, otherwise we might end up repeating ourselves on several callsites or the log messages gets outdated if the behaviour changes.
These intermediate structs were creating unnecessary noise. The peer id
and multiaddr fields are going to be removed in the future further
reducing the need to have seperate structs for cancel, resume and
refund.
If communication with the other party fails the program should stop and the user should see the respective error.
Communication errors are handled in the event-loop. Upon a communication error the event loop is stopped.
Since the event loop is only stopped upon error the Result returned from the event loop is Infallible.
If one of the two futures, event loop and swap, finishes (success/failure) the other future should be stopped as well.
We use tokio::selec! to stop either future if the other stops.
Failure does not express what the error represents. It is only used for communication
errors for quote requests, receiving the XMR transfer proof and sending the encryption signature.
If the current balance is 0, we wait until the user deposits money
to the given address. After that, we simply swap the full balance.
Not only does this simplify the interface by removing a parameter,
but it also integrates the `deposit` command into the `buy-xmr`
command.
Syncing a wallet that is backed by electrum includes transactions
that are part of the mempool when computing the balance.
As such, waiting for a deposit is a very quick action because it
allows us to build our lock transaction on top of the yet to be
confirmed deposit transactions.
This patch introduces another function to the `bitcoin::Wallet` that
relies on the currently statically encoded fee rate. To make sure
future developers don't forget to adjust both, we extract a function
that "selects" a fee rate and return the constant from there.
Fixes#196.
These traits were only used once within the `TxLock` constructor.
Looking at the rest of the codebase, we don't really seem to follow
any abstractions here where the protocol shouldn't know about the
exact types that is being passed in.
As such, these types are just noise and might as well be removed in
favor of simplicity.
The only reason we need this argument is because we need to access
the output descriptor. We can save that one ahead of time at when
we construct the type.