github.com/pokt-network/tendermint@v0.32.11-0.20230426215212-59310158d3e9/consensus/types/round_state.go (about) 1 package types 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "time" 7 8 "github.com/tendermint/tendermint/libs/bytes" 9 "github.com/tendermint/tendermint/types" 10 ) 11 12 //----------------------------------------------------------------------------- 13 // RoundStepType enum type 14 15 // RoundStepType enumerates the state of the consensus state machine 16 type RoundStepType uint8 // These must be numeric, ordered. 17 18 // RoundStepType 19 const ( 20 RoundStepNewHeight = RoundStepType(0x01) // Wait til CommitTime + timeoutCommit 21 RoundStepNewRound = RoundStepType(0x02) // Setup new round and go to RoundStepPropose 22 RoundStepPropose = RoundStepType(0x03) // Did propose, gossip proposal 23 RoundStepPrevote = RoundStepType(0x04) // Did prevote, gossip prevotes 24 RoundStepPrevoteWait = RoundStepType(0x05) // Did receive any +2/3 prevotes, start timeout 25 RoundStepPrecommit = RoundStepType(0x06) // Did precommit, gossip precommits 26 RoundStepPrecommitWait = RoundStepType(0x07) // Did receive any +2/3 precommits, start timeout 27 RoundStepCommit = RoundStepType(0x08) // Entered commit state machine 28 // NOTE: RoundStepNewHeight acts as RoundStepCommitWait. 29 30 // NOTE: Update IsValid method if you change this! 31 ) 32 33 // IsValid returns true if the step is valid, false if unknown/undefined. 34 func (rs RoundStepType) IsValid() bool { 35 return uint8(rs) >= 0x01 && uint8(rs) <= 0x08 36 } 37 38 // String returns a string 39 func (rs RoundStepType) String() string { 40 switch rs { 41 case RoundStepNewHeight: 42 return "RoundStepNewHeight" 43 case RoundStepNewRound: 44 return "RoundStepNewRound" 45 case RoundStepPropose: 46 return "RoundStepPropose" 47 case RoundStepPrevote: 48 return "RoundStepPrevote" 49 case RoundStepPrevoteWait: 50 return "RoundStepPrevoteWait" 51 case RoundStepPrecommit: 52 return "RoundStepPrecommit" 53 case RoundStepPrecommitWait: 54 return "RoundStepPrecommitWait" 55 case RoundStepCommit: 56 return "RoundStepCommit" 57 default: 58 return "RoundStepUnknown" // Cannot panic. 59 } 60 } 61 62 //----------------------------------------------------------------------------- 63 64 // RoundState defines the internal consensus state. 65 // NOTE: Not thread safe. Should only be manipulated by functions downstream 66 // of the cs.receiveRoutine 67 type RoundState struct { 68 Height int64 `json:"height"` // Height we are working on 69 Round int `json:"round"` 70 Step RoundStepType `json:"step"` 71 StartTime time.Time `json:"start_time"` 72 73 // Subjective time when +2/3 precommits for Block at Round were found 74 CommitTime time.Time `json:"commit_time"` 75 Validators *types.ValidatorSet `json:"validators"` 76 Proposal *types.Proposal `json:"proposal"` 77 ProposalBlock *types.Block `json:"proposal_block"` 78 ProposalBlockParts *types.PartSet `json:"proposal_block_parts"` 79 LockedRound int `json:"locked_round"` 80 LockedBlock *types.Block `json:"locked_block"` 81 LockedBlockParts *types.PartSet `json:"locked_block_parts"` 82 83 // Last known round with POL for non-nil valid block. 84 ValidRound int `json:"valid_round"` 85 ValidBlock *types.Block `json:"valid_block"` // Last known block of POL mentioned above. 86 87 // Last known block parts of POL metnioned above. 88 ValidBlockParts *types.PartSet `json:"valid_block_parts"` 89 Votes *HeightVoteSet `json:"votes"` 90 CommitRound int `json:"commit_round"` // 91 LastCommit *types.VoteSet `json:"last_commit"` // Last precommits at Height-1 92 LastValidators *types.ValidatorSet `json:"last_validators"` 93 TriggeredTimeoutPrecommit bool `json:"triggered_timeout_precommit"` 94 } 95 96 // Compressed version of the RoundState for use in RPC 97 type RoundStateSimple struct { 98 HeightRoundStep string `json:"height/round/step"` 99 StartTime time.Time `json:"start_time"` 100 ProposalBlockHash bytes.HexBytes `json:"proposal_block_hash"` 101 LockedBlockHash bytes.HexBytes `json:"locked_block_hash"` 102 ValidBlockHash bytes.HexBytes `json:"valid_block_hash"` 103 Votes json.RawMessage `json:"height_vote_set"` 104 } 105 106 // Compress the RoundState to RoundStateSimple 107 func (rs *RoundState) RoundStateSimple() RoundStateSimple { 108 votesJSON, err := rs.Votes.MarshalJSON() 109 if err != nil { 110 panic(err) 111 } 112 return RoundStateSimple{ 113 HeightRoundStep: fmt.Sprintf("%d/%d/%d", rs.Height, rs.Round, rs.Step), 114 StartTime: rs.StartTime, 115 ProposalBlockHash: rs.ProposalBlock.Hash(), 116 LockedBlockHash: rs.LockedBlock.Hash(), 117 ValidBlockHash: rs.ValidBlock.Hash(), 118 Votes: votesJSON, 119 } 120 } 121 122 // NewRoundEvent returns the RoundState with proposer information as an event. 123 func (rs *RoundState) NewRoundEvent() types.EventDataNewRound { 124 addr := rs.Validators.GetProposer().Address 125 idx, _ := rs.Validators.GetByAddress(addr) 126 127 return types.EventDataNewRound{ 128 Height: rs.Height, 129 Round: rs.Round, 130 Step: rs.Step.String(), 131 Proposer: types.ValidatorInfo{ 132 Address: addr, 133 Index: idx, 134 }, 135 } 136 } 137 138 // CompleteProposalEvent returns information about a proposed block as an event. 139 func (rs *RoundState) CompleteProposalEvent() types.EventDataCompleteProposal { 140 // We must construct BlockID from ProposalBlock and ProposalBlockParts 141 // cs.Proposal is not guaranteed to be set when this function is called 142 blockID := types.BlockID{ 143 Hash: rs.ProposalBlock.Hash(), 144 PartsHeader: rs.ProposalBlockParts.Header(), 145 } 146 147 return types.EventDataCompleteProposal{ 148 Height: rs.Height, 149 Round: rs.Round, 150 Step: rs.Step.String(), 151 BlockID: blockID, 152 } 153 } 154 155 // RoundStateEvent returns the H/R/S of the RoundState as an event. 156 func (rs *RoundState) RoundStateEvent() types.EventDataRoundState { 157 return types.EventDataRoundState{ 158 Height: rs.Height, 159 Round: rs.Round, 160 Step: rs.Step.String(), 161 } 162 } 163 164 // String returns a string 165 func (rs *RoundState) String() string { 166 return rs.StringIndented("") 167 } 168 169 // StringIndented returns a string 170 func (rs *RoundState) StringIndented(indent string) string { 171 return fmt.Sprintf(`RoundState{ 172 %s H:%v R:%v S:%v 173 %s StartTime: %v 174 %s CommitTime: %v 175 %s Validators: %v 176 %s Proposal: %v 177 %s ProposalBlock: %v %v 178 %s LockedRound: %v 179 %s LockedBlock: %v %v 180 %s ValidRound: %v 181 %s ValidBlock: %v %v 182 %s Votes: %v 183 %s LastCommit: %v 184 %s LastValidators:%v 185 %s}`, 186 indent, rs.Height, rs.Round, rs.Step, 187 indent, rs.StartTime, 188 indent, rs.CommitTime, 189 indent, rs.Validators.StringIndented(indent+" "), 190 indent, rs.Proposal, 191 indent, rs.ProposalBlockParts.StringShort(), rs.ProposalBlock.StringShort(), 192 indent, rs.LockedRound, 193 indent, rs.LockedBlockParts.StringShort(), rs.LockedBlock.StringShort(), 194 indent, rs.ValidRound, 195 indent, rs.ValidBlockParts.StringShort(), rs.ValidBlock.StringShort(), 196 indent, rs.Votes.StringIndented(indent+" "), 197 indent, rs.LastCommit.StringShort(), 198 indent, rs.LastValidators.StringIndented(indent+" "), 199 indent) 200 } 201 202 // StringShort returns a string 203 func (rs *RoundState) StringShort() string { 204 return fmt.Sprintf(`RoundState{H:%v R:%v S:%v ST:%v}`, 205 rs.Height, rs.Round, rs.Step, rs.StartTime) 206 } 207 208 //----------------------------------------------------------- 209 // These methods are for Protobuf Compatibility 210 211 // Size returns the size of the amino encoding, in bytes. 212 func (rs *RoundStateSimple) Size() int { 213 bs, _ := rs.Marshal() 214 return len(bs) 215 } 216 217 // Marshal returns the amino encoding. 218 func (rs *RoundStateSimple) Marshal() ([]byte, error) { 219 return cdc.MarshalBinaryBare(rs) 220 } 221 222 // MarshalTo calls Marshal and copies to the given buffer. 223 func (rs *RoundStateSimple) MarshalTo(data []byte) (int, error) { 224 bs, err := rs.Marshal() 225 if err != nil { 226 return -1, err 227 } 228 return copy(data, bs), nil 229 } 230 231 // Unmarshal deserializes from amino encoded form. 232 func (rs *RoundStateSimple) Unmarshal(bs []byte) error { 233 return cdc.UnmarshalBinaryBare(bs, rs) 234 }