github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/spec/abci++/v0.md (about) 1 # Tendermint v0 Markdown pseudocode 2 3 This translates the latex code for Tendermint consensus from the Tendermint paper into markdown. 4 5 ### Initialization 6 7 ```go 8 h_p ← 0 9 round_p ← 0 10 step_p is one of {propose, prevote, precommit} 11 decision_p ← Vector() 12 lockedRound_p ← -1 13 lockedValue_p ← nil 14 validValue_p ← nil 15 validRound_p ← -1 16 ``` 17 18 ### StartRound(round) 19 20 ```go 21 function startRound(round) { 22 round_p ← round 23 step_p ← propose 24 if proposer(h_p, round_p) = p { 25 if validValue_p != nil { 26 proposal ← validValue_p 27 } else { 28 proposal ← getValue() 29 } 30 broadcast ⟨PROPOSAL, h_p, round_p, proposal, validRound_p⟩ 31 } else { 32 schedule OnTimeoutPropose(h_p,round_p) to be executed after timeoutPropose(round_p) 33 } 34 } 35 ``` 36 37 ### ReceiveProposal 38 39 In the case where the local node is not locked on any round, the following is ran: 40 41 ```go 42 upon ⟨PROPOSAL, h_p, round_p, v, −1) from proposer(h_p, round_p) while step_p = propose do { 43 if valid(v) ∧ (lockedRound_p = −1 ∨ lockedValue_p = v) { 44 broadcast ⟨PREVOTE, h_p, round_p, id(v)⟩ 45 } else { 46 broadcast ⟨PREVOTE, h_p, round_p, nil⟩ 47 } 48 step_p ← prevote 49 } 50 ``` 51 52 In the case where the node is locked on a round, the following is ran: 53 54 ```go 55 upon ⟨PROPOSAL, h_p, round_p, v, vr⟩ from proposer(h_p, round_p) 56 AND 2f + 1 ⟨PREVOTE, h_p, vr, id(v)⟩ 57 while step_p = propose ∧ (vr ≥ 0 ∧ vr < round_p) do { 58 if valid(v) ∧ (lockedRound_p ≤ vr ∨ lockedValue_p = v) { 59 broadcast ⟨PREVOTE, h_p, round_p, id(v)⟩ 60 } else { 61 broadcast ⟨PREVOTE, h_p, round_p, nil⟩ 62 } 63 step_p ← prevote 64 } 65 ``` 66 67 ### Prevote timeout 68 69 Upon receiving 2f + 1 prevotes, setup a timeout. 70 71 ```go 72 upon 2f + 1 ⟨PREVOTE, h_p, vr, *⟩ with step_p = prevote for the first time, do { 73 schedule OnTimeoutPrevote(h_p, round_p) to be executed after timeoutPrevote(round_p) 74 } 75 ``` 76 77 with OnTimeoutPrevote defined as: 78 79 ```go 80 function OnTimeoutPrevote(height, round) { 81 if (height = h_p && round = round_p && step_p = prevote) { 82 broadcast ⟨PRECOMMIT, h_p, round_p, nil⟩ 83 step_p ← precommit 84 } 85 } 86 ``` 87 88 ### Receiving enough prevotes to precommit 89 90 The following code is ran upon receiving 2f + 1 prevotes for the same block 91 92 ```go 93 upon ⟨PROPOSAL, h_p, round_p, v, *⟩ 94 from proposer(h_p, round_p) 95 AND 2f + 1 ⟨PREVOTE, h_p, round_p, id(v)⟩ 96 while valid(v) ∧ step_p >= prevote for the first time do { 97 if (step_p = prevote) { 98 lockedValue_p ← v 99 lockedRound_p ← round_p 100 broadcast ⟨PRECOMMIT, h_p, round_p, id(v)⟩ 101 step_p ← precommit 102 } 103 validValue_p ← v 104 validRound_p ← round_p 105 } 106 ``` 107 108 And upon receiving 2f + 1 prevotes for nil: 109 110 ```go 111 upon 2f + 1 ⟨PREVOTE, h_p, round_p, nil⟩ 112 while step_p = prevote do { 113 broadcast ⟨PRECOMMIT, h_p, round_p, nil⟩ 114 step_p ← precommit 115 } 116 ``` 117 118 ### Precommit timeout 119 120 Upon receiving 2f + 1 precommits, setup a timeout. 121 122 ```go 123 upon 2f + 1 ⟨PRECOMMIT, h_p, vr, *⟩ for the first time, do { 124 schedule OnTimeoutPrecommit(h_p, round_p) to be executed after timeoutPrecommit(round_p) 125 } 126 ``` 127 128 with OnTimeoutPrecommit defined as: 129 130 ```go 131 function OnTimeoutPrecommit(height, round) { 132 if (height = h_p && round = round_p) { 133 StartRound(round_p + 1) 134 } 135 } 136 ``` 137 138 ### Upon Receiving 2f + 1 precommits 139 140 The following code is ran upon receiving 2f + 1 precommits for the same block 141 142 ```go 143 upon ⟨PROPOSAL, h_p, r, v, *⟩ 144 from proposer(h_p, r) 145 AND 2f + 1 ⟨ PRECOMMIT, h_p, r, id(v)⟩ 146 while decision_p[h_p] = nil do { 147 if (valid(v)) { 148 decision_p[h_p] ← v 149 h_p ← h_p + 1 150 reset lockedRound_p, lockedValue_p,validRound_p and validValue_p to initial values 151 StartRound(0) 152 } 153 } 154 ``` 155 156 If we don't see 2f + 1 precommits for the same block, we wait until we get 2f + 1 precommits, and the timeout occurs.