github.com/evdatsion/aphelion-dpos-bft@v0.32.1/rpc/core/consensus.go (about) 1 package core 2 3 import ( 4 cm "github.com/evdatsion/aphelion-dpos-bft/consensus" 5 ctypes "github.com/evdatsion/aphelion-dpos-bft/rpc/core/types" 6 rpctypes "github.com/evdatsion/aphelion-dpos-bft/rpc/lib/types" 7 sm "github.com/evdatsion/aphelion-dpos-bft/state" 8 "github.com/evdatsion/aphelion-dpos-bft/types" 9 ) 10 11 // Get the validator set at the given block height. 12 // If no height is provided, it will fetch the current validator set. 13 // Note the validators are sorted by their address - this is the canonical 14 // order for the validators in the set as used in computing their Merkle root. 15 // 16 // ```shell 17 // curl 'localhost:26657/validators' 18 // ``` 19 // 20 // ```go 21 // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket") 22 // err := client.Start() 23 // if err != nil { 24 // // handle error 25 // } 26 // defer client.Stop() 27 // state, err := client.Validators() 28 // ``` 29 // 30 // The above command returns JSON structured like this: 31 // 32 // ```json 33 // { 34 // "error": "", 35 // "result": { 36 // "validators": [ 37 // { 38 // "proposer_priority": "0", 39 // "voting_power": "10", 40 // "pub_key": { 41 // "data": "68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D", 42 // "type": "ed25519" 43 // }, 44 // "address": "E89A51D60F68385E09E716D353373B11F8FACD62" 45 // } 46 // ], 47 // "block_height": "5241" 48 // }, 49 // "id": "", 50 // "jsonrpc": "2.0" 51 // } 52 // ``` 53 func Validators(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultValidators, error) { 54 // The latest validator that we know is the 55 // NextValidator of the last block. 56 height := consensusState.GetState().LastBlockHeight + 1 57 height, err := getHeight(height, heightPtr) 58 if err != nil { 59 return nil, err 60 } 61 62 validators, err := sm.LoadValidators(stateDB, height) 63 if err != nil { 64 return nil, err 65 } 66 return &ctypes.ResultValidators{ 67 BlockHeight: height, 68 Validators: validators.Validators}, nil 69 } 70 71 // DumpConsensusState dumps consensus state. 72 // UNSTABLE 73 // 74 // ```shell 75 // curl 'localhost:26657/dump_consensus_state' 76 // ``` 77 // 78 // ```go 79 // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket") 80 // err := client.Start() 81 // if err != nil { 82 // // handle error 83 // } 84 // defer client.Stop() 85 // state, err := client.DumpConsensusState() 86 // ``` 87 // 88 // The above command returns JSON structured like this: 89 // 90 // ```json 91 // { 92 // "jsonrpc": "2.0", 93 // "id": "", 94 // "result": { 95 // "round_state": { 96 // "height": "7185", 97 // "round": "0", 98 // "step": "1", 99 // "start_time": "2018-05-12T13:57:28.440293621-07:00", 100 // "commit_time": "2018-05-12T13:57:27.440293621-07:00", 101 // "validators": { 102 // "validators": [ 103 // { 104 // "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244", 105 // "pub_key": { 106 // "type": "tendermint/PubKeyEd25519", 107 // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg=" 108 // }, 109 // "voting_power": "10", 110 // "proposer_priority": "0" 111 // } 112 // ], 113 // "proposer": { 114 // "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244", 115 // "pub_key": { 116 // "type": "tendermint/PubKeyEd25519", 117 // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg=" 118 // }, 119 // "voting_power": "10", 120 // "proposer_priority": "0" 121 // } 122 // }, 123 // "proposal": null, 124 // "proposal_block": null, 125 // "proposal_block_parts": null, 126 // "locked_round": "0", 127 // "locked_block": null, 128 // "locked_block_parts": null, 129 // "valid_round": "0", 130 // "valid_block": null, 131 // "valid_block_parts": null, 132 // "votes": [ 133 // { 134 // "round": "0", 135 // "prevotes": "_", 136 // "precommits": "_" 137 // } 138 // ], 139 // "commit_round": "-1", 140 // "last_commit": { 141 // "votes": [ 142 // "Vote{0:B5B3D40BE539 7184/00/2(Precommit) 14F946FA7EF0 /702B1B1A602A.../ @ 2018-05-12T20:57:27.342Z}" 143 // ], 144 // "votes_bit_array": "x", 145 // "peer_maj_23s": {} 146 // }, 147 // "last_validators": { 148 // "validators": [ 149 // { 150 // "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244", 151 // "pub_key": { 152 // "type": "tendermint/PubKeyEd25519", 153 // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg=" 154 // }, 155 // "voting_power": "10", 156 // "proposer_priority": "0" 157 // } 158 // ], 159 // "proposer": { 160 // "address": "B5B3D40BE53982AD294EF99FF5A34C0C3E5A3244", 161 // "pub_key": { 162 // "type": "tendermint/PubKeyEd25519", 163 // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg=" 164 // }, 165 // "voting_power": "10", 166 // "proposer_priority": "0" 167 // } 168 // } 169 // }, 170 // "peers": [ 171 // { 172 // "node_address": "30ad1854af22506383c3f0e57fb3c7f90984c5e8@172.16.63.221:26656", 173 // "peer_state": { 174 // "round_state": { 175 // "height": "7185", 176 // "round": "0", 177 // "step": "1", 178 // "start_time": "2018-05-12T13:57:27.438039872-07:00", 179 // "proposal": false, 180 // "proposal_block_parts_header": { 181 // "total": "0", 182 // "hash": "" 183 // }, 184 // "proposal_block_parts": null, 185 // "proposal_pol_round": "-1", 186 // "proposal_pol": "_", 187 // "prevotes": "_", 188 // "precommits": "_", 189 // "last_commit_round": "0", 190 // "last_commit": "x", 191 // "catchup_commit_round": "-1", 192 // "catchup_commit": "_" 193 // }, 194 // "stats": { 195 // "last_vote_height": "7184", 196 // "votes": "255", 197 // "last_block_part_height": "7184", 198 // "block_parts": "255" 199 // } 200 // } 201 // } 202 // ] 203 // } 204 // } 205 // ``` 206 func DumpConsensusState(ctx *rpctypes.Context) (*ctypes.ResultDumpConsensusState, error) { 207 // Get Peer consensus states. 208 peers := p2pPeers.Peers().List() 209 peerStates := make([]ctypes.PeerStateInfo, len(peers)) 210 for i, peer := range peers { 211 peerState, ok := peer.Get(types.PeerStateKey).(*cm.PeerState) 212 if !ok { // peer does not have a state yet 213 continue 214 } 215 peerStateJSON, err := peerState.ToJSON() 216 if err != nil { 217 return nil, err 218 } 219 peerStates[i] = ctypes.PeerStateInfo{ 220 // Peer basic info. 221 NodeAddress: peer.SocketAddr().String(), 222 // Peer consensus state. 223 PeerState: peerStateJSON, 224 } 225 } 226 // Get self round state. 227 roundState, err := consensusState.GetRoundStateJSON() 228 if err != nil { 229 return nil, err 230 } 231 return &ctypes.ResultDumpConsensusState{ 232 RoundState: roundState, 233 Peers: peerStates}, nil 234 } 235 236 // ConsensusState returns a concise summary of the consensus state. 237 // UNSTABLE 238 // 239 // ```shell 240 // curl 'localhost:26657/consensus_state' 241 // ``` 242 // 243 // ```go 244 // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket") 245 // err := client.Start() 246 // if err != nil { 247 // // handle error 248 // } 249 // defer client.Stop() 250 // state, err := client.ConsensusState() 251 // ``` 252 // 253 // The above command returns JSON structured like this: 254 // 255 // ```json 256 //{ 257 // "jsonrpc": "2.0", 258 // "id": "", 259 // "result": { 260 // "round_state": { 261 // "height/round/step": "9336/0/1", 262 // "start_time": "2018-05-14T10:25:45.72595357-04:00", 263 // "proposal_block_hash": "", 264 // "locked_block_hash": "", 265 // "valid_block_hash": "", 266 // "height_vote_set": [ 267 // { 268 // "round": "0", 269 // "prevotes": [ 270 // "nil-Vote" 271 // ], 272 // "prevotes_bit_array": "BA{1:_} 0/10 = 0.00", 273 // "precommits": [ 274 // "nil-Vote" 275 // ], 276 // "precommits_bit_array": "BA{1:_} 0/10 = 0.00" 277 // } 278 // ] 279 // } 280 // } 281 //} 282 //``` 283 func ConsensusState(ctx *rpctypes.Context) (*ctypes.ResultConsensusState, error) { 284 // Get self round state. 285 bz, err := consensusState.GetRoundStateSimpleJSON() 286 return &ctypes.ResultConsensusState{RoundState: bz}, err 287 } 288 289 // Get the consensus parameters at the given block height. 290 // If no height is provided, it will fetch the current consensus params. 291 // 292 // ```shell 293 // curl 'localhost:26657/consensus_params' 294 // ``` 295 // 296 // ```go 297 // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket") 298 // err := client.Start() 299 // if err != nil { 300 // // handle error 301 // } 302 // defer client.Stop() 303 // state, err := client.ConsensusParams() 304 // ``` 305 // 306 // The above command returns JSON structured like this: 307 // 308 // ```json 309 // { 310 // "jsonrpc": "2.0", 311 // "id": "", 312 // "result": { 313 // "block_height": "1", 314 // "consensus_params": { 315 // "block_size_params": { 316 // "max_txs_bytes": "22020096", 317 // "max_gas": "-1" 318 // }, 319 // "evidence_params": { 320 // "max_age": "100000" 321 // } 322 // } 323 // } 324 // } 325 // ``` 326 func ConsensusParams(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultConsensusParams, error) { 327 height := consensusState.GetState().LastBlockHeight + 1 328 height, err := getHeight(height, heightPtr) 329 if err != nil { 330 return nil, err 331 } 332 333 consensusparams, err := sm.LoadConsensusParams(stateDB, height) 334 if err != nil { 335 return nil, err 336 } 337 return &ctypes.ResultConsensusParams{ 338 BlockHeight: height, 339 ConsensusParams: consensusparams}, nil 340 }