Commit Graph

261 Commits (818147a6298a1376d8df91b8cc684a1a3fc4ee30)

Author SHA1 Message Date
Daniel Karzel 818147a629
`swap_setup` instead of `spot_price` and `execution_setup`
Having `spot_price` and `execution_setup` as separate protocols did not bring any advantages, but was problematic because we had to ensure that `execution_setup` would be triggered after `spot_price`. Because of this dependency it is better to combine the protocols into one.

Combining the protocols also allows a refactoring to get rid of the `libp2p-async-await` dependency.

Alice always listens for the `swap_setup` protocol. When Bob opens a substream on that protocol the spot price is communicated, and then all execution setup messages (swap-id and signature exchange).
3 years ago
Thomas Eizinger 90deb6451c
Rename swarm constructors to be per tool instead of per role 3 years ago
Daniel Karzel af60d3bb54
Network check upon spot price request 3 years ago
Philipp Hoenisch 1706b36800
Log exchange rate at each state. 3 years ago
Daniel Karzel 652aae9590
Introduce a minimum buy amount
Introduces a minimum buy Bitcoin amount similar to the maximum amount already present.
For the CLI the minimum amount is enforced by waiting until at least the minimum is available as max-giveable amount.
3 years ago
Daniel Karzel daa572e5bf
Move recovery commands in dedicated module
Less clutter in the folder structure.
3 years ago
Daniel Karzel 4deb96a3c5
ASB manual recovery commands
Adds `cancel`, `refund`, `punish`, `redeem` and `safely-abort` commands to the ASB that can be used to trigger the specific scenario for the swap by ID.
3 years ago
Daniel Karzel 0c616c7437
Move loading the state into the function
In the production code it is a weird indirection that we load the state and then pass in the state and the database.
In the tests we have one additional load by doing it inside the command, but loading from the db is not expensive.
3 years ago
Daniel Karzel 52f648e1de
Alice's spot price logic into dedicated behaviour
Move Alice's spot price logic into a dedicated network behaviour that handles all the logic.
The new behaviour encapsulates the complete state necessary for spot price request decision making.
The network behaviour cannot handle asynchronous calls, thus the balance is managed inside the spot price and has to updated regularly from the outside to ensure the spot price balance check has up to date data.
At the moment the balance is updated upon an incoming quote requests.

Code that is relevant for both ASB and CLI remains in the `network::spot_price` module (e.g. `network::spot_price::Error`).
3 years ago
Daniel Karzel f6497778ed
Add resume-only mode for the ASB
Resume-only is a maintenance mode where no swaps are accepted but unfinished swaps are resumed.
This is achieve by ignoring incoming spot-price requests (that would lead to execution setup) in the event-loop.
3 years ago
Philipp Hoenisch dc8dd5af28
Add relative and absolute max transaction fee. 3 years ago
Philipp Hoenisch dc6ab0fa52
Ensure that constant weights do not go out of sync with code. 3 years ago
Philipp Hoenisch 9e8b788aa9
Rename weight constants. 3 years ago
Philipp Hoenisch ee90c228b4
Dynamically calculate fees using electrum's estimate_fee.
Electrum has an estimate-fee feature which takes as input the block you want a tx to be included.
The result is a recommendation of BTC/vbyte.
Using this recommendation and the knowledge about the size of our transactions we compute an appropriate fee.
The size of the transactions were taken from real transactions as published on bitcoin testnet.
Note: in reality these sizes might fluctuate a bit but not for much.
3 years ago
Philipp Hoenisch 38540b4de5
Dynamically chose fee for TxCancel.
Bob chooses the fee for TxCancel because he is the one that cares.
3 years ago
Philipp Hoenisch 1012e39527
Dynamically chose fee for TxRefund and TxPunish.
Alice chooses the fee for TxPunish because she is the one that cares.
Bob chooses the fee for TxRefund because he is the one that cares.

