github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/spec/consensus/proposer-based-timestamp/v1/pbts-algorithm_001_draft.md (about)

     1  # PBTS: Protocol Specification (first draft)
     2  
     3  This specification is **OUTDATED**. Please refer to the [new version][algorithm].
     4  
     5  ## Updated Consensus Algorithm
     6  
     7  ### Outline
     8  
     9  The algorithm in the [arXiv paper][arXiv] evaluates rules of the received messages without making explicit how these messages are received. In our solution, we will make some message filtering explicit. We will assume that there are message reception steps (where messages are received and possibly stored locally for later evaluation of rules) and processing steps (the latter roughly as described in a way similar to the pseudo code of the arXiv paper).
    10  
    11  In contrast to the original algorithm the field `proposal` in the `PROPOSE` message is a pair `(v, time)`, of the proposed consensus value `v` and the proposed time `time`.
    12  
    13  #### **[PBTS-RECEPTION-STEP.0]**
    14  
    15  In the reception step at process `p` at local time `now_p`, upon receiving a message `m`:
    16  
    17  - if the message `m` is of type `PROPOSE` and satisfies `now_p - PRECISION <  m.time < now_p + PRECISION + MSGDELAY`, then mark the message as `timely`
    18  
    19  > if `m` does not satisfy the constraint consider it `untimely`
    20  
    21  
    22  #### **[PBTS-PROCESSING-STEP.0]**
    23  
    24  In the processing step, based on the messages stored, the rules of the algorithms are
    25  executed. Note that the processing step only operates on messages
    26  for the current height. The consensus algorithm rules are defined by the following updates to arXiv paper.
    27  
    28  #### New `StartRound`
    29  
    30  There are two additions
    31  
    32  - in case the proposer's local time is smaller than the time of the previous block, the proposer waits until this is not the case anymore (to ensure the block time is monotonically increasing)
    33  - the proposer sends its time `now_p` as part of its proposal
    34  
    35  We update the timeout for the `PROPOSE` step according to the following reasoning:
    36  
    37  - If a correct proposer needs to wait to make sure its proposed time is larger than the `blockTime` of the previous block, then it sends by realtime `blockTime + ACCURACY` (By this time, its local clock must exceed `blockTime`)
    38  - the receiver will receive a `PROPOSE` message by `blockTime + ACCURACY + MSGDELAY`
    39  - the receiver's local clock will be `<= blockTime + 2 * ACCURACY + MSGDELAY`
    40  - thus when the receiver `p` enters this round it can set its timeout to a value `waitingTime => blockTime + 2 * ACCURACY + MSGDELAY - now_p`
    41  
    42  So we should set the timeout to `max(timeoutPropose(round_p), waitingTime)`.
    43  
    44  > If, in the future, a block delay parameter `BLOCKDELAY` is introduced, this means
    45  that the proposer should wait for `now_p > blockTime + BLOCKDELAY` before sending a `PROPOSE` message.
    46  Also, `BLOCKDELAY` needs to be added to `waitingTime`.
    47  
    48  #### **[PBTS-ALG-STARTROUND.0]**
    49  
    50  ```go
    51  function StartRound(round) {
    52    blockTime ← block time of block h_p - 1
    53    waitingTime ← blockTime + 2 * ACCURACY + MSGDELAY - now_p
    54    round_p ← round
    55    step_p ← propose
    56    if proposer(h_p, round_p) = p {
    57      wait until now_p > blockTime // new wait condition
    58      if validValue_p != nil {
    59        proposal ← (validValue_p, now_p) // added "now_p"
    60      }
    61      else {
    62        proposal ← (getValue(), now_p)   // added "now_p"
    63      }
    64      broadcast ⟨PROPOSAL, h_p, round_p, proposal, validRound_p⟩
    65    }
    66    else {
    67      schedule OnTimeoutPropose(h_p,round_p) to be executed after max(timeoutPropose(round_p), waitingTime)
    68    }
    69  }
    70  ```
    71  
    72  #### New Rule Replacing Lines 22 - 27
    73  
    74  - a validator prevotes for the consensus value `v` **and** the time `t`
    75  - the code changes as the `PROPOSAL` message carries time (while `lockedValue` does not)
    76  
    77  #### **[PBTS-ALG-UPON-PROP.0]**
    78  
    79  ```go
    80  upon timely(⟨PROPOSAL, h_p, round_p, (v,t), −1⟩) from proposer(h_p, round_p) while step_p = propose do {
    81    if valid(v) ∧ (lockedRound_p = −1 ∨ lockedValue_p = v) {
    82      broadcast ⟨PREVOTE, h_p, round_p, id(v,t)⟩ 
    83    }
    84    else {
    85      broadcast ⟨PREVOTE, h_p, round_p, nil⟩ 
    86    }
    87    step_p ← prevote
    88  }
    89  ```
    90  
    91  #### New Rule Replacing Lines 28 - 33
    92  
    93  In case consensus is not reached in round 1, in `StartRound` the proposer of future rounds may propose the same value but with a different time.
    94  Thus, the time `tprop` in the `PROPOSAL` message need not match the time `tvote` in the (old) `PREVOTE` messages.
    95  A validator may send `PREVOTE` for the current round as long as the value `v` matches.
    96  This gives the following rule:
    97  
    98  #### **[PBTS-ALG-OLD-PREVOTE.0]**
    99  
   100  ```go
   101  upon timely(⟨PROPOSAL, h_p, round_p, (v, tprop), vr⟩) from proposer(h_p, round_p) AND 2f + 1 ⟨PREVOTE, h_p, vr, id((v, tvote)⟩ 
   102  while step_p = propose ∧ (vr ≥ 0 ∧ vr < round_p) do {
   103    if valid(v) ∧ (lockedRound_p ≤ vr ∨ lockedValue_p = v) {
   104      broadcast ⟨PREVOTE, h_p, roundp, id(v, tprop)⟩
   105    }
   106    else {
   107      broadcast ⟨PREVOTE, hp, roundp, nil⟩
   108    }
   109    step_p ← prevote
   110  }
   111  ```
   112  
   113  #### New Rule Replacing Lines 36 - 43
   114  
   115  - As above, in the following `(v,t)` is part of the message rather than `v`
   116  - the stored values (i.e., `lockedValue`, `validValue`) do not contain the time
   117  
   118  #### **[PBTS-ALG-NEW-PREVOTE.0]**
   119  
   120  ```go
   121  upon timely(⟨PROPOSAL, h_p, round_p, (v,t), ∗⟩) from proposer(h_p, round_p) AND 2f + 1 ⟨PREVOTE, h_p, round_p, id(v,t)⟩ while valid(v) ∧ step_p ≥ prevote for the first time do {
   122    if step_p = prevote {
   123      lockedValue_p ← v
   124      lockedRound_p ← round_p
   125      broadcast ⟨PRECOMMIT, h_p, round_p, id(v,t))⟩ 
   126      step_p ← precommit
   127    }
   128    validValue_p ← v 
   129    validRound_p ← round_p
   130  }
   131  ```
   132  
   133  #### New Rule Replacing Lines 49 - 54
   134  
   135  - we decide on `v` as well as on the time from the proposal message
   136  - here we do not care whether the proposal was received timely.
   137  
   138  > In particular we need to take care of the case where the proposer is untimely to one correct validator only. We need to ensure that this validator decides if all decide.
   139  
   140  #### **[PBTS-ALG-DECIDE.0]**
   141  
   142  ```go
   143  upon ⟨PROPOSAL, h_p, r, (v,t), ∗⟩ from proposer(h_p, r) AND 2f + 1 ⟨PRECOMMIT, h_p, r, id(v,t)⟩ while decisionp[h_p] = nil do {
   144    if valid(v) {
   145      decision_p [h_p] = (v,t) // decide on time too
   146      h_p ← h_p + 1
   147      reset lockedRound_p , lockedValue_p, validRound_p and validValue_p to initial values and empty message log 
   148      StartRound(0)
   149    }
   150  }
   151  ```
   152  
   153  **All other rules remains unchanged.**
   154  
   155  Back to [main document][main_v1].
   156  
   157  [main_v1]: ./pbts_001_draft.md
   158  
   159  [algorithm]: ../pbts-algorithm_002_draft.md
   160  [algorithm_v1]: ./pbts-algorithm_001_draft.md
   161  
   162  [arXiv]: https://arxiv.org/abs/1807.04938