Git Product home page Git Product logo

joinmarket-clientserver's Introduction

Release workflow status

joinmarket-clientserver

JoinMarket is software to create a special kind of bitcoin transaction called a CoinJoin transaction. Its aim is to improve the confidentiality and privacy of bitcoin transactions.

A CoinJoin transaction requires other people to take part. The right resources (coins) have to be in the right place, at the right time, in the right quantity. This isn't a software or tech problem, it's an economic problem. JoinMarket works by creating a new kind of market that would allocate these resources in the best way.

One group of participants (called market makers) will always be available to take part in CoinJoins at any time. Other participants (called market takers) can create a CoinJoin at any time. The takers pay a fee which incentivizes the makers. A form of smart contract is created, meaning the private keys will never be broadcasted outside of your computer, resulting in virtually zero risk of loss (aside from malware or bugs). As a result of free-market forces the fees will eventually be next to nothing.

Widespread use of JoinMarket improves bitcoin's fungibility and privacy. This implementation of JoinMarket also implements PayJoin.

For a quick introduction to Joinmarket you can watch this demonstration of installation and usage given by Adam Gibson during the Understanding Bitcoin conference on April 6 2019.

Wallet features

  • Segwit addresses (native bech32 ('bc1') by default; p2sh wrapped ('3') optionally).
  • Multiple "mixdepths" or pockets (by default 5) for better coin isolation
  • Ability to spend directly, or with coinjoin; export private keys; BIP84/49 compatible seed (Trezor, Samourai etc.) and mnemonic extension option
  • Fine-grained control over bitcoin transaction fees
  • Basic coin control - can freeze individual utxos to stop them being spent in any transaction
  • Can run sequence of coinjoins in automated form, either auto-generated (see tumbler.py) or self-generated sequence.
  • Can specify exact amount of coinjoin (figures from 0.01 to 30.0 btc and higher are practical), can choose time and number of counterparties
  • Uses fidelity bonds for protection against sybil attacks.
  • Can run passively to receive small payouts for taking part in coinjoins (see doc page)
  • GUI to support Taker role, including tumbler/automated coinjoin sequence.
  • PayJoin - BIP78 to pay users of other wallets (e.g. merchants), as well as between two compatible wallet users (Joinmarket, Wasabi, others). This is a way to boost fungibility/privacy while paying.
  • Protection from forced address reuse attacks.
  • Address labeling

Quickstart - RECOMMENDED INSTALLATION METHOD (Linux and macOS only)

Download the latest release as tar or zip, and extract it.

Make sure to validate the signature on the tar/zip file provided with the release (or check the signature in git if you install that way using git log --show-signature).

JoinMarket requires Python >=3.8, <3.13 installed.

