premerge2: rpc -> rpc/tendermint

This commit is contained in:
Ethan Buchman
2017-04-21 17:39:51 -04:00
parent 0017fb7ffe
commit 992b11c450
37 changed files with 0 additions and 0 deletions

View File

@ -1,30 +0,0 @@
package core
import (
abci "github.com/tendermint/abci/types"
data "github.com/tendermint/go-data"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)
//-----------------------------------------------------------------------------
func ABCIQuery(path string, data data.Bytes, prove bool) (*ctypes.ResultABCIQuery, error) {
resQuery, err := proxyAppQuery.QuerySync(abci.RequestQuery{
Path: path,
Data: data,
Prove: prove,
})
if err != nil {
return nil, err
}
log.Info("ABCIQuery", "path", path, "data", data, "result", resQuery)
return &ctypes.ResultABCIQuery{resQuery}, nil
}
func ABCIInfo() (*ctypes.ResultABCIInfo, error) {
resInfo, err := proxyAppQuery.InfoSync()
if err != nil {
return nil, err
}
return &ctypes.ResultABCIInfo{resInfo}, nil
}

View File

@ -1,71 +0,0 @@
package core
import (
"fmt"
. "github.com/tendermint/go-common"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
)
//-----------------------------------------------------------------------------
// TODO: limit/permission on (max - min)
func BlockchainInfo(minHeight, maxHeight int) (*ctypes.ResultBlockchainInfo, error) {
if maxHeight == 0 {
maxHeight = blockStore.Height()
} else {
maxHeight = MinInt(blockStore.Height(), maxHeight)
}
if minHeight == 0 {
minHeight = MaxInt(1, maxHeight-20)
}
log.Debug("BlockchainInfoHandler", "maxHeight", maxHeight, "minHeight", minHeight)
blockMetas := []*types.BlockMeta{}
for height := maxHeight; height >= minHeight; height-- {
blockMeta := blockStore.LoadBlockMeta(height)
blockMetas = append(blockMetas, blockMeta)
}
return &ctypes.ResultBlockchainInfo{blockStore.Height(), blockMetas}, nil
}
//-----------------------------------------------------------------------------
func Block(height int) (*ctypes.ResultBlock, error) {
if height == 0 {
return nil, fmt.Errorf("Height must be greater than 0")
}
if height > blockStore.Height() {
return nil, fmt.Errorf("Height must be less than the current blockchain height")
}
blockMeta := blockStore.LoadBlockMeta(height)
block := blockStore.LoadBlock(height)
return &ctypes.ResultBlock{blockMeta, block}, nil
}
//-----------------------------------------------------------------------------
func Commit(height int) (*ctypes.ResultCommit, error) {
if height == 0 {
return nil, fmt.Errorf("Height must be greater than 0")
}
storeHeight := blockStore.Height()
if height > storeHeight {
return nil, fmt.Errorf("Height must be less than or equal to the current blockchain height")
}
header := blockStore.LoadBlockMeta(height).Header
// If the next block has not been committed yet,
// use a non-canonical commit
if height == storeHeight {
commit := blockStore.LoadSeenCommit(height)
return &ctypes.ResultCommit{header, commit, false}, nil
}
// Return the canonical commit (comes from the block at height+1)
commit := blockStore.LoadBlockCommit(height)
return &ctypes.ResultCommit{header, commit, true}, nil
}

View File

@ -1,26 +0,0 @@
package core
import (
"github.com/tendermint/go-wire"
cm "github.com/tendermint/tendermint/consensus"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
)
func Validators() (*ctypes.ResultValidators, error) {
blockHeight, validators := consensusState.GetValidators()
return &ctypes.ResultValidators{blockHeight, validators}, nil
}
func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
roundState := consensusState.GetRoundState()
peerRoundStates := []string{}
for _, peer := range p2pSwitch.Peers().List() {
// TODO: clean this up?
peerState := peer.Data.Get(types.PeerStateKey).(*cm.PeerState)
peerRoundState := peerState.GetRoundState()
peerRoundStateStr := peer.Key + ":" + string(wire.JSONBytes(peerRoundState))
peerRoundStates = append(peerRoundStates, peerRoundStateStr)
}
return &ctypes.ResultDumpConsensusState{roundState.String(), peerRoundStates}, nil
}

View File

