Skip to content
This repository has been archived by the owner on Jun 3, 2018. It is now read-only.

Double spend notification draft spec #57

Closed
wants to merge 0 commits into from
Closed

Double spend notification draft spec #57

wants to merge 0 commits into from

Conversation

cpacia
Copy link

@cpacia cpacia commented Mar 27, 2018

No description provided.

@dgenr8
Copy link
Contributor

dgenr8 commented Mar 27, 2018

I strongly agree with the policy of alerting peers to the first respend event for a utxo, for the reasons given in the draft, and more. But relaying the respend transaction itself is a better option than the proposed proof message.

-- The proof message strips the outputs from the respend which means, if the merchant happens to see the illegitimate transaction first, he will not see the tx that pays him until its possible confirmation, nor will he see any notification until then. This will not be uncommon since it is difficult for the attacker to target the merchant and miner nodes.

A better UX is to notify the victim immediately of the double-spend attempt regardless of the order in which he sees the messages. This requires relaying the full second-seen transaction.

-- The proof message adds complexity. Instead of two transactions on the network, you have two transactions and two versions of the alert. In fact, to be sure of alerting all nodes, the detecting relay node has to generate two alerts: the additional one is for the transaction the detecting node actually saw first but which may not have been seen first by others.

-- Relaying the second-seen transaction does not increase the risk of a successful economic double-spend. Clients would simply be modified to stop ignoring such transactions and instead treat them as alerts.

There is one advantage of the proposed special-purpose 'dblspndnotif' proof message, which is a somewhat smaller and more predictable size.

In this comment I assumed one utxo and just two spends for clarity.

@HostFat
Copy link

HostFat commented Mar 28, 2018

-- The proof message strips the outputs from the respend which means, if the merchant happens to see the illegitimate transaction first, he will not see the tx that pays him until its possible confirmation

If the merchant doesn't see the legit tx, it isn't an issue, he will just NOT give the product/service.
If he receive the alert before the legit tx, when/if he will receive the legit tx, the wallet will show the warning.
The warning/alert remains "invisible" on the wallet interface until he receive the legit tx.

@Danconnolly
Copy link

