github.com/Team-Kujira/tendermint@v0.34.24-indexer/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 int32 `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 int32 `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 int32 `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 mentioned above. 88 ValidBlockParts *types.PartSet `json:"valid_block_parts"` 89 Votes *HeightVoteSet `json:"votes"` 90 CommitRound int32 `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 Proposer types.ValidatorInfo `json:"proposer"` 105 } 106 107 // Compress the RoundState to RoundStateSimple 108 func (rs *RoundState) RoundStateSimple() RoundStateSimple { 109 votesJSON, err := rs.Votes.MarshalJSON() 110 if err != nil { 111 panic(err) 112 } 113 114 addr := rs.Validators.GetProposer().Address 115 idx, _ := rs.Validators.GetByAddress(addr) 116 117 return RoundStateSimple{ 118 HeightRoundStep: fmt.Sprintf("%d/%d/%d", rs.Height, rs.Round, rs.Step), 119 StartTime: rs.StartTime, 120 ProposalBlockHash: rs.ProposalBlock.Hash(), 121 LockedBlockHash: rs.LockedBlock.Hash(), 122 ValidBlockHash: rs.ValidBlock.Hash(), 123 Votes: votesJSON, 124 Proposer: types.ValidatorInfo{ 125 Address: addr, 126 Index: idx, 127 }, 128 } 129 } 130 131 // NewRoundEvent returns the RoundState with proposer information as an event. 132 func (rs *RoundState) NewRoundEvent() types.EventDataNewRound { 133 addr := rs.Validators.GetProposer().Address 134 idx, _ := rs.Validators.GetByAddress(addr) 135 136 return types.EventDataNewRound{ 137 Height: rs.Height, 138 Round: rs.Round, 139 Step: rs.Step.String(), 140 Proposer: types.ValidatorInfo{ 141 Address: addr, 142 Index: idx, 143 }, 144 } 145 } 146 147 // CompleteProposalEvent returns information about a proposed block as an event. 148 func (rs *RoundState) CompleteProposalEvent() types.EventDataCompleteProposal { 149 // We must construct BlockID from ProposalBlock and ProposalBlockParts 150 // cs.Proposal is not guaranteed to be set when this function is called 151 blockID := types.BlockID{ 152 Hash: rs.ProposalBlock.Hash(), 153 PartSetHeader: rs.ProposalBlockParts.Header(), 154 } 155 156 return types.EventDataCompleteProposal{ 157 Height: rs.Height, 158 Round: rs.Round, 159 Step: rs.Step.String(), 160 BlockID: blockID, 161 } 162 } 163 164 // RoundStateEvent returns the H/R/S of the RoundState as an event. 165 func (rs *RoundState) RoundStateEvent() types.EventDataRoundState { 166 return types.EventDataRoundState{ 167 Height: rs.Height, 168 Round: rs.Round, 169 Step: rs.Step.String(), 170 } 171 } 172 173 // String returns a string 174 func (rs *RoundState) String() string { 175 return rs.StringIndented("") 176 } 177 178 // StringIndented returns a string 179 func (rs *RoundState) StringIndented(indent string) string { 180 return fmt.Sprintf(`RoundState{ 181 %s H:%v R:%v S:%v 182 %s StartTime: %v 183 %s CommitTime: %v 184 %s Validators: %v 185 %s Proposal: %v 186 %s ProposalBlock: %v %v 187 %s LockedRound: %v 188 %s LockedBlock: %v %v 189 %s ValidRound: %v 190 %s ValidBlock: %v %v 191 %s Votes: %v 192 %s LastCommit: %v 193 %s LastValidators:%v 194 %s}`, 195 indent, rs.Height, rs.Round, rs.Step, 196 indent, rs.StartTime, 197 indent, rs.CommitTime, 198 indent, rs.Validators.StringIndented(indent+" "), 199 indent, rs.Proposal, 200 indent, rs.ProposalBlockParts.StringShort(), rs.ProposalBlock.StringShort(), 201 indent, rs.LockedRound, 202 indent, rs.LockedBlockParts.StringShort(), rs.LockedBlock.StringShort(), 203 indent, rs.ValidRound, 204 indent, rs.ValidBlockParts.StringShort(), rs.ValidBlock.StringShort(), 205 indent, rs.Votes.StringIndented(indent+" "), 206 indent, rs.LastCommit.StringShort(), 207 indent, rs.LastValidators.StringIndented(indent+" "), 208 indent) 209 } 210 211 // StringShort returns a string 212 func (rs *RoundState) StringShort() string { 213 return fmt.Sprintf(`RoundState{H:%v R:%v S:%v ST:%v}`, 214 rs.Height, rs.Round, rs.Step, rs.StartTime) 215 }