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