@ -1,72 +0,0 @@
package core
import (
"fmt"
"os"
"runtime/pprof"
"strconv"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)
func UnsafeFlushMempool() (*ctypes.ResultUnsafeFlushMempool, error) {
mempool.Flush()
return &ctypes.ResultUnsafeFlushMempool{}, nil
}
func UnsafeSetConfig(typ, key, value string) (*ctypes.ResultUnsafeSetConfig, error) {
switch typ {
case "string":
config.Set(key, value)
case "int":
val, err := strconv.Atoi(value)
if err != nil {
return nil, fmt.Errorf("non-integer value found. key:%s; value:%s; err:%v", key, value, err)
}
config.Set(key, val)
case "bool":
switch value {
case "true":
config.Set(key, true)
case "false":
config.Set(key, false)
default:
return nil, fmt.Errorf("bool value must be true or false. got %s", value)
}
default:
return nil, fmt.Errorf("Unknown type %s", typ)
}
return &ctypes.ResultUnsafeSetConfig{}, nil
}
var profFile *os.File
func UnsafeStartCPUProfiler(filename string) (*ctypes.ResultUnsafeProfile, error) {
var err error
profFile, err = os.Create(filename)
if err != nil {
return nil, err
}
err = pprof.StartCPUProfile(profFile)
if err != nil {
return nil, err
}
return &ctypes.ResultUnsafeProfile{}, nil
}
func UnsafeStopCPUProfiler() (*ctypes.ResultUnsafeProfile, error) {
pprof.StopCPUProfile()
profFile.Close()
return &ctypes.ResultUnsafeProfile{}, nil
}
func UnsafeWriteHeapProfile(filename string) (*ctypes.ResultUnsafeProfile, error) {
memProfFile, err := os.Create(filename)
if err != nil {
return nil, err
}
pprof.WriteHeapProfile(memProfFile)
memProfFile.Close()
return &ctypes.ResultUnsafeProfile{}, nil
}

View File

@ -1,24 +0,0 @@
package core
import (
"github.com/tendermint/go-rpc/types"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
)
func Subscribe(wsCtx rpctypes.WSRPCContext, event string) (*ctypes.ResultSubscribe, error) {
log.Notice("Subscribe to event", "remote", wsCtx.GetRemoteAddr(), "event", event)
types.AddListenerForEvent(wsCtx.GetEventSwitch(), wsCtx.GetRemoteAddr(), event, func(msg types.TMEventData) {
// NOTE: EventSwitch callbacks must be nonblocking
// NOTE: RPCResponses of subscribed events have id suffix "#event"
tmResult := ctypes.TMResult(&ctypes.ResultEvent{event, msg})
wsCtx.TryWriteRPCResponse(rpctypes.NewRPCResponse(wsCtx.Request.ID+"#event", &tmResult, ""))
})
return &ctypes.ResultSubscribe{}, nil
}
func Unsubscribe(wsCtx rpctypes.WSRPCContext, event string) (*ctypes.ResultUnsubscribe, error) {
log.Notice("Unsubscribe to event", "remote", wsCtx.GetRemoteAddr(), "event", event)
wsCtx.GetEventSwitch().RemoveListenerForEvent(event, wsCtx.GetRemoteAddr())
return &ctypes.ResultUnsubscribe{}, nil
}

View File

@ -1,7 +0,0 @@
package core
import (
"github.com/tendermint/log15"
)
var log = log15.New("module", "rpc")

View File