If the merchant does not see the "legit" tx at all then this will cause confusion (scene: coffee shop - waiting for point of sale system (POS) .. where's the tx? I dunno? Is something wrong with the POS? I dunno ... hey Jim, take a look ... etc, etc)

@HostFat
Copy link

HostFat commented Mar 28, 2018

If it is a double spend attack, the merchant will receive one tx for sure.

I can agree that an alert from receiving the double-spend tx attempt or the double_spend_proof can be likely the same from the point of view of the merchant, but with the double_spend_proof, the attacker has a higher risk that one tx (the first one that attacker wants to show to the merchant) will reach the merchant, but still there will be the alert showed.

So money "lost" (from the attacker) and bad publicity.
I think that on this way the incentive to make double spend attempts will be lower ...

@HostFat
Copy link

HostFat commented Mar 28, 2018

@Danconnolly
Maybe you are right, I mean the attacker can show the phone to the merchant, to show that he did the tx, while the merchant only received the double_spend_proof, and this can cause some confusion.

But it is still bad for the attacker, he is losing time, and if he remains here, the merchant will likely receive the warning on the phone/pos. (both the double_spend_proof and the right tx)

The attacker to be able to succeed he needs both that the miner where he sent the double-spend tx will not spread it on the network and that he will mine the next block.

@cpacia
Copy link
Author

cpacia commented Mar 28, 2018

-- The proof message strips the outputs from the respend which means, if the merchant happens to see the illegitimate transaction first, he will not see the tx that pays him until its possible confirmation, nor will he see any notification until then.

So it should be noted that this currently happens on the network since double spends do not propagate. So this isn't exactly new behavior. Also, to the extent the merchant and buyer use bip70 the merchant will always see the payment tx since the payment protocol has the ability to push the tx directly to the merchant.

@cpacia
Copy link
Author

cpacia commented Mar 28, 2018

So let me give a concrete example from a few years ago and compare what the outcome would have been under double spend relaying vs double spend proof relaying:

Eligius mining pool, with 10% of the network hashrate, has a mempool policy where they refuse admittance for any transactions paying to a Satoshi Dice output. Knowing this, an attacker creates a transaction with one output paying a merchant and another output sending a small amount of coins to Satoshi Dice. This transaction propagates around the network and is rejected by Eligius. The merchant waits 10 seconds listening for double spends, and when none come, accepts the payment. The buyer leaves the store then broadcasts his double spend.

Under double spend relaying: the double spend propagates around the network reaching Eligius, who accepts it into its mempool. The double spend now has a 10% chance of being mined.

Under proof relaying: the double spend never makes it past the first nodes the buyer sent it to. Eligius receives the double spend proof but since it's not a valid transaction, the double spend does not get included in its mempool and never gets mined.

Of course this isn't going to prevent everything but it does reduce the likelihood that the double spend will make it to miners. Marginally improving security.

@avl42
Copy link
Contributor

avl42 commented Mar 28, 2018

I'd like to add an idea, that I didn't see in the spec: a double-spend proof message might be designed to also contain the original receivers, such that merchants who do not run a full node but instead filter for their addresses might still notice the double spend. This might not be trivial, and I haven't yet thought through all corner cases like e.g. triple-spends, but maybe, if details can be worked out, then it might in future obviate the need for merchants to run full (though typically non-mining) nodes.

@dgenr8
Copy link
Contributor

dgenr8 commented Mar 28, 2018

@cpacia We can't rely on the attacker to fail to propagate his attack to the miner.

Do you agree that two 'dblspndnotify' alerts would need to be generated as I described? In the case of a small time gap between the transactions, a particular alert is invisible to half the network because nodes are 'taking sides' on the identity of the respend.

Another attack relies on a non-standard and malicious first spend placed with a miner many seconds before the merchant is paid. In this case, the second-seen transaction is the legitimate one. This can be addressed by creating super-standard criteria required for double-spend protection, and a replacement rule where non-super-standard mempool transactions are replaced by a super-standard conflict.

@jasonbcox
Copy link

I agree. Simply propagating double spend transactions rather than proofs + deprecation of blocks with double spends is the simpler solution in the long run (since we need deprecation of blocks with double spends whether we use proofs or not).

@cpacia In the situation of Eligius, assuming we have deprecating of blocks with double spends, Eligius simply puts themselves in a position of increased orphan rates. The rest of the network is unharmed.

@cpacia
Copy link
Author

cpacia commented Mar 30, 2018

In the case of a small time gap between the transactions, a particular alert is invisible to half the network because nodes are 'taking sides' on the identity of the respend.

I'm not sure. If you imagine two conflicting txs introduced from the edges of the network, while they are propagating the other tx will be invisible to the other side. But eventually they will meet somewhere in the center and some nodes will detect the double spend and send out the alert going back in the direction it came from. I'm not sure it's possible to prevent the alert from propagating.

Another attack relies on a non-standard and malicious first spend placed with a miner many seconds before the merchant is paid. In this case, the second-seen transaction is the legitimate one. This can be addressed by creating super-standard criteria required for double-spend protection, and a replacement rule where non-super-standard mempool transactions are replaced by a super-standard conflict.

Not sure I follow but this seems like it could be another reason for using an alert rather than the double spend itself. If the double spend is non-standard it will have a hard time propagating to all nodes. But alerts don't care about standardness.

@tyler-smith
Copy link

Instead of two transactions on the network, you have two transactions and two versions of the alert. In fact, to be sure of alerting all nodes, the detecting relay node has to generate two alerts: the additional one is for the transaction the detecting node actually saw first but which may not have been seen first by others.

Do you agree that two 'dblspndnotify' alerts would need to be generated as I described? In the case of a small time gap between the transactions, a particular alert is invisible to half the network because nodes are 'taking sides' on the identity of the respend.

I don't think an alert needs to attempt to specify which tx is the double (or triple, etc) spend, it should be sufficient to prove that some UTXO was attempted to be spent multiple times. That should be all a merchant needs in order to know it can't trust 0-conf for this transaction and needs to wait until there's a confirmation before accepting the payment.

Perhaps I'm missing something, but what information would be gained by having a separate alert for each spend attempt instead of just one for all multi-spend attempts for a given UTXO?

@dgenr8
Copy link
Contributor

dgenr8 commented Mar 31, 2018

@cpacia That's why I said a particular alert. Anyway I'm not convinced by your argument that merchants in half the network already can't detect the respend today since that is the problem we're trying to solve.

In the last example, the attacker specifically relies on the transaction not propagating because it's malicious and placed directly with a miner.

@tyler-smith Anything that isn't signed by the utxo owner can be trivially faked.

@zander
Copy link
Contributor

zander commented Apr 2, 2018

You may be interested in this writeup I did about the design for proofs.
https://bitco.in/forum/threads/buip085-double-spend-relaying.9306/#post-60999

The proofs in that writeup allow you to

  • validate the proofs validity without the presence of either transaction in your mempool.
  • Have a constant-size proof. You don't include scriptsigs etc, nor any part of the transaction that is irrelevant to the point-of-sale merchant.
  • avoid giving one priority over the other. This is really important.
    I suggest the spec specifying to sort spends by hash (txid) to avoid having two proofs of the same double-spend.
  • avoid sending a second transaction in total. Just like today.
    This eliminates the problem where a huge second transaction would delay PoS notifications.
  • And, to address dgenr8's point. This means that the complexity of the proof is thus lower that the complexity of having to send&parse two transactions. One canonical proof instead of two inv's that may or may not be related.

@HostFat re the first tx seen part...

I expect that block-explorers will be updated to show that the transaction is a double-spend after this spec gets implemented. At such a moment where the customer uses old-fashioned QR codes and then insists that he paid, they can go to any of the block-explorers to validate this claim and that will just lead the customer to get caught again.

I really so no downsides to the usecase where the merchant never sees the tx meant for him due to double-spend getting it rejected. The customer doesn't get his product. Simple.

Oh, and yeah, we want to get rid of that system anyway. Wallets should give their transaction to the merchant, so the merchant can broadcast it.

Cheers.

@dgenr8
Copy link
Contributor

dgenr8 commented Apr 2, 2018

Downsides:

  • Can't distinguish this problem from a network or other problem
  • Wastes 30+ seconds of everyone's time in the line behind our attacker ("sorry folks ... bitcoin ...")
  • Thinks it's not a double spend because "when it's a double spend, the transaction appears and turns red"

@zander
Copy link
Contributor

zander commented Apr 2, 2018

The last problem you mention may be easiest to address with a payment protocol that makes the user send his transaction to the merchant instead of to the network. Something we already see a large step towards today (bitpay).

As NFC payments rise, I expect this practice (of sending the tx to the merchant) to continue and the problem you worry about to also vanish.

@dgenr8
Copy link
Contributor

dgenr8 commented Apr 2, 2018

Maybe we have different goals. I think it's just as important for these alerts to work for individual users where it may not be practical to receive the transmission directly.

Also, the double spender can switch his strategy to placing a non-relayable self-paying transaction with miners just before paying the merchant. A little more is required to solve this, but a proof solution will work against getting the legitimate tx mined.

@zander
Copy link
Contributor

zander commented Apr 2, 2018

It is super important to work for all users. Definitely agreed!

As an aside, I love we have a general agreement on most of this.

Yes, this issue you found is tricky. Mostly because it is about people being in conflict.
The idea of using NFC to do payments is not limited to merchants, however. We have seen this also advocated for person-to-person payments. As a long time Blackberry user, I can attest to the fact that the NFC concept is awesome. I use it to share pictures with people I just met and don't even know the name of.
The point being that a NFC based payment protocol isn't just for merchants.

This approach would solve a host of other issues with SPV wallets, like privacy and off-line wallets. (off-topic here)

To see more info on the topic of double-spends, please see the FAQ here;

https://www.yours.org/content/a7b728f7bc2c

@cpacia
Copy link
Author

cpacia commented Apr 5, 2018

@zander how does the spec in this PR differ from what you had in mind for proofs?

@zander
Copy link
Contributor

zander commented Apr 5, 2018

@cpacia this spec doesn't give all the information needed to create a sighash and as such you can't use the pubkey from the script to validate the proofs.

It isn't a proof because anyone can create a bogus alert.

See the code here to show all the pieces of info you need;
https://github.com/floweethehub/hub/blob/master/libs/server/script/interpreter.cpp#L1240

I would also suggest sorting the proofs based on some hash in order to make sure that only one proof can be generated from any number of double spends (i.e. reordering becomes impossible).

Copy link

@alexisbasques1 alexisbasques1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t see an issue

@schancel schancel force-pushed the master branch 4 times, most recently from 474191d to 8ce6798 Compare May 14, 2018 20:26
@cpacia cpacia closed this Apr 2, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants