coder5876 / simple-multisig

Simple multisig for Ethereum using detached signatures
MIT License
247 stars 108 forks source link

Nonce window #32

Closed devrandom closed 6 years ago

devrandom commented 6 years ago

Motivation

Multi-sig transactions are likely to take longer to finalize, because of the need to collect signatures from multiple parties. For higher security setups that include offline keys, this may be hours or days. When a transaction is pending, it is difficult to start the workflow for a second transaction, because we don't know what nonce to use. Optimistically it should be the next value, but if the current transaction is rejected, that value would not be useful since nonces must be consumed in strict sequence.

Description

This PR converts the scalar state nonce into the state array noncesArr. Multiple transactions can use different slots in this array. A pending transaction can be aborted by use of cancel_nonce() and the slot freed up for further use.

coder5876 commented 6 years ago

@devrandom This looks like a great example of the type of complexity this multisig contract was specifically designed to avoid. Skimming through the description and the code I have a very hard time reasoning about what's going on, and the new code introduces complex state like the ability to cancel stuff and some new admin address that have some special powers.

Reading the Motivation section above, it looks like you can easily overcome those challenges using the current version of the contract by simply signing a transaction multiple times with increasing nonces. I.e. if the nonce is currently 5, sign the transaction with nonces 5, 6, 7. Then if some other transaction uses nonce 5 you can execute with nonce 6 instead.

devrandom commented 6 years ago

I do understand that the goal is to keep complexity low, but this particular motivation (transaction signing taking a significant amount of time, resulting in overlapping signing processes) is specific to multisig setups.

The problem with the solution in the second paragraph is that it defeats the purpose of the nonce - preventing replay attacks. Signing with multiple nonce values can result in an attacker publishing the same intended transaction multiple times.

coder5876 commented 6 years ago

A solution that is more secure against double spending:

If you sign a transaction with a nonce n you can simultaneously sign a "cancellation" transaction with the same nonce, that would send a transaction of zero ETH to a specifically chosen address not used for anything else.

Then if you need to cancel a transaction you would send the cancellation transaction instead of the real one, and this way you can make sure the nonce will always update even if you cancel your original transaction.

devrandom commented 6 years ago

That sounds reasonable. A small issue with this is that you can't publish transactions out of order.

Closing this PR and will think about it further. Thank you.