joinmarket-clientserver
joinmarket-clientserver copied to clipboard
Announcement of fidelity bonds in public (ob-watcher)
This follows up from several reports on this repo and elsewhere of fidelity bonds not showing up or being announced or reannounced.
See #1032 #1234 for recent reports here (not identical, but similar).
I believe that one main issue behind this is as follows:
On startup, a maker will announce with a public message like:
!sw0reloffer 0 201671 496095825 0 0.000019
Notice here that there is no fidelity bond data published.
On seeing an !orderbook
pubmsg, a maker will respond with a private message like this:
!sw0reloffer 0 201671 496095825 0 0.000019!tbond <bunch of base64>
, which does include a !tbond
fidelity bond proof message.
The reason for this difference: the fidelity bond proof messages contain signatures over the two nicks involved in the conversation, i.e. the nicks of the maker and taker (this is obviously needed to prevent replay of messages; we don't want a third party to just reuse our fidelity bond!). As such, it intrinsically is not a public message.
In a normal taker workflow, this is fine. The sequence of events is:
- Taker sends
!orderbook
in public - All the makers respond with a privmsg like the second of the two examples, including a FB proof
- Taker verifies the proofs and uses them in choice algo
- Coinjoin negotiation starts with
!fill
privmsg from taker to chosen makers
But in other cases, not so much. For the ob-watcher.py
tool, this doesn't work over time: the ob-watcher starts just as above, and verifies proofs just as above, but as new maker bots arrive, they will only publish as per the first message above, with no FB proof (as explained, that's not possible), so the FB entry for the new bots is shown as 0/empty, even though the bot prints out Announcing fidelity bond
in the terminal as it starts up (a correct statement, in the sense that when takers arrive and start up it will announce to them; it just hasn't announced yet).
I am going to add more analysis to this over time.
I can reproduce the behaviour (which as explained above, is expected), as follows: on regtest with 3 makers running before starting ob-watcher, I start a new maker with a FB. On refreshing the orderbook page, it correctly shows me the new bot's offer, but with 0 FB. Then if I click check for timed out counterparties
, the ob-watcher
script publishes a new !orderbook
and after that, my FB's value is correctly shown.
I am currently of the following opinion about this rather slippery topic:
- Tell users to click
Check for timed out counterparties
on their local ob-watcher instance. If they are accessing a public one, where this has been disabled, the host has probably configured it to reissue this request periodically, so the FB might show up over time, but better to just run it locally (note, nowadays it doesn't require Bitcoin Core! So it can be run kind of anywhere). - The above is a suboptimal solution; we don't want to be endlessly broadcasting
!orderbook
requests if we can avoid it. The solution might be to have the maker bot publish!sw0reloffer <stuff>!tbondclaim <amount> <timelock>
. Note that the offer itself is already only a claim in public, it's only in private that it gets validated with utxos and signatures after podle etc.; the orderbook that's public can be a lie, so it'd be fine to have publically claimed rather than validated FBs; we'd still follow the same procedure as above to prove before choosing. Note that this would be backwards compatible as old bots will ignore commands of a type they don't recognize. Still, it's a bit of work. - I can already see at least 1 other issue that's tangentially related to this about the OB not being always accurate in certain important ways. I will try to address that in separate Issues/PRs.
To address some other scenarios:
- tumbler - it's fine I believe, just like any taker scenario, we send out
!orderbook
before any attempt to negotiate a coinjoin, so we get fresh FB info at that step, for every join. - What about when a maker reannounces their offer, after a join? It's no different - the public info currently does not add or alter the existing DB info about FBs for that maker, because again, this data is only ever conveyed in privmsg. But as per previous bullet point, this doesn't lead to incorrect info for takers.
Came here to report this issue, did my duty and searched first, can confirm 1) solves the issue without restarting the whole obwatcher