@ -1,114 +0,0 @@
package core
import (
"fmt"
"time"
abci "github.com/tendermint/abci/types"
data "github.com/tendermint/go-data"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
)
//-----------------------------------------------------------------------------
// NOTE: tx should be signed, but this is only checked at the app level (not by Tendermint!)
// Returns right away, with no response
func BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
err := mempool.CheckTx(tx, nil)
if err != nil {
return nil, fmt.Errorf("Error broadcasting transaction: %v", err)
}
return &ctypes.ResultBroadcastTx{Hash: tx.Hash()}, nil
}
// Returns with the response from CheckTx
func BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
resCh := make(chan *abci.Response, 1)
err := mempool.CheckTx(tx, func(res *abci.Response) {
resCh <- res
})
if err != nil {
return nil, fmt.Errorf("Error broadcasting transaction: %v", err)
}
res := <-resCh
r := res.GetCheckTx()
return &ctypes.ResultBroadcastTx{
Code: r.Code,
Data: r.Data,
Log: r.Log,
Hash: tx.Hash(),
}, nil
}
// CONTRACT: only returns error if mempool.BroadcastTx errs (ie. problem with the app)
// or if we timeout waiting for tx to commit.
// If CheckTx or DeliverTx fail, no error will be returned, but the returned result
// will contain a non-OK ABCI code.
func BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
// subscribe to tx being committed in block
deliverTxResCh := make(chan types.EventDataTx, 1)
types.AddListenerForEvent(eventSwitch, "rpc", types.EventStringTx(tx), func(data types.TMEventData) {
deliverTxResCh <- data.(types.EventDataTx)
})
// broadcast the tx and register checktx callback
checkTxResCh := make(chan *abci.Response, 1)
err := mempool.CheckTx(tx, func(res *abci.Response) {
checkTxResCh <- res
})
if err != nil {
log.Error("err", "err", err)
return nil, fmt.Errorf("Error broadcasting transaction: %v", err)
}
checkTxRes := <-checkTxResCh
checkTxR := checkTxRes.GetCheckTx()
if checkTxR.Code != abci.CodeType_OK {
// CheckTx failed!
return &ctypes.ResultBroadcastTxCommit{
CheckTx: checkTxR,
DeliverTx: nil,
Hash: tx.Hash(),
}, nil
}
// Wait for the tx to be included in a block,
// timeout after something reasonable.
// TODO: configureable?
timer := time.NewTimer(60 * 2 * time.Second)
select {
case deliverTxRes := <-deliverTxResCh:
// The tx was included in a block.
deliverTxR := &abci.ResponseDeliverTx{
Code: deliverTxRes.Code,
Data: deliverTxRes.Data,
Log: deliverTxRes.Log,
}
log.Notice("DeliverTx passed ", "tx", data.Bytes(tx), "response", deliverTxR)
return &ctypes.ResultBroadcastTxCommit{
CheckTx: checkTxR,
DeliverTx: deliverTxR,
Hash: tx.Hash(),
Height: deliverTxRes.Height,
}, nil
case <-timer.C:
log.Error("failed to include tx")
return &ctypes.ResultBroadcastTxCommit{
CheckTx: checkTxR,
DeliverTx: nil,
Hash: tx.Hash(),
}, fmt.Errorf("Timed out waiting for transaction to be included in a block")
}
panic("Should never happen!")
}
func UnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
txs := mempool.Reap(-1)
return &ctypes.ResultUnconfirmedTxs{len(txs), txs}, nil
}
func NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
return &ctypes.ResultUnconfirmedTxs{N: mempool.Size()}, nil
}

View File

@ -1,53 +0,0 @@
package core
import (
"fmt"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)
//-----------------------------------------------------------------------------
func NetInfo() (*ctypes.ResultNetInfo, error) {
listening := p2pSwitch.IsListening()
listeners := []string{}
for _, listener := range p2pSwitch.Listeners() {
listeners = append(listeners, listener.String())
}
peers := []ctypes.Peer{}
for _, peer := range p2pSwitch.Peers().List() {
peers = append(peers, ctypes.Peer{
NodeInfo: *peer.NodeInfo,
IsOutbound: peer.IsOutbound(),
ConnectionStatus: peer.Connection().Status(),
})
}
return &ctypes.ResultNetInfo{
Listening: listening,
Listeners: listeners,
Peers: peers,
}, nil
}
//-----------------------------------------------------------------------------
// Dial given list of seeds
func UnsafeDialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) {
if len(seeds) == 0 {
return &ctypes.ResultDialSeeds{}, fmt.Errorf("No seeds provided")
}
// starts go routines to dial each seed after random delays
log.Info("DialSeeds", "addrBook", addrBook, "seeds", seeds)
err := p2pSwitch.DialSeeds(addrBook, seeds)
if err != nil {
return &ctypes.ResultDialSeeds{}, err
}
return &ctypes.ResultDialSeeds{"Dialing seeds in progress. See /net_info for details"}, nil
}
//-----------------------------------------------------------------------------
func Genesis() (*ctypes.ResultGenesis, error) {
return &ctypes.ResultGenesis{genDoc}, nil
}

View File

@ -1,94 +0,0 @@
package core
import (
cfg "github.com/tendermint/go-config"
crypto "github.com/tendermint/go-crypto"
p2p "github.com/tendermint/go-p2p"
"github.com/tendermint/tendermint/consensus"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/state/txindex"
"github.com/tendermint/tendermint/types"
)
//----------------------------------------------
// These interfaces are used by RPC and must be thread safe
type Consensus interface {
GetValidators() (int, []*types.Validator)
GetRoundState() *consensus.RoundState
}
type P2P interface {
Listeners() []p2p.Listener
Peers() p2p.IPeerSet
NumPeers() (outbound, inbound, dialig int)
NodeInfo() *p2p.NodeInfo
IsListening() bool
DialSeeds(*p2p.AddrBook, []string) error
}
//----------------------------------------------
var (
// external, thread safe interfaces
eventSwitch types.EventSwitch
proxyAppQuery proxy.AppConnQuery
config cfg.Config
// interfaces defined in types and above
blockStore types.BlockStore
mempool types.Mempool
consensusState Consensus
p2pSwitch P2P
// objects
pubKey crypto.PubKey
genDoc *types.GenesisDoc // cache the genesis structure
addrBook *p2p.AddrBook
txIndexer txindex.TxIndexer
)
func SetConfig(c cfg.Config) {
config = c
}
func SetEventSwitch(evsw types.EventSwitch) {
eventSwitch = evsw
}
func SetBlockStore(bs types.BlockStore) {
blockStore = bs
}
func SetMempool(mem types.Mempool) {
mempool = mem
}
func SetConsensusState(cs Consensus) {
consensusState = cs
}
func SetSwitch(sw P2P) {
p2pSwitch = sw
}
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
}

View File

@ -1,147 +0,0 @@
package core
import (
data "github.com/tendermint/go-data"
rpc "github.com/tendermint/go-rpc/server"
"github.com/tendermint/go-rpc/types"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
)
// TODO: better system than "unsafe" prefix
var Routes = map[string]*rpc.RPCFunc{
// subscribe/unsubscribe are reserved for websocket events.
"subscribe": rpc.NewWSRPCFunc(SubscribeResult, "event"),
"unsubscribe": rpc.NewWSRPCFunc(UnsubscribeResult, "event"),
// info API
"status": rpc.NewRPCFunc(StatusResult, ""),
"net_info": rpc.NewRPCFunc(NetInfoResult, ""),
"blockchain": rpc.NewRPCFunc(BlockchainInfoResult, "minHeight,maxHeight"),
"genesis": rpc.NewRPCFunc(GenesisResult, ""),
"block": rpc.NewRPCFunc(BlockResult, "height"),
"commit": rpc.NewRPCFunc(CommitResult, "height"),
"tx": rpc.NewRPCFunc(TxResult, "hash,prove"),
"validators": rpc.NewRPCFunc(ValidatorsResult, ""),
"dump_consensus_state": rpc.NewRPCFunc(DumpConsensusStateResult, ""),
"unconfirmed_txs": rpc.NewRPCFunc(UnconfirmedTxsResult, ""),
"num_unconfirmed_txs": rpc.NewRPCFunc(NumUnconfirmedTxsResult, ""),
// broadcast API
"broadcast_tx_commit": rpc.NewRPCFunc(BroadcastTxCommitResult, "tx"),
"broadcast_tx_sync": rpc.NewRPCFunc(BroadcastTxSyncResult, "tx"),
"broadcast_tx_async": rpc.NewRPCFunc(BroadcastTxAsyncResult, "tx"),
// abci API
"abci_query": rpc.NewRPCFunc(ABCIQueryResult, "path,data,prove"),
"abci_info": rpc.NewRPCFunc(ABCIInfoResult, ""),
// control API
"dial_seeds": rpc.NewRPCFunc(UnsafeDialSeedsResult, "seeds"),
"unsafe_flush_mempool": rpc.NewRPCFunc(UnsafeFlushMempool, ""),
"unsafe_set_config": rpc.NewRPCFunc(UnsafeSetConfigResult, "type,key,value"),
// profiler API
"unsafe_start_cpu_profiler": rpc.NewRPCFunc(UnsafeStartCPUProfilerResult, "filename"),
"unsafe_stop_cpu_profiler": rpc.NewRPCFunc(UnsafeStopCPUProfilerResult, ""),
"unsafe_write_heap_profile": rpc.NewRPCFunc(UnsafeWriteHeapProfileResult, "filename"),
}
func SubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (ctypes.TMResult, error) {
return Subscribe(wsCtx, event)
}
func UnsubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (ctypes.TMResult, error) {
return Unsubscribe(wsCtx, event)
}
func StatusResult() (ctypes.TMResult, error) {
return Status()
}
func NetInfoResult() (ctypes.TMResult, error) {
return NetInfo()
}
func UnsafeDialSeedsResult(seeds []string) (ctypes.TMResult, error) {
return UnsafeDialSeeds(seeds)
}
func BlockchainInfoResult(min, max int) (ctypes.TMResult, error) {
return BlockchainInfo(min, max)
}
func GenesisResult() (ctypes.TMResult, error) {
return Genesis()
}
func BlockResult(height int) (ctypes.TMResult, error) {
return Block(height)
}
func CommitResult(height int) (ctypes.TMResult, error) {
return Commit(height)
}
func ValidatorsResult() (ctypes.TMResult, error) {
return Validators()
}
func DumpConsensusStateResult() (ctypes.TMResult, error) {
return DumpConsensusState()
}
func UnconfirmedTxsResult() (ctypes.TMResult, error) {
return UnconfirmedTxs()
}
func NumUnconfirmedTxsResult() (ctypes.TMResult, error) {
return NumUnconfirmedTxs()
}
// Tx allow user to query the transaction results. `nil` could mean the
// transaction is in the mempool, invalidated, or was not send in the first
// place.
func TxResult(hash []byte, prove bool) (ctypes.TMResult, error) {
return Tx(hash, prove)
}
func BroadcastTxCommitResult(tx types.Tx) (ctypes.TMResult, error) {
return BroadcastTxCommit(tx)
}
func BroadcastTxSyncResult(tx types.Tx) (ctypes.TMResult, error) {
return BroadcastTxSync(tx)
}
func BroadcastTxAsyncResult(tx types.Tx) (ctypes.TMResult, error) {
return BroadcastTxAsync(tx)
}
func ABCIQueryResult(path string, data data.Bytes, prove bool) (ctypes.TMResult, error) {
return ABCIQuery(path, data, prove)
}
func ABCIInfoResult() (ctypes.TMResult, error) {
return ABCIInfo()
}
func UnsafeFlushMempoolResult() (ctypes.TMResult, error) {
return UnsafeFlushMempool()
}
func UnsafeSetConfigResult(typ, key, value string) (ctypes.TMResult, error) {
return UnsafeSetConfig(typ, key, value)
}
func UnsafeStartCPUProfilerResult(filename string) (ctypes.TMResult, error) {
return UnsafeStartCPUProfiler(filename)
}
func UnsafeStopCPUProfilerResult() (ctypes.TMResult, error) {
return UnsafeStopCPUProfiler()
}
func UnsafeWriteHeapProfileResult(filename string) (ctypes.TMResult, error) {
return UnsafeWriteHeapProfile(filename)
}

View File

@ -1,31 +0,0 @@
package core
import (
data "github.com/tendermint/go-data"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
)
func Status() (*ctypes.ResultStatus, error) {
latestHeight := blockStore.Height()
var (
latestBlockMeta *types.BlockMeta
latestBlockHash data.Bytes
latestAppHash data.Bytes
latestBlockTime int64
)
if latestHeight != 0 {
latestBlockMeta = blockStore.LoadBlockMeta(latestHeight)
latestBlockHash = latestBlockMeta.BlockID.Hash
latestAppHash = latestBlockMeta.Header.AppHash
latestBlockTime = latestBlockMeta.Header.Time.UnixNano()
}
return &ctypes.ResultStatus{
NodeInfo: p2pSwitch.NodeInfo(),
PubKey: pubKey,
LatestBlockHash: latestBlockHash,
LatestAppHash: latestAppHash,
LatestBlockHeight: latestHeight,
LatestBlockTime: latestBlockTime}, nil
}

View File

@ -1,43 +0,0 @@
package core
import (
"fmt"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/state/txindex/null"
"github.com/tendermint/tendermint/types"
)
func Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
// if index is disabled, return error
if _, ok := txIndexer.(*null.TxIndex); ok {
return nil, fmt.Errorf("Transaction indexing is disabled.")
}
r, err := txIndexer.Get(hash)
if err != nil {
return nil, err
}
if r == nil {
return nil, fmt.Errorf("Tx (%X) not found", hash)
}
height := int(r.Height) // XXX
index := int(r.Index)
var proof types.TxProof
if prove {
block := blockStore.LoadBlock(height)
proof = block.Data.Txs.Proof(index)
}
return &ctypes.ResultTx{
Height: height,
Index: index,
TxResult: r.Result,
Tx: r.Tx,
Proof: proof,
}, nil
}

