github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/rpc/core/pipe.go (about)

     1  package core
     2  
     3  import (
     4  	"fmt"
     5  	"log/slog"
     6  
     7  	"github.com/gnolang/gno/tm2/pkg/bft/appconn"
     8  	cnscfg "github.com/gnolang/gno/tm2/pkg/bft/consensus/config"
     9  	cstypes "github.com/gnolang/gno/tm2/pkg/bft/consensus/types"
    10  	mempl "github.com/gnolang/gno/tm2/pkg/bft/mempool"
    11  	cfg "github.com/gnolang/gno/tm2/pkg/bft/rpc/config"
    12  	sm "github.com/gnolang/gno/tm2/pkg/bft/state"
    13  	"github.com/gnolang/gno/tm2/pkg/bft/types"
    14  	"github.com/gnolang/gno/tm2/pkg/crypto"
    15  	dbm "github.com/gnolang/gno/tm2/pkg/db"
    16  	"github.com/gnolang/gno/tm2/pkg/events"
    17  	"github.com/gnolang/gno/tm2/pkg/p2p"
    18  )
    19  
    20  const (
    21  	// see README
    22  	defaultPerPage = 30
    23  	maxPerPage     = 100
    24  )
    25  
    26  // ----------------------------------------------
    27  // These interfaces are used by RPC and must be thread safe
    28  
    29  type Consensus interface {
    30  	GetConfigDeepCopy() *cnscfg.ConsensusConfig
    31  	GetState() sm.State
    32  	GetValidators() (int64, []*types.Validator)
    33  	GetLastHeight() int64
    34  	GetRoundStateDeepCopy() *cstypes.RoundState
    35  	GetRoundStateSimple() cstypes.RoundStateSimple
    36  }
    37  
    38  type transport interface {
    39  	Listeners() []string
    40  	IsListening() bool
    41  	NodeInfo() p2p.NodeInfo
    42  }
    43  
    44  type peers interface {
    45  	AddPersistentPeers([]string) error
    46  	DialPeersAsync([]string) error
    47  	NumPeers() (outbound, inbound, dialig int)
    48  	Peers() p2p.IPeerSet
    49  }
    50  
    51  // ----------------------------------------------
    52  // These package level globals come with setters
    53  // that are expected to be called only once, on startup
    54  
    55  var (
    56  	// external, thread safe interfaces
    57  	proxyAppQuery appconn.Query
    58  
    59  	// interfaces defined in types and above
    60  	stateDB        dbm.DB
    61  	blockStore     sm.BlockStore
    62  	consensusState Consensus
    63  	p2pPeers       peers
    64  	p2pTransport   transport
    65  
    66  	// objects
    67  	pubKey        crypto.PubKey
    68  	genDoc        *types.GenesisDoc // cache the genesis structure
    69  	evsw          events.EventSwitch
    70  	gTxDispatcher *txDispatcher
    71  	mempool       mempl.Mempool
    72  	getFastSync   func() bool // avoids dependency on consensus pkg
    73  
    74  	logger *slog.Logger
    75  
    76  	config cfg.RPCConfig
    77  )
    78  
    79  func SetStateDB(db dbm.DB) {
    80  	stateDB = db
    81  }
    82  
    83  func SetBlockStore(bs sm.BlockStore) {
    84  	blockStore = bs
    85  }
    86  
    87  func SetMempool(mem mempl.Mempool) {
    88  	mempool = mem
    89  }
    90  
    91  func SetConsensusState(cs Consensus) {
    92  	consensusState = cs
    93  }
    94  
    95  func SetP2PPeers(p peers) {
    96  	p2pPeers = p
    97  }
    98  
    99  func SetP2PTransport(t transport) {
   100  	p2pTransport = t
   101  }
   102  
   103  func SetPubKey(pk crypto.PubKey) {
   104  	pubKey = pk
   105  }
   106  
   107  func SetGenesisDoc(doc *types.GenesisDoc) {
   108  	genDoc = doc
   109  }
   110  
   111  func SetProxyAppQuery(appConn appconn.Query) {
   112  	proxyAppQuery = appConn
   113  }
   114  
   115  func SetGetFastSync(v func() bool) {
   116  	getFastSync = v
   117  }
   118  
   119  func SetLogger(l *slog.Logger) {
   120  	logger = l
   121  }
   122  
   123  func SetEventSwitch(sw events.EventSwitch) {
   124  	evsw = sw
   125  	gTxDispatcher = newTxDispatcher(evsw)
   126  }
   127  
   128  func Start() {
   129  	gTxDispatcher.Start()
   130  }
   131  
   132  // SetConfig sets an RPCConfig.
   133  func SetConfig(c cfg.RPCConfig) {
   134  	config = c
   135  }
   136  
   137  func validatePage(page, perPage, totalCount int) (int, error) {
   138  	if perPage < 1 {
   139  		panic(fmt.Sprintf("zero or negative perPage: %d", perPage))
   140  	}
   141  
   142  	if page == 0 {
   143  		return 1, nil // default
   144  	}
   145  
   146  	pages := ((totalCount - 1) / perPage) + 1
   147  	if pages == 0 {
   148  		pages = 1 // one page (even if it's empty)
   149  	}
   150  	if page < 0 || page > pages {
   151  		return 1, fmt.Errorf("page should be within [0, %d] range, given %d", pages, page)
   152  	}
   153  
   154  	return page, nil
   155  }
   156  
   157  func validatePerPage(perPage int) int {
   158  	if perPage < 1 {
   159  		return defaultPerPage
   160  	} else if perPage > maxPerPage {
   161  		return maxPerPage
   162  	}
   163  	return perPage
   164  }