JoinMarket-Org / joinmarket-clientserver

Bitcoin CoinJoin implementation with incentive structure to convince people to take part
GNU General Public License v3.0
728 stars 178 forks source link

[Request] Can you allow `POST /wallet/{walletname}/taker/coinjoin` to accept a list of UTXOs instead of just the mixdepth? #1561

Open FeatureSpitter opened 1 year ago

FeatureSpitter commented 1 year ago

I want to specify exactly the UTXOs I want to use on a coinjoin, which allows for a much more granular selection than a mixdepth.

How difficult is it to change the class Taker in this direction?

AdamISZ commented 1 year ago

(Edit: this response was to the more general question of 'how to only spend certain coins'; the answer to the title is in the below comments).

To specify that only a specific set of utxos are to be spent in a coinjoin, or an ordinary transaction, you can use the method freeze of the script wallet-tool (or use the utxos tab in the Joinmarket Qt; not sure about the interface in JAM but it is also supported there iirc). Using this method you can toggle status of individual utxos from 'frozen' to 'not frozen'. Doing this you can spend only specific coins.

However what Joinmarket will not allow is co-spending of coins from different mixdepths. Because this will retroactively break the privacy of earlier transactions.

AdamISZ commented 1 year ago

Oh sorry! My previous response was only to the question, I completely ignored the title. I'll take a look at that.

AdamISZ commented 1 year ago

See https://joinmarket-org.github.io/joinmarket-clientserver/api/#operation/freeze for the freeze operation I described above.

So, perhaps it isn't the most convenient, but this persists to the actual wallet file that a particular utxo is unavailable for spending. And then you toggle, as described, to re-enable it.

FeatureSpitter commented 1 year ago

See https://joinmarket-org.github.io/joinmarket-clientserver/api/#operation/freeze for the freeze operation I described above.

So, perhaps it isn't the most convenient, but this persists to the actual wallet file that a particular utxo is unavailable for spending. And then you toggle, as described, to re-enable it.

I can live with that, as long as the frozen UTXOs don't suddenly unfreeze. Even if I close the wallet, they will stay frozen until I explicitly call that endpoint again?

FeatureSpitter commented 1 year ago

@AdamISZ your approach has one BIG issue:

If in the time between freezing the UTXOs and using the unfrozen ones, I receive new UTXOs, those will get used as well.

I.e.:

  1. Freeze unwanted UTXOs
  2. New sats arrive as new UTXOs (which are not frozen--unless I can make any new UTXOs frozen by default)
  3. I sweep the unfrozen UTXOs

Suddenly, I screwed up and spent the newly arrived UTXOs as well....

But if, alternatively, I can specify exactly which UTXOs to use in the coinjoin, then all is well!

Your method assumes that no new UTXOs will arrive between the time you freeze the UTXOs you don't want to sweep and the sweeping itself.

AdamISZ commented 1 year ago

Yes that's a good point, and certainly a stronger argument than inconvenience, that "spend these specific coins" is a feature we should add. We went for that 'freeze' approach originally because the majority of the time we're trying to permanently not spend something (the classic so-called 'dust attack' was the first motivation); but then we told people "also, you can use this for coin control". As you point out there is an edge case where it could fail.

(One thing to bear in mind, relatedly, is that there is no general assumption, in the way the wallet is designed, that coins in the same mixdepth are ever unlinked. Often they are unlinked, but that is due to specific scenarios, it's never guaranteed, so to speak. Whereas coins in different mixdepths are unlinked, at least, modulo the efficacy of coinjoins. Well, you get the general idea.)

FeatureSpitter commented 1 year ago

Alternatively, if it is easier to deploy, JM could just have an option (possible to change via the API) that allows freezing all new UTXOs.

So this way I can freeze all the UTXOs I want, and if any new UTXOs shows up, it will be frozen by default, thus not a problem.

AdamISZ commented 1 year ago

So this way I can freeze all the UTXOs I want, and if any new UTXOs shows up, it will be frozen by default, thus not a problem.

True. But what do you think? I think the former probably makes more sense, i.e. an optional argument including a list of utxos to spend. Actually, I think somebody might have PR-ed something similar a while ago, although it wasn't merged. I'll check.

AdamISZ commented 1 year ago

It was this one: https://github.com/JoinMarket-Org/joinmarket-clientserver/pull/1112

The thing is, as you can see from the conversation, I was quite confused that other people thought it made sense to list input addresses, I thought it made much more sense to list input utxos.

But at that point I hadn't appreciated the edge case you mentioned, so I guess I was not very enthused to have that extra feature.

FeatureSpitter commented 1 year ago

So this way I can freeze all the UTXOs I want, and if any new UTXOs shows up, it will be frozen by default, thus not a problem.

True. But what do you think? I think the former probably makes more sense, i.e. an optional argument including a list of utxos to spend. Actually, I think somebody might have PR-ed something similar a while ago, although it wasn't merged. I'll check.

It depends.

The freeze-by-default has one use case that comes to my mind and it has already been desired by me in the past: If I don't want to manage exactly the UTXOs I want to freeze, but I am most sure that I don't want to drain any newly incoming UTXO, then I would make incoming UTXOs freezing by default. Just like a "time checkpoint". From this point on I want to spend all my UTXOs, but none of the new ones I might have coming in my direction.

Then you have this other feature that allows you to specify which UTXOs you want to use on a direct spend or coinjoin transaction.

Both make sense to me, for different scenarios :smile:

But the one that allows only specific UTXOs to be assigned to a coinjoin is by far the most useful of the two IMO.

FeatureSpitter commented 1 year ago

@AdamISZ thank you for considering this! :)

AdamISZ commented 1 year ago

I think it's a bit technically difficult, but your last suggestion does make a lot of sense: a temporary freeze during a specific sending event (if the user has specified a specific input coin choice edit: that's not right, i should say 'if the user has not specified specific coins').