Improvement proposal: Dynamic TX confirmation times

Given recent 51% attacks, it has become apparent that exchanges are not waiting an appropriate confirmation time before approving deposits. My speculation, is that “lazy” exchanges or users may simply query the reference wallet API to determine when a transaction is considered confirmed, and today that period is fixed to 10 blocks. This period is very short and any exchange that uses only a 10 block period is quite vulnerable to 51% attacks.

I would like to propose changing the default wallet confirmation time to a dynamic confirmation time proportional to the value of a transaction (keeping 10 as the minimum confirmation time). This way, the default behavior will be “slow but secure”. Advanced users may still choose to override this, and use a “faster” confirmation time depending on their need. This will help any non-technical (or “lazy”) user/exchange avoid using unwise confirmation times; thus helping reduce the viability of 51% attacks.

For example: when receiving a small transaction (say 60 Grin), the wallet will still display a confirmation time of only 10 blocks. For a large transaction (say 6,000 Grin), the wallet will display an appropriately larger confirmation time.

This is simply a wallet UX proposal. I am not suggesting any network/protocol change.

I am willing take the time to formalize an RFC and even take on the appropriate development effort (if applicable). Before starting down that road, I would first like to solicit some feedback from the community on the following questions:

Do people agree with the idea of the reference wallet defaulting to dynamic confirmation times?
Is this a waste of time? Maybe its just better to spend effort educating users & exchanges about appropriate confirmation times? Maybe my assumption is wrong, and exchanges don’t even use the reference wallet? Even if these are the case, I still think its a good idea to adjust the default wallet behavior, but I would like to know what the community thinks.

What is an appropriate calculation for confirmation time?
A naive approach would say wait amt/60 blocks (6000 Grin would wait 100 blocks). A 51% attacker may still profit from performing a 100 block reorg (attacker gets 100 blocks reward + double spend their 6000 Grin TX to you + maybe other double spends in the same 100 block period). I don’t think there is an answer for “how long should confirmation take” that applies to all users in all use cases, so it may be a lost cause trying to answer this question perfectly. In that case, what do you think is a “reasonable default” that would be “more secure for the average user”? Maybe the wallet communicate the risk to the user better to the user, so the user can make an informed decision on their own?

How should this be designed?
My original idea is this:

  • Default wallet API provides the default dynamic confirmation time.
  • Users may override this in their grin-wallet.toml to be some other fixed time (or perhaps adjust the calculation)
  • Default “send” API will not allow to spend unconfirmed UTXOs, but this can be overridden with a --force option, or something like that.

Any suggestions or constructive criticism is greatly appreciated. Feel free to tell me if you think this idea is a waste of time and should be abandoned :slight_smile:

1 Like

I’d like to add a disclaimer. I am a Rust developer and fairly technical, but I am not very familiar with the Grin codebase. Its possible I am misunderstanding certain details about the wallet functionality, in which case I wholeheartedly welcome an education from those who are more familiar with the inner workings.

Your idea is a reasonable approach. However, it’s hard to have a native wallet calculation determine the real world financial value security; The parameters range from grin’s price to ASIC effectiveness, not sure how the calculation can be made?

The calculation would have to work under the assumption that ASICs do not significantly impact Grin’s graphrate. Which is the case today. But may not hold in the near future.

For a rough calculation, let’s say the attacker wants to have 56.5% of total graphrate. That means they need to rent 56.5 / 43.5 ~ 1.3 times the current graphrate.
Assuming a tidy profit for nicehash, and some overhead for cashing out, this might cost them 1.5 Grin per second. (actually, the nicehash c32 rental price went up by x1.7 during the attack, so it might have cost them closer to 2 Grin per second.we’re just being conservative here).
To doublespend X Grin in N blocks, they spend N * 90 Grin and gain X + N * 60 Grin, for a net gain of X - N * 30 Grin. So we’d like N > X / 30 to make the attack unprofitable.

1 Like

I like the idear, protecting users in addition to educating them is never wrong. If exchanges or users overwrite the default confitmation time that protects them, it is safe to assume they know what they are doing.
Not sure about the exact calculation but anything that takes into account the value of the transfer is better than having the fixed confirmation time of 10 blocks.

In addition, if a warning system to detect anomolies in the hash rate is setup, it would be cool if somehow users could get a warning in the wallet itself, not sure if and how this is possible though.

1 Like

I agree, the calculation should not be impacted by the introduction of ASICs. That said, any calculation I can think of depends on only the TX value and block reward. Factors such as network difficulty, graph rate, block time, etc, need not play into the calculation. Given this, I don’t think ASIC introduction or other graph dynamics would impact the security of this calculation.

I think there is a mistake in your calculation. The attacker not only gets back the X he gave to you, but presumably redeemed X Grin worth of goods/services/BTC from you in exchange. Since those goods/services/BTC were worth X grin, that means the reward for his attack is really:

attack_reward = X           /* Reclaim X Grin sent to victim */
              + N * 60      /* Claim N block rewards */
              + X;          /* Claim X Grin worth of goods/services/BTC from victim */

Which really comes out to an attacker reward of 2X + 60N. Parameterizing the attacker’s cost multiplier P (the relative cost to rent hashpower for the attack), the modified equation becomes:

attacker_profit = 2X+60N-60*N*P
                = 2X - 60N*(P-1)

To be "financially secure", choose N such that:
N >= X/(30(P-1))

For your example where the attacker pays 1.5 Grin per second (i.e. P = 1.5), we should choose N >= X / 15.

Unfortunately this is still a naive computation, as we cannot know if the attacker may double spend other victims in the same attack (increasing attacker’s reward), but it seems better than the current fixed value of 10, and I’m not sure we can do any better than this without knowing the value of other pending UTXOs (which obviously we cannot see).

I suggest we go forward with this equation and choose default P = 1 (pessimistic assumption that attacker can buy hashpower at 1 Grin per second), and allow advanced users to override P if they are comfortable with shorter confirmation times, based on their own security concerns.

This is an interesting subject too. I believe @notguilty is playing around with this idea for a separate feature/service, but I may be wrong.

1 Like

Yes, which is a net profit of X, not 2X.

Ah yes, your original equation was correct. Thats what I get for responding before having my coffee :man_facepalming: