2018-06-20 17:35:30 -07:00
|
|
|
package core
|
|
|
|
|
|
|
|
import (
|
2019-07-23 12:25:59 +04:00
|
|
|
"fmt"
|
2019-03-20 00:45:51 +01:00
|
|
|
"time"
|
|
|
|
|
2019-03-11 22:45:58 +04:00
|
|
|
cfg "github.com/tendermint/tendermint/config"
|
2018-06-20 17:35:30 -07:00
|
|
|
"github.com/tendermint/tendermint/consensus"
|
2018-11-28 11:53:04 -08:00
|
|
|
"github.com/tendermint/tendermint/crypto"
|
2018-08-10 00:25:57 -05:00
|
|
|
"github.com/tendermint/tendermint/libs/log"
|
2018-08-08 16:03:58 +04:00
|
|
|
mempl "github.com/tendermint/tendermint/mempool"
|
2018-06-20 17:35:30 -07:00
|
|
|
"github.com/tendermint/tendermint/p2p"
|
|
|
|
"github.com/tendermint/tendermint/proxy"
|
|
|
|
sm "github.com/tendermint/tendermint/state"
|
|
|
|
"github.com/tendermint/tendermint/state/txindex"
|
|
|
|
"github.com/tendermint/tendermint/types"
|
2019-07-19 07:54:45 +02:00
|
|
|
dbm "github.com/tendermint/tm-cmn/db"
|
2018-06-20 17:35:30 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// see README
|
|
|
|
defaultPerPage = 30
|
|
|
|
maxPerPage = 100
|
|
|
|
|
2019-03-20 00:45:51 +01:00
|
|
|
// SubscribeTimeout is the maximum time we wait to subscribe for an event.
|
|
|
|
// must be less than the server's write timeout (see rpcserver.DefaultConfig)
|
|
|
|
SubscribeTimeout = 5 * time.Second
|
|
|
|
)
|
2018-06-20 17:35:30 -07:00
|
|
|
|
|
|
|
//----------------------------------------------
|
|
|
|
// These interfaces are used by RPC and must be thread safe
|
|
|
|
|
|
|
|
type Consensus interface {
|
|
|
|
GetState() sm.State
|
|
|
|
GetValidators() (int64, []*types.Validator)
|
2018-06-26 16:52:38 -07:00
|
|
|
GetLastHeight() int64
|
2018-06-20 17:35:30 -07:00
|
|
|
GetRoundStateJSON() ([]byte, error)
|
|
|
|
GetRoundStateSimpleJSON() ([]byte, error)
|
|
|
|
}
|
|
|
|
|
2018-09-18 22:14:40 +02:00
|
|
|
type transport interface {
|
|
|
|
Listeners() []string
|
2018-06-20 17:35:30 -07:00
|
|
|
IsListening() bool
|
2018-09-18 22:14:40 +02:00
|
|
|
NodeInfo() p2p.NodeInfo
|
|
|
|
}
|
|
|
|
|
|
|
|
type peers interface {
|
p2p: make persistent prop independent of conn direction (#3593)
## Description
Previously only outbound peers can be persistent.
Now, even if the peer is inbound, if it's marked as persistent, when/if conn is lost,
Tendermint will try to reconnect. This part is actually optional and can be reverted.
Plus, seed won't disconnect from inbound peer if it's marked as
persistent. Fixes #3362
## Commits
* make persistent prop independent of conn direction
Previously only outbound peers can be persistent. Now, even if the peer
is inbound, if it's marked as persistent, when/if conn is lost,
Tendermint will try to reconnect.
Plus, seed won't disconnect from inbound peer if it's marked as
persistent. Fixes #3362
* fix TestPEXReactorDialPeer test
* add a changelog entry
* update changelog
* add two tests
* reformat code
* test UnsafeDialPeers and UnsafeDialSeeds
* add TestSwitchDialPeersAsync
* spec: update p2p/config spec
* fixes after Ismail's review
* Apply suggestions from code review
Co-Authored-By: melekes <anton.kalyaev@gmail.com>
* fix merge conflict
* remove sleep from TestPEXReactorDoesNotDisconnectFromPersistentPeerInSeedMode
We don't need it actually.
2019-05-03 17:21:56 +04:00
|
|
|
AddPersistentPeers([]string) error
|
|
|
|
DialPeersAsync([]string) error
|
2018-09-18 22:14:40 +02:00
|
|
|
NumPeers() (outbound, inbound, dialig int)
|
|
|
|
Peers() p2p.IPeerSet
|
2018-06-20 17:35:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------
|
|
|
|
// These package level globals come with setters
|
|
|
|
// that are expected to be called only once, on startup
|
|
|
|
|
|
|
|
var (
|
|
|
|
// external, thread safe interfaces
|
|
|
|
proxyAppQuery proxy.AppConnQuery
|
|
|
|
|
|
|
|
// interfaces defined in types and above
|
|
|
|
stateDB dbm.DB
|
|
|
|
blockStore sm.BlockStore
|
|
|
|
evidencePool sm.EvidencePool
|
|
|
|
consensusState Consensus
|
2018-09-18 22:14:40 +02:00
|
|
|
p2pPeers peers
|
|
|
|
p2pTransport transport
|
2018-06-20 17:35:30 -07:00
|
|
|
|
|
|
|
// objects
|
|
|
|
pubKey crypto.PubKey
|
|
|
|
genDoc *types.GenesisDoc // cache the genesis structure
|
|
|
|
addrBook p2p.AddrBook
|
|
|
|
txIndexer txindex.TxIndexer
|
|
|
|
consensusReactor *consensus.ConsensusReactor
|
|
|
|
eventBus *types.EventBus // thread safe
|
2019-05-04 10:41:31 +04:00
|
|
|
mempool mempl.Mempool
|
2018-06-20 17:35:30 -07:00
|
|
|
|
|
|
|
logger log.Logger
|
2019-03-11 22:45:58 +04:00
|
|
|
|
|
|
|
config cfg.RPCConfig
|
2018-06-20 17:35:30 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
func SetStateDB(db dbm.DB) {
|
|
|
|
stateDB = db
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetBlockStore(bs sm.BlockStore) {
|
|
|
|
blockStore = bs
|
|
|
|
}
|
|
|
|
|
2019-05-04 10:41:31 +04:00
|
|
|
func SetMempool(mem mempl.Mempool) {
|
2018-06-20 17:35:30 -07:00
|
|
|
mempool = mem
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetEvidencePool(evpool sm.EvidencePool) {
|
|
|
|
evidencePool = evpool
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetConsensusState(cs Consensus) {
|
|
|
|
consensusState = cs
|
|
|
|
}
|
|
|
|
|
2018-09-18 22:14:40 +02:00
|
|
|
func SetP2PPeers(p peers) {
|
|
|
|
p2pPeers = p
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetP2PTransport(t transport) {
|
|
|
|
p2pTransport = t
|
2018-06-20 17:35:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func SetPubKey(pk crypto.PubKey) {
|
|
|
|
pubKey = pk
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetGenesisDoc(doc *types.GenesisDoc) {
|
|
|
|
genDoc = doc
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetAddrBook(book p2p.AddrBook) {
|
|
|
|
addrBook = book
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetProxyAppQuery(appConn proxy.AppConnQuery) {
|
|
|
|
proxyAppQuery = appConn
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetTxIndexer(indexer txindex.TxIndexer) {
|
|
|
|
txIndexer = indexer
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetConsensusReactor(conR *consensus.ConsensusReactor) {
|
|
|
|
consensusReactor = conR
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetLogger(l log.Logger) {
|
|
|
|
logger = l
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetEventBus(b *types.EventBus) {
|
|
|
|
eventBus = b
|
|
|
|
}
|
|
|
|
|
2019-03-11 22:45:58 +04:00
|
|
|
// SetConfig sets an RPCConfig.
|
|
|
|
func SetConfig(c cfg.RPCConfig) {
|
|
|
|
config = c
|
|
|
|
}
|
|
|
|
|
2019-07-23 12:25:59 +04:00
|
|
|
func validatePage(page, perPage, totalCount int) (int, error) {
|
2018-06-20 17:35:30 -07:00
|
|
|
if perPage < 1 {
|
2019-07-23 12:25:59 +04:00
|
|
|
panic(fmt.Sprintf("zero or negative perPage: %d", perPage))
|
|
|
|
}
|
|
|
|
|
|
|
|
if page == 0 {
|
|
|
|
return 1, nil // default
|
2018-06-20 17:35:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pages := ((totalCount - 1) / perPage) + 1
|
2019-07-23 12:25:59 +04:00
|
|
|
if pages == 0 {
|
|
|
|
pages = 1 // one page (even if it's empty)
|
|
|
|
}
|
|
|
|
if page < 0 || page > pages {
|
|
|
|
return 1, fmt.Errorf("page should be within [0, %d] range, given %d", pages, page)
|
2018-06-20 17:35:30 -07:00
|
|
|
}
|
|
|
|
|
2019-07-23 12:25:59 +04:00
|
|
|
return page, nil
|
2018-06-20 17:35:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func validatePerPage(perPage int) int {
|
2019-01-15 02:35:31 +04:00
|
|
|
if perPage < 1 {
|
2018-06-20 17:35:30 -07:00
|
|
|
return defaultPerPage
|
2019-01-15 02:35:31 +04:00
|
|
|
} else if perPage > maxPerPage {
|
|
|
|
return maxPerPage
|
2018-06-20 17:35:30 -07:00
|
|
|
}
|
|
|
|
return perPage
|
|
|
|
}
|
2019-01-14 06:34:29 +11:00
|
|
|
|
|
|
|
func validateSkipCount(page, perPage int) int {
|
|
|
|
skipCount := (page - 1) * perPage
|
|
|
|
if skipCount < 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
return skipCount
|
|
|
|
}
|