github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/spec/consensus/proposer-based-timestamp/v1/pbts_001_draft.md (about) 1 <!-- markdown-link-check-disable --> 2 3 # Proposer-Based Time (first draft) 4 5 ## Current BFTTime 6 7 ### Description 8 9 In Tendermint consensus, the first version of how time is computed and stored in a block works as follows: 10 11 - validators send their current local time as part of `precommit` messages 12 - upon collecting the `precommit` messages that the proposer uses to build a commit to be put in the next block, the proposer computes the `time` of the next block as the median (weighted over voting power) of the times in the `precommit` messages. 13 14 ### Analysis 15 16 1. **Fault tolerance.** The computed median time is called [`bfttime`][bfttime] as it is indeed fault-tolerant: if **less than a third** of the validators is faulty (counted in voting power), it is guaranteed that the computed time lies between the minimum and the maximum times sent by correct validators. 17 1. **Effect of faulty validators.** If more than `1/2` of the voting power (which is in fact more than one third and less than two thirds of the voting power) is held by faulty validators, then the time is under total control of the faulty validators. (This is particularly challenging in the context of [lightclient][lcspec] security.) 18 1. **Proposer influence on block time.** The proposer of the next block has a degree of freedom in choosing the `bfttime`, since it computes the median time based on the timestamps from `precommit` messages sent by 19 `2f + 1` correct validators. 20 1. If there are `n` different timestamps in the `precommit` messages, the proposer can use any subset of timestamps that add up to `2f + 1` 21 of the voting power in order to compute the median. 22 1. If the validators decide in different rounds, the proposer can decide on which round the median computation is based. 23 1. **Liveness.** The liveness of the protocol: 24 1. does not depend on clock synchronization, 25 1. depends on bounded message delays. 26 1. **Relation to real time.** There is no clock synchronizaton, which implies that there is **no relation** between the computed block `time` and real time. 27 1. **Aggregate signatures.** As the `precommit` messages contain the local times, all these `precommit` messages typically differ in the time field, which **prevents** the use of aggregate signatures. 28 29 ## Suggested Proposer-Based Time 30 31 ### Outline 32 33 An alternative approach to time has been discussed: Rather than having the validators send the time in the `precommit` messages, the proposer in the consensus algorithm sends its time in the `propose` message, and the validators locally check whether the time is OK (by comparing to their local clock). 34 35 This proposed solution adds the requirement of having synchronized clocks, and other implicit assumptions. 36 37 ### Comparison of the Suggested Method to the Old One 38 39 1. **Fault tolerance.** Maintained in the suggested protocol. 40 1. **Effect of faulty validators.** Eliminated in the suggested protocol, 41 that is, the block `time` can be corrupted only in the extreme case when 42 `>2/3` of the validators are faulty. 43 1. **Proposer influence on block time.** The proposer of the next block 44 has less freedom when choosing the block time. 45 1. This scenario is eliminated in the suggested protocol, provided that there are `<1/3` faulty validators. 46 1. This scenario is still there. 47 1. **Liveness.** The liveness of the suggested protocol: 48 1. depends on the introduced assumptions on synchronized clocks (see below), 49 1. still depends on the message delays (unavoidable). 50 1. **Relation to real time.** We formalize clock synchronization, and obtain a **well-defined relation** between the block `time` and real time. 51 1. **Aggregate signatures.** The `precommit` messages free of time, which **allows** for aggregate signatures. 52 53 ### Protocol Overview 54 55 #### Proposed Time 56 57 We assume that the field `proposal` in the `PROPOSE` message is a pair `(v, time)`, of the proposed consensus value `v` and the proposed time `time`. 58 59 #### Reception Step 60 61 In the reception step at node `p` at local time `now_p`, upon receiving a message `m`: 62 63 - **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`. 64 (`PRECISION` and `MSGDELAY` being system parameters, see [below](#safety-and-liveness)) 65 66 > after the presentation in the dev session, we realized that different semantics for the reception step is closer aligned to the implementation. Instead of dropping propose messages, we keep all of them, and mark timely ones. 67 68 #### Processing Step 69 70 - Start round 71 72 <table> 73 <tr> 74 <th>arXiv paper</th> 75 <th>Proposer-based time</th> 76 </tr> 77 78 <tr> 79 <td> 80 81 ```go 82 function StartRound(round) { 83 round_p ← round 84 step_p ← propose 85 if proposer(h_p, round_p) = p { 86 87 88 if validValue_p != nil { 89 90 proposal ← validValue_p 91 } else { 92 93 proposal ← getValue() 94 } 95 broadcast ⟨PROPOSAL, h_p, round_p, proposal, validRound_p⟩ 96 } else { 97 schedule OnTimeoutPropose(h_p,round_p) to 98 be executed after timeoutPropose(round_p) 99 } 100 } 101 ``` 102 103 </td> 104 105 <td> 106 107 ```go 108 function StartRound(round) { 109 round_p ← round 110 step_p ← propose 111 if proposer(h_p, round_p) = p { 112 // new wait condition 113 wait until now_p > block time of block h_p - 1 114 if validValue_p != nil { 115 // add "now_p" 116 proposal ← (validValue_p, now_p) 117 } else { 118 // add "now_p" 119 proposal ← (getValue(), now_p) 120 } 121 broadcast ⟨PROPOSAL, h_p, round_p, proposal, validRound_p⟩ 122 } else { 123 schedule OnTimeoutPropose(h_p,round_p) to 124 be executed after timeoutPropose(round_p) 125 } 126 } 127 ``` 128 129 </td> 130 </tr> 131 </table> 132 133 - Rule on lines 28-35 134 135 <table> 136 <tr> 137 <th>arXiv paper</th> 138 <th>Proposer-based time</th> 139 </tr> 140 141 <tr> 142 <td> 143 144 ```go 145 upon timely(⟨PROPOSAL, h_p, round_p, v, vr⟩) 146 from proposer(h_p, round_p) 147 AND 2f + 1 ⟨PREVOTE, h_p, vr, id(v)⟩ 148 while step_p = propose ∧ (vr ≥ 0 ∧ vr < round_p) do { 149 if valid(v) ∧ (lockedRound_p ≤ vr ∨ lockedValue_p = v) { 150 151 broadcast ⟨PREVOTE, h_p, round_p, id(v)⟩ 152 } else { 153 broadcast ⟨PREVOTE, hp, round_p, nil⟩ 154 } 155 } 156 ``` 157 158 </td> 159 160 <td> 161 162 ```go 163 upon timely(⟨PROPOSAL, h_p, round_p, (v, tprop), vr⟩) 164 from proposer(h_p, round_p) 165 AND 2f + 1 ⟨PREVOTE, h_p, vr, id(v, tvote)⟩ 166 while step_p = propose ∧ (vr ≥ 0 ∧ vr < round_p) do { 167 if valid(v) ∧ (lockedRound_p ≤ vr ∨ lockedValue_p = v) { 168 // send hash of v and tprop in PREVOTE message 169 broadcast ⟨PREVOTE, h_p, round_p, id(v, tprop)⟩ 170 } else { 171 broadcast ⟨PREVOTE, hp, round_p, nil⟩ 172 } 173 } 174 ``` 175 176 </td> 177 </tr> 178 </table> 179 180 - Rule on lines 49-54 181 182 <table> 183 <tr> 184 <th>arXiv paper</th> 185 <th>Proposer-based time</th> 186 </tr> 187 188 <tr> 189 <td> 190 191 ```go 192 upon ⟨PROPOSAL, h_p, r, v, ∗⟩ from proposer(h_p, r) 193 AND 2f + 1 ⟨PRECOMMIT, h_p, r, id(v)⟩ 194 while decisionp[h_p] = nil do { 195 if valid(v) { 196 197 decision_p [h_p] = v 198 h_p ← h_p + 1 199 reset lockedRound_p , lockedValue_p, validRound_p and 200 validValue_p to initial values and empty message log 201 StartRound(0) 202 } 203 } 204 ``` 205 206 </td> 207 208 <td> 209 210 ```go 211 upon ⟨PROPOSAL, h_p, r, (v,t), ∗⟩ from proposer(h_p, r) 212 AND 2f + 1 ⟨PRECOMMIT, h_p, r, id(v,t)⟩ 213 while decisionp[h_p] = nil do { 214 if valid(v) { 215 // decide on time too 216 decision_p [h_p] = (v,t) 217 h_p ← h_p + 1 218 reset lockedRound_p , lockedValue_p, validRound_p and 219 validValue_p to initial values and empty message log 220 StartRound(0) 221 } 222 } 223 ``` 224 225 </td> 226 </tr> 227 </table> 228 229 - Other rules are extended in a similar way, or remain unchanged 230 231 ### Property Overview 232 233 #### Safety and Liveness 234 235 For safety (Point 1, Point 2, Point 3i) and liveness (Point 4) we need 236 the following assumptions: 237 238 - There exists a system parameter `PRECISION` such that for any two correct validators `V` and `W`, and at any real-time `t`, their local times `C_V(t)` and `C_W(t)` differ by less than `PRECISION` time units, 239 i.e., `|C_V(t) - C_W(t)| < PRECISION` 240 - The message end-to-end delay between a correct proposer and a correct validator (for `PROPOSE` messages) is less than `MSGDELAY`. 241 242 #### Relation to Real-Time 243 244 For analyzing real-time safety (Point 5), we use a system parameter `ACCURACY`, such that for all real-times `t` and all correct validators `V`, we have `| C_V(t) - t | < ACCURACY`. 245 246 > `ACCURACY` is not necessarily visible at the code level. We might even view `ACCURACY` as variable over time. The smaller it is during a consensus instance, the closer the block time will be to real-time. 247 > 248 > Note that `PRECISION` and `MSGDELAY` show up in the code. 249 250 ### Detailed Specification 251 252 This specification describes the changes needed to be done to the Tendermint consensus algorithm as described in the [arXiv paper][arXiv] and the simplified specification in [TLA+][tlatender], and makes precise the underlying assumptions and the required properties. 253 254 - [Part I - System Model and Properties][sysmodel_v1] 255 - [Part II - Protocol specification][algorithm_v1] 256 - [TLA+ Specification][proposertla] 257 258 [algorithm_v1]: ./pbts-algorithm_001_draft.md 259 260 [sysmodel_v1]: ./pbts-sysmodel_001_draft.md 261 262 [proposertla]: ../tla/TendermintPBT_001_draft.tla 263 264 [bfttime]: ../../bft-time.md 265 [tlatender]: https://github.com/tendermint/spec/blob/master/rust-spec/tendermint-accountability/README.md 266 [lcspec]: ../../light-client/ 267 [arXiv]: https://arxiv.org/abs/1807.04938