(macOS users: Make sure that you have Homebrew and Apple's Command Line Tools installed.)

./install.sh

(There are options you can apply to the installation - see ./install.sh -?. But the defaults should work.)

Follow instructions on screen; provide sudo password when prompted, then when finished:

source jmvenv/bin/activate
cd scripts

You can optionally install a Qt GUI application, you will be prompted to choose this during installation.

You should now be able to run the scripts like python wallet-tool.py etc., just as you did in the previous Joinmarket version.

Alternative to this "quickstart": follow the install guide.

More installation guides

Usage

If you are new, follow and read the links in the usage guide.

If you are running Joinmarket-Qt, you can instead use the walkthrough to start.

If you used the old version of Joinmarket, the notes in the scripts readme help to understand what has and hasn't changed about the scripts (warning: this refers to changes from several years ago, so may be slightly outdated).

If you are looking for the available makers, run the orderbook. It's recommended to run your own orderbook locally, but there are also public mirrors:

Useful third-party projects

PayJoin

If you want to use the PayJoin feature to pay/receive money to/from another BIP78-supporting wallet, read this guide.

Joinmarket-Qt

Provides single join and multi-join/tumbler functionality (i.e. "Taker") only, in a GUI.

If binaries are built, they will be gpg signed and announced on the Releases page.

If you haven't chosen the Qt option during installation with install.sh, then to run the script joinmarket-qt.py from the command line you will need to install two more packages. Use these 2 commands while the jmvenv virtual environment is activated:

pip install .[gui]

After this, the command python joinmarket-qt.py from within the scripts subdirectory should work. There is a walkthrough for what to do next.

Architecture notes

See architecture-notes.md.

TESTING

Instructions for developers for testing here. If you want to help improve the project, please have a read of this todo list and the Help Wanted tag on the issue tracker.

Community

joinmarket-clientserver's People

Contributors

abhishek0405 avatar adamisz avatar adlai avatar alexcato avatar chris-belcher avatar csh7kmcc9 avatar d3spwn avatar dennisreimann avatar dependabot[bot] avatar domob1812 avatar dongcarl avatar eduard6 avatar erikarvstedt avatar fivepiece avatar jameshilliard avatar kristapsk avatar laanwj avatar marnixcroes avatar mecampbellsoup avatar nixbitcoin avatar openoms avatar pulpcattel avatar qubenix avatar roshii avatar sangaman avatar st3b1t avatar takinbo avatar theborakompanioni avatar undeath avatar whitslack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

joinmarket-clientserver's Issues

One bad IRC connection prevents starting

To reproduce:

  • Have two IRC in joinmarket.cfg
[MESSAGING]
socks5 = true, true
socks5_host = localhost, localhost
socks5_port = 9050, 9050
channel = joinmarket-pit, joinmarket-pit
host = 6dvj6v5imhny3anf.onion, cfyfz6afpgfeirst.onion
port = 6698, 6667
usessl = true, false
  • Replace one host with bad host (6dvj6v5imhn12345.onion)
  • Start sendpayment.py or tumbler.py as normal (tested tumbler.py only)

Expected result:

  • One IRC connection will work and one will fail
  • Script will continue

Result:

[MainThread  ] [DEBUG]  building irc 
[MainThread  ] [DEBUG]  building irc 
[MainThread  ] [DEBUG]  (unhandled) noticed:  agora.anarplex.net Auth *** Looking up your hostname...
[MainThread  ] [DEBUG]  (unhandled) noticed:  agora.anarplex.net *** Skipping host resolution (disabled by server administrator)
[MainThread  ] [DEBUG]  (unhandled) noticed:  agora.anarplex.net Auth Welcome to ^Bagora-irc^B!
[MainThread  ] [DEBUG]  signedOn:
[MainThread  ] [DEBUG]  (unhandled) noticed:  [email protected] NICKNAME [^BLogon News^B - Sep 14 2011] PLEASE: Register with nickserv. (/query nickserv help register)
[MainThread  ] [DEBUG]  joined:  #joinmarket-pit

...10 minutes...

[MainThread  ] [INFO ]  STALL MONITOR:
[MainThread  ] [INFO ]  No stall detected, continuing

Script never continues.

Prettify schedule view during multijoin

Currently schedules dynamically update in the view pane during mutliple join run, however this is a flat view of CSV, should be (a) grid, (b) highlighting/bolding active entry, (c) explanatory notes e.g. headers. Perhaps other things. Low priority.

Qt tumbler need not abort on commitments error

In tumbler.py if commitments are too new it just keeps trying.

A pecularity of the Qt approach is that the taker info callback is perceived as requesting SpendTab.abortTransactions() to be called if the info type is 'warning' ('ABORT' -> 'warn' messagebox type), so the tumbler aborts on the first failed commitment, even if the reason is 'too new'. Should be fixed to give better robustness. Fairly high priority.

New client with same daemon creates new IRC session unnecessarily

If joinmarketd is run persistently with new clients connecting, new instances of JMDaemonServerProtocol are created, meaning that the member variable self.irc_config is reset to None, meaning a new IRC session + nick is created even though the IRC config is the same.

The parts of the class instance which manage the connection should therefore be class variables, but this requires a bit of work. At least the messagechannelcollection object must be thus, and also it seems the orderbookwatch related data. So this is a bit more of a rework than I'd thought it would be. Also there might be something simpler than moving to class variables, perhaps moving these elements to the JMDaemonServerProtocolFactory, not sure.

This isn't labeled as a bug because it does not break functionality, but any long running daemon used repeatedly by clients will create a bunch of useless IRC connections, so it nearly counts. Should be fixed soon.

Add maker and yield-generator

Steps to achieve this:

  1. Add maker client-server commands to jmbase/commands.py.
  2. Add and refactor maker.py with Maker object to jmclient package. Refactoring means similar to what has been done for Taker; bundle stage 1 and stage 2 operations.
  3. Refactor a base CJPeer class again to remove duplication between Maker and Taker (but note Orderbookwatch is already factored out to jmdaemon. Note that some part of the unconfirm/confirm callback handling might be refactorable into the base class here.
  4. Add code to jmclient/client_protocol.py in line with step 1.
  5. Re-add at least one yieldgenerator script to scripts/ instantiating Maker.

Currently considering this a longer term goal, it'll probably be the last step to complete the replication of functionality in the current Joinmarket repo.

Electrum add_tx_notify

To schedule multiple transactions for Electrum requires add_tx_notify to work in the jmclient.blockchaininterface.ElectrumWalletInterface; currently it is just a dummy do-nothing.

I haven't investigated but presumably it requires something like subscribing to an address, may be a non-trivial job.

Coveralls trigger fails

Message in travis after tests end is "Coverage.py: warning no data" or similar. Saw this once locally, don't know the reason, perhaps something to do with versions (although they should have been fixed in the yaml).

Give up if no commitments

On failure to source commitment in Qt, currently shows commitments_debug info in popup, but does not abandon the join.

tx_broadcast has no effect

Steps to Reproduce

blockchain_source = bitcoin-rpc

tx_broadcast = not-self
or
tx_broadcast = random-maker

Expected result:

Sends tx through other peer / maker.

Actual result:

Does sendrawtransaction using Bitcoin RPC.

UI for TUMBLE.log in Qt

Not strictly required, so not high priority, but this 'view' of progress is intended for readability so particularly applicable to GUI setup.

Calculated transaction fee too large for our inputs

Error:

exceptions.ValueError: Calculated transaction fee of: 2XXXXX is too large for our inputs;Please try again`

When using sendpayment.py script exits with fatal error.

When using tumbler.py:

STALL MONITOR:
Stall detected. Regenerating transactions and retrying.
Schedule entry: [0, 0.152566362877, 6, 'INTERNAL', 22.73, 0] failed after timeout, trying again
...
STALL MONITOR:
No stall detected, continuing

but does not make progress (only left running for 1 hour, maybe it would make progress later).

Input UTXO was small, amount sent was small, amount sent + transaction fee > amount of input UTXO. Other input UTXO were available.

Tumbler always uses mixdepth 0

To reproduce:

  • Create wallet with coins in just mixdepth 1
  • python tumbler.py --schedulefile schedule.schedule wallet.json <addr>

Expected result:

  • Tumble starts, mixdepth 1 is the lowest mixdepth

Result:

TIMESTAMP_0000000000013 [MainThread  ] [DEBUG]  get_utxos_by_mixdepth =
{0: {},
 1: {u'TXID_INDEX_00000000000000000000000000000000000000000000000000000001': {'address': u'1ADDRESS_00000000000000000000001',
                                                                             'value': VALUE_0000000001},
     u'TXID_INDEX_00000000000000000000000000000000000000000000000000000002': {'address': u'1ADDRESS_00000000000000000000002',
                                                                             'value': VALUE_0000000002},
     u'TXID_INDEX_00000000000000000000000000000000000000000000000000000003': {'address': u'1ADDRESS_00000000000000000000003',
                                                                             'value': VALUE_0000000003}},
 2: {},
 3: {}}
TIMESTAMP_0000000000014 [MainThread  ] [DEBUG]  Coinjoin amount too low, bringing up.
TIMESTAMP_0000000000015 [MainThread  ] [INFO ]  Choosing a destination from mixdepth: 1
TIMESTAMP_0000000000016 [MainThread  ] [INFO ]  Chose destination address: 1ADDRESS_00000000000000000000004
...
TIMESTAMP_0000000000025 [MainThread  ] [INFO ]  rel/abs average fee = REL_FEE_00001 / ABS_FEE_00001
TIMESTAMP_0000000000026 [MainThread  ] [DEBUG]  INFO:Preparing bitcoin data..
TIMESTAMP_0000000000027 [MainThread  ] [DEBUG]  total estimated amount spent = EST_AMT_00001
TIMESTAMP_0000000000028 [MainThread  ] [DEBUG]  get_utxos_by_mixdepth =
{0: {},
 1: {u'TXID_INDEX_00000000000000000000000000000000000000000000000000000004': {'address': u'1ADDRESS_00000000000000000000005',
                                                                             'value': VALUE_0000000004},
     u'TXID_INDEX_00000000000000000000000000000000000000000000000000000005': {'address': u'1ADDRESS_00000000000000000000006',
                                                                             'value': VALUE_0000000005},
     u'TXID_INDEX_00000000000000000000000000000000000000000000000000000006': {'address': u'1ADDRESS_00000000000000000000007',
                                                                             'value': VALUE_0000000006}},
 2: {},
 3: {}}
TIMESTAMP_0000000000029 [MainThread  ] [DEBUG]  ABORT:Unable to select sufficient coins: Exception('Not enough funds',)
TIMESTAMP_0000000000030 [MainThread  ] [INFO ]  Taker not continuing after receipt of orderbook

Notes:

  • tumbler seems like chooses mixdepth=1 but uses mixdepth=0 later
  • mixdepth 1 has enough funds (> 0.5 BTC)
  • Completes ok if mixdepth 0 only has coins or mixdepths 0,1 have coins

Allow error messages from makers to get to client

Currently on_JM_FILL_RESPONSE only returns "Makers didn't respond" in case of less than minimum_makers number of valid ioauth responses. Need client to see if there were specific error messages, or in any case get more fine grained information.

amp.TooLong exception for offer list

The list of offers delivered from the pit is now in the several hundreds, which creates a data blob too big to be sent over one response, amp limits the size to 65535 bytes. Current hack in the code to only deliver the first hundred offers just to allow it to work on mainnet (needed for testing Electrum already, because Electrum has no testnet interface).

Thus fairly urgent solution required, see https://amp-protocol.net/DontPanic/ , it should not be very hard to batch send, hopefully. Edit: or probably simpler to use the BigString solution suggested there.

Add/remove utxo for multijoin for non-tumble

Wallet sync between schedule entries should not be done, first because it's slow and unnecessary, but also because it resets the index; hence the tumble style multi-join's use of add/remove utxos should be replicated; slight current technical difficulty is that this code is folded into the tumbler's taker_finished_update code in tumble_support.py (to re-use with CLI version).

This trivial but slightly tangly situation is a result of an artificial distinction between the 'tumble' and 'multijoin from manually created schedule' cases, so the issue should probably be extended more broadly.

Rebuild test suite

It may be possible to just drop-in most or even all of the current test suite in https://github.com/Joinmarket-org/joinmarket , but even if it is, will need to build some tests differently. Some ideas for now, since this will be a big job:

  • Use a DummyMessageChannel as a way to test the functionality of MessageChannelCollection.
  • Create a daemon tester using a dummy client to call its functions.
  • Create a DummyBlockchainInterface with some tricks to allow testing of Taker functions like receive_utxos in isolation. In general, creating a suite of Taker tests that don't depend in any way on the blockchain interface would be a huge help (we already have the win that it no longer depends on the message channel).

I will add more here as I think of it.

Layout suggestions from /u/chuckymcgee (reddit)

Quote:

"
Thanks a bunch for putting out this initial qt. I've taken a look and have some initial feedback.

Most of my suggestions are just about making it simpler and easier for users who aren't familiar with coinjoins or joinmarket at all. Streamlining the interface to explain a bit more and otherwise keep things intuitive is my aim. I think the ultimate goal of the gui should be that someone only generally familiar with sending bitcoins to addresses should be able to run the qt and perform joins just by looking through options and following prompts, referring to documentation just to be certain. In that vein then, providing expanded descriptions of prompts and instructions and otherwise not showing particular elements until they become relevant can help a new user navigate the program without becoming too overwhelmed.

Switch the order of tabs to reflect the order a user would want to tinker with- JM Wallet, Coinjoins, TX History, Settings (eventually I think we'll want to use buttons similar to what's in the bitcoin-qt, so users will feel more familiar)

When Current Wallet=None, Blank out address/index/balance/used/new, do not show mixdepths.- In mixdepths field say- "No Wallet Loaded. Please create a new wallet to get started!"

Coinjoins- grey out fields/ box initially- "No wallet loaded. Please create or load a Joinmarket wallet to get started!"-> "Wallet loaded, but no funds present. Please send funds to an address listed in JM Wallet to get started!"

When a wallet with 0 BTC funds is loaded, show a column next to external addresses "Send funds to one of these addresses to begin using joinmarket!" or otherwise prompt with an address to send funds to.

Wallet- (use expanded descriptions) "Create New Wallet" "Load Wallet From Saved wallet.json file" "Recover Wallet Using Mnemonic Word Strings" "Export Private Keys" "Exit"

Settings- Put settings a novice is likely to tinker with up front, otherwise hide.

Add checkbox "Show Advanced Settings" to show these more advanced settings Add a "Restore Default Settings" in case the user screws up settings.

"Recover Wallet Using 12-Word Recovery Seed" "Enter your wallet recovery word string here to recover a lost Joinmarket wallet" (Separate fields for each word?)

Generate- "You are going to generate a new wallet. In a moment, a wallet recovery seed of 12 words will appear. It's VERY IMPORTANT you write this recovery seed down. If your computer crashes you may have no other way of retrieving your coins!" Continue/Cancel

New Recovery Seed Displayed Screen->Continue->Create Password Screen-> Recovery Seed Check Prompt->Name your wallet

Recovery Seed Check Prompt- "Please enter the 12 word recovery seed you were just shown. You must have this seed written down"->Continue/Retry With New Seed/Cancel (if the seed isn't correct, do not allow the user to proceed)

Recover from Seed "Enter the 12 words of your Joinmarket recovery seed separated by spaces:" (or just have separate fields for each word)

I would hope these changes should be relatively simply to implement. I'm still looking at the actual coinjoin options and flow for advice there. Let me know what you think. Really appreciate the work you're putting in.
"

Add developer instructions

Using python setupall.py installs packages into virtualenv site-packages directory. After that the changes made to local code are ignored because site-packages is used.

I'm not sure the best way to use the local code. This kind of works but only for one package at a time:

cd <package>; python setup.py develop; cd ..

Credentials/auth for client connection

Also, encryption/TLS. Not sure of the right approach here; it looks like it's fairly easy to add credentials to the AMP connection. The connection is currently hardcoded to localhost, but clearly it would be either nice or essential to add security to this inter process communication, depending on how you look at it.

Add commitments view

Most likely a separate tab, or perhaps a separate window that can be chosen from the menu. User probably needs an at-a-glance view of current status re: commitments (already have a popup with commitments debug text if something goes wrong). Ideally includes GUI based tools for adding (replicating add-utxo.py functionality).

Handle connection drops correctly

Exceptions are thrown when the client disconnects at the moment. It doesn't seem to cause functional problems (can reconnect and run OK), but should be fixed.

More generally there are places where addErrback needs to be used.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.