-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Disputes runtime #2947
Disputes runtime #2947
Changes from 60 commits
8bd80d3
101fde9
4198797
7dac193
dd01c06
ef153dc
8dea7e6
f70f6e2
0451139
6748578
95d6c19
ce5906b
01e948e
8e25b48
271434b
310ee52
37c3c3a
8180eae
2ed7fe5
31c27c0
cfdbebd
dcd410c
ebd8b18
da2d43a
d09c851
cfe3241
d14e904
7ffe889
3638877
82e86da
955e0c4
83e7b62
fc3ab87
6fa374c
1b4838d
c0d15be
7ef44b5
7570236
6dd0ad6
040cc17
4a3eeba
6f5b27f
aacc3de
993709b
5b7928a
14bd62d
776b3b6
a4ee80f
b0d579c
9430d3c
0680641
a715d61
3f6ce32
8ebc635
f3e22c0
53e2ccb
4f4b84b
a7ad191
7b04be6
c6cf3f7
3acf2c1
9aa95b4
ff06d0f
dd35e7f
df6bfa8
9214a99
eb81811
c7afa0c
4378b5c
8a7abdb
663b5cc
3be97bb
bb47ed4
5ecf237
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,11 +42,12 @@ Included: double_map (SessionIndex, CandidateHash) -> Option<BlockNumber>, | |
| // fewer than `byzantine_threshold + 1` validators. | ||
| // | ||
| // The i'th entry of the vector corresponds to the i'th validator in the session. | ||
drahnr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| SpamSlots: map SessionIndex -> Vec<u32>, | ||
| // Whether the chain is frozen or not. Starts as `false`. When this is `true`, | ||
| // the chain will not accept any new parachain blocks for backing or inclusion. | ||
| // It can only be set back to `false` by governance intervention. | ||
| Frozen: bool, | ||
| SpamSlots: map SessionIndex -> Option<Vec<u32>>, | ||
| // Whether the chain is frozen or not. Starts as `None`. When this is `Some`, | ||
| // the chain will not accept any new parachain blocks for backing or inclusion, | ||
| // and its value indicates the last valid block number in the chain. | ||
| // It can only be set back to `None` by governance intervention. | ||
| Frozen: Option<BlockNumber>, | ||
| ``` | ||
|
|
||
| > `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 }`. | ||
|
|
@@ -65,7 +66,6 @@ Frozen: bool, | |
| ## Routines | ||
|
|
||
| * `provide_multi_dispute_data(MultiDisputeStatementSet) -> Vec<(SessionIndex, Hash)>`: | ||
| 1. Fail if any disputes in the set are duplicate or concluded before the `config.dispute_post_conclusion_acceptance_period` window relative to now. | ||
gui1117 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 1. Pass on each dispute statement set to `provide_dispute_data`, propagating failure. | ||
| 1. Return a list of all candidates who just had disputes initiated. | ||
|
|
||
|
|
@@ -75,18 +75,18 @@ Frozen: bool, | |
| 1. If there is no dispute under `Disputes`, create a new `DisputeState` with blank bitfields. | ||
| 1. If `concluded_at` is `Some`, and is `concluded_at + config.post_conclusion_acceptance_period < now`, return false. | ||
| 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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does overlap mean intersection or union here? Either way I don't think either works perfectly. Assuming the first message is less than the threshold, in the intersection case, the second could be a disjoint set and hence be empty and marked as spam. Assuming the union, and Could elaborate a bit on the intended spam mechanics?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, yes, it should be a union. a dispute is unconfirmed until it has |
||
| 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. | ||
| 1. If the value for any spam slot exceeds `config.dispute_max_spam_slots`, return false. | ||
| 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. | ||
| 1. If the value for any spam slot exceeds `config.dispute_max_spam_slots`, return false. | ||
| 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`. | ||
| 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. | ||
| 1. If `concluded_at` is `None`, reward all statements slightly less. | ||
| 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. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Iirc, voting twice for a validator in opposing ways is not an issue, since that would impose slashing itself for sure.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Voting twice in opposing ways doesn't necessarily need to lead to a slash as long as it's -EV. The way that disputes are designed now ensures that it is -EV as it raises the likelihood of ending up against a supermajority. |
||
| 1. If `concluded_at` is `None`, reward all statements. | ||
| 1. If `concluded_at` is `Some`, reward all statements slightly less. | ||
| 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)`. | ||
| 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`. | ||
| 1. If just concluded against the candidate and the `Included` map contains `(session, candidate)`: invoke `revert_and_freeze` with the stored block number. | ||
| 1. Return true if just initiated, false otherwise. | ||
|
|
||
| * `disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)>`: Get a list of all disputes and info about dispute state. | ||
| 1. Iterate over all disputes in `Disputes`. Set the flag according to `concluded`. | ||
| 1. Iterate over all disputes in `Disputes` and collect into a vector. | ||
|
|
||
| * `note_included(SessionIndex, CandidateHash, included_in: BlockNumber)`: | ||
| 1. Add `(SessionIndex, CandidateHash)` to the `Included` map with `included_in - 1` as the value. | ||
|
|
@@ -95,9 +95,10 @@ Frozen: bool, | |
|
|
||
| * `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. | ||
|
|
||
| * `is_frozen()`: Load the value of `Frozen` from storage. | ||
| * `is_frozen()`: Load the value of `Frozen` from storage. Return true if `Some` and false if `None`. | ||
|
|
||
| * `revert_and_freeze(BlockNumber): | ||
| * `last_valid_block()`: Load the value of `Frozen` from storage and return. None indicates that all blocks in the chain are potentially valid. | ||
|
|
||
| * `revert_and_freeze(BlockNumber)`: | ||
| 1. If `is_frozen()` return. | ||
| 1. issue a digest in the block header which indicates the chain is to be abandoned back to the stored block number. | ||
| 1. Set `Frozen` to true. | ||
| 1. Set `Frozen` to `Some(BlockNumber)` to indicate a rollback to the given block number is necessary. | ||
Uh oh!
There was an error while loading. Please reload this page.