Commit Graph

1357 Commits

Author SHA1 Message Date
Daniel Karzel
7f8af7926d
ASB config may specify finality confirmations
By default the finality confirmations of the network's `env::Config` will be applied and no finality confirmations will be persisted on disk in the config file.
It is however possible to set finality confirmations in the config file for bitcoin and monero for power users at their own risk.
If set the defaults will be overwritten with the parameter from the config file upon startup.
2021-05-20 13:05:51 +10:00
Daniel Karzel
7ec323ea1f
Mainnet changelog entry 2021-05-20 13:03:33 +10:00
Daniel Karzel
af60d3bb54
Network check upon spot price request 2021-05-20 13:03:29 +10:00
Daniel Karzel
02974811ad
Activate mainnet for the ASB
To run the ASB on testnet, one actively has to provide the `--testnet` flag.
Mainnet and testnet data and config are separated into sub-folders, i.e. `{data/config-dir}/asb/testnet` and `{data-dir}/asb/mainnet`.
The initial setup is also per network. If (default) config for the network cannot be found the initial setup is triggered.
Startup includes network check to ensure the bitcoin/monero network in config file is the same as the one in the `env::Config`.

Note: Wallet initialization is done with the network set in the `env::Config`, the network saved in the config file is just to indicate what network the config file is for.
2021-05-20 12:58:39 +10:00
Daniel Karzel
9ac5b635d7
Introduce own de-/serializable monero::Network 2021-05-20 12:58:30 +10:00
Daniel Karzel
69cf12620d
Activate mainnet for the CLI
This includes testing CLI commandline args
Clap's `default_value_with` actually did not work on `Subcommand`s because the parent's flags were not picked up.
This was fixed by changing parameters dependent on testnet/mainnet to options.
This problem should have been detected by tests, that's why the command line parameter tests were finally (re-)added.

Thanks to @rishflab for some pre-work for this.
2021-05-20 12:57:58 +10:00
Daniel Karzel
1cdc23de32
Explicitly specify monero-wallet-rpc deamon port
In order to allow people to plug into public nodes / be more flexible with their own setup we now enforce specifying the monero daemon port to be used by the `monero-wallet-rpc`.
2021-05-14 09:50:52 +10:00
Daniel Karzel
343badbb4b
Remove duplication and cleanup
In the past we had problems with flags/parameter changes several times, where on instance was changed, buy another one was missed. This should mitigate this problem.
This patch introduces structs for all duplicated parameters and uses flatten to only have one point for changes.

Additionally removes all mentions of `alice` from the commands / variables. This code is on an application level and should not be concerned with swap protocol roles.
2021-05-14 09:50:50 +10:00
Daniel Karzel
4e1f3f82bd
Remove param from names
Did not add any value, more readable with just bitcoin and monero.
2021-05-14 09:50:49 +10:00
Daniel Karzel
657ac1e2e4
Bitcoin parameters that can be reused
Get rid of parameter duplication.
2021-05-14 09:50:47 +10:00
Daniel Karzel
a489564857
Remove unused Electrum HTTP default URL 2021-05-14 09:50:44 +10:00
bors[bot]
496ceab3cb
Merge #493
493: Add checks to max_giveable amount. r=da-kami a=bonomat

We need to check two things:
- balance to be higher than dust amount (546).
- balance to be higher than min-relay fee.

Additionally, the tx_builder might fail if not enough funds are in the wallet to pay for the overall transaction fees. In both cases, we return 0. 

fixes #487 

Co-authored-by: Philipp Hoenisch <philipp@hoenisch.at>
2021-05-13 22:54:53 +00:00
Philipp Hoenisch
493545d07f
Improve logging for Swap Cli. 2021-05-12 16:31:32 +10:00
Philipp Hoenisch
4f45a26a83
Move check for max_giveable into the function. 2021-05-12 16:31:32 +10:00
Philipp Hoenisch
7fc5a47619
Add checks to max_giveable amount.
We need to check two things:
- balance to be higher than dust amount (546).
- balance to be higher than min-relay fee.

Additionally, the tx_builder might fail if not enough funds are in the wallet to pay for the overall transaction fees.
2021-05-12 16:31:32 +10:00
bors[bot]
6bc21a9318
Merge #476 #477
476: Bump dprint/check from v1.3 to v1.4 r=thomaseizinger a=dependabot[bot]

