Closed aesedepece closed 1 month ago
Some previous discussions about this topic:
Some interesting reading:
Some proposals from my end to be discussed:
Just to make sure I'm following, we are only debating power slashing here, right?
Some notes:
n+1
when epoch n
had no block proposed. I think this tackles the weaknesses in your second (and third) proposal. I'm not quite sure why you would only do it at the boundary of a super epoch, but maybe I missed something in our previous discussions.rf
implemented because that makes it truly variable and so it needs to be saved somewhere, not just as a code constant.I think the most reasonable take is to:
rf
most powerful validators (stake entries, actually!) are eligible for block proposing.h
), or none if no candidates were received.I see this as a simple and elegant solution that disincentivizes power hoarding and largely mitigates the potential harm to network liveness and oracle service quality that powerful yet lazy, malicious or faulty validators could have.
For more color on the proposal above:
rf
power elite but less powerful than the winning one (e.g. you receive candidates from 3rd and 4rd, consolidate 3rd and slash 1st, 2nd and 4th). However, the consolidation of a certain block candidate (and eventual signaling through beacons) only evinces that you received no more powerful candidates, but the fact that you received less powerful block candidates is hidden from beacons. This is to say that I would run away from this type of slashing for now because, paradoxically, it could be a source of forks and therefore work against liveness of the network which is what we're trying to go after with this debate.
- Power-slashing happens in the same epoch. By the end of each epoch, when the winning block gets consolidated, the slashes are applied accordingly so that the eligibility for the next epoch already takes into account the updated powers.
I'm a bit confused by this statement. Unless I misunderstand the code, block consolidation happens at the beginning of the next epoch, not at the end of the current epoch. This also implies that slashing needs to happen at that time and not earlier.
This is not an issue for data request and block mining. Block mining already is postponed through a ctx.run_later
call which results in a block being built mid-epoch (so long after the power changes). Data request mining happens in the EpochNotification handle
function a couple of lines after slashing the power if no block was consolidated. I think both of these mechanisms result in the node always having a correct view of the stake powers when using them to check its eligibility.
I'm a bit confused by this statement. Unless I misunderstand the code, block consolidation happens at the beginning of the next epoch, not at the end of the current epoch. This also implies that slashing needs to happen at that time and not earlier.
Sorry I was speaking top of my head. It is exactly as you mentioned. I was speaking rather from the perspective of protocol design than the particular implementation in witnet-rust. The logic is still the same. The bottom line is that coin ages get adjusted upon consolidation just like UTXO set or any other data structures that belong to the chain state are.
Sorry I was speaking top of my head.
No worries, just wanted to make sure we were completely on the same page as this is a pretty important decision and has a significant impact on the consensus algorithm.
3. Power-slash every stake entry with a power higher than the one that was consolidated.
Note that his is currently not implemented for the simple reason that, in my mind, it is a much more severe penalization mechanism. My goal with the slashing was purely to preserve chain liveness with as little impact as possible. If we go the route of slashing everyone with a higher power too, we wander into the area of potentially slashing nodes that are being censored, DOS'd, etc. I consider that to be more contentious and I wanted to steer clear from it the initial wit\2 integration.
If we go the route of slashing everyone with a higher power too
Then your suggestion is to apply slashing to everyone in the rf
commitee only in the scenario where there is no block candidates?
If we go the route of slashing everyone with a higher power too
Then your suggestion is to apply slashing to everyone in the
rf
commitee only in the scenario where there is no block candidates?
That is what I have currently implemented, yes, but solely for the sake of (game-theoretic) simplicity. I'm not opposed to the other option, I just wanted to keep my patch as little contentious as possible.
The one thing I'm still not sure about is if I like the slash proportional to the rank option because slashing a high-power node by, e.g., 1/3 of his power feels a bit futile (at least on my artificial testnets).
we wander into the area of potentially slashing nodes that are being censored, DOS'd, etc.
I had this same concern, and that's why the article about the Witnet P2P Bucketing System was linked above. After solving multiple questions and possible flaws on current bucketing system, we came to agree that we should consider it to be strong enough to not auto-limit ourselves when thinking on possible slashing solutions.
not sure about is if I like the slash proportional to the rank option
Slashing in different proportions wipes out any attempt of an attacker feeding validators with exactly the same staked amount (the most naive way to take over the RF
top ranking arena), and also prevents reluctant top stakers having accrued similar power end up entering back into the top RF
rank on a periodical base.
e.g., 1/3 of his power feels a bit futile (at least on my artificial testnets).
I would need to assess the tests or simulations being done. A priori, I don't believe that reducing the power of a rank-3 validator by a third would be futile. What matters most is not how much power is reduced in absolute terms, though, but how much power is reduced in relation to higher ranked validators.
What about increasing RF
if no block was produced on previous epoch?
No matter the slashing approach we ultimately decide upon, there can always be the chance of an attacker taking over the RF
top ranking list. For the current value of RF = 4
, I think the chances are too high, and therefore we should either consider
(a) settle a higher value for the RF
constant,
(b) dynamically increase RF
in some proportion (maybe not double the previous value, but perhaps summing up RF
instead, for instance) if no block was produced in previous epoch (and reset to RF
otherwise),
(c) or both.
apply slashing to everyone in the
rf
commitee only in the scenario where there is no block candidates?
Because there can always be the chance of an attacker taking over the "rf
committee", slashing everyone in such committee if no block was consolidated on previous epoch should be a MUST. The ideal thing would be to power-slash all members of previous rf
committee at the beginning of the new epoch, so a new "rf
commitee" gets selected.
I had this same concern, and that's why the article about the Witnet P2P Bucketing System was linked above.
I'm inclined to agree with the article, I just wanted the current patch to be non-contentious. If no one objects to slashing stakers 1
to k-1
on consolidating a block from staker k
, I'm fully onboard with implementing this.
Slashing in different proportions wipes out any attempt of an attacker feeding validators with exactly the same staked amount (the most naive way to take over the RF top ranking arena), and also prevents reluctant top stakers having accrued similar power end up entering back into the top RF rank on a periodical base.
It does, but at the cost of having more epochs where one or more validators can refuse a block. I'm not really against it, but the consequence over fully slashing all validators is significant and I'm mainly wondering about the actual slashing ratios.
A priori, I don't believe that reducing the power of a rank-3 validator to a third would be futile.
Note that you are not reducing it to a third, but rather reducing it by a third (otherwise a rank 3 validator would be punished harsher than a rank 2 validator).
What about increasing RF if no block was produced on previous epoch?
Certainly not against it as that was part of my initial proposal, I'm just not sure how to implement it because that changes the rf
from a constant to a variable thing meaning it probably needs to be save in some chain state.
Note that you are not reducing it to a third, but rather reducing it by a third (otherwise a rank 3 validator would be punished harsher than a rank 2 validator).
Agreed, I actually meant "by a third" too, and just fixed it above.
It does, but at the cost of having more epochs where one or more validators can refuse a block. I'm not really against it, but the consequence over fully slashing all validators is significant and I'm mainly wondering about the actual slashing ratios.
I'd be more concerned about the number of epochs where all validators are prone to refuse a block. As a way to minimize periodical situations where all validators refuse a block, sequential prime numbers (p
) could be used to settle the slashing ratios (e.g. (p-1)/p
).
it probably needs to be save in some chain state.
Not really. Block proposers in epoch N
should know the last epoch M on which a block was consolidated. So the rf
value in epoch N
could be calculated as (N-M)*RF
, or RF*2^(N-M-1)
, for example.
Not really. Block proposers in epoch
N
should know the last epoch M on which a block was consolidated. So therf
value in epochN
could be calculated as(N-M)*RF
, orRF*2^(N-M-1)
, for example.
From what I can tell, this is true, if we're saying N
is the epoch of a block candidate (block.block_header.beacon.checkpoint
) and M
is the epoch of the last consolidated block (self.chain_state.unwrap().highest_block_checkpoint
).
Under that perspective, there would be a base replication factor constant, and a separate effective replication factor that grows progressively as epochs are completed without a consolidated block, and goes back to the value of the base constant as soon as a block is consolidated.
Is this what you are suggesting @guidiaz ?
self.chain_state.unwrap().highest_block_checkpoint
This may be interesting (and workable) as an approach. I was not sure how we could increment the rf
for nodes that were synchronizing (either from start or from recovering from a shallow fork) since I think they do not go through the consolidate block flow.
Under that perspective, there would be a base replication factor constant, and a separate effective replication factor that grows progressively as epochs are completed without a consolidated block, and goes back to the value of the base constant as soon as a block is consolidated.
Yes, that is what we discussed before on Telegram as a way to tackle the issue where there are more than the base rf
attackers.
This may be interesting (and workable) as an approach. I was not sure how we could increment the
rf
for nodes that were synchronizing (either from start or from recovering from a shallow fork) since I think they do not go through the consolidate block flow.
Nodes that are synchronizing do not go into validating anything related to eligibility, as they can't compare block candidates, etc.
About witnessing power-slashing
Because block proposers are sovereign to decide what dr-commit transactions to include, if any at all, there's no actual possible way to power-slash reluctant witnesses.
However, we should definitely care to reset the coin age of all different "witnessing identities" for whom at least on valid dr-commit transaction gets included in a block (a "witnessing identity" being any the unique validator-withdrawer pair in the Stake Tracker).
About validation of dr-commit transactions
From a block validator point of view, the following rules should apply in order to consider whether the dr-commit transactions contained within a block proposal are valid:
a) they have to refer to a not-yet-committed and not-yet-expired DR.
b) they have to refer an existing "witnessing identity" in the Stake Tracker.
c) referred "witnessing identities" should be within the resulting range described in witnessing eligibility condition (2) below.
d) their VRFs should be equal or greater than the threshold described in witnessing eligibility condition (3) below.
e) the current coins
field of the corresponding "witnessing identity" needs to be equal or greater as the DR's collateral.
f) every time a dr-commit transaction gets verified, the coins
field of the corresponding "witnessing identity" should be decreased in the same amount as the referred DR's collateral.
Should any "witnessing identity" get its coins
value below zero during the block validation, the whole block proposal should then considered to be invalid. On the contrary, if all dr-commit transactions within a block proposal get successfully verified:
coin_age
MUST be set to 1
on all different "witnessing identities" referred by the dr-commit transactions included in the block.coins
values MUST be consolidated as the new status when processing block candidates on following epochs.About validation of dr-tally transactions
I partially concur with the idea proposed in #2446 about:
...letting a block proposer to include dr-tally transactions embedding a specific error (to-be-named) if a DR getting included within the same block requires a number of witnesses greater than the number of entries in the Stake Tracker...
but adding this extra condition:
...with at least as much stake (i.e. coins
) as the DR's collateral, divided by a replication factor (ie. see rf
below).
On another note, instead of naming this specific tally error as "too many witnesses", I'd rather suggest to name it as InsufficientWitnesses
, because of two reasons:
(a) coherence with the InsufficientReveals
and InsufficientCommits
proposed in https://github.com/witnet/witnet-rust/discussions/2430;
(b) "too many witnesses" could give the wrong idea that the data requester is trying to require an "illegal" number of witnesses, whereas the fact is that the scarcity of witnesses may just be something temporary and eventually self-amended in the short-term.
Finally, I think we should decide on whether the block proposer should earn double or single fee: one mining fee for including the DR tx and another mining fee for including the DR Tally tx as well, or just one mining fee for including both (as if including the former without the later would invalidate the whole block being proposed). What do you think guys @aesedepece @drcpu-github @Tommytrg ?
Because block proposers are sovereign to decide what dr-commit transactions to include, if any at all, there's no actual possible way to power-slash reluctant witnesses.
I remember there was a reason for the inclusion of commit transactions to be essentially random, but I cannot remember what it was and I don't know if this still holds up. I wonder if we can require the included commits to be ranked by power (and then we can introduce slashing). Of course, that only works under the assumption that no one is censoring nodes (but we are assuming that anyway).
Let block proposers include dr-tally transactions referring "insufficient witnesses" if a not-yet-committed DR requires a number of witnesses greater than the number of entries in the Stake Tracker with at least as much stake (i.e. coins) as the DR's collateral. In this case, the block proposer would earn the DR's "mining fee"... wip...
I'm not quite sure, but this sounds like you are (partially) referring to this PR? Note that this simply takes into account the number of stakers, not their coins. I don't think taking into account the number of coins is relevant though since there is a minimum stakeable amount of 10k coins and it seems unlikely we'll see DR's requesting that kind of collateral as long as they have to pay 1/125 of the requested collateral as reward to each witness.
I'm not quite sure, but this sounds like you are (partially) referring to this PR? Note that this simply takes into account the number of stakers, not their coins. I don't think taking into account the number of coins is relevant though since there is a minimum stakeable amount of 10k coins and it seems unlikely we'll see DR's requesting that kind of collateral as long as they have to pay 1/125 of the requested collateral as reward to each witness.
I wasn't directly referring to that PR, but yeah, stating a similar idea I guess. In fact, the one proposed in the PR is even better, because the tally transaction would be included together with the DR transaction itself, which is even more efficient. However, I'd strongly suggest the condition to be "not enough entries in the Stake Tracker with at least as much stake (i.e. coins
) as the DR's collateral". The reason being "market freedom". Why should we limit the amount of reward, ergo collateral, that a data requester may be willing to pay for a DR getting solved?
About witnessing eligibility
(Summarizing a few ideas and conclusions after in-depth chatting with @aesedepece)
Based on what's currently stated in the Wit/2 WIP, some variants are proposed below for your consideration, pretending to:
max_rounds
to 3 while preserving QoS (i.e. DR successful resolution ratio).() For a commitment transaction to be considered for inclusion in a block, it MUST refer to a (a) not-yet-committed data request, (b) the referred DR's round is 3 or less, (c) the committer (i.e. validator-withdrawer pair) holds an stake (i.e. coins
) greater than the DR's collateral, (d) the committer holds certain amount of witnessing
power, and (e) the committer provides a valid VRF proof that MUST satisfy all the following requirements, depending on the current DR's round:
i
-th quartile of most powerful witnessing identities having at least as much stake as the DR's collateral (ie. Q1, Q2 or Q3).Ri
is greater or equal than `witnesses rf`.*Where:
rf
is the replication factor (same on all rounds),i
is the DR's round number calculated as the difference between current epoch and the epoch on which the referred DR was included on a block,witnesses
is the DR's witnesses value,Qi
is the i
-quartile of the Stake Tracker (e.g. Q1
would be the witnessing power threshold that at least 25% of the Stake Tracker entries staking at least the DR's collateral can be proven to have),Ri
is the number of witnessing identities having a stake equal or greater to the DR's collateral, and a witnessing power of at least the Qi
.
Currently, we don't have a slashing mechanism in Witnet 2.0 branches. We have to discuss the different proposals and decide whether to implement one for the first release candidate or for upcoming ones.