diff --git a/cmd/nodemanager/full_node_maker.go b/cmd/nodemanager/full_node_maker.go index 451a37fa2..607538d57 100644 --- a/cmd/nodemanager/full_node_maker.go +++ b/cmd/nodemanager/full_node_maker.go @@ -11,6 +11,7 @@ import ( "github.com/vitelabs/go-vite/v2/common" "github.com/vitelabs/go-vite/v2/log15" "github.com/vitelabs/go-vite/v2/node" + nodeconfig "github.com/vitelabs/go-vite/v2/node/config" ) var defaultNodeConfigFileName = "node_config.json" @@ -34,8 +35,8 @@ func (maker FullNodeMaker) MakeNode(ctx *cli.Context) (*node.Node, error) { return node, nil } -func (maker FullNodeMaker) MakeNodeConfig(ctx *cli.Context) (*node.Config, error) { - cfg := node.DefaultNodeConfig +func (maker FullNodeMaker) MakeNodeConfig(ctx *cli.Context) (*nodeconfig.Config, error) { + cfg := nodeconfig.DefaultNodeConfig log.Info(fmt.Sprintf("DefaultNodeconfig: %v", cfg)) // 1: Load config file. @@ -62,7 +63,7 @@ func (maker FullNodeMaker) MakeNodeConfig(ctx *cli.Context) (*node.Config, error } // SetNodeConfig applies node-related command line flags to the config. -func mappingNodeConfig(ctx *cli.Context, cfg *node.Config) { +func mappingNodeConfig(ctx *cli.Context, cfg *nodeconfig.Config) { //Global Config if dataDir := ctx.GlobalString(utils.DataDirFlag.Name); len(dataDir) > 0 { @@ -165,7 +166,7 @@ func mappingNodeConfig(ctx *cli.Context, cfg *node.Config) { } } -func overrideNodeConfigs(ctx *cli.Context, cfg *node.Config) { +func overrideNodeConfigs(ctx *cli.Context, cfg *nodeconfig.Config) { if len(cfg.DataDir) == 0 || cfg.DataDir == "" { cfg.DataDir = common.DefaultDataDir() @@ -216,7 +217,7 @@ func overrideNodeConfigs(ctx *cli.Context, cfg *node.Config) { } } -func loadNodeConfigFromFile(ctx *cli.Context, cfg *node.Config) error { +func loadNodeConfigFromFile(ctx *cli.Context, cfg *nodeconfig.Config) error { configFile := ctx.GlobalString(utils.ConfigFileFlag.Name) if configFile == "" { @@ -236,7 +237,7 @@ func IsExist(f string) bool { return err == nil || os.IsExist(err) } -func makeRunLogFile(cfg *node.Config) { +func makeRunLogFile(cfg *nodeconfig.Config) { defaultHandler := common.LogHandler(cfg.RunLogDir(), "", "vite.log", cfg.LogLevel) errorHandler := common.LogHandler(cfg.RunLogDir(), "error", "vite.error.log", log15.LvlError.String()) diff --git a/cmd/nodemanager/local_node_maker.go b/cmd/nodemanager/local_node_maker.go index c859d9cc3..8abc9f6b9 100644 --- a/cmd/nodemanager/local_node_maker.go +++ b/cmd/nodemanager/local_node_maker.go @@ -7,6 +7,7 @@ import ( "github.com/vitelabs/go-vite/v2/common" "github.com/vitelabs/go-vite/v2/node" + nodeconfig "github.com/vitelabs/go-vite/v2/node/config" ) type LocalNodeMaker struct { @@ -29,8 +30,8 @@ func (maker LocalNodeMaker) MakeNode(ctx *cli.Context) (*node.Node, error) { return node, nil } -func (maker LocalNodeMaker) MakeNodeConfig(ctx *cli.Context) (*node.Config, error) { - cfg := &node.DefaultNodeConfig +func (maker LocalNodeMaker) MakeNodeConfig(ctx *cli.Context) (*nodeconfig.Config, error) { + cfg := &nodeconfig.DefaultNodeConfig log.Info(fmt.Sprintf("DefaultNodeconfig: %v", cfg)) // 1: Load config file. @@ -59,7 +60,7 @@ func (maker LocalNodeMaker) MakeNodeConfig(ctx *cli.Context) (*node.Config, erro return cfg, nil } -func makeLocalNodeCfg(ctx *cli.Context, cfg *node.Config) { +func makeLocalNodeCfg(ctx *cli.Context, cfg *nodeconfig.Config) { // single mode cfg.Single = true // no miner diff --git a/cmd/nodemanager/node_maker.go b/cmd/nodemanager/node_maker.go index 091326845..b87555bef 100644 --- a/cmd/nodemanager/node_maker.go +++ b/cmd/nodemanager/node_maker.go @@ -4,6 +4,7 @@ import ( "gopkg.in/urfave/cli.v1" "github.com/vitelabs/go-vite/v2/node" + nodeconfig "github.com/vitelabs/go-vite/v2/node/config" ) type NodeMaker interface { @@ -12,5 +13,5 @@ type NodeMaker interface { MakeNode(ctx *cli.Context) (*node.Node, error) //create NodeConfig - MakeNodeConfig(ctx *cli.Context) (*node.Config, error) + MakeNodeConfig(ctx *cli.Context) (*nodeconfig.Config, error) } diff --git a/common/types/enum.go b/common/types/enum.go new file mode 100644 index 000000000..b4981ebb7 --- /dev/null +++ b/common/types/enum.go @@ -0,0 +1,7 @@ +package types + +type Enum interface { + name() string + ordinal() int + values() *[]string +} diff --git a/node/config.go b/node/config/config.go similarity index 92% rename from node/config.go rename to node/config/config.go index 5c8da872a..eb49a483a 100644 --- a/node/config.go +++ b/node/config/config.go @@ -1,4 +1,4 @@ -package node +package nodeconfig import ( "encoding/hex" @@ -117,25 +117,25 @@ type Config struct { InfluxDBHostTag *string `json:"InfluxDBHostTag"` } -func (c *Config) makeWalletConfig() *config.Wallet { +func (c *Config) MakeWalletConfig() *config.Wallet { return &config.Wallet{DataDir: c.KeyStoreDir} } -func (c *Config) makeViteConfig() *config.Config { +func (c *Config) MakeViteConfig() *config.Config { return &config.Config{ - Chain: c.makeChainConfig(), - Producer: c.makeMinerConfig(), + Chain: c.MakeChainConfig(), + Producer: c.MakeMinerConfig(), DataDir: c.DataDir, - Net: c.makeNetConfig(), - Vm: c.makeVmConfig(), - Subscribe: c.makeSubscribeConfig(), - NodeReward: c.makeRewardConfig(), + Net: c.MakeNetConfig(), + Vm: c.MakeVmConfig(), + Subscribe: c.MakeSubscribeConfig(), + NodeReward: c.MakeRewardConfig(), Genesis: config.MakeGenesisConfig(c.GenesisFile), LogLevel: c.LogLevel, } } -func (c *Config) makeNetConfig() *config.Net { +func (c *Config) MakeNetConfig() *config.Net { datadir := filepath.Join(c.DataDir, config.DefaultNetDirName) return &config.Net{ @@ -167,14 +167,14 @@ func (c *Config) makeNetConfig() *config.Net { } } -func (c *Config) makeRewardConfig() *config.NodeReward { +func (c *Config) MakeRewardConfig() *config.NodeReward { return &config.NodeReward{ RewardAddr: c.RewardAddr, Name: c.Identity, } } -func (c *Config) makeVmConfig() *config.Vm { +func (c *Config) MakeVmConfig() *config.Vm { return &config.Vm{ IsVmTest: c.VMTestEnabled, IsUseVmTestParam: c.VMTestParamEnabled, @@ -183,12 +183,12 @@ func (c *Config) makeVmConfig() *config.Vm { } } -func (c *Config) makeSubscribeConfig() *config.Subscribe { +func (c *Config) MakeSubscribeConfig() *config.Subscribe { return &config.Subscribe{ IsSubscribe: c.SubscribeEnabled, } } -func (c *Config) makeMinerConfig() *config.Producer { +func (c *Config) MakeMinerConfig() *config.Producer { cfg := &config.Producer{ Producer: c.MinerEnabled, Coinbase: c.CoinBase, @@ -202,7 +202,7 @@ func (c *Config) makeMinerConfig() *config.Producer { return cfg } -func (c *Config) makeChainConfig() *config.Chain { +func (c *Config) MakeChainConfig() *config.Chain { // is open ledger gc ledgerGc := true diff --git a/node/config_test.go b/node/config/config_test.go similarity index 93% rename from node/config_test.go rename to node/config/config_test.go index a901be529..29a1f77c0 100644 --- a/node/config_test.go +++ b/node/config/config_test.go @@ -1,4 +1,4 @@ -package node +package nodeconfig import ( "encoding/json" @@ -24,7 +24,7 @@ func TestChainConfig(t *testing.T) { t.Fatal(err) } - configchain := config.makeChainConfig() + configchain := config.MakeChainConfig() if len(configchain.VmLogWhiteList) != 1 { t.Fatal("length must be 1") } @@ -40,7 +40,7 @@ func TestChainConfig(t *testing.T) { t.Fatal(err) } - configchainB := configB.makeChainConfig() + configchainB := configB.MakeChainConfig() if configchainB.VmLogAll != true { t.Fatal("VmLogAll must be true ") diff --git a/node/defaults.go b/node/config/defaults.go similarity index 98% rename from node/defaults.go rename to node/config/defaults.go index 58fc03686..e02567f08 100644 --- a/node/defaults.go +++ b/node/config/defaults.go @@ -1,4 +1,4 @@ -package node +package nodeconfig import ( "os" diff --git a/node/node.go b/node/node.go index 2d76c88ea..615a9a01b 100644 --- a/node/node.go +++ b/node/node.go @@ -17,6 +17,7 @@ import ( "github.com/vitelabs/go-vite/v2/common/config" "github.com/vitelabs/go-vite/v2/log15" "github.com/vitelabs/go-vite/v2/monitor" + nodeconfig "github.com/vitelabs/go-vite/v2/node/config" "github.com/vitelabs/go-vite/v2/pow" "github.com/vitelabs/go-vite/v2/pow/remote" "github.com/vitelabs/go-vite/v2/rpc" @@ -31,7 +32,7 @@ var ( // Node is chain container that manages p2p、rpc、vite modules type Node struct { - config *Config + config *nodeconfig.Config //wallet walletConfig *config.Wallet @@ -66,11 +67,11 @@ type Node struct { instanceDirLock flock.Releaser // prevents concurrent use of instance directory } -func New(conf *Config) (*Node, error) { +func New(conf *nodeconfig.Config) (*Node, error) { return &Node{ config: conf, - walletConfig: conf.makeWalletConfig(), - viteConfig: conf.makeViteConfig(), + walletConfig: conf.MakeWalletConfig(), + viteConfig: conf.MakeViteConfig(), ipcEndpoint: conf.IPCEndpoint(), httpEndpoint: conf.HTTPEndpoint(), wsEndpoint: conf.WSEndpoint(), @@ -224,7 +225,7 @@ func (node *Node) Vite() *vite.Vite { return node.viteServer } -func (node *Node) Config() *Config { +func (node *Node) Config() *nodeconfig.Config { return node.config } diff --git a/rpc/server.go b/rpc/server.go index 5521bd80e..41ecd3b92 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -19,13 +19,14 @@ package rpc import ( "context" "fmt" - "github.com/vitelabs/go-vite/v2/rpcapi/api" "reflect" "runtime" "strings" "sync" "sync/atomic" + "github.com/vitelabs/go-vite/v2/rpcapi/api" + mapset "github.com/deckarep/golang-set" log "github.com/vitelabs/go-vite/v2/log15" ) @@ -74,6 +75,28 @@ func (s *RPCService) Modules() map[string]string { return modules } +// Methods returns the list of RPC services with their method names +func (s *Server) Methods() map[string][]string { + modules := make(map[string][]string) + for svcName, svc := range s.services { + for name := range svc.callbacks { + modules[svcName] = append(modules[svcName], name) + } + } + return modules +} + +// Subscriptions returns the list of RPC services with their subscription names +func (s *Server) Subscriptions() map[string][]string { + modules := make(map[string][]string) + for svcName, svc := range s.services { + for name := range svc.subscriptions { + modules[svcName] = append(modules[svcName], name) + } + } + return modules +} + // RegisterName will create chain service for the given rcvr type under the given name. When no methods on the given rcvr // match the criteria to be either chain RPC method or chain subscription an error is returned. Otherwise chain new service is // created and added to the service collection this server instance serves. diff --git a/rpcapi/apis.go b/rpcapi/apis.go index 41eeecaf3..f3dec1f8a 100644 --- a/rpcapi/apis.go +++ b/rpcapi/apis.go @@ -7,6 +7,79 @@ import ( "github.com/vitelabs/go-vite/v2/rpcapi/api/filters" ) +type ApiType uint + +const ( + HEALTH = iota + WALLET + PRIVATE_ONROAD + POW + DEBUG + CONSENSUSGROUP + LEDGER + PUBLIC_ONROAD + NET + CONTRACT + REGISTER + VOTE + MINTAGE + PLEDGE + DEXFUND + DEXTRADE + DEX + PRIVATE_DEX + TX + DASHBOARD + SUBSCRIBE + SBPSTATS + UTIL + DATA + LEDGERDEBUG + MINER + apiTypeLimit // this will be the last ApiType + 1 +) + +var apiTypeStrings = []string{ + "health", + "wallet", + "private_onroad", + "pow", + "debug", + "consensusGroup", + "ledger", + "public_onroad", + "net", + "contract", + "register", + "vote", + "mintage", + "pledge", + "dexfund", + "dextrade", + "dex", + "private_dex", + "tx", + "dashboard", + "subscribe", + "sbpstats", + "util", + "data", + "ledgerdebug", + "miner", +} + +func (at ApiType) name() string { + return apiTypeStrings[at] +} + +func (at ApiType) ordinal() int { + return int(at) +} + +func (at ApiType) values() *[]string { + return &apiTypeStrings +} + func Init(dir, lvl string, testApi_prikey, testApi_tti string, netId uint, dexAvailable *bool) { api.InitLog(dir, lvl) api.InitTestAPIParams(testApi_prikey, testApi_tti) @@ -16,184 +89,183 @@ func Init(dir, lvl string, testApi_prikey, testApi_tti string, netId uint, dexAv func GetApi(vite *vite.Vite, apiModule string) rpc.API { switch apiModule { // private IPC - case "health": + case ApiType(HEALTH).name(): return rpc.API{ Namespace: "health", Version: "1.0", Service: api.NewHealthApi(vite), Public: true, } - case "wallet": + case ApiType(WALLET).name(): return rpc.API{ Namespace: "wallet", Version: "1.0", Service: api.NewWalletApi(vite), Public: false, } - case "private_onroad": + case ApiType(PRIVATE_ONROAD).name(): return rpc.API{ Namespace: "onroad", Version: "1.0", Service: api.NewPrivateOnroadApi(vite), Public: false, } - // public WS HTTP IPC - - case "pow": + // public WS HTTP IPC + case ApiType(POW).name(): return rpc.API{ Namespace: "pow", Version: "1.0", Service: api.NewPow(vite), Public: true, } - case "debug": + case ApiType(DEBUG).name(): return rpc.API{ Namespace: "debug", Version: "1.0", Service: api.NewDeprecated(), Public: true, } - case "consensusGroup": + case ApiType(CONSENSUSGROUP).name(): return rpc.API{ Namespace: "debug", Version: "1.0", Service: api.NewDeprecated(), Public: true, } - case "ledger": + case ApiType(LEDGER).name(): return rpc.API{ Namespace: "ledger", Version: "1.0", Service: api.NewLedgerApi(vite), Public: true, } - case "public_onroad": + case ApiType(PUBLIC_ONROAD).name(): return rpc.API{ Namespace: "onroad", Version: "1.0", Service: api.NewPublicOnroadApi(vite), Public: true, } - case "net": + case ApiType(NET).name(): return rpc.API{ Namespace: "net", Version: "1.0", Service: api.NewNetApi(vite), Public: true, } - case "contract": + case ApiType(CONTRACT).name(): return rpc.API{ Namespace: "contract", Version: "1.0", Service: api.NewContractApi(vite), Public: true, } - case "register": + case ApiType(REGISTER).name(): return rpc.API{ Namespace: "register", Version: "1.0", Service: api.NewRegisterApi(vite), Public: true, } - case "vote": + case ApiType(VOTE).name(): return rpc.API{ Namespace: "vote", Version: "1.0", Service: api.NewVoteApi(vite), Public: true, } - case "mintage": + case ApiType(MINTAGE).name(): return rpc.API{ Namespace: "mintage", Version: "1.0", Service: api.NewMintageAPI(vite), Public: true, } - case "pledge": + case ApiType(PLEDGE).name(): return rpc.API{ Namespace: "pledge", Version: "1.0", Service: api.NewQuotaApi(vite), Public: true, } - case "dexfund": + case ApiType(DEXFUND).name(): return rpc.API{ Namespace: "dexfund", Version: "1.0", Service: api.NewDexFundApi(vite), Public: true, } - case "dextrade": + case ApiType(DEXTRADE).name(): return rpc.API{ Namespace: "dextrade", Version: "1.0", Service: api.NewDexTradeApi(vite), Public: true, } - case "dex": + case ApiType(DEX).name(): return rpc.API{ Namespace: "dex", Version: "1.0", Service: api.NewDexApi(vite), Public: true, } - case "private_dex": + case ApiType(PRIVATE_DEX).name(): return rpc.API{ Namespace: "dex", Version: "1.0", Service: api.NewDexPrivateApi(vite), Public: false, } - case "tx": + case ApiType(TX).name(): return rpc.API{ Namespace: "tx", Version: "1.0", Service: api.NewTxApi(vite), Public: true, } - case "dashboard": + case ApiType(DASHBOARD).name(): return rpc.API{ Namespace: "dashboard", Version: "1.0", Service: api.NewDashboardApi(vite), Public: true, } - case "subscribe": + case ApiType(SUBSCRIBE).name(): return rpc.API{ Namespace: "subscribe", Version: "1.0", Service: filters.NewSubscribeApi(vite), Public: true, } - case "sbpstats": + case ApiType(SBPSTATS).name(): return rpc.API{ Namespace: "sbpstats", Version: "1.0", Service: api.NewStatsApi(vite), Public: true, } - case "util": + case ApiType(UTIL).name(): return rpc.API{ Namespace: "util", Version: "1.0", Service: api.NewUtilApi(vite), Public: true, } - case "data": + case ApiType(DATA).name(): return rpc.API{ Namespace: "data", Version: "1.0", Service: api.NewDataApi(vite), Public: true, } - case "ledgerdebug": + case ApiType(LEDGERDEBUG).name(): return rpc.API{ Namespace: "ledgerdebug", Version: "1.0", Service: api.NewLedgerDebugApi(vite), Public: false, } - case "miner": + case ApiType(MINER).name(): return rpc.API{ Namespace: "miner", Version: "1.0", @@ -235,5 +307,5 @@ func MergeApis(first map[string]rpc.API, second map[string]rpc.API) []rpc.API { } func GetPublicApis(vite *vite.Vite) map[string]rpc.API { - return GetApis(vite, "ledger", "net", "contract", "util", "health") + return GetApis(vite, ApiType(LEDGER).name(), ApiType(NET).name(), ApiType(CONTRACT).name(), ApiType(UTIL).name(), ApiType(HEALTH).name()) } diff --git a/rpcapi/apis_test.go b/rpcapi/apis_test.go new file mode 100644 index 000000000..c5b56de3b --- /dev/null +++ b/rpcapi/apis_test.go @@ -0,0 +1,77 @@ +package rpcapi + +import ( + "fmt" + "testing" + + "github.com/vitelabs/go-vite/v2" + "github.com/vitelabs/go-vite/v2/rpc" + "github.com/vitelabs/go-vite/v2/rpcapi/api/filters" +) + +type Service struct{} + +func TestApiTypeValues(t *testing.T) { + expected := apiTypeLimit + actual := len(apiTypeStrings) + if actual != expected { + t.Fatalf("length of apiTypeStrings %v does not match with apiTypeLimit %v", actual, expected) + } +} + +func TestApiTypeName(t *testing.T) { + expected1 := "health" + actual1 := ApiType(HEALTH).name() + if actual1 != expected1 { + t.Fatalf("expected ApiType name: %s / actual: %s", expected1, actual1) + } + + expected2 := "miner" + actual2 := ApiType(MINER).name() + if actual2 != expected2 { + t.Fatalf("expected ApiType name: %s / actual: %s", expected2, actual2) + } +} + +func TestPrintAllApiTypes(t *testing.T) { + for at := ApiType(0); at < apiTypeLimit; at++ { + fmt.Println(at.name()) + } +} + +func createServer(t *testing.T) *rpc.Server { + viteServer, err := vite.NewMock(nil, nil) + if err != nil { + t.Fatalf("create viteServer failed, %v", err) + } + filters.Es = filters.NewEventSystem(viteServer) + + server := rpc.NewServer() + + for at := ApiType(0); at < apiTypeLimit; at++ { + api := GetApi(viteServer, at.name()) + server.RegisterName(api.Namespace, api.Service) + } + + return server +} + +func TestPrintAllExposedApiMethods(t *testing.T) { + server := createServer(t) + + for svcName, methods := range server.Methods() { + for m := range methods { + fmt.Printf("%s_%s\n", svcName, methods[m]) + } + } +} + +func TestPrintAllExposedApiSubscriptions(t *testing.T) { + server := createServer(t) + + for svcName, subs := range server.Subscriptions() { + for s := range subs { + fmt.Printf("%s_%s\n", svcName, subs[s]) + } + } +} diff --git a/vite_mock.go b/vite_mock.go new file mode 100644 index 000000000..39f1e8c42 --- /dev/null +++ b/vite_mock.go @@ -0,0 +1,34 @@ +package vite + +import ( + "github.com/vitelabs/go-vite/v2/common/config" + nodeconfig "github.com/vitelabs/go-vite/v2/node/config" + "github.com/vitelabs/go-vite/v2/wallet" +) + +func NewMock(cfg *config.Config, walletManager *wallet.Manager) (vite *Vite, err error) { + var nodeConfig *nodeconfig.Config + if cfg == nil || walletManager == nil { + nodeConfig = &nodeconfig.Config{} + //nodeConfig.ParseFromFile("~/go/src/github.com/vitelabs/go-vite/conf/evm/node_config.json") + } + if cfg == nil { + cfg = nodeConfig.MakeViteConfig() + } + if walletManager == nil { + walletManager = wallet.New(nodeConfig.MakeWalletConfig()) + } + + // TODO: use mocks for net, chain, pool, etc. + + vite = &Vite{ + config: cfg, + walletManager: walletManager, + net: nil, + chain: nil, + pool: nil, + consensus: nil, + verifier: nil, + } + return +}