-
Notifications
You must be signed in to change notification settings - Fork 29
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
[WIP] Safe cancel #71
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
|
||
- Title: safe-cancel | ||
- Authors: [John Tromp](mailto:[email protected]) | ||
- Start date: Oct 10, 2019 | ||
- RFC PR: Edit if merged: [mimblewimble/grin-rfcs#0000](https://github.com/mimblewimble/grin-rfcs/pull/0000) | ||
- Tracking issue: [Edit if merged with link to tracking github issue] | ||
|
||
--- | ||
|
||
## Summary | ||
[summary]: #summary | ||
|
||
Allow for safe cancellation of pending transactions, preventing future so-called play attacks. | ||
|
||
## Motivation | ||
[motivation]: #motivation | ||
|
||
A wallet cannot simply cancel a pending transaction by forgetting about it and returning its inputs to the wallet balance. | ||
Especially not when the other party is responsible for completing and broadcasting the transaction. | ||
They may still do so at any time as long as the inputs are not spent differently. | ||
|
||
## Community-level explanation | ||
[community-level-explanation]: #community-level-explanation | ||
|
||
Suppose Bob as the receiver sends Alice as the sender an invoice slatepack | ||
(Receiver-Sender-Receiver or RSR flow) to which Alice responds, but then Bob | ||
doesn't finalize it. He might suggest a problem with the invoice, with his | ||
wallet, or the exchange rate, or the (suddenly realized) | ||
need to pay in a different currency. Whatever the case, he convinces Alice to | ||
have the current transaction cancelled. Alice is fine with that, but needs to | ||
make sure that Bob doesn't later complete the transaction and steal Alice's | ||
inputs. | ||
|
||
Alice has two options; spend a transaction input back to herself (a self-spend), or | ||
construct a new transaction that shares at least one input with the | ||
old transaction. The former is cleaner, but requires separate fees, and possibly waiting | ||
for confirmation. | ||
|
||
The wallet provides a command for each of these options. | ||
|
||
grin-wallet respend [OPTIONS] | ||
|
||
will mark the pending transaction, specified either by ID or TxID UUID, | ||
as requiring one of its inputs to be spent in the very next wallet spend. | ||
|
||
grin-wallet unspend [OPTIONS] | ||
|
||
will generate and broadcast a self spend of an input of | ||
the pending transaction, specified either by ID or TxID UUID, | ||
|
||
The problem is not limited to RSR flow. In the more common SRS flow, once the | ||
sender has signed and published the transaction, it can still fail to confirm. | ||
|
||
It could be that one of the nodes in the Dandelion stem drops it, either by | ||
accident or on purpose. Alternatively, it could be explicitly rejected by the | ||
mempool. | ||
The receiver can arrange for that to happen by (slightly earlier) publishing | ||
another transaction with an identical output. When two transaction conflict by | ||
sharing either an input or an output, the first to enter the mempool will block | ||
the second from entering. | ||
|
||
In case the sender's wallet notices that failure to confirm is due to a | ||
conflicting transaction, it should alert the user that the receiver is being | ||
malicious. | ||
|
||
## Reference-level explanation | ||
[reference-level-explanation]: #reference-level-explanation | ||
|
||
## Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
The user is required to understand the trade-offs between the two types of cancel. | ||
|
||
## Rationale and alternatives | ||
[rationale-and-alternatives]: #rationale-and-alternatives | ||
|
||
The simpler alternative is to always do a self spend. Giving the user control | ||
over whether to spend extra fees seems preferrable though. | ||
|
||
## Prior art | ||
[prior-art]: #prior-art | ||
|
||
Coins such as Monero suggest the use of self spends to reduce linkability, but our motivation is quite different, | ||
and with likely no aggregation in the Dandelion stem phase, self-spends in Grin do nothing to reduce linkability. | ||
|
||
## Unresolved questions | ||
[unresolved-questions]: #unresolved-questions | ||
|
||
## Future possibilities | ||
[future-possibilities]: #future-possibilities | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One possibility that came to mind: mitigate the receiver's ability to block by creating another transaction with the same output. Not sure exactly how this would work, but maybe including in the output some contribution from the sender that can't be included/unlocked by the receiver until the transaction is fully signed. My understanding of the problem is that the receiver creates/spends a transaction between step 2-3 in SRS flow (1-2 or later in RSR), which spends their output added in step 2. If the sender creates the receiver's output, and includes a contribution (something like a commitment opened at the end of step 3), then the receiver would be unable to create a tx with the duplicate output. Again, not sure exactly how that would work, since the commitment would need contribution from both sender and receiver, else sender could just steal back the output from the receiver. What do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are 2 ways to attack as the receiver:
If I understand correctly, you're tackling the 1. problem with your idea. I thought about a similar concept a long time ago which I referred to as "unpredictable outputs" where I wanted to randomize the commitments based on the PoW in the block (or block hash) they were included in (you know in which block an output was added so you could get the original commitment back through a simple computation), but this has some obvious downsides:
I think your direction of having the output have this unpredictability at the transaction level does not suffer from these two issues and might solve the blocking tx problem (however, the withholding would still be an issue I believe). But I'm not sure how this would be done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that the receiver in MW should have full control over their outputs, which includes the ability to create duplicates. It doesn't seem too difficult to identify the reason why a published tx fails to confirm. |
||
|
||
## References | ||
[references]: #references | ||
|
||
Include any references such as links to other documents or reference implementations. | ||
|
||
- [reference 1](link) | ||
- [reference 2](link) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make
respend/unspend
one sub-command with options to choose the transaction-style + fees. Think this would be clearer to the user, and could even have an interactive UI component explaining the tradeoffs (more of an implementation detail).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking about this as well. We will have 3 ways to cancel a transaction "cancel, unspend, respend" which might be confusing to the user. Would it make sense to join these commands e.g.
./grin-wallet cancel -unspend
or./grin-wallet cancel -respend
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and grin-wallet cancel -unsafe to reproduce current behaviour?