Skip to content
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

Punish disrupting coins based on misbehavior #11052

Merged
merged 9 commits into from Jul 28, 2023
Merged

Conversation

lontivero
Copy link
Collaborator

@lontivero lontivero commented Jul 17, 2023

According to the document [WIP] Denial of Service Protection, section: How to protect Wasabi / Banning offending coins. We need to remember offending coins in order to be able to ban a family of coins (a coin and all its descendants tree) which should inherit the punishment for n generations.

The document also highlights that different misbehavior should be punished differently and also that the severity should be based on the amount involved, the number of times that the coin had misbehaved and whether it comes from a previous conjoin or not.

In order to implement those features we need to store additional information like the amount used to attack the coordinator, the kind of misbehavior (failed to verify, failed to confirm, failed to sign, double spent, cheating with invalid data/crypto, and maybe other in the future).

A draft punishment calculation is included here too and works as follow:

  • Punishment for FailToVerify is fixed (a configurable constant in the config file)
  • Punishment for Cheating is fixed (a configurable constant in the config file)
  • Punishment for RoundDisruption are calculated as follow:

$punishment = amount / severity * 2 ^ {countOffenses} * greatestOffenseFactor$ where $greatestOffenseFactor$ is the factor of the biggest offense made with the coin.

Finally, there is a minimum time in prison that can be used to prevent banning coins for a very short period of time or to mimic previously know noted punishment.

Copy link
Collaborator

@adamPetho adamPetho left a comment

Choose a reason for hiding this comment

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

Before this gets deployed, we will need to delete the existing Prison.txt, right?

@lontivero
Copy link
Collaborator Author

Before this gets deployed, we will need to delete the existing Prison.txt, right?

No, the Warden will delete it because there will be problems deserializing it.

Copy link
Collaborator

@kiminuo kiminuo left a comment

Choose a reason for hiding this comment

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

First minor review. Will continue tomorrow.

WalletWasabi/WabiSabi/Backend/Rounds/TimeFrame.cs Outdated Show resolved Hide resolved
namespace WalletWasabi.WabiSabi.Backend.DoSPrevention;

