github.com/okex/exchain@v1.8.0/libs/tendermint/rpc/core/env.go (about)

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