You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Copy file name to clipboardExpand all lines: roadmap/implementers-guide/src/runtime/disputes.md
+22-20
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ However, this isn't the end of the story. We are working in a forkful blockchain
6
6
7
7
1. For security, validators that misbehave shouldn't only be slashed on one fork, but on all possible forks. Validators that misbehave shouldn't be able to create a new fork of the chain when caught and get away with their misbehavior.
8
8
1. It is possible (and likely) that the parablock being contested has not appeared on all forks.
9
-
1. If a block author believes that there is a disputed parablock on a specific fork that will resolve to a reversion of the fork, that block author is better incentivized to build on a different fork which does not include that parablock.
9
+
1. If a block author believes that there is a disputed parablock on a specific fork that will resolve to a reversion of the fork, that block author has more incentive to build on a different fork which does not include that parablock.
10
10
11
11
This means that in all likelihood, there is the possibility of disputes that are started on one fork of the relay chain, and as soon as the dispute resolution process starts to indicate that the parablock is indeed invalid, that fork of the relay chain will be abandoned and the dispute will never be fully resolved on that chain.
// fewer than `byzantine_threshold + 1` validators.
43
43
//
44
44
// The i'th entry of the vector corresponds to the i'th validator in the session.
45
-
SpamSlots:mapSessionIndex->Vec<u32>,
46
-
// Whether the chain is frozen or not. Starts as `false`. When this is `true`,
47
-
// the chain will not accept any new parachain blocks for backing or inclusion.
48
-
// It can only be set back to `false` by governance intervention.
49
-
Frozen:bool,
45
+
SpamSlots:mapSessionIndex->Option<Vec<u32>>,
46
+
// Whether the chain is frozen or not. Starts as `None`. When this is `Some`,
47
+
// the chain will not accept any new parachain blocks for backing or inclusion,
48
+
// and its value indicates the last valid block number in the chain.
49
+
// It can only be set back to `None` by governance intervention.
50
+
Frozen:Option<BlockNumber>,
50
51
```
51
52
52
53
> `byzantine_threshold` refers to the maximum number `f` of validators which may be byzantine. The total number of validators is `n = 3f + e` where `e in { 1, 2, 3 }`.
53
54
54
55
## Session Change
55
56
56
57
1. If the current session is not greater than `config.dispute_period + 1`, nothing to do here.
57
-
1. Set `pruning_target = current_session - config.dispute_period - 1`. We add the extra `1` because we want to keep things for `config.dispute_period`_full_ sessions. The stuff at the end of the most recent session has been around for ~0 sessions, not ~1.
58
+
1. Set `pruning_target = current_session - config.dispute_period - 1`. We add the extra `1` because we want to keep things for `config.dispute_period`_full_ sessions.
59
+
The stuff at the end of the most recent session has been around for a little over 0 sessions, not a little over 1.
58
60
1. If `LastPrunedSession` is `None`, then set `LastPrunedSession` to `Some(pruning_target)` and return.
59
61
1. Otherwise, clear out all disputes, included candidates, and `SpamSlots` entries in the range `last_pruned..=pruning_target` and set `LastPrunedSession` to `Some(pruning_target)`.
1. Fail if any disputes in the set are duplicate or concluded before the `config.dispute_post_conclusion_acceptance_period` window relative to now.
69
70
1. Pass on each dispute statement set to `provide_dispute_data`, propagating failure.
70
71
1. Return a list of all candidates who just had disputes initiated.
71
72
@@ -75,29 +76,30 @@ Frozen: bool,
75
76
1. If there is no dispute under `Disputes`, create a new `DisputeState` with blank bitfields.
76
77
1. If `concluded_at` is `Some`, and is `concluded_at + config.post_conclusion_acceptance_period < now`, return false.
77
78
1. If the overlap of the validators in the `DisputeStatementSet` and those already present in the `DisputeState` is fewer in number than `byzantine_threshold + 1` and the candidate is not present in the `Included` map
78
-
1. increment `SpamSlots` for each validator in the `DisputeStatementSet` which is not already in the `DisputeState`. Initialize the `SpamSlots` to a zeroed vector first, if necessary.
79
-
1. If the value for any spam slot exceeds `config.dispute_max_spam_slots`, return false.
80
-
1. If the overlap of the validators in the `DisputeStatementSet` and those already present in the `DisputeState` is at least `byzantine_threshold + 1`, the `DisputeState` has fewer than `byzantine_threshold + 1` validators, and the candidate is not present in the `Included` map, decrement `SpamSlots` for each validator in the `DisputeState`.
81
-
1. Import all statements into the dispute. This should fail if any statements are duplicate; if the corresponding bit for the corresponding validator is set in the dispute already.
82
-
1. If `concluded_at` is `None`, reward all statements slightly less.
79
+
1. increment `SpamSlots` for each validator in the `DisputeStatementSet` which is not already in the `DisputeState`. Initialize the `SpamSlots` to a zeroed vector first, if necessary. do not increment `SpamSlots` if the candidate is local.
80
+
1. If the value for any spam slot exceeds `config.dispute_max_spam_slots`, return false.
81
+
1. If the overlap of the validators in the `DisputeStatementSet` and those already present in the `DisputeState` is at least `byzantine_threshold + 1`, the `DisputeState` has fewer than `byzantine_threshold + 1` validators, and the candidate is not present in the `Included` map, then decrease `SpamSlots` by 1 for each validator in the `DisputeState`.
82
+
1. Import all statements into the dispute. This should fail if any statements are duplicate or if the corresponding bit for the corresponding validator is set in the dispute already.
83
+
1. If `concluded_at` is `None`, reward all statements.
83
84
1. If `concluded_at` is `Some`, reward all statements slightly less.
84
-
1. If either side now has supermajority, slash the other side. This may be both sides, and we support this possibility in code, but note that this requires validators to participate on both sides which has negative expected value. Set `concluded_at` to `Some(now)`.
85
+
1. If either side now has supermajority and did not previously, slash the other side. This may be both sides, and we support this possibility in code, but note that this requires validators to participate on both sides which has negative expected value. Set `concluded_at` to `Some(now)` if it was `None`.
85
86
1. If just concluded against the candidate and the `Included` map contains `(session, candidate)`: invoke `revert_and_freeze` with the stored block number.
86
87
1. Return true if just initiated, false otherwise.
87
88
88
89
*`disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)>`: Get a list of all disputes and info about dispute state.
89
-
1. Iterate over all disputes in `Disputes`. Set the flag according to `concluded`.
90
+
1. Iterate over all disputes in `Disputes` and collect into a vector.
1. Add `(SessionIndex, CandidateHash)` to the `Included` map with `included_in - 1` as the value.
93
-
1. If there is a dispute under `(Sessionindex, CandidateHash)` with fewer than `byzantine_threshold + 1` participating validators, decrement`SpamSlots` for each validator in the `DisputeState`.
94
+
1. If there is a dispute under `(Sessionindex, CandidateHash)` with fewer than `byzantine_threshold + 1` participating validators, decrease`SpamSlots` by 1 for each validator in the `DisputeState`.
94
95
1. If there is a dispute under `(SessionIndex, CandidateHash)` that has concluded against the candidate, invoke `revert_and_freeze` with the stored block number.
95
96
96
97
*`could_be_invalid(SessionIndex, CandidateHash) -> bool`: Returns whether a candidate has a live dispute ongoing or a dispute which has already concluded in the negative.
97
98
98
-
*`is_frozen()`: Load the value of `Frozen` from storage.
99
+
*`is_frozen()`: Load the value of `Frozen` from storage. Return true if `Some` and false if `None`.
99
100
100
-
* `revert_and_freeze(BlockNumber):
101
+
*`last_valid_block()`: Load the value of `Frozen` from storage and return. None indicates that all blocks in the chain are potentially valid.
102
+
103
+
*`revert_and_freeze(BlockNumber)`:
101
104
1. If `is_frozen()` return.
102
-
1. issue a digest in the block header which indicates the chain is to be abandoned back to the stored block number.
103
-
1. Set `Frozen` to true.
105
+
1. Set `Frozen` to `Some(BlockNumber)` to indicate a rollback to the given block number is necessary.
0 commit comments