public record DoSConfiguration(
decimal Severity,
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be easier to review knowing what exactly this value means and what the range of values is.

Looking at how it is used, it seems like it's a value in BTC. If it is in BTC, then knowing the unit (calling it SeverityBtc?) is easier to review and harder to make a mistake (e.g. assigning a value in sats).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Severity is what in the design document we call "penalty unit": #10831

How long to ban

The severity of the penalty should take into account the type of infringement, the residence and the amount involved. One possible alternative would be to introduce a penalty unit: btc/hr. For example, imagine we establish the standard severity as 10btc/hrs so, if the offending coin is 1btc then it should be banned for 10hrs, if the offending coin is 5btc then it should be banned for 2hrs.

I don't know how to pick a better name, what about SeverityInBitcoinsPerHour? It sucks but at least is more descriptive WDYT?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Btw, is it better to think in btc/hr or hr/btc?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Imho the source of truth is the source code. So it can be called Severity and it can have a comment explaining what it is. Not everything can fit into a variable.

Or one can just mention #10831 link.

SeverityInBitcoinsPerHour sounds OK to me. It's bit mouthful but it helps to read the code so I find it good.

Btw, is it better to think in btc/hr or hr/btc?

Hm, I don't know. I guess I can more easily compute in hr/btc and what we want to express is the time, so having a unit which expresses primarily the time might be good.

1 hr/btc would mean ban 1 BTC for 1 hour, but it can also mean "ban 0.5 BTC for 30 minutes"

WalletWasabi/WabiSabi/Backend/WabiSabiConfig.cs Outdated Show resolved Hide resolved
@adamPetho
Copy link
Collaborator

I'm testing this on RegTest and it works fine.

But I think we need to fine tune the banning periods.

My coin (2.47 BTC) "failed" to confirm connection and now is banned for 2 days + 2 hours.
It was the first misbehavior of that coin.

Same coin with clean history (deleted Prison.txt) "failed" to sign and now is banned for 3 days + 2 hours.

Isn't this a bit harsh?

@lontivero
Copy link
Collaborator Author

@adamPetho that was a bug. Under those conditions your coin should have been banned for 16 minutes.

@turbolay
Copy link
Collaborator

Should the SelectCoinsForRound take this into account? Maybe it would become interesting in some conditions to wait the few minutes required so that a certain coin will be unbanned.

I like the idea of banning for a small amount of time because it could be a net benefit as it would make the client wait when conditions are temporarily bad, but I'm concerned about making suboptimal selections because of this, and so that clients end up using more block space.

WalletWasabi/WabiSabi/Backend/DoSPrevention/Offender.cs Outdated Show resolved Hide resolved
WalletWasabi/WabiSabi/Backend/DoSPrevention/Prison.cs Outdated Show resolved Hide resolved
WalletWasabi/WabiSabi/Backend/DoSPrevention/Prison.cs Outdated Show resolved Hide resolved
namespace WalletWasabi.WabiSabi.Backend.DoSPrevention;

public record DoSConfiguration(
decimal Severity,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Imho the source of truth is the source code. So it can be called Severity and it can have a comment explaining what it is. Not everything can fit into a variable.

Or one can just mention #10831 link.

SeverityInBitcoinsPerHour sounds OK to me. It's bit mouthful but it helps to read the code so I find it good.

Btw, is it better to think in btc/hr or hr/btc?

Hm, I don't know. I guess I can more easily compute in hr/btc and what we want to express is the time, so having a unit which expresses primarily the time might be good.

1 hr/btc would mean ban 1 BTC for 1 hour, but it can also mean "ban 0.5 BTC for 30 minutes"

Copy link
Collaborator

@kiminuo kiminuo left a comment

Choose a reason for hiding this comment

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

Second review batch

@adamPetho
Copy link
Collaborator

adamPetho commented Jul 21, 2023

I think there is still a bug in the punishment calculation.
My coin (0.00039366 BTC) failed to confirm connection once and got banned until 1st of August.
My other coin (0.00065536 BTC) failed to confirm once and got banned until 28th of July.

@lontivero
Copy link
Collaborator Author

@adamPetho why do you think there is a problem? I don't know all the details but it makes sense to ban the smaller coin for much longer than the bigger coin, that's the whole idea.

@adamPetho
Copy link
Collaborator

adamPetho commented Jul 21, 2023

@adamPetho why do you think there is a problem?

If it's not a bug, then we are just way too harsh IMO.
One failed confirmation (one mistake) and the coin is banned for 12 days?

IMO it's a bit tough.

Also, failing to confirm and failing to sign seemingly gives my coin the same banning period. (Until 1st of August)

Punishing bigger coins seems to work fine.
Coin (0.01 BTC) failed to sign and banned until 07/22 3:28 AM. This seems reasonable.

@lontivero
Copy link
Collaborator Author

lontivero commented Jul 21, 2023

That's why this is configurable. The idea is to review the code (the logic) because the parameters are unknown and should be tuned by the administrator. If you think that the punishment for fail to confirm should be 10 times less then you can switch the PenaltyFactorForDisruptingConfirmation from 1 to 0.1.

If the air conditioner is cooling the room too much, that doesn't mean that it is broken but that it was configured to keep a low temperature that is uncomfortable for someone.

@lontivero
Copy link
Collaborator Author

@adamPetho @kiminuo is there something else that you need to approve this thing?

Copy link
Collaborator

@adamPetho adamPetho left a comment

Choose a reason for hiding this comment

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

@adamPetho @kiminuo is there something else that you need to approve this thing?

Not from my side.

tACK on RegTest

@lontivero lontivero merged commit dae3b7f into zkSNACKs:master Jul 28, 2023
6 of 7 checks passed
@lontivero lontivero changed the title [PoC] Redo prison Punish disrupting coins based on misbehavior Aug 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants