github.com/evdatsion/aphelion-dpos-bft@v0.32.1/rpc/core/status.go (about) 1 package core 2 3 import ( 4 "bytes" 5 "time" 6 7 cmn "github.com/evdatsion/aphelion-dpos-bft/libs/common" 8 "github.com/evdatsion/aphelion-dpos-bft/p2p" 9 ctypes "github.com/evdatsion/aphelion-dpos-bft/rpc/core/types" 10 rpctypes "github.com/evdatsion/aphelion-dpos-bft/rpc/lib/types" 11 sm "github.com/evdatsion/aphelion-dpos-bft/state" 12 "github.com/evdatsion/aphelion-dpos-bft/types" 13 ) 14 15 // Get Tendermint status including node info, pubkey, latest block 16 // hash, app hash, block height and time. 17 // 18 // ```shell 19 // curl 'localhost:26657/status' 20 // ``` 21 // 22 // ```go 23 // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket") 24 // err := client.Start() 25 // if err != nil { 26 // // handle error 27 // } 28 // defer client.Stop() 29 // result, err := client.Status() 30 // ``` 31 // 32 // > The above command returns JSON structured like this: 33 // 34 // ```json 35 // { 36 // "jsonrpc": "2.0", 37 // "id": "", 38 // "result": { 39 // "node_info": { 40 // "protocol_version": { 41 // "p2p": "4", 42 // "block": "7", 43 // "app": "0" 44 // }, 45 // "id": "53729852020041b956e86685e24394e0bee4373f", 46 // "listen_addr": "10.0.2.15:26656", 47 // "network": "test-chain-Y1OHx6", 48 // "version": "0.24.0-2ce1abc2", 49 // "channels": "4020212223303800", 50 // "moniker": "ubuntu-xenial", 51 // "other": { 52 // "tx_index": "on", 53 // "rpc_addr": "tcp://0.0.0.0:26657" 54 // } 55 // }, 56 // "sync_info": { 57 // "latest_block_hash": "F51538DA498299F4C57AC8162AAFA0254CE08286", 58 // "latest_app_hash": "0000000000000000", 59 // "latest_block_height": "18", 60 // "latest_block_time": "2018-09-17T11:42:19.149920551Z", 61 // "catching_up": false 62 // }, 63 // "validator_info": { 64 // "address": "D9F56456D7C5793815D0E9AF07C3A355D0FC64FD", 65 // "pub_key": { 66 // "type": "tendermint/PubKeyEd25519", 67 // "value": "wVxKNtEsJmR4vvh651LrVoRguPs+6yJJ9Bz174gw9DM=" 68 // }, 69 // "voting_power": "10" 70 // } 71 // } 72 // } 73 // ``` 74 func Status(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) { 75 var latestHeight int64 76 if consensusReactor.FastSync() { 77 latestHeight = blockStore.Height() 78 } else { 79 latestHeight = consensusState.GetLastHeight() 80 } 81 var ( 82 latestBlockMeta *types.BlockMeta 83 latestBlockHash cmn.HexBytes 84 latestAppHash cmn.HexBytes 85 latestBlockTimeNano int64 86 ) 87 if latestHeight != 0 { 88 latestBlockMeta = blockStore.LoadBlockMeta(latestHeight) 89 latestBlockHash = latestBlockMeta.BlockID.Hash 90 latestAppHash = latestBlockMeta.Header.AppHash 91 latestBlockTimeNano = latestBlockMeta.Header.Time.UnixNano() 92 } 93 94 latestBlockTime := time.Unix(0, latestBlockTimeNano) 95 96 var votingPower int64 97 if val := validatorAtHeight(latestHeight); val != nil { 98 votingPower = val.VotingPower 99 } 100 101 result := &ctypes.ResultStatus{ 102 NodeInfo: p2pTransport.NodeInfo().(p2p.DefaultNodeInfo), 103 SyncInfo: ctypes.SyncInfo{ 104 LatestBlockHash: latestBlockHash, 105 LatestAppHash: latestAppHash, 106 LatestBlockHeight: latestHeight, 107 LatestBlockTime: latestBlockTime, 108 CatchingUp: consensusReactor.FastSync(), 109 }, 110 ValidatorInfo: ctypes.ValidatorInfo{ 111 Address: pubKey.Address(), 112 PubKey: pubKey, 113 VotingPower: votingPower, 114 }, 115 } 116 117 return result, nil 118 } 119 120 func validatorAtHeight(h int64) *types.Validator { 121 privValAddress := pubKey.Address() 122 123 // If we're still at height h, search in the current validator set. 124 lastBlockHeight, vals := consensusState.GetValidators() 125 if lastBlockHeight == h { 126 for _, val := range vals { 127 if bytes.Equal(val.Address, privValAddress) { 128 return val 129 } 130 } 131 } 132 133 // If we've moved to the next height, retrieve the validator set from DB. 134 if lastBlockHeight > h { 135 vals, err := sm.LoadValidators(stateDB, h) 136 if err != nil { 137 return nil // should not happen 138 } 139 _, val := vals.GetByAddress(privValAddress) 140 return val 141 } 142 143 return nil 144 }