The world moves forward. Joinmarket has been in operation for many years, and while a ton of work has gone into let's say the "bottom" and the "top" of the application ("bottom" example: complete refactoring of bitcoin libraries such as that in this PR, "top" example: a ton of work making a functioning Qt app for Takers and all basic features like coin control), and extra tools around the basic coinjoin primitive (coin control, payjoin etc etc), the central mechanisms have not really changed since late 2016.

So obviously this raises the question of what we could and should change in those core mechanisms. I'm going to assume:

  • we just wipe the slate clean and any change is on the table
  • no limitation in developer/time resources.

The awards ceremony

So here is a list of some changes presented as a "award for best .." in each case, including links to relevant discussion or background information.

Opinions expressed here are my own! (not boilerplate language - here it really means something, as it's only currently what I think ... we might work as a project on having a collaborative design document where we debate these points and come to some kind of conclusion). I'm sure others would have quite different lists ...

  • Best network messaging layer or "bulletin board": onions in p2p configuration

I think this is the most difficult and the most important question on how we upgrade the system, and my choice of "winner" is kinda "out-there", and, even more, it lacks detail (how exactly do we set this up? We already have code set up for every bot to start an onion service; and it's already being used, for payjoin receiving. But that's just the start!).

The first thing to note here is that an extensive discussion around the topic was started by contributor undeath in this issue some time ago. That lays out a significantly ambitious architectural plan; it might be the way to go, but I'm not really sure.

We want relatively low latency with anonymity; Tor satisfies this within reason, but the biggest difficulty is to get reasonable reliability and some reasonable censorship resistance.

If we feel that this is not quite reliable enough, not quite low enough latency, or not quite censorship resistant enough, we can go back to a bulletin board style server, but it needs to not have the strong aversion to bursts of traffic (and they will get really quite large in case JM scales to several thousand users instead of several hundred), and we would need to somehow continue to address the censorship problem with the kind of redundancy we currently have, except preferably way better than just a couple of IRC servers (or 3 if you're lucky). Also whichever model we choose, we always have the inherent tension that the market element of Joinmarket is intrinsically public, even if everything else is "E2E-encrypted-dark".

  • Best coinjoin negotiation mechanism: ...

I feel like there are two sensible options here:

(1) Coinshuffle++ may well be the right tool here. It has some overhead in terms of 4 rounds of communication (which interplays with the above), and some extra number crunching, but it gets us the very clean no-central-coordinator feature. (2) It is not crazy to stick with our existing negotiation mechanism; it is set up to allow a market to decide the value of being the coordinator yourself. This is a fairly unique feature.

  • Best coinjoin construction type: CoinJoinXT

Before getting into this, it's worth mentioning there is a huge list of ideas about this topic, i.e. "how to best configure a coinjoin transaction system". So this is definitely not a "settled issue"!

CJXT is described in detail here, also see video presentation from Lisbon 2018 here .

Of course it may be just my bias; but my strong sense is that within the realm of Coinjoin specifically, this is the best model, because it can be and will be (see next point) very nearly perfectly steganographic, without trading off large high-latency interaction with participants (it can be negotiated in a couple of rounds with multiple parties with almost no extra overhead compared to current Joinmarket style negotiation), with no cross-block interactivity.

The biggest challenge with this approach is almost the most exciting aspect: imagine creating a graph of 10 transactions with multiple entry points that was randomly constructed from a statistical distribution of existing transactions on the blockchain; it could look totally non-distinct from what's around it, including timings. This would be some relatively difficult developer work, but it could be pretty powerful.

You might think it's too expensive to create a lot of transactions, but with the steganographic element, it'll actually make sense to use fairly low anon sets for individual negotiations, which trades it off. Also you would be entirely free to negotiate large anon-set, small tx number configurations if you preferred to ditch the stega- aspect.

  • Best scriptpubkey type: taproot (segwit v1)

There are several reasons to want to move to this anonymity set when it becomes available, the principle one being this is where most contracting will sit once people figure out how to do at least 2 of 2 MuSig2 (see previous blog post for some gory details), and others will probably/hopefully join in even for single sig. Note, for CoinJoinXT, as per previous 'award', and also for LN/coinjoin shenanigans (see below), we need MuSig2 negotiation and the blending in will be a crucial part of making those technique actually effective in hiding in the crowd.

  • Best anti-Sybil: fidelity bonds

Do note that we currently have weak anti-Sybil with fee choice randomization.

Fidelity bonds: first, let's say that it looks like this may get merged into current Joinmarket before wider protocol upgrade.

See the gist by Chris Belcher and the first discussion in the main repo here, following up also there is wallet code merged from here, and more work is coming on this shortly.

There are many nuances to consider here. We don't need all makers to provide fidelity bonds. There will be timelock and funds burn options. Also, it can be a "soft fork" style change, because it would be a new offer type which new takers can inspect but old takers can ignore.

  • Best language: Python or golang

These are just two preferences from my own experience, so again - bias, although partly that's an inertia bias.

Go has better tooling in my opinion, but both of these options may suffer a little from lacking GUI elements "out of the box". I would be entirely open to other opinions on good languages.

If we stick with Python we might want to start being a lot more serious about typing, as duck-typing causes a lot of problems in a big project.

  • Best additional features: (multiple winners)

(1) Payjoin

This one we already have - see PRs 648, 640, 636, several others, and the root mega-PR 536 (which did other stuff too). Most importantly it's a full (both directions) BIP78 implementation so should be compatible with all other BIP78 clients. We would certainly want to keep this feature I think.

(2) LN channel open (incl. dual funding) with a JM coinjoin

One of the most likely/interesting long term uses of coinjoin may well be this: in opening Lightning channels you are not very constrained about amounts (this is very relevant to CoinJoin!), and you are somewhat patient. If people get most of their privacy via second layer, it will be all the more important to bolster fungibility in base layer payments, and coinjoins on creation of LN channels (possibly also, closing, but that's a much less clear case) will be a natural focus. This somewhat merges with the issue of dual-funding (although it is separate of course); in the most general case we could have 2N participants all contributing inputs to N channel openings all at once. There are many avenues to explore here, but it's something I think should be strongly borne in mind by anybody implementing Coinjoin today.

(3) Hardware wallet support

See 663; should be practically possible for maker side at least. The ckBunker initiative looks like a promising angle. This sort of thing does require a lot of care and attention in creating testing setups though.

Finally, not an award but things to pay attention to:

  • General coding and architecture issues:

(1) Single overarching API, accessible via one command line tool (so like a joinmarket-cli) or via json-rpc style RPC. See which is really more of a project than just a PR, I have also coded up a basic Javascript (Angular) example of using that RPC here, and here are a couple of screenshots. This can also encompass other cleanups like that suggested in this issue.

(2) Better use of asynchronous coding (if still Python, asyncio vs Twisted).

(3) It's worth thinking about how well partitioned the various functions are. The current repo was called the rather dumb name "joinmarket-clientserver" specifically because it separated out the network communications and protected that "side" of processing from knowing anything about bitcoin. I think we could push this general principle way further, having multiple separate modules only communicating (blockchain <--> wallet-service <--> business-logic client <--> protocol <--> network .. something like that) in very fixed ways (which is only half-true today), with an API plugged in. Also the first glimmer of a "plugin" architecture started when I implemented SNICKER, but that might also be useful going forwards.