Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions KIPs/kip-227.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ The framework promotes consistent uptime and reliability. Validators have an inc

### Parameters

| Constant | Value/Definition |
| :-------------------------- | :---------------------------------------------------------------------- |
| `FORK_BLOCK` | TBD |
| `CANDIDATE_MSG_TIMEOUT` | Protocol parameter (milliseconds). Default = 500ms. |
| `EPOCH_LENGTH` | 86,400 blocks (approximately 1 day, assuming 1-second block time) |
| `MAX_BYZANTINE_NODES` (`F`) | Calculated as `F = (n - 1) // 3`, where `n` is the number of validators |
| `PFS_THRESHOLD` | 2 (max proposal failures per epoch) |
| `CFS_THRESHOLD` | 300 (max candidate failures per epoch) |
| Constant | Value/Definition |
| :-------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FORK_BLOCK` | TBD |
| `CANDIDATE_MSG_TIMEOUT` | Protocol parameter (milliseconds). Default = 500ms. |
| `EPOCH_LENGTH` | 86,400 blocks (approximately 1 day, assuming 1-second block time) |
| `MAX_BYZANTINE_NODES` (`F`) | Calculated as `F = floor(len(proposerSet) / 3)`, where `proposerSet` is the set of distinct proposers observed in the current epoch up to and including the block at which CFS is computed |
| `PFS_THRESHOLD` | 2 (max proposal failures per epoch) |
| `CFS_THRESHOLD` | 300 (max candidate failures per epoch) |

### Data Structures and Protocol Primitives

Expand Down Expand Up @@ -158,7 +158,8 @@ Each score is per epoch, computed from `pfReport` and `cfReport` in epoch blocks
Format: `pfs(N) -> map[proposerAddr]score`

**Candidate Failure Score (CFS)**: For a given block number `N`, CFS MUST be computed from `cfReport(b)` for blocks `b ∈ [epochStart(N), N]` (note that `cfReport(epochStart(N))` is empty).
For each candidate `C` and reporter (proposer of block `N`): if `C` is in `cfReport(N)`, that counts as 1 failure.
For each candidate `C` and reporter (proposer of block `b`): if `C` is in `cfReport(b)`, that counts as 1 failure.
Let `proposerSet` be the set of distinct proposers across all blocks `b ∈ [epochStart(N), N]` (every block contributes its proposer to `proposerSet`, including blocks with an empty `cfReport`), and let `F = floor(len(proposerSet) / 3)`.
For each candidate, sum failures per reporter over the epoch, discard the highest `F` reporter totals (Byzantine filtering), and sum the remainder to obtain CFS.

Format: `cfs(N) -> map[candidateAddr]score`
Expand All @@ -169,15 +170,16 @@ _Example 1: Short epoch_

```
epoch = 5
len(validator) = 4
len(candidates) = 3
F = 1

proposer(5)=P1, cfReport(5)=[]
proposer(6)=P2, cfReport(6)=[]
proposer(7)=P3, cfReport(7)=[C1,C2,C3]
proposer(8)=P4, cfReport(8)=[C1,C2]
proposer(9)=P4, cfReport(9)=[C1,C2]

proposerSet = {P1, P2, P3, P4}
F = len(proposerSet) / 3 = 4 / 3 = 1
```

Aggregated `cfReport(N)` where N ∈ \[5, 9\]:
Expand Down
Loading