JoinMarket-Org / joinmarket

CoinJoin implementation with incentive structure to convince people to take part
398 stars 119 forks source link

Experimental electrum plugin #549

Open AdamISZ opened 8 years ago

AdamISZ commented 8 years ago

See https://github.com/AdamISZ/electrum-joinmarket-plugin

The philosophy behind this is something like: while joinmarket-qt (found in the JMBinary repo for this org) was about creating the simplest possible GUI interface to do coinjoins, let's apply the same logic to Electrum, inheriting its own wallet management and blockchain interface features. This is useful in itself, quite apart from a more fully-featured approach where joinmarket has its own daemon.

It turned out there were a few steps of refactoring to make this workable.

  1. Make libnacl an external dependency (this is something we could have done long ago, but it's a useful first refactoring step)
  2. Make the directory in this repo joinmarket its own package. This would allow an Electrum plugin (or any other interface) to reference joinmarket in a cleaner way. Implemented here. As you can imagine this took a bit of fiddling about with imports, plus there are some minor code changes. This of course makes more sense if we make it a repo here on this org, and then after a painful manual merge, make this joinmarket repo inherit it.
  3. Implement an ElectrumWrapWallet wallet type which can ditch a lot of the heavy workload of the joinmarket Wallet class such as encryption and persistence and syncing (all done by Electrum). Also transaction signing can be deferred to this wallet class rather than be part of the btc code as currently.
  4. Implement an ElectrumWalletInterface instance of BlockchainInterface which is a fair bit simplified, as for the above (syncing and notifying not needed).
  5. Create an interface module within joinmarket/ called btc.py which decides whether to load the current bitcoin/ module from within normal joinmarket, or load another implementation of the same API for bitcoin code. The Electrum interface, using wherever possible Electrum's own bitcoin code (which is based on python.ecdsa for mathematical internals), has been coded. This is in a quite elementary state, although working, it needs to be redesigned to flexibly inherit code for multiple bitcoin interfaces presumably.
  6. Once the above was done, the Electrum plugin could be written; inheriting the same basic design as joinmarket-qt it is done here consisting of the normal plugin stuff and inheriting the above joinmarket_core package and gui code for the JoinmarketTab in joinmarket_gui.py.

Having done all this, the right way to install it is a bit unclear. I made some notes on this in the README of the repo and also in the reddit post I just made. Hopefully the manual install can be clean enough that semi-technical people can use it, at least.

I've done about 7 transactions so far, it seems to be basically functional at least.

There are also notes at the end of the README about how easily (or not) this might be extensible into more powerful code for some kind of tumbler implementation and/or yield generator. A back-end joinmarket daemon, as has been discussed before, will probably work better. I actually think it wouldn't be that big of a deal to switch to that model, taking this (both the packaging, and the Qt/plugin elements) as a base.

Thoughts welcome.

chris-belcher commented 8 years ago

I intended to do an electrum plugin using a sidecar daemon but this method is much better.

AdamISZ commented 8 years ago

I'm not sure without going into a lot more detail, but I think the idea of a daemon is kind of orthogonal to what's going on in the above setup. For example, if there was a joinmarketd that accepted instructions like !orderbook and so on and returned the answers, I think the changes to the plugin code above would be small-ish (the GUI part wouldn't change at all I guess).

As you mentioned, it would at the very least make more sense in as much as you could maintain a persistent connection to the message channel instead of re-joining for each transaction.

I'd be interested on thoughts on the start of the long description above. joinmarket_core as a package and as a repo in this org? It occurs to me today that another option is to have a setup.py in the existing main joinmarket repo that builds the joinmarket/ directory as a package (whether it's called _core or not, whatever). Superficially that's less complicated but maybe it's cleaner to have a separate repo. Then the main joinmarket repo that we have today would just be the user-level scripts and our bitcoin code. The libnacl can be ditched as an external dependency.