mukan-consensus/rpc/test/helpers.go
Mukan Erkin Törük ef24c0b67e
Some checks are pending
docker-build-cometbft / vars (push) Waiting to run
docker-build-cometbft / build-images (amd64, ubuntu-24.04) (push) Blocked by required conditions
docker-build-cometbft / build-images (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
docker-build-cometbft / merge-images (push) Blocked by required conditions
docker-build-e2e-node / vars (push) Waiting to run
docker-build-e2e-node / build-images (amd64, ubuntu-24.04) (push) Blocked by required conditions
docker-build-e2e-node / build-images (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
docker-build-e2e-node / merge-images (push) Blocked by required conditions
initial: sovereign Mukan Network fork
2026-05-11 03:18:27 +03:00

204 lines
5 KiB
Go

package rpctest
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"time"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/internal/test"
"github.com/cometbft/cometbft/libs/log"
cfg "github.com/cometbft/cometbft/config"
cmtnet "github.com/cometbft/cometbft/libs/net"
nm "github.com/cometbft/cometbft/node"
"github.com/cometbft/cometbft/p2p"
"github.com/cometbft/cometbft/privval"
"github.com/cometbft/cometbft/proxy"
ctypes "github.com/cometbft/cometbft/rpc/core/types"
core_grpc "github.com/cometbft/cometbft/rpc/grpc"
rpcclient "github.com/cometbft/cometbft/rpc/jsonrpc/client"
)
// Options helps with specifying some parameters for our RPC testing for greater
// control.
type Options struct {
suppressStdout bool
recreateConfig bool
maxReqBatchSize int
}
var (
globalConfig *cfg.Config
defaultOptions = Options{
suppressStdout: false,
recreateConfig: false,
}
)
func waitForRPC() {
laddr := GetConfig().RPC.ListenAddress
client, err := rpcclient.New(laddr)
if err != nil {
panic(err)
}
result := new(ctypes.ResultStatus)
for {
_, err := client.Call(context.Background(), "status", map[string]interface{}{}, result)
if err == nil {
return
}
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.ReplaceAll(p, sep, "_")
}
func randPort() int {
port, err := cmtnet.GetFreePort()
if err != nil {
panic(err)
}
return port
}
func makeAddrs() (string, string, string) {
return fmt.Sprintf("tcp://127.0.0.1:%d", randPort()),
fmt.Sprintf("tcp://127.0.0.1:%d", randPort()),
fmt.Sprintf("tcp://127.0.0.1:%d", randPort())
}
func createConfig() *cfg.Config {
pathname := makePathname()
c := test.ResetTestRoot(pathname)
// and we use random ports to run in parallel
tm, rpc, grpc := makeAddrs()
c.P2P.ListenAddress = tm
c.RPC.ListenAddress = rpc
c.RPC.CORSAllowedOrigins = []string{"https://cometbft.com/"}
c.RPC.GRPCListenAddress = grpc
return c
}
// GetConfig returns a config for the test cases as a singleton
func GetConfig(forceCreate ...bool) *cfg.Config {
if globalConfig == nil || (len(forceCreate) > 0 && forceCreate[0]) {
globalConfig = createConfig()
}
return globalConfig
}
func GetGRPCClient() core_grpc.BroadcastAPIClient {
grpcAddr := globalConfig.RPC.GRPCListenAddress
//nolint:staticcheck // SA1019: core_grpc.StartGRPCClient is deprecated: A new gRPC API will be introduced after v0.38.
return core_grpc.StartGRPCClient(grpcAddr)
}
// StartTendermint starts a test CometBFT server in a go routine and returns when it is initialized
func StartTendermint(app abci.Application, opts ...func(*Options)) *nm.Node {
nodeOpts := defaultOptions
for _, opt := range opts {
opt(&nodeOpts)
}
node := NewTendermint(app, &nodeOpts)
err := node.Start()
if err != nil {
panic(err)
}
// wait for rpc
waitForRPC()
waitForGRPC()
if !nodeOpts.suppressStdout {
fmt.Println("CometBFT running!")
}
return node
}
// StopTendermint stops a test CometBFT server, waits until it's stopped and
// cleans up test/config files.
func StopTendermint(node *nm.Node) {
if err := node.Stop(); err != nil {
node.Logger.Error("Error when trying to stop node", "err", err)
}
node.Wait()
os.RemoveAll(node.Config().RootDir)
}
// NewTendermint creates a new CometBFT server and sleeps forever
func NewTendermint(app abci.Application, opts *Options) *nm.Node {
// Create & start node
config := GetConfig(opts.recreateConfig)
var logger log.Logger
if opts.suppressStdout {
logger = log.NewNopLogger()
} else {
logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout))
logger = log.NewFilter(logger, log.AllowError())
}
if opts.maxReqBatchSize > 0 {
config.RPC.MaxRequestBatchSize = opts.maxReqBatchSize
}
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),
cfg.DefaultDBProvider,
nm.DefaultMetricsProvider(config.Instrumentation),
logger)
if err != nil {
panic(err)
}
return node
}
// SuppressStdout is an option that tries to make sure the RPC test CometBFT
// node doesn't log anything to stdout.
func SuppressStdout(o *Options) {
o.suppressStdout = true
}
// RecreateConfig instructs the RPC test to recreate the configuration each
// time, instead of treating it as a global singleton.
func RecreateConfig(o *Options) {
o.recreateConfig = true
}
// MaxReqBatchSize is an option to limit the maximum number of requests per batch.
func MaxReqBatchSize(o *Options) {
o.maxReqBatchSize = 2
}