github.com/soomindae/tendermint@v0.0.5-0.20210528140126-84a0c70c8162/rpc/core/env.go (about) 1 package core 2 3 import ( 4 "fmt" 5 "time" 6 7 cfg "github.com/soomindae/tendermint/config" 8 "github.com/soomindae/tendermint/consensus" 9 "github.com/soomindae/tendermint/crypto" 10 "github.com/soomindae/tendermint/libs/log" 11 mempl "github.com/soomindae/tendermint/mempool" 12 "github.com/soomindae/tendermint/p2p" 13 "github.com/soomindae/tendermint/proxy" 14 sm "github.com/soomindae/tendermint/state" 15 "github.com/soomindae/tendermint/state/indexer" 16 "github.com/soomindae/tendermint/state/txindex" 17 "github.com/soomindae/tendermint/types" 18 ) 19 20 const ( 21 // see README 22 defaultPerPage = 30 23 maxPerPage = 100 24 25 // SubscribeTimeout is the maximum time we wait to subscribe for an event. 26 // must be less than the server's write timeout (see rpcserver.DefaultConfig) 27 SubscribeTimeout = 5 * time.Second 28 ) 29 30 var ( 31 // set by Node 32 env *Environment 33 ) 34 35 // SetEnvironment sets up the given Environment. 36 // It will race if multiple Node call SetEnvironment. 37 func SetEnvironment(e *Environment) { 38 env = e 39 } 40 41 //---------------------------------------------- 42 // These interfaces are used by RPC and must be thread safe 43 44 type Consensus interface { 45 GetState() sm.State 46 GetValidators() (int64, []*types.Validator) 47 GetLastHeight() int64 48 GetRoundStateJSON() ([]byte, error) 49 GetRoundStateSimpleJSON() ([]byte, error) 50 } 51 52 type transport interface { 53 Listeners() []string 54 IsListening() bool 55 NodeInfo() p2p.NodeInfo 56 } 57 58 type peers interface { 59 AddPersistentPeers([]string) error 60 AddUnconditionalPeerIDs([]string) error 61 AddPrivatePeerIDs([]string) error 62 DialPeersAsync([]string) error 63 Peers() p2p.IPeerSet 64 } 65 66 //---------------------------------------------- 67 // Environment contains objects and interfaces used by the RPC. It is expected 68 // to be setup once during startup. 69 type Environment struct { 70 // external, thread safe interfaces 71 ProxyAppQuery proxy.AppConnQuery 72 ProxyAppMempool proxy.AppConnMempool 73 74 // interfaces defined in types and above 75 StateStore sm.Store 76 BlockStore sm.BlockStore 77 EvidencePool sm.EvidencePool 78 ConsensusState Consensus 79 P2PPeers peers 80 P2PTransport transport 81 82 // objects 83 PubKey crypto.PubKey 84 GenDoc *types.GenesisDoc // cache the genesis structure 85 TxIndexer txindex.TxIndexer 86 BlockIndexer indexer.BlockIndexer 87 ConsensusReactor *consensus.Reactor 88 EventBus *types.EventBus // thread safe 89 Mempool mempl.Mempool 90 91 Logger log.Logger 92 93 Config cfg.RPCConfig 94 } 95 96 //---------------------------------------------- 97 98 func validatePage(pagePtr *int, perPage, totalCount int) (int, error) { 99 if perPage < 1 { 100 panic(fmt.Sprintf("zero or negative perPage: %d", perPage)) 101 } 102 103 if pagePtr == nil { // no page parameter 104 return 1, nil 105 } 106 107 pages := ((totalCount - 1) / perPage) + 1 108 if pages == 0 { 109 pages = 1 // one page (even if it's empty) 110 } 111 page := *pagePtr 112 if page <= 0 || page > pages { 113 return 1, fmt.Errorf("page should be within [1, %d] range, given %d", pages, page) 114 } 115 116 return page, nil 117 } 118 119 func validatePerPage(perPagePtr *int) int { 120 if perPagePtr == nil { // no per_page parameter 121 return defaultPerPage 122 } 123 124 perPage := *perPagePtr 125 if perPage < 1 { 126 return defaultPerPage 127 } else if perPage > maxPerPage { 128 return maxPerPage 129 } 130 return perPage 131 } 132 133 func validateSkipCount(page, perPage int) int { 134 skipCount := (page - 1) * perPage 135 if skipCount < 0 { 136 return 0 137 } 138 139 return skipCount 140 } 141 142 // latestHeight can be either latest committed or uncommitted (+1) height. 143 func getHeight(latestHeight int64, heightPtr *int64) (int64, error) { 144 if heightPtr != nil { 145 height := *heightPtr 146 if height <= 0 { 147 return 0, fmt.Errorf("height must be greater than 0, but got %d", height) 148 } 149 if height > latestHeight { 150 return 0, fmt.Errorf("height %d must be less than or equal to the current blockchain height %d", 151 height, latestHeight) 152 } 153 base := env.BlockStore.Base() 154 if height < base { 155 return 0, fmt.Errorf("height %d is not available, lowest height is %d", 156 height, base) 157 } 158 return height, nil 159 } 160 return latestHeight, nil 161 } 162 163 func latestUncommittedHeight() int64 { 164 nodeIsSyncing := env.ConsensusReactor.WaitSync() 165 if nodeIsSyncing { 166 return env.BlockStore.Height() 167 } 168 return env.BlockStore.Height() + 1 169 }