View File

@ -1,208 +0,0 @@
package core_types
import (
"strings"
abci "github.com/tendermint/abci/types"
"github.com/tendermint/go-crypto"
data "github.com/tendermint/go-data"
"github.com/tendermint/go-p2p"
"github.com/tendermint/go-rpc/types"
"github.com/tendermint/go-wire"
"github.com/tendermint/tendermint/types"
)
type ResultBlockchainInfo struct {
LastHeight int `json:"last_height"`
BlockMetas []*types.BlockMeta `json:"block_metas"`
}
type ResultGenesis struct {
Genesis *types.GenesisDoc `json:"genesis"`
}
type ResultBlock struct {
BlockMeta *types.BlockMeta `json:"block_meta"`
Block *types.Block `json:"block"`
}
type ResultCommit struct {
Header *types.Header `json:"header"`
Commit *types.Commit `json:"commit"`
CanonicalCommit bool `json:"canonical"`
}
type ResultStatus struct {
NodeInfo *p2p.NodeInfo `json:"node_info"`
PubKey crypto.PubKey `json:"pub_key"`
LatestBlockHash data.Bytes `json:"latest_block_hash"`
LatestAppHash data.Bytes `json:"latest_app_hash"`
LatestBlockHeight int `json:"latest_block_height"`
LatestBlockTime int64 `json:"latest_block_time"` // nano
}
func (s *ResultStatus) TxIndexEnabled() bool {
if s == nil || s.NodeInfo == nil {
return false
}
for _, s := range s.NodeInfo.Other {
info := strings.Split(s, "=")
if len(info) == 2 && info[0] == "tx_index" {
return info[1] == "on"
}
}
return false
}
type ResultNetInfo struct {
Listening bool `json:"listening"`
Listeners []string `json:"listeners"`
Peers []Peer `json:"peers"`
}
type ResultDialSeeds struct {
Log string `json:"log"`
}
type Peer struct {
p2p.NodeInfo `json:"node_info"`
IsOutbound bool `json:"is_outbound"`
ConnectionStatus p2p.ConnectionStatus `json:"connection_status"`
}
type ResultValidators struct {
BlockHeight int `json:"block_height"`
Validators []*types.Validator `json:"validators"`
}
type ResultDumpConsensusState struct {
RoundState string `json:"round_state"`
PeerRoundStates []string `json:"peer_round_states"`
}
type ResultBroadcastTx struct {
Code abci.CodeType `json:"code"`
Data data.Bytes `json:"data"`
Log string `json:"log"`
Hash []byte `json:"hash"`
}
type ResultBroadcastTxCommit struct {
CheckTx *abci.ResponseCheckTx `json:"check_tx"`
DeliverTx *abci.ResponseDeliverTx `json:"deliver_tx"`
Hash []byte `json:"hash"`
Height int `json:"height"`
}
type ResultTx struct {
Height int `json:"height"`
Index int `json:"index"`
TxResult abci.ResponseDeliverTx `json:"tx_result"`
Tx types.Tx `json:"tx"`
Proof types.TxProof `json:"proof,omitempty"`
}
type ResultUnconfirmedTxs struct {
N int `json:"n_txs"`
Txs []types.Tx `json:"txs"`
}
type ResultABCIInfo struct {
Response abci.ResponseInfo `json:"response"`
}
type ResultABCIQuery struct {
Response abci.ResponseQuery `json:"response"`
}
type ResultUnsafeFlushMempool struct{}
type ResultUnsafeSetConfig struct{}
type ResultUnsafeProfile struct{}
type ResultSubscribe struct {
}
type ResultUnsubscribe struct {
}
type ResultEvent struct {
Name string `json:"name"`
Data types.TMEventData `json:"data"`
}
//----------------------------------------
// response & result types
const (
// 0x0 bytes are for the blockchain
ResultTypeGenesis = byte(0x01)
ResultTypeBlockchainInfo = byte(0x02)
ResultTypeBlock = byte(0x03)
ResultTypeCommit = byte(0x04)
// 0x2 bytes are for the network
ResultTypeStatus = byte(0x20)
ResultTypeNetInfo = byte(0x21)
ResultTypeDialSeeds = byte(0x22)
// 0x4 bytes are for the consensus
ResultTypeValidators = byte(0x40)
ResultTypeDumpConsensusState = byte(0x41)
// 0x6 bytes are for txs / the application
ResultTypeBroadcastTx = byte(0x60)
ResultTypeUnconfirmedTxs = byte(0x61)
ResultTypeBroadcastTxCommit = byte(0x62)
ResultTypeTx = byte(0x63)
// 0x7 bytes are for querying the application
ResultTypeABCIQuery = byte(0x70)
ResultTypeABCIInfo = byte(0x71)
// 0x8 bytes are for events
ResultTypeSubscribe = byte(0x80)
ResultTypeUnsubscribe = byte(0x81)
ResultTypeEvent = byte(0x82)
// 0xa bytes for testing
ResultTypeUnsafeSetConfig = byte(0xa0)
ResultTypeUnsafeStartCPUProfiler = byte(0xa1)
ResultTypeUnsafeStopCPUProfiler = byte(0xa2)
ResultTypeUnsafeWriteHeapProfile = byte(0xa3)
ResultTypeUnsafeFlushMempool = byte(0xa4)
)
type TMResult interface {
rpctypes.Result
}
// for wire.readReflect
var _ = wire.RegisterInterface(
struct{ TMResult }{},
wire.ConcreteType{&ResultGenesis{}, ResultTypeGenesis},
wire.ConcreteType{&ResultBlockchainInfo{}, ResultTypeBlockchainInfo},
wire.ConcreteType{&ResultBlock{}, ResultTypeBlock},
wire.ConcreteType{&ResultCommit{}, ResultTypeCommit},
wire.ConcreteType{&ResultStatus{}, ResultTypeStatus},
wire.ConcreteType{&ResultNetInfo{}, ResultTypeNetInfo},
wire.ConcreteType{&ResultDialSeeds{}, ResultTypeDialSeeds},
wire.ConcreteType{&ResultValidators{}, ResultTypeValidators},
wire.ConcreteType{&ResultDumpConsensusState{}, ResultTypeDumpConsensusState},
wire.ConcreteType{&ResultBroadcastTx{}, ResultTypeBroadcastTx},
wire.ConcreteType{&ResultBroadcastTxCommit{}, ResultTypeBroadcastTxCommit},
wire.ConcreteType{&ResultTx{}, ResultTypeTx},
wire.ConcreteType{&ResultUnconfirmedTxs{}, ResultTypeUnconfirmedTxs},
wire.ConcreteType{&ResultSubscribe{}, ResultTypeSubscribe},
wire.ConcreteType{&ResultUnsubscribe{}, ResultTypeUnsubscribe},
wire.ConcreteType{&ResultEvent{}, ResultTypeEvent},
wire.ConcreteType{&ResultUnsafeSetConfig{}, ResultTypeUnsafeSetConfig},
wire.ConcreteType{&ResultUnsafeProfile{}, ResultTypeUnsafeStartCPUProfiler},
wire.ConcreteType{&ResultUnsafeProfile{}, ResultTypeUnsafeStopCPUProfiler},
wire.ConcreteType{&ResultUnsafeProfile{}, ResultTypeUnsafeWriteHeapProfile},
wire.ConcreteType{&ResultUnsafeFlushMempool{}, ResultTypeUnsafeFlushMempool},
wire.ConcreteType{&ResultABCIQuery{}, ResultTypeABCIQuery},
wire.ConcreteType{&ResultABCIInfo{}, ResultTypeABCIInfo},
)

View File

@ -1,38 +0,0 @@
package core_types
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/tendermint/go-p2p"
)
func TestStatusIndexer(t *testing.T) {
assert := assert.New(t)
var status *ResultStatus
assert.False(status.TxIndexEnabled())
status = &ResultStatus{}
assert.False(status.TxIndexEnabled())
status.NodeInfo = &p2p.NodeInfo{}
assert.False(status.TxIndexEnabled())
cases := []struct {
expected bool
other []string
}{
{false, nil},
{false, []string{}},
{false, []string{"a=b"}},
{false, []string{"tx_indexiskv", "some=dood"}},
{true, []string{"tx_index=on", "tx_index=other"}},
{true, []string{"^(*^(", "tx_index=on", "a=n=b=d="}},
}
for _, tc := range cases {
status.NodeInfo.Other = tc.other
assert.Equal(tc.expected, status.TxIndexEnabled())
}
}

View File

@ -1,5 +0,0 @@
package core
// a single integer is sufficient here
const Version = "3" // rpc routes for profiling, setting config