You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

150 lines
3.7 KiB

package rpctest
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/tendermint/tendermint/libs/log"
abci "github.com/tendermint/tendermint/abci/types"
cfg "github.com/tendermint/tendermint/config"
cmn "github.com/tendermint/tendermint/libs/common"
nm "github.com/tendermint/tendermint/node"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
core_grpc "github.com/tendermint/tendermint/rpc/grpc"
rpcclient "github.com/tendermint/tendermint/rpc/lib/client"
)
var globalConfig *cfg.Config
func waitForRPC() {
laddr := GetConfig().RPC.ListenAddress
client := rpcclient.NewJSONRPCClient(laddr)
ctypes.RegisterAmino(client.Codec())
result := new(ctypes.ResultStatus)
for {
_, err := client.Call("status", map[string]interface{}{}, result)
if err == nil {
return
} else {
fmt.Println("error", err)
time.Sleep(time.Millisecond)
}
}
}
func waitForGRPC() {
client := GetGRPCClient()
for {
_, err := client.Ping(context.Background(), &core_grpc.RequestPing{})
if err == nil {
return
}
}
}
// f**ing long, but unique for each test
func makePathname() string {
// get path
p, err := os.Getwd()
if err != nil {
panic(err)
}
// fmt.Println(p)
sep := string(filepath.Separator)
return strings.Replace(p, sep, "_", -1)
}
func randPort() int {
port, err := cmn.GetFreePort()
if err != nil {
panic(err)
}
return port
}
func makeAddrs() (string, string, string) {
return fmt.Sprintf("tcp://0.0.0.0:%d", randPort()),
fmt.Sprintf("tcp://0.0.0.0:%d", randPort()),
fmt.Sprintf("tcp://0.0.0.0:%d", randPort())
}
// GetConfig returns a config for the test cases as a singleton
func GetConfig() *cfg.Config {
if globalConfig == nil {
pathname := makePathname()
globalConfig = cfg.ResetTestRoot(pathname)
// and we use random ports to run in parallel
tm, rpc, grpc := makeAddrs()
globalConfig.P2P.ListenAddress = tm
globalConfig.RPC.ListenAddress = rpc
globalConfig.RPC.CORSAllowedOrigins = []string{"https://tendermint.com/"}
globalConfig.RPC.GRPCListenAddress = grpc
globalConfig.TxIndex.IndexTags = "app.creator,tx.height" // see kvstore application
}
return globalConfig
}
func GetGRPCClient() core_grpc.BroadcastAPIClient {
grpcAddr := globalConfig.RPC.GRPCListenAddress
return core_grpc.StartGRPCClient(grpcAddr)
}
// StartTendermint starts a test tendermint server in a go routine and returns when it is initialized
func StartTendermint(app abci.Application) *nm.Node {
node := NewTendermint(app)
err := node.Start()
if err != nil {
panic(err)
}
// wait for rpc
waitForRPC()
waitForGRPC()
fmt.Println("Tendermint running!")
return node
}
// StopTendermint stops a test tendermint server, waits until it's stopped and
// cleans up test/config files.
func StopTendermint(node *nm.Node) {
node.Stop()
node.Wait()
os.RemoveAll(node.Config().RootDir)
}
// NewTendermint creates a new tendermint server and sleeps forever
func NewTendermint(app abci.Application) *nm.Node {
// Create & start node
config := GetConfig()
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
logger = log.NewFilter(logger, log.AllowError())
pvKeyFile := config.PrivValidatorKeyFile()
pvKeyStateFile := config.PrivValidatorStateFile()
pv := privval.LoadOrGenFilePV(pvKeyFile, pvKeyStateFile)
papp := proxy.NewLocalClientCreator(app)
nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
if err != nil {
panic(err)
}
node, err := nm.NewNode(config, pv, nodeKey, papp,
nm.DefaultGenesisDocProviderFunc(config),
nm.DefaultDBProvider,
nm.DefaultMetricsProvider(config.Instrumentation),
logger)
if err != nil {
panic(err)
}
return node
}