Note must be taken here because if the fee is too low (e.g. < min tx fee) then she might not be able to publish TxRedeem at all.
3 years ago
Philipp Hoenisch d5c1b6693e
Dynamically chose fee for TxRedeem.
Alice chooses the fee for TxRedeem because she is the one that cares. Note must be taken here because if the fee is too low (e.g. < min tx fee) then she might not be able to publish TxRedeem at all.
3 years ago
Philipp Hoenisch 002e7b38c3
Define TX_FEE within test files only. 3 years ago
Philipp Hoenisch 632293cf91
Add support for swapping through Tor.
This PR does a few things.
* It adds a TorTransport which either dials through Tor's socks5 proxy or via clearnet.
* It enables ASB to register hidden services for each network it is listening on. We assume that we only care about different ports and re-use the same onion-address for all of them. The ASB requires to have access to Tor's control port.
* It adds support to dial through a local Tor socks5 proxy. We assume that Tor is always available on localhost.  Swap cli only requires Tor to be running so that it can send messages via Tor's socks5 proxy.
* It adds a new e2e test which swaps through Tor. For this we assume that Tor is currently running on localhost. All other tests are running via clear net.
3 years ago
Thomas Eizinger 8d76607343
Refactor monero-harness containers
1. Split up image::Monero into Monerod and MoneroWalletRpc
2. Don't use `bash` to run the internal command. Instead we disable
the entrypoint script as per https://github.com/XMRto/monero#raw-commands
3. Remove the start up delay by listening for the correct log message.
To make this more resilient, we make the log level NOT configurable and
instead always log verbosely.
3 years ago
Thomas Eizinger 0970c2bc72
Initialize reqwest clients with verbose logging 3 years ago
Thomas Eizinger dc840e1562
Take wallet names by reference
We are always passing constants here. Make that more ergonomic.
3 years ago
Thomas Eizinger 22bdc08c83
Get rid of Bob's swap Builder
Doesn't serve any purpose. We are better of just having two
constructors.
3 years ago
Thomas Eizinger e266fb07ef
Don't stutter 3 years ago
Thomas Eizinger a31d6febca
We don't need to import ourselves 3 years ago
Thomas Eizinger 881913ad9c
Re-order content of harness/mod.rs in a sane way
Most important things come first, remaining items are defined roughly
in the order they are used by the top level components.
3 years ago
dependabot[bot] 19483c5ead
Bump libp2p from 0.36.0 to 0.37.1
Bumps [libp2p](https://github.com/libp2p/rust-libp2p) from 0.36.0 to 0.37.1.
- [Release notes](https://github.com/libp2p/rust-libp2p/releases)
- [Changelog](https://github.com/libp2p/rust-libp2p/blob/master/CHANGELOG.md)
- [Commits](https://github.com/libp2p/rust-libp2p/compare/v0.36.0...v0.37.1)

Signed-off-by: dependabot[bot] <support@github.com>
3 years ago
Thomas Eizinger f0f7288bb6
Introduce a `redial::Behaviour`
This behaviour makes Bob re-dial Alice with an exponential backoff as
soon as the connection is lost.
3 years ago
Thomas Eizinger d4c10a1292
Introduce swarm::{alice,bob} function to construct a Swarm instance 3 years ago
Daniel Karzel c976358c37
Multiple swaps with the same peer
- Swap-id is exchanged during execution setup. CLI (Bob) sends the swap-id to be used in his first message.
- Transfer poof and encryption signature messages include the swap-id so it can be properly associated with the correct swap.
- ASB: Encryption signatures are associated with swaps by swap-id, not peer-id.
- ASB: Transfer proofs are still associated to peer-ids (because they have to be sent to the respective peer), but the ASB can buffer multiple
- CLI: Incoming transfer proofs are checked for matching swap-id. If a transfer proof with a different swap-id than the current executing swap is received it will be ignored. We can change this to saving into the database.

Includes concurrent swap tests with the same Bob.

- One test that pauses and starts an additional swap after the transfer proof was received. Results in both swaps being redeemed after resuming the first swap.
- One test that pauses and starts an additional swap before the transfer proof is sent (just after BTC locked). Results in the second swap redeeming and the first swap being refunded (because the transfer proof on Bob's side is lost). Once we store transfer proofs that we receive during executing a different swap into the database both swaps should redeem.

Note that the monero harness was adapted to allow creating wallets with multiple outputs, which is needed for Alice.
3 years ago
Daniel Karzel 46f144ac67
Switch monero-rpc to debug in tests
To be able to see CI monero RPC errors.
3 years ago
Thomas Eizinger 3e0301a9d4
Move `FixedRate` into event_loop module
This is where these types are used, they can be defined in there.
3 years ago
Daniel Karzel 084fc618b4 Test Alice refunds if restarted and Bob refunded 3 years ago
Daniel Karzel 2135a6e53e
Alice resumes swaps 3 years ago
Daniel Karzel b6e4fb4f9d
Improve comment 3 years ago
Daniel Karzel 183e8f02de
Wait for lock tx and send transfer proof in separate state
Sending the transfer transaction in a distinct state helps ensuring
that we do not send the Monero lock transaction twice in a restart
scenario.
Waiting for the first transaction confirmation in a separate state
helps ensuring that we send the transfer proof in a restart scenario.
3 years ago
Daniel Karzel dfd69c9c80
Alice aborts if any timelock expired before locking XMR
Once we resume unfinished swaps upon startup we have to ensure that
it is safe for Alice to act.
If Bob has locked BTC it is only make sense for Alice to lock up the
XMR as long as no timelock has expired. Hence we abort if the BTC is
locked, but any timelock expired already.
3 years ago
Thomas Eizinger b9d8cbeaa2
Rename testutils to harness
This allows us to bring in a dependency named `testutils`.
3 years ago
Thomas Eizinger 01739eddb1
Introduce a more flexible transaction subscription system
Instead of watching for status changes directly on bitcoin::Wallet,
we return a Subscription object back to the caller. This subscription
object can be re-used multiple times.

Among other things, this now allows callers of `broadcast` to decide
on what to wait for given the returned Subscription object.

The new API is also more concise which allows us to remove some of
the functions on the actor states in favor of simple inline calls.

Co-authored-by: rishflab <rishflab@hotmail.com>
3 years ago
Thomas Eizinger 0a82ce989b
Improve resilience of balance assertions
Sometimes, a single sync is not enough because we are still waiting
for the block to be mined.

We introduce an abstraction that loops on fetching the latest balance
with a certain timeout for asserting the balance.
3 years ago
Thomas Eizinger a4c70dfe94
Don't call as_ref() unless necessary 3 years ago
Thomas Eizinger 4ab7e83806
Make use of `cargo test`s scoped test output
By using `test_writer`, cargo can automatically scope the output
of the test to the relevant thread and will also only output it
if the test fails or is run with `--nocapture`.
3 years ago
Thomas Eizinger 908dae3442
Inline tracing initialization
This code snippet is so short, it might as well be inlined to give
the test more control over what it wants to log.
3 years ago
Thomas Eizinger c01cccb288
Use `tracing-log` feature flag instead of manual initialization
This also formats `log` events more nicely. Instead of

```
Mar 29 09:46:16.775  INFO log: Found message after comparing 82 lines log.target="testcontainers::core::wait_for_message" log.module_path="testcontainers::core::wait_for_message" log.file="/home/thomas/.cargo/registry/src/github.com-1ecc6299db9ec823/testcontainers-0.12.0/src/core/wait_for_message.rs" log.line=35
```

We now have

```
Mar 29 09:57:15.860  INFO testcontainers::core::wait_for_message: Found message after comparing 81 lines
```
3 years ago
Thomas Eizinger 638a169a04
Buffer transfer proof if we are not connected to Bob
The request-response behaviour that is used for sending the transfer
proof actually has a functionality for buffering a message if we
are currently not connected. However, the request-response behaviour
also emits a dial attempt and **drops** all buffered messages if this
dial attempt fails. For us, the dial attempt will very likely always
fail because Bob is very likely behind NAT and we have to wait for
him to reconnect to us.

To mitigate this, we build our own buffer within the EventLoop and
send transfer proofs as soon as we are connected again.

Resolves #348.
3 years ago
Thomas Eizinger cde3f0f74a
Remove connection handling from swap execution
The swap should not be concerned with connection handling. This is
the responsibility of the overall application.

All but the execution-setup NetworkBehaviour are `request-response`
behaviours. These have built-in functionality to automatically emit
a dial attempt in case we are not connected at the time we want to
send a message. We remove all of the manual dialling code from the
swap in favor of this behaviour.

Additionally, we make sure to establish a connection as soon as the
EventLoop gets started. In case we ever loose the connection to Alice,
we try to re-establish it.
3 years ago
Thomas Eizinger 2200fce3f3
Pass Swarm into EventLoop
This reduces the amount of arguments we need to pass into the eventloop
at the expense of slightly more setup of the swarm.
3 years ago
Thomas Eizinger 73f30320a6
Seed should neither be Clone nor Copy
It is better to not copy around secret data within our process to
make heartbleed-like attacks harder.
3 years ago
Daniel Karzel 396c4177a6 Alice sweeps refunded funds into default wallet
Since Alice's refund scenario starts with generating the temporary wallet
from keys to claim the XMR which results in Alice' unloading the wallet.
Alice then loads her original wallet to be able to handle more swaps.
Since Alice is in the role of the long running daemon handling concurrent
swaps, the operation to close, claim and re-open her default wallet must
be atomic.
This PR adds an additional step, that sweeps all the refunded XMR back into
the default wallet. In order to ensure that this is possible, Alice has to
ensure that the locked XMR got enough confirmations.
These changes allow us to assert Alice's balance after refunding.
3 years ago
Thomas Eizinger 09c41f89c4
Rename ExecutionParams to EnvironmentConfig 3 years ago