Bumps [dprint/check](https://github.com/dprint/check) from v1.3 to v1.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/dprint/check/releases">dprint/check's releases</a>.</em></p>
<blockquote>
<h2>v1.4</h2>
<p>Upgrade to dprint 0.13.1</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="a3ed4347fe"><code>a3ed434</code></a> fix: Update to dprint 0.13.1</li>
<li>See full diff in <a href="https://github.com/dprint/check/compare/v1.3...a3ed4347fef5b3b2bf68cc38b44885d9df913253">compare view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

477: Bump sha2 from 0.9.3 to 0.9.4 r=thomaseizinger a=dependabot[bot]

Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.9.3 to 0.9.4.
<details>
<summary>Commits</summary>
<ul>
<li><a href="c1ed4b1cbc"><code>c1ed4b1</code></a> sha2 v0.9.4 (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/265">#265</a>)</li>
<li><a href="1bf768865d"><code>1bf7688</code></a> sha-1 v0.9.5 (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/264">#264</a>)</li>
<li><a href="bf761edb53"><code>bf761ed</code></a> sha1+sha2: switch from <code>cpuid-bool</code> to <code>cpufeatures</code> (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/263">#263</a>)</li>
<li><a href="1e775edda2"><code>1e775ed</code></a> sha2: bump <code>sha2-asm</code> to v0.6.1 release (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/262">#262</a>)</li>
<li><a href="e8b3abe442"><code>e8b3abe</code></a> feat(sha2): use latest sha2-asm and enable M1 (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/261">#261</a>)</li>
<li><a href="ee361ed25f"><code>ee361ed</code></a> build(deps): bump libc from 0.2.88 to 0.2.93 (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/254">#254</a>)</li>
<li><a href="0bf77b52b1"><code>0bf77b5</code></a> build(deps): bump byteorder from 1.4.2 to 1.4.3 (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/245">#245</a>)</li>
<li><a href="dd9086ad8c"><code>dd9086a</code></a> sha1: add multiplatform tests (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/252">#252</a>)</li>
<li><a href="1c1182c8b8"><code>1c1182c</code></a> rustfmt (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/253">#253</a>)</li>
<li><a href="ad19dffcbe"><code>ad19dff</code></a> build(deps): bump libc from 0.2.86 to 0.2.88 (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/244">#244</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/RustCrypto/hashes/compare/sha2-v0.9.3...sha2-v0.9.4">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=sha2&package-manager=cargo&previous-version=0.9.3&new-version=0.9.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-11 22:11:21 +00:00
bors[bot]
a948ccb51b
Merge #483
483: Bump url from 2.2.1 to 2.2.2 r=thomaseizinger a=dependabot[bot]

Bumps [url](https://github.com/servo/rust-url) from 2.2.1 to 2.2.2.
<details>
<summary>Commits</summary>
<ul>
<li><a href="6c22912c31"><code>6c22912</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/servo/rust-url/issues/709">#709</a> from BramBonne/bump-version</li>
<li><a href="0707a58b91"><code>0707a58</code></a> Bump minor version number</li>
<li><a href="991e438ff1"><code>991e438</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/servo/rust-url/issues/708">#708</a> from BramBonne/test-syntax-violations</li>
<li><a href="744b76332c"><code>744b763</code></a> Remove stray comma</li>
<li><a href="5793b7ef14"><code>5793b7e</code></a> Check parsing result in SyntaxViolation test</li>
<li><a href="0659871a26"><code>0659871</code></a> Add tests for SyntaxViolation callback types</li>
<li><a href="c6f60fe5ff"><code>c6f60fe</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/servo/rust-url/issues/668">#668</a> from sdroege/make-relative</li>
<li><a href="d51cec4803"><code>d51cec4</code></a> Add Url::make_relative() as the inverse of Url::join()</li>
<li><a href="77fb472619"><code>77fb472</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/servo/rust-url/issues/703">#703</a> from BramBonne/slicing-tests</li>
<li><a href="ea2342e182"><code>ea2342e</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/servo/rust-url/issues/705">#705</a> from BramBonne/test-quirks</li>
<li>Additional commits viewable in <a href="https://github.com/servo/rust-url/compare/v2.2.1...v2.2.2">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=url&package-manager=cargo&previous-version=2.2.1&new-version=2.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-11 21:52:35 +00:00
dependabot[bot]
2c31536311
Bump url from 2.2.1 to 2.2.2
Bumps [url](https://github.com/servo/rust-url) from 2.2.1 to 2.2.2.
- [Release notes](https://github.com/servo/rust-url/releases)
- [Commits](https://github.com/servo/rust-url/compare/v2.2.1...v2.2.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-11 06:49:11 +00:00
bors[bot]
f03e8fa5af
Merge #474
474: Add more log details r=bonomat a=bonomat

Resolves #448 

1. The first commit adds an additional log statement of the exchange rate for each state-update. This is useful because it allows us to measure profitability easily, i.e. by knowing what was the exchange rate when the swap was started and what was it when it was finalized.
2. The second commit changes a bunch of log messages. 
3. The third commit is adds a new commandline flag to toggle json format.




Co-authored-by: Philipp Hoenisch <philipp@hoenisch.at>
Co-authored-by: Philipp Hoenisch <philipp@coblox.tech>
2021-05-11 06:31:32 +00:00
Philipp Hoenisch
26e0383e17
Apply suggestions from code review
Co-authored-by: Daniel Karzel <daniel.karzel@coblox.tech>
2021-05-11 16:06:44 +10:00
Philipp Hoenisch
fc0cceb180
Toggle json logs using commandline flag. 2021-05-11 15:28:25 +10:00
Philipp Hoenisch
316f95c65b
Always log whole causality chain for errors. 2021-05-11 15:27:53 +10:00
Philipp Hoenisch
c011e95062
Improve logging by adding details as fields instead of into the msg. 2021-05-11 15:27:53 +10:00
Philipp Hoenisch
1706b36800
Log exchange rate at each state. 2021-05-11 15:27:49 +10:00
bors[bot]
227c383d76
Merge #481
481: Min buy amount r=da-kami a=da-kami



Co-authored-by: Daniel Karzel <daniel@comit.network>
2021-05-11 04:08:59 +00:00
bors[bot]
af2938a39a
Merge #485
485: Update assert_weight test to account for a range up to 8 bytes. r=bonomat a=bonomat

Fixes #482 

Weights fluctuate because of the length of the signatures. Valid ecdsa signatures can have 68, 69, 70, 71, or 72 bytes. Since most of our transactions have 2 signatures the weight can be up to 8 bytes less than the static weight (4 bytes per signature). 
Since it is really hard to get these short signatures (<1 in 100), I also include the transaction in the assert message which will help for debugging purposes. 

Source: https://medium.com/coinmonks/on-bitcoin-transaction-sizes-97e31bc9d816

Co-authored-by: Philipp Hoenisch <philipp@hoenisch.at>
2021-05-11 02:56:30 +00:00
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.
2021-05-11 12:03:02 +10:00
Daniel Karzel
6d3cf0af91
Include too low balance into Alice's error 2021-05-11 12:03:02 +10:00
Daniel Karzel
1d62f4916c
Move max_buy and ask_spread into config
Max-buy and spread is not something that one would configure on every run.
More convenient to keep this in the config.

The max-buy Bitcoin value was adapted to `0.02` which is more reasonable for mainnet.
Activated feature `serde-float` to serialize the spread (Decimal) as float instead of string.

```
...

[maker]
max_buy_btc = 0.02
ask_spread = 0.02
```
2021-05-11 12:02:57 +10:00
Philipp Hoenisch
330269a1e9
Update assert_weight test to account for a range up to 8 bytes.
Weights fluctuate because of the length of the signatures. Valid ecdsa signatures can have 68, 69, 70, 71, or 72 bytes. Since most of our transactions have 2 signatures the weight can be up to 8 bytes less than the static weight (4 bytes per signature).
2021-05-11 10:50:24 +10:00
Daniel Karzel
538b25a6dd
Only create config-directory on init success
We should only create the file if the user finished the initial setup correctly.
2021-05-11 10:32:25 +10:00
bors[bot]
d96e20a5b0
Merge #479
479: Use rust_decimal in estimate_fee function. r=bonomat a=bonomat

Follow-up PR from #466 

Co-authored-by: Philipp Hoenisch <philipp@hoenisch.at>
2021-05-10 23:00:12 +00:00
Philipp Hoenisch
b5073e3052
Use rust_decimal in estimate_fee function. 2021-05-10 10:53:43 +10:00
bors[bot]
86bcef8eba
Merge #452
452: Asb manual recovery commands r=da-kami a=da-kami

Fixes #377 

Allows us to manually finish swaps if we run into error scenarios during execution.

I opted for putting all these commands under subcommand `manual-recovery` to run them e.g. (cancel):

```
./asb manual-recovery cancel [--force] --swap-id (...)
```

I combined the `cancel` and `refund` command in the same commit, because I only adapted the e2e tests once cancel and refund were implemented (cancel alone is a bit useless anyway...).

Co-authored-by: Daniel Karzel <daniel@comit.network>
2021-05-10 00:09:59 +00:00
Daniel Karzel
23d9637a4b
Work in review comments 2021-05-07 16:21:02 +10:00
Daniel Karzel
daa572e5bf
Move recovery commands in dedicated module
Less clutter in the folder structure.
2021-05-07 16:21:02 +10:00
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.
2021-05-07 16:19:11 +10:00
Daniel Karzel
efcd39eeef
Add info messages to each subcommand
`asb --help` :

(...)

SUBCOMMANDS:
    balance         Prints the Bitcoin and Monero balance. Requires the monero-wallet-rpc to be running.
    help            Prints this message or the help of the given subcommand(s)
    history         Prints swap-id and the state of each swap ever made.
    start           Main command to run the ASB.
    withdraw-btc    Allows withdrawing BTC from the internal Bitcoin wallet.
2021-05-07 16:12:50 +10:00
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.
2021-05-07 16:12:49 +10:00
bors[bot]
095d67f946
Merge #461
461: Add resume-only mode for the ASB r=da-kami a=da-kami

Fixes #378 

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.

- [x] Refactor `spot_price`, move Alice's decision logic into dedicated `NetworkBehaviour`
- [x] Protocol (network) level tests for the `spot_price` behaviour

Co-authored-by: Daniel Karzel <daniel@comit.network>
2021-05-07 05:13:18 +00:00
Daniel Karzel
89b3d07eba
Network protocol tests for spot_price behaviour
Each test spawns swarm for Alice and Bob that only contains the spot_price behaviours and uses a memory transport.
Tests cover happy path (i.e. expected price is returned) and error scenarios.
Implementation of `TestRate` on `LatestRate` allows testing rate fetch error and quote calculation error behaviour.

Thanks to @thomaseizinger for ramping up the test framework for comit-rs in the past!
2021-05-07 15:00:29 +10:00
Daniel Karzel
03a0dc73cd
Alice's spot_price Behaviour reports back Error
Instead of handling all errors on the inside spot_price errors are bubbled up (as `SwapRequestDeclined`).
This allows us to test both Alice's and Bob's behaviour for all scenarios.
2021-05-07 15:00:29 +10:00
Daniel Karzel
5aac76598d
Decouple ASB/CLI Errors from Error sent over wire
What goes over the wire should not be coupled to the errors being printed.
For the CLI and ASB we introduce a separate error enum that is used for logging.
When sending over the wire the errors are mapped to and from the `network::spot_price::Error`.

As part of Bob-specific spot_price code was moved from the network into bob.
Clearly separation of the network API from bob/alice.
2021-05-07 15:00:29 +10:00
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`).
2021-05-07 15:00:29 +10:00
Daniel Karzel
ea76ae5821
Return proper error to CLI for all expected scenarios
When a CLI requests a spot price have some errors that are expected, where we can provide a proper error message for the CLI:
- Balance of ASB too low
- Buy amount sent by CLI exceeds maximum buy amount accepted by ASB
- ASB is running in maintenance mode and does not accept incoming swap requests

All of these errors returns a proper error to the CLI and prints a warning in the ASB logs.
Any other unexpected error will result in closing the channel with the CLI and printing an error in the ASB logs.
2021-05-07 14:52:51 +10:00
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.
2021-05-07 14:52:51 +10:00
bors[bot]
08d7d587cf
Merge #466
466: Add support to dynamically chose bitcoin transaction fees.  r=bonomat a=bonomat

Resolves #443 (Bitcoin only). 

@da-kami  /@thomaseizinger: do you know how fees work in Monero? 
If not, I'll read up on it and to come up with a proper strategy. 

Monero Fees will be covered in #470

Note: 
The there is a hardcoded relative and absolute upper bound. I personally feel safer if this is hardcoded for now as it is too easy to get wrong. 
At the time of writing, this equals roughly USD $56. 
Eventually we will want to make this also configurable.


Co-authored-by: Philipp Hoenisch <philipp@hoenisch.at>
Co-authored-by: Philipp Hoenisch <philipp@coblox.tech>
2021-05-07 00:35:49 +00:00
Philipp Hoenisch
0090e3b48e
Typo 2021-05-07 10:35:22 +10:00
Philipp Hoenisch
59a55dcbdd
Remove todo for cleanup note. 2021-05-07 10:24:41 +10:00
Philipp Hoenisch
e93eeb81a2
Added some proptests. 2021-05-07 10:24:41 +10:00