-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider forbidding or warning on non-wallet-type outputs #864
Comments
I can only express agreement really. I worry about the explosion of different features, advice, warning and configuration in this application. But on the other hand, I worry that people are too in the dark about what the smart way to use the application, is. These two are in tension. I always tend to lean towards giving the user control, even at the cost of difficulty of grasping every detail. I guess a lot of "power" users already know that this ability exists (cj-out with non-standard address), and also know it's best not to use it, generally. But we still see coinjoins like this from time to time. No strong opinion. |
I think this is not a useful idea. We already know that single JoinMarket coinjoins arent very useful for privacy, and users who want to mix their coins should use the tumbler algorithm to create multiple coinjoins. The main reason for this is that all the maker's TXOs will be later spent in another coinjoin, but the taker's TXOs will likely be spent in a non-coinjoin. So to a passive observer of the blockchain they can pretty easily tell which coinjoin output belonged to the taker just by looking at how the coinjoin outputs were later spent. This is true even if the taker's coinjoin address is the same address type. So in summary: if a user creates just a single coinjoin then they are easily unmixed, even if the destination is the same address type. If a user creates multiple coinjoins with the tumbler algorithm then their privacy is good, even if the final destination addresses are of a different address type. So adding barriers to different-address-type makes joinmarket less useful (e.g. because you can't send to a merchant who uses a different address type), without any privacy benefit. |
Well, not exactly. Everything here is probabilistic; the probability of the assumption "this is the taker's address" is substantially different if it's a legacy address cf if it happens to be the case that it doesn't get spent in a JM coinjoin. The latter could easily be a maker who changed roles (not assigning X% prob but it's much larger), cf basically 0% chance that makers will have reconfigured their JM software to send the cj-out to a legacy.
Tend to agree, just don't think the case is at all watertight. |
I'd argue the probability of a taker's single-coinjoin being spent by someone else who also creates JoinMarket coinjoins is very very low. The only time that probability will be non-negligible is if the ecosystem reaches the utopia of "make every transaction a coinjoin", and that to me seems very unlikely to ever happen because 1. it increases miner fee costs, and people who don't care about privacy won't pay extra, and 2. a huge amount of the economic weight in the ecosystem is like KYC exchanges, required by regulation to spy on their customers, and therefore will never adopt coinjoin themselves. I think makers-changing-roles-to-sometimes-to-be-takers is irrelevant here? Because if a maker-turned-taker creates a taker-coinjoin which goes to a different address type, then the adversary still doesn't learn anyway because all the maker-turned-taker's UTXOs come from a long line of previous coinjoins. |
Yes sure but that's not what I was saying. I was saying that: if the taker's single-coinjoin output is spent in a non-JMcoinjoin tx, the deduction "that is the taker's output" is wrong for the cases where a maker sent a non-JMcoinjoin tx using their output from that same coinjoin. I was comparing the case: output goes to non-JMcoinjoin against the case: output is legacy (i.e. not bech32), saying the latter is a tremendously stronger watermark of "definitely the taker", than the former. |
I tend to agree that forbidding this would make JoinMarket less useful without necessarily protecting privacy. I also agree that non-wallet-type outputs tend to identify those outputs as belonging to the taker. However:
I think the real problem here is not with non-wallet-type custom change addresses (except for the fingerprinting risk from using exotic P2SH scripts), but with non-wallet-type main CJ outputs. With a wallet-type main CJ output, there is no ambiguity about which inputs are the taker's, no ambiguity about which change output is the taker's or if it's a sweep, but some ambiguity about which main CJ output is being paid by the taker. On the other hand, with a non-wallet-type main CJ output, there is no ambiguity about anything. Which raises the question: If there is no benefit and only costs, does the user really want to do that? Here's my idea:
I appreciate @AdamISZ's concern about the proliferation of warnings, advice, etc. but this case seems to have zero benefit while users might mistakenly think they're getting some privacy benefit. For this kind of situation I think it's important to at least tell the user that we think they're doing something dumb. |
This has been dormant but afaict there is a simple actionable item coming out of the discussion, namely:
Labelling it as such. |
The path to follow is to forbid the use of non-v0 P2WPKH outputs for coinjoins and leave it available only when the number of counterparties is zero.
This isn't a new feature. We may even consider it removing a feature
The thing is that sending funds to a non-v0 P2WPKH output inside a Joinmarket coinjoin is a mistake. So we shouldn't be looking at it as a tool that power users may know the existance of but rather as a way that newcomers may shoot themselves on the foot.
Nothing is gained from sending payment to a non-v0 P2WPKH in a coinjoin the ability should be removed. If a user wants to pay a non-v0 P2WPKH output they should be only be able to do so with zero counterparties so it's made clear to them that there's no advantage in using the sendpayment tool for such case. |
What about non-v0 p2wpkh addresses that get used as tumbler destinations? If you do the quoted thing you said then it becomes impossible to use tumbler to send coins to many places if they don't use v0-P2WPKH, even though the privacy of sending coins somewhere with tumbler is pretty good regardless of the destination address type. The real problem is from people using sendpayment.py where the inputs are UTXOs that didnt come from a long line of earlier coinjoins. Remember there's also the privacy leak of sending to a v0-P2WPKH address but where that coin is later not spent in another coinjoin, or where the address is reused, or otherwise clearly belonging to a non-maker. |
I'm doubtful of that and I think that any speding towards a non-v0 p2wpkh output have no place in Joinmarket coinjoins. But assuming you are correct that should only apply to the Tumbler then and be removed from the Single Coinjoin tool. |
I don't think forbiding taker to send to different output type will solve anything, he will just be forced to send to p2wpkh first and then create another transaction with zero counterparties, thus just wasting extra blockchain space, to send to final address. Any blockchain observer will with high probablity figure out who is taker anyway. Warning is ok, as newcomers might not know the nuances of Bitcoin privacy, but forbiding is almost useless. |
It's true, I will explain why. Imagine if you saw a coinjoin where one of the coinjoin outputs was a non-v0 p2wpkh address, because of this you know that this output is the taker's. OK so now you try to go backwards in history to figure out the initial source of these coins. But you have a problem, all the input UTXOs themselves come from a long line of previous coinjoins, which means you can't figure out much. At the risk of repeating myself in this thread, trying to ban non-v0 p2wpkh address is not the root cause of the problem. The root cause is people doing single coinjoins where the input UTXOs did not come from a long list of previous coinjoins. We should add a warning about that. Concretely, if you withdraw coins from a KYC exchange into your joinmarket wallet, and then do a single coinjoin to pay for a domain name, then that coinjoin can be unmixed even if you sent to a p2wpkh address. The reason is that it's overwhelmingly likely that the domain name host provider won't be spending your coins with a joinmarket coinjoin themselves. |
I think that's wrong? Why do we need to "send to p2wpkh" first? We can directly send with 0 counterparties, thus saving blockchain space. let DAT = Different Address Type Let's try to look at the actual scenarios:
These are the 2 extreme scenarios, but any shade in between does not sound much different.
That's clearly true, but I don't think it's relevant? Point 2 above works better without a CoinJoin anyway. All that being said, IMHO a warning is enough (if anything just to let tumblers happy), though I have to say this is one of the cases where I really don't see any benefit whatsoever in a taker CoinJoin to DAT. |
You're right that if all UTXOs in a wallet come from a long line of coinjoins then you may as well use direct-send. And if they don't come from a long line of coinjoins then you shouldnt create a single coinjoin at all. To me that sounds like an argument for just removing single-coinjoins entirely from the project, and only supporting tumbler and direct-send. Thinking about it now, when are single coinjoins ever useful? I can only think of one specific case, which is when someone wants to run a yield-generator to slowly mix their coins, but after receiving coins they first do a sweep-coinjoin sending the coins back to themselves so that all their coins go through a coinjoin with no change address. After all as a yield-generator all your coinjoins will always have a change address. |
If you remove the "DAT" element, then I think the argument is far weaker, as per what Waxwing said here. Also, manual mixing relies on being able to do single CoinJoin over time, so it doesn't seem at all something that we want to remove from JoinMarket. |
I'd argue the probability of maker's changing roles to sometimes become takers is very low, because it's just not incentive-compatible behaviour. Makers are there to earn money, not spend money. If you put cash in a savings account how often will you be transferring the whole stash in and out? You need a checking account not a savings account. Probably if yield-generators were not running bots those coins would just be sitting in cold storage doing nothing. Because a maker is an alternative to cold storage that means makers are unlikely to create many transactions. I bet many of them take part in thousands of coinjoin transactions and only single-digit numbers of initiating a transaction of their own. Meaning if you replace DAT with "Address which is Later Spent in a Non-CoinJoin" (ALSNCJ) in your argument, then it still works. Our only defence is multiple coinjoins. We've been talking about how single coinjoins can be easily unmixed due to DAT and ALSNCJ, but their inputs and change addresses can also be often (but not always) unmixed due to solving the subset sum problem on the input and change values. See https://gist.github.com/chris-belcher/7e92810f07328fdfdef2ce444aad0968#appendix This is another reason that multiple coinjoins are our only defence, because they eventually make this subset sum problem stop working for the attacker. Manual mixing is not in the documentation anywhere, the JoinMarket project doesn't tell its users to do that. I'd argue manual mixing is tricky to get right and users shouldn't do it. Tumbler is finely tuned to have as good privacy as possible. See the above document That's why I'm thinking if we do anything it would be to put warnings on single coinjoins. Almost everyone should just be using tumbler instead. The only good example I know of single coinjoin is doing a sweep-coinjoin to the same wallet and then running a yield-generator. |
A sidebar to this issue, but: I've always thought this argument isn't quite right. What I believe is the incorrect assumption: that the gain that makers seek is only sats reward. I believe that makers, over time, have correctly realised that their advantage is a mix of sats reward and privacy boost, traded off against what they increasingly perceived as a very low cost - which is mainly the hot wallet risk, and if I'm right that perception of that cost being low is a function of the software operating correctly, mainly. In that regard, a maker's use of the coinjoin market as taker occasionally can certainly make sense. It's a calculation that everyone has to make, whether it's worthwhile to spend back most or all of the sats you earned, in return for increasing the quality of privacy gained by everyone including yourself, as well as changing the quality of privacy in that specific transfer, itself. You can certainly reasonably assert that I'm wrong and in fact almost everyone running a maker is only focused on earning sats, and perhaps I am wrong. I think it's relevant, though, that unless you put very large amounts of BTC in, the return rate is tiny (for now! before fidelity bonds). |
First, let me say that I don't disagree with the concept, I do think some users are erroneously overestimating their privacy even without a DAT element when using single CoinJoin, and general warnings about that can't be wrong.
IMHO comparing DAT and ALSNCJ like if they are equal is a fallacy, the latter can still be much better than nothing (while the former is basically 100% useless).
JoinMarket is a great tool for power users and manual mixing is part of that.
And of course, manual mixing can be combined wth tumbler or YG, we don't have to pick one and forget the others. Note how we could consider manual mixing as a variant of "stopping and resuming the tumbler multiple times, doing one or more CoinJoins with a new user defined schedule each time". But anyway, I don't want to preach manual mixing, I was just noting how hugely different the impact/complexity is between just removing DAT from JM CoinJoin vs entirely removing single CoinJoins. |
Huh, quite a discussion going on here :) On "manual mixing" and "single vs tumbler" I just wanted to drop a mention of "schedule". It's not perhaps used much but the whole idea was we could fold the two scripts into one and it's just a question of if you use the tumbler's algorithm to generate the schedule, or do it your own way. Belcher's arguments for why using tumbler is better make sense, but I like that users can make their own schedule. I'm in the "let people come up with their own way" camp, as long as it's backed up with "you can follow our advice based on detailed analysis" (tumbler). Having said that I guess I have no objection to warnings about both single coinjoins and DAT. But removing single coinjoins (which in the software is a schedule of only one entry) I'd definitely be strongly against. |
Maybe this is something that should be added to documentation as a recommended practice for increased privacy? In mixed maker/taker role scenario, this will ensure that, any inputs you have available for payment, in history will as a source have at least one cj-out output (not just series of cj change outputs, that could be case if you do a payment from mixdepth to which you have deposited funds previously). |
See the discussion in #859 . Any output type other than v0 P2WPKH currently identifies the output as belonging to the taker or the taker's payee. Further, this presents a non-obvious fingerprinting risk from sending coins to e.g. atypical P2SH scriptPubKeys.
I think everyone agrees that at the very least non-v0 P2WPKH custom change addresses should prompt a warning. There is also an argument to also warn the user for non-v0 P2WPKH receiving addresses. Finally there is an argument simply to forbid sending directly to non-v0 P2WPKH addresses in the CoinJoin transaction at all.
What to do, if anything?
The text was updated successfully, but these errors were encountered: