About this post

It seems like a good idea to start using this blog to spread a little bit more information to users and other interested parties, about Joinmarket, in particular about how it might change.

First, please note this is a personal blog, there is nothing "official" here (and the same would go for anyone else's blog about Joinmarket! - this is an open source project).

Second, please note that for years now I have been microblogging here; so, if you're interested to keep in touch with what I'm doing (and often, reading, or just thinking) day by day, you're welcome to follow that account. I personally like keeping track of people over RSS with fraidyc.at, but whatever suits you. Just know that Joinmarket related announcements are often made there first (I don't and will not use any corporate-owned social media sites).

Joinmarket status.

0.7.1 of Joinmarket was released 12 days ago, and introduced receiving BIP78 payjoins, on the GUI and on command line.

In the next few days 0.7.2 will be released. It is principally a bugfix release.

(Although there will be one small new feature - not-self broadcasting is finally reimplemented. You'll want to be careful about using it, especially to start with (since it'll only work with counterparties that also have the latest release); there will of course be advice about this in the release notes. Consider it an advanced feature, and consider using tor-only in your Core node if the base level of privacy in broadcasting transactions isn't enough for you.)

The bugs fixed are things that came out of interoperability tests on BIP78.

Over the last few weeks I, Kristaps Kaupe and some people on other dev teams have been running a variety of testnet, mainnet, regtest tests of Payjoin functionality between btcpayserver, Wasabi and Joinmarket.

We found various edge cases, like hex instead of base64 being transferred (not in spec but people were doing it anyway), incorrectly shuffled output ordering (my bad!), combinations of parameters in the HTTP request that I interpreted the BIP as saying was not allowed, but btcpayserver was sending anyway (but: not always! - testing can be a real pain sometimes!) and a few more.

Remember two things about Payjoin though:

  1. It is a protocol designed to accept a failure to negotiate as a common event - the payment goes through anyway, it's just not a coinjoin then.
  2. The most common incompatibility between wallets will be different address types. Then nothing can be done, as it would be slightly silly to do a Payjoin like that - we fall back, as per (1).

So hopefully we will have some wallets that can send and receive Payjoins up and running by .. well, now actually! It is already possible and working, we are just smoothing out edge cases here.

If you didn't get a chance, please watch this demo video of sending and receiving payjoins between Joinmarket wallets (note: the dialog is now improved, as I comment here):

JM-JM Payjoin demo video

It only has 31 views, many of which were me, so I guess not many people saw it :)

About point (2) above, note that you'll probably need to be using a Joinmarket bech32 wallet (yes, we've had them for quite a while!) if you want to send or receive with Wasabi. So, more on that next:

Joinmarket future plans (tentative!)

Bech32 in 0.8.0

We have this PR open from jules23 and it represents a very impactful (but happily, not large technically) change that is proposed: to switch to a "bech32 orderbook", by which we mean making changes like this

  • The default wallet changes to native segwit (bech32, bc1.. addresses)
  • Joinmarket coinjoins (i.e. maker/taker coinjoins) are offered as sw0reloffer, sw0absoffer in the trading pit

Both of these changes would not be "mandatory", just as when we switched to segwit in 2017, it was not mandatory, but would be default in the new version. The fees for coinjoins will be significantly reduced from the current "wrapped segwit" addresses, and we would gain better compatibility with Wasabi and a number of other modern wallets that default to bech32.

The general problem with these updates (which we've only done once before) is that they cause a "liquidity split" temporarily, as not everyone migrates to the new address type at the same time. This is unfortunate, but I feel less concerned about it than last time, as the amount of maker liquidity is much larger (more on that below, about IRC). Another reason to be slightly unsure about this update is that taproot activation may be coming quite soon, but it seems unlikely that the real activation on the live network will take less than 1 year from now (does it)?, so probably we should do this anyway. That's my opinion.

The general idea would be to make a new 0.8.0 version next after this, including this change. More testing is needed, but it's mostly ready. If you have opinions about the technical implementation of this, feel free to discuss on the above github PR thread. For more general discussion I'd suggest using #joinmarket on freenode.

New message channel implementations vs IRC

This part is far more speculative. We have had several discussions about message channels over the years. As early as 2016/17 I abstracted out the message channel "layer" so that IRC was just an implementation (see jmclient/jmclient/message_channel.py) of a few key methods. Alternative implementations have always been possible, but nobody either found time, or found a practical way, to make an alternative implementation. This issue is becoming more pressing. As a simple example, only this week we had IRC ops come to us complaining (very politely, it wasn't a disaster) that about 450 bots had suddenly shown up in our joinmarket test pit. This is in some ways less interesting than the real scalability problem: Joinmarket uses broadcast for offers, but also a sort of "anti-broadcast" mechanism: when a new Taker shows up, they ask every Maker for their current offers, and the Makers all send them at the same time, to that one Taker. So this doesn't scale very well and IRC as a messaging layer doesn't like it; this is the main reason negotiation of a Joinmarket coinjoin takes ~ 1 minute instead of 1-5 seconds (we have to deliberately throttle/slow down messages).

We rather badly need a more scalable messaging layer. I'd appeal for help on this, and I'd also appeal for public discussion of ideas on github (we've had such threads in the past, but nothing really happened).

Let's not forget that related to all that is DOS. Depending on implementation, DOS attacks can be a real problem. Chris Belcher's fidelity bond wallets were implemented within Joinmarket's code already, earlier this year, see here for documentation explaining this, but implementing it as a requirement for Makers is another step, and it might be an important part of the puzzle of getting a scalable messaging layer right.

Getting this right won't just help Joinmarket coinjoins, but also various other systems we might want to integrate over time (SNICKER? CoinjoinXT? CoinSwap? something else?).