From 14cf0c274d84a26ed359e52bf7e10597b355432a Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Wed, 20 Jul 2022 14:51:21 -0500 Subject: [PATCH 01/36] first iteration for draft PR with issues --- local/config.go | 11 ++++++++++ local/network.go | 44 ++++++++++++++++++++++++++++++++++++-- local/network_test.go | 5 ++++- server/network.go | 19 ++--------------- server/network_test.go | 7 +++--- server/server.go | 48 ++++++++---------------------------------- 6 files changed, 71 insertions(+), 63 deletions(-) create mode 100644 local/config.go diff --git a/local/config.go b/local/config.go new file mode 100644 index 00000000..12ce5531 --- /dev/null +++ b/local/config.go @@ -0,0 +1,11 @@ +package local + +var DefaultFlags = map[string]interface{}{ + "network-peer-list-gossip-frequency": "250ms", + "network-max-reconnect-delay": "1s", + "public-ip": "127.0.0.1", + "health-check-frequency": "2s", + "api-admin-enabled": true, + "api-ipcs-enabled": true, + "index-enabled": true, +} diff --git a/local/network.go b/local/network.go index 31a7cfc4..78e2ad4b 100644 --- a/local/network.go +++ b/local/network.go @@ -95,6 +95,8 @@ type localNetwork struct { flags map[string]interface{} // directory where networks can be persistently saved snapshotsDir string + + defaultNodeConfig *node.Config } var ( @@ -118,6 +120,7 @@ func init() { defaultNetworkConfig = network.Config{ NodeConfigs: make([]node.Config, DefaultNumNodes), + Flags: DefaultFlags, } genesis, err := fs.ReadFile(configsDir, "genesis.json") @@ -426,6 +429,7 @@ func (ln *localNetwork) loadConfig(ctx context.Context, networkConfig network.Co return fmt.Errorf("couldn't get network ID from genesis: %w", err) } + // TODO put defaults? ln.flags = networkConfig.Flags // Sort node configs so beacons start first @@ -441,7 +445,23 @@ func (ln *localNetwork) loadConfig(ctx context.Context, networkConfig network.Co } } - for _, nodeConfig := range nodeConfigs { + for i, nodeConfig := range nodeConfigs { + // init the default config if they haven't been initialized yet + // this should therefore be running for the first node only + if i == 0 { + if ln.defaultNodeConfig == nil { + ln.defaultNodeConfig = &node.Config{ + Flags: DefaultFlags, + ChainConfigFiles: map[string]string{}, + } + ln.defaultNodeConfig.Flags[config.WhitelistedSubnetsKey] = nodeConfig.Flags[config.WhitelistedSubnetsKey] + + for k, v := range nodeConfig.ChainConfigFiles { + ln.defaultNodeConfig.ChainConfigFiles[k] = v + } + } + } + if _, err := ln.addNode(nodeConfig); err != nil { if err := ln.stop(ctx); err != nil { // Clean up nodes already created @@ -463,6 +483,12 @@ func (ln *localNetwork) AddNode(nodeConfig node.Config) (node.Node, error) { return nil, network.ErrStopped } + // set defaults only if this is not the first node + if ln.defaultNodeConfig != nil { + nodeConfig.Flags = ln.defaultNodeConfig.Flags + nodeConfig.ChainConfigFiles = ln.defaultNodeConfig.ChainConfigFiles + } + return ln.addNode(nodeConfig) } @@ -472,6 +498,17 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { nodeConfig.Flags = make(map[string]interface{}) } + // it shouldn't happen that just one is empty, most probably both, + // but in any case if just one is empty it's unusable so we just assign a new one. + if nodeConfig.StakingCert == "" || nodeConfig.StakingKey == "" { + stakingCert, stakingKey, err := staking.NewCertAndKeyBytes() + if err != nil { + return nil, fmt.Errorf("couldn't generate staking Cert/Key: %w", err) + } + nodeConfig.StakingCert = string(stakingCert) + nodeConfig.StakingKey = string(stakingKey) + } + if err := ln.setNodeName(&nodeConfig); err != nil { return nil, err } @@ -828,7 +865,10 @@ func (ln *localNetwork) loadSnapshot( if err != nil { return fmt.Errorf("failure reading network config file from snapshot: %w", err) } - networkConfig := network.Config{} + // set default flags for all nodes + networkConfig := network.Config{ + Flags: DefaultFlags, + } err = json.Unmarshal(networkConfigJSON, &networkConfig) if err != nil { return fmt.Errorf("failure unmarshaling network config from snapshot: %w", err) diff --git a/local/network_test.go b/local/network_test.go index 1037fa39..f5b1245c 100644 --- a/local/network_test.go +++ b/local/network_test.go @@ -160,6 +160,8 @@ func newLocalTestOneNodeCreator(assert *assert.Assertions, networkConfig network func (lt *localTestOneNodeCreator) NewNodeProcess(config node.Config, log logging.Logger, flags ...string) (NodeProcess, error) { lt.assert.True(config.IsBeacon) expectedConfig := lt.networkConfig.NodeConfigs[0] + // TODO without this the test FAILS, is this the correct way to fix it? + expectedConfig.Flags = DefaultFlags lt.assert.EqualValues(expectedConfig.ChainConfigFiles, config.ChainConfigFiles) lt.assert.EqualValues(expectedConfig.ConfigFile, config.ConfigFile) lt.assert.EqualValues(expectedConfig.BinaryPath, config.BinaryPath) @@ -678,7 +680,8 @@ func TestStoppedNetwork(t *testing.T) { } func TestGetAllNodes(t *testing.T) { - t.Parallel() + // TODO: with this enabled we get "FATAL: concurrent map writes" + // t.Parallel() assert := assert.New(t) networkConfig := testNetworkConfig(t) net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "") diff --git a/server/network.go b/server/network.go index 2651bce1..768f2dfe 100644 --- a/server/network.go +++ b/server/network.go @@ -24,18 +24,6 @@ import ( "go.uber.org/zap" ) -const ( - defaultNodeConfig = `{ - "network-peer-list-gossip-frequency":"250ms", - "network-max-reconnect-delay":"1s", - "public-ip":"127.0.0.1", - "health-check-frequency":"2s", - "api-admin-enabled":true, - "api-ipcs-enabled":true, - "index-enabled":true - }` -) - var ignoreFields = map[string]struct{}{ "public-ip": {}, "http-port": {}, @@ -147,10 +135,7 @@ func (lc *localNetwork) createConfig() error { return err } - var defaultConfig, globalConfig map[string]interface{} - if err := json.Unmarshal([]byte(defaultNodeConfig), &defaultConfig); err != nil { - return err - } + var globalConfig map[string]interface{} if lc.options.globalNodeConfig != "" { if err := json.Unmarshal([]byte(lc.options.globalNodeConfig), &globalConfig); err != nil { @@ -171,7 +156,7 @@ func (lc *localNetwork) createConfig() error { cfg.NodeConfigs[i].ChainConfigFiles[k] = v } - mergedConfig, err := mergeNodeConfig(defaultConfig, globalConfig, lc.options.customNodeConfigs[nodeName]) + mergedConfig, err := mergeNodeConfig(local.DefaultFlags, globalConfig, lc.options.customNodeConfigs[nodeName]) if err != nil { return fmt.Errorf("failed merging provided configs: %w", err) } diff --git a/server/network_test.go b/server/network_test.go index ebda1fce..87b684f7 100644 --- a/server/network_test.go +++ b/server/network_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "testing" + "github.com/ava-labs/avalanche-network-runner/local" "github.com/stretchr/testify/assert" ) @@ -18,8 +19,7 @@ func TestEvalConfig(t *testing.T) { var defaultConfig, globalConfig map[string]interface{} - err := json.Unmarshal([]byte(defaultNodeConfig), &defaultConfig) - assert.NoError(err) + defaultConfig = local.DefaultFlags config, err := mergeNodeConfig(defaultConfig, globalConfig, "") assert.NoError(err) @@ -31,8 +31,7 @@ func TestEvalConfig(t *testing.T) { assert.NoError(err) var test1Map map[string]interface{} - err = json.Unmarshal([]byte(defaultNodeConfig), &test1Map) - assert.NoError(err) + test1Map = local.DefaultFlags // ...all default config entries should still be there... for k, v := range test1Map { assert.Equal(controlMap[k], v) diff --git a/server/server.go b/server/server.go index 2b8d39f9..69ce8ac0 100644 --- a/server/server.go +++ b/server/server.go @@ -20,13 +20,14 @@ import ( "sync" "time" + "github.com/ava-labs/avalanche-network-runner/local" "github.com/ava-labs/avalanche-network-runner/network/node" "github.com/ava-labs/avalanche-network-runner/rpcpb" "github.com/ava-labs/avalanche-network-runner/utils" + "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/network/peer" "github.com/ava-labs/avalanchego/snow/networking/router" - "github.com/ava-labs/avalanchego/staking" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "go.uber.org/zap" "google.golang.org/grpc" @@ -319,7 +320,7 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta zap.String("rootDataDir", rootDataDir), zap.String("pluginDir", pluginDir), zap.Any("chainConfigs", req.ChainConfigs), - zap.String("defaultNodeConfig", globalNodeConfig), + zap.String("globalNodeConfig", globalNodeConfig), ) if s.network != nil { @@ -706,8 +707,6 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb s.mu.Lock() defer s.mu.Unlock() - var whitelistedSubnets string - if _, exists := s.network.nodeInfos[req.Name]; exists { return nil, fmt.Errorf("node with name %s already exists", req.Name) } @@ -729,55 +728,29 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb return nil, fmt.Errorf("failed to stat exec %q (%w)", execPath, err) } - // use same configs from other nodes - whitelistedSubnets = s.network.options.whitelistedSubnets + // as execPath can be provided by this function, we might need a new `build-dir` buildDir, err := getBuildDir(execPath, s.network.pluginDir) if err != nil { return nil, err } - rootDataDir := s.clusterInfo.RootDataDir - - logDir := filepath.Join(rootDataDir, req.Name, "log") - dbDir := filepath.Join(rootDataDir, req.Name, "db-dir") - - var defaultConfig, globalConfig map[string]interface{} - if err := json.Unmarshal([]byte(defaultNodeConfig), &defaultConfig); err != nil { - return nil, err - } + var globalConfig map[string]interface{} if req.StartRequest.GetGlobalNodeConfig() != "" { if err := json.Unmarshal([]byte(req.StartRequest.GetGlobalNodeConfig()), &globalConfig); err != nil { return nil, err } } - var mergedConfig map[string]interface{} - // we only need to merge from the default node config here, as we are only adding one node - mergedConfig, err = mergeNodeConfig(defaultConfig, globalConfig, "") - if err != nil { - return nil, fmt.Errorf("failed merging provided configs: %w", err) - } - configFile, err := createConfigFileString(mergedConfig, logDir, dbDir, buildDir, whitelistedSubnets) - if err != nil { - return nil, fmt.Errorf("failed to generate json node config string: %w", err) - } - stakingCert, stakingKey, err := staking.NewCertAndKeyBytes() - if err != nil { - return nil, fmt.Errorf("couldn't generate staking Cert/Key: %w", err) - } + globalConfig[config.BuildDirKey] = buildDir + nodeConfig := node.Config{ Name: req.Name, - ConfigFile: configFile, - StakingKey: string(stakingKey), - StakingCert: string(stakingCert), + Flags: globalConfig, BinaryPath: execPath, RedirectStdout: s.cfg.RedirectNodesOutput, RedirectStderr: s.cfg.RedirectNodesOutput, } nodeConfig.ChainConfigFiles = map[string]string{} - for k, v := range s.network.chainConfigs { - nodeConfig.ChainConfigFiles[k] = v - } for k, v := range req.StartRequest.ChainConfigs { nodeConfig.ChainConfigFiles[k] = v } @@ -849,10 +822,7 @@ func (s *server) RestartNode(ctx context.Context, req *rpcpb.RestartNodeRequest) nodeInfo.DbDir = filepath.Join(req.GetRootDataDir(), req.Name, "db-dir") } - var defaultConfig map[string]interface{} - if err := json.Unmarshal([]byte(defaultNodeConfig), &defaultConfig); err != nil { - return nil, err - } + defaultConfig := local.DefaultFlags buildDir, err := getBuildDir(nodeInfo.ExecPath, nodeInfo.PluginDir) if err != nil { From 6318093c0056ba1fb92640ec2bf34393097932a6 Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Wed, 20 Jul 2022 14:57:49 -0500 Subject: [PATCH 02/36] race in tests --- local/network_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/local/network_test.go b/local/network_test.go index f5b1245c..d49418a6 100644 --- a/local/network_test.go +++ b/local/network_test.go @@ -478,7 +478,8 @@ func TestUnhealthyNetwork(t *testing.T) { // Create a network without giving names to nodes. // Checks that the generated names are the correct number and unique. func TestGeneratedNodesNames(t *testing.T) { - t.Parallel() + // TODO to make these pass + // t.Parallel() assert := assert.New(t) networkConfig := testNetworkConfig(t) for i := range networkConfig.NodeConfigs { From 65c8da2a26346daaf468ec16f2b68866b1303ea0 Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Thu, 21 Jul 2022 16:36:50 -0500 Subject: [PATCH 03/36] fixed flags sequence --- local/config.go | 18 +++++++------- local/network.go | 54 ++++++++++++++++++++++-------------------- local/network_test.go | 31 ++++++++++++++---------- server/network.go | 2 +- server/network_test.go | 4 ++-- server/server.go | 4 +++- tests/e2e/e2e_test.go | 22 ++++++++--------- 7 files changed, 74 insertions(+), 61 deletions(-) diff --git a/local/config.go b/local/config.go index 12ce5531..e1b3fd0e 100644 --- a/local/config.go +++ b/local/config.go @@ -1,11 +1,13 @@ package local -var DefaultFlags = map[string]interface{}{ - "network-peer-list-gossip-frequency": "250ms", - "network-max-reconnect-delay": "1s", - "public-ip": "127.0.0.1", - "health-check-frequency": "2s", - "api-admin-enabled": true, - "api-ipcs-enabled": true, - "index-enabled": true, +func GetDefaultFlags() map[string]interface{} { + return map[string]interface{}{ + "network-peer-list-gossip-frequency": "250ms", + "network-max-reconnect-delay": "1s", + "public-ip": "127.0.0.1", + "health-check-frequency": "2s", + "api-admin-enabled": true, + "api-ipcs-enabled": true, + "index-enabled": true, + } } diff --git a/local/network.go b/local/network.go index 78e2ad4b..d65449fa 100644 --- a/local/network.go +++ b/local/network.go @@ -91,11 +91,11 @@ type localNetwork struct { // rootDir is the root directory under which we write all node // logs, databases, etc. rootDir string - // Flags to apply to all nodes if not present - flags map[string]interface{} + // flags from the networkConfig + networkConfigFlags map[string]interface{} // directory where networks can be persistently saved snapshotsDir string - + // config to apply to all nodes as default defaultNodeConfig *node.Config } @@ -120,7 +120,7 @@ func init() { defaultNetworkConfig = network.Config{ NodeConfigs: make([]node.Config, DefaultNumNodes), - Flags: DefaultFlags, + Flags: GetDefaultFlags(), } genesis, err := fs.ReadFile(configsDir, "genesis.json") @@ -429,8 +429,7 @@ func (ln *localNetwork) loadConfig(ctx context.Context, networkConfig network.Co return fmt.Errorf("couldn't get network ID from genesis: %w", err) } - // TODO put defaults? - ln.flags = networkConfig.Flags + ln.networkConfigFlags = networkConfig.Flags // Sort node configs so beacons start first var nodeConfigs []node.Config @@ -445,23 +444,7 @@ func (ln *localNetwork) loadConfig(ctx context.Context, networkConfig network.Co } } - for i, nodeConfig := range nodeConfigs { - // init the default config if they haven't been initialized yet - // this should therefore be running for the first node only - if i == 0 { - if ln.defaultNodeConfig == nil { - ln.defaultNodeConfig = &node.Config{ - Flags: DefaultFlags, - ChainConfigFiles: map[string]string{}, - } - ln.defaultNodeConfig.Flags[config.WhitelistedSubnetsKey] = nodeConfig.Flags[config.WhitelistedSubnetsKey] - - for k, v := range nodeConfig.ChainConfigFiles { - ln.defaultNodeConfig.ChainConfigFiles[k] = v - } - } - } - + for _, nodeConfig := range nodeConfigs { if _, err := ln.addNode(nodeConfig); err != nil { if err := ln.stop(ctx); err != nil { // Clean up nodes already created @@ -498,6 +481,25 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { nodeConfig.Flags = make(map[string]interface{}) } + // init the default config if they haven't been initialized yet + // this should therefore be running for the first node only + if ln.defaultNodeConfig == nil { + ln.defaultNodeConfig = &node.Config{ + Flags: GetDefaultFlags(), + ChainConfigFiles: map[string]string{}, + } + // after the defaults, assign all the ones from the networkConfig + for k, v := range ln.networkConfigFlags { + ln.defaultNodeConfig.Flags[k] = v + } + if nodeConfig.Flags[config.WhitelistedSubnetsKey] != nil { + ln.defaultNodeConfig.Flags[config.WhitelistedSubnetsKey] = nodeConfig.Flags[config.WhitelistedSubnetsKey] + } + + for k, v := range nodeConfig.ChainConfigFiles { + ln.defaultNodeConfig.ChainConfigFiles[k] = v + } + } // it shouldn't happen that just one is empty, most probably both, // but in any case if just one is empty it's unusable so we just assign a new one. if nodeConfig.StakingCert == "" || nodeConfig.StakingKey == "" { @@ -782,7 +784,7 @@ func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) ( } // make copy of network flags networkConfigFlags := make(map[string]interface{}) - for fk, fv := range ln.flags { + for fk, fv := range ln.defaultNodeConfig.Flags { networkConfigFlags[fk] = fv } // remove all log dir references @@ -867,7 +869,7 @@ func (ln *localNetwork) loadSnapshot( } // set default flags for all nodes networkConfig := network.Config{ - Flags: DefaultFlags, + Flags: GetDefaultFlags(), } err = json.Unmarshal(networkConfigJSON, &networkConfig) if err != nil { @@ -1113,7 +1115,7 @@ func (ln *localNetwork) buildFlags( ) (buildFlagsReturn, error) { // Add flags in [ln.Flags] to [nodeConfig.Flags] // Assumes [nodeConfig.Flags] is non-nil - addNetworkFlags(ln.log, ln.flags, nodeConfig.Flags) + addNetworkFlags(ln.log, ln.defaultNodeConfig.Flags, nodeConfig.Flags) // httpHost from all configs for node httpHost, err := getConfigEntry(nodeConfig.Flags, configFile, config.HTTPHostKey, "") diff --git a/local/network_test.go b/local/network_test.go index d49418a6..7d89bad8 100644 --- a/local/network_test.go +++ b/local/network_test.go @@ -161,7 +161,7 @@ func (lt *localTestOneNodeCreator) NewNodeProcess(config node.Config, log loggin lt.assert.True(config.IsBeacon) expectedConfig := lt.networkConfig.NodeConfigs[0] // TODO without this the test FAILS, is this the correct way to fix it? - expectedConfig.Flags = DefaultFlags + expectedConfig.Flags = GetDefaultFlags() lt.assert.EqualValues(expectedConfig.ChainConfigFiles, config.ChainConfigFiles) lt.assert.EqualValues(expectedConfig.ConfigFile, config.ConfigFile) lt.assert.EqualValues(expectedConfig.BinaryPath, config.BinaryPath) @@ -478,8 +478,6 @@ func TestUnhealthyNetwork(t *testing.T) { // Create a network without giving names to nodes. // Checks that the generated names are the correct number and unique. func TestGeneratedNodesNames(t *testing.T) { - // TODO to make these pass - // t.Parallel() assert := assert.New(t) networkConfig := testNetworkConfig(t) for i := range networkConfig.NodeConfigs { @@ -681,8 +679,6 @@ func TestStoppedNetwork(t *testing.T) { } func TestGetAllNodes(t *testing.T) { - // TODO: with this enabled we get "FATAL: concurrent map writes" - // t.Parallel() assert := assert.New(t) networkConfig := testNetworkConfig(t) net, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestSuccessfulNodeProcessCreator{}, "", "") @@ -719,15 +715,20 @@ func TestFlags(t *testing.T) { "common-config-flag": "this should be added", } } + expectedFlags := map[string]interface{}{ + "test-network-config-flag": "something", + "common-config-flag": "this should be added", + "test-node-config-flag": "node", + "test2-node-config-flag": "config", + } + + for k, v := range GetDefaultFlags() { + expectedFlags[k] = v + } nw, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestFlagCheckProcessCreator{ // after creating the network, one flag should have been overridden by the node configs - expectedFlags: map[string]interface{}{ - "test-network-config-flag": "something", - "common-config-flag": "this should be added", - "test-node-config-flag": "node", - "test2-node-config-flag": "config", - }, - assert: assert, + expectedFlags: expectedFlags, + assert: assert, }, "", "", @@ -751,6 +752,9 @@ func TestFlags(t *testing.T) { v := &networkConfig.NodeConfigs[i] v.Flags = flags } + for k, v := range GetDefaultFlags() { + flags[k] = v + } nw, err = newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestFlagCheckProcessCreator{ // after creating the network, only node configs should exist expectedFlags: flags, @@ -777,6 +781,9 @@ func TestFlags(t *testing.T) { v := &networkConfig.NodeConfigs[i] v.Flags = nil } + for k, v := range GetDefaultFlags() { + flags[k] = v + } nw, err = newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestFlagCheckProcessCreator{ // after creating the network, only flags from the network config should exist expectedFlags: flags, diff --git a/server/network.go b/server/network.go index 768f2dfe..ca95a30b 100644 --- a/server/network.go +++ b/server/network.go @@ -156,7 +156,7 @@ func (lc *localNetwork) createConfig() error { cfg.NodeConfigs[i].ChainConfigFiles[k] = v } - mergedConfig, err := mergeNodeConfig(local.DefaultFlags, globalConfig, lc.options.customNodeConfigs[nodeName]) + mergedConfig, err := mergeNodeConfig(local.GetDefaultFlags(), globalConfig, lc.options.customNodeConfigs[nodeName]) if err != nil { return fmt.Errorf("failed merging provided configs: %w", err) } diff --git a/server/network_test.go b/server/network_test.go index 87b684f7..481d7840 100644 --- a/server/network_test.go +++ b/server/network_test.go @@ -19,7 +19,7 @@ func TestEvalConfig(t *testing.T) { var defaultConfig, globalConfig map[string]interface{} - defaultConfig = local.DefaultFlags + defaultConfig = local.GetDefaultFlags() config, err := mergeNodeConfig(defaultConfig, globalConfig, "") assert.NoError(err) @@ -31,7 +31,7 @@ func TestEvalConfig(t *testing.T) { assert.NoError(err) var test1Map map[string]interface{} - test1Map = local.DefaultFlags + test1Map = local.GetDefaultFlags() // ...all default config entries should still be there... for k, v := range test1Map { assert.Equal(controlMap[k], v) diff --git a/server/server.go b/server/server.go index 69ce8ac0..868cc7d3 100644 --- a/server/server.go +++ b/server/server.go @@ -739,6 +739,8 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb if err := json.Unmarshal([]byte(req.StartRequest.GetGlobalNodeConfig()), &globalConfig); err != nil { return nil, err } + } else { + globalConfig = map[string]interface{}{} } globalConfig[config.BuildDirKey] = buildDir @@ -822,7 +824,7 @@ func (s *server) RestartNode(ctx context.Context, req *rpcpb.RestartNodeRequest) nodeInfo.DbDir = filepath.Join(req.GetRootDataDir(), req.Name, "db-dir") } - defaultConfig := local.DefaultFlags + defaultConfig := local.GetDefaultFlags() buildDir, err := getBuildDir(nodeInfo.ExecPath, nodeInfo.PluginDir) if err != nil { diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 33f3393a..62e84710 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -20,7 +20,7 @@ import ( "github.com/ava-labs/avalanche-network-runner/server" "github.com/ava-labs/avalanche-network-runner/utils" - "github.com/ava-labs/avalanchego/api/admin" + "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/utils/constants" @@ -46,13 +46,13 @@ var ( newNodeName = "test-add-node" customNodeConfigs = map[string]string{ - "node1": `{"api-admin-enabled":true}`, - "node2": `{"api-admin-enabled":true}`, - "node3": `{"api-admin-enabled":true}`, - "node4": `{"api-admin-enabled":false}`, - "node5": `{"api-admin-enabled":false}`, - "node6": `{"api-admin-enabled":false}`, - "node7": `{"api-admin-enabled":false}`, + "node1": `{"api-info-enabled":true}`, + "node2": `{"api-info-enabled":true}`, + "node3": `{"api-info-enabled":true}`, + "node4": `{"api-info-enabled":false}`, + "node5": `{"api-info-enabled":false}`, + "node6": `{"api-info-enabled":false}`, + "node7": `{"api-info-enabled":false}`, } numNodes = uint32(5) ) @@ -343,13 +343,13 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { color.Outf("{{green}}expected number of nodes up:{{/}} %q\n", len(customNodeConfigs)) color.Outf("{{green}}checking correct admin APIs are enabled resp. disabled") - // we have 7 nodes, 3 have the admin API enabled, the other 4 disabled + // we have 7 nodes, 3 have the info API enabled, the other 4 disabled // therefore we expect exactly 4 calls to fail and exactly 3 to succeed. ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second) errCnt := 0 for i := 0; i < len(uris); i++ { - cli := admin.NewClient(uris[i]) - err := cli.LockProfile(ctx) + cli := info.NewClient(uris[i]) + _, err := cli.GetNodeID(ctx) if err != nil { errCnt++ } From 264d997bde9068564836891d019a8e972373dbb2 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 22 Jul 2022 12:33:46 -0300 Subject: [PATCH 04/36] revert e2e test --- tests/e2e/e2e_test.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 62e84710..33f3393a 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -20,7 +20,7 @@ import ( "github.com/ava-labs/avalanche-network-runner/server" "github.com/ava-labs/avalanche-network-runner/utils" - "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/utils/constants" @@ -46,13 +46,13 @@ var ( newNodeName = "test-add-node" customNodeConfigs = map[string]string{ - "node1": `{"api-info-enabled":true}`, - "node2": `{"api-info-enabled":true}`, - "node3": `{"api-info-enabled":true}`, - "node4": `{"api-info-enabled":false}`, - "node5": `{"api-info-enabled":false}`, - "node6": `{"api-info-enabled":false}`, - "node7": `{"api-info-enabled":false}`, + "node1": `{"api-admin-enabled":true}`, + "node2": `{"api-admin-enabled":true}`, + "node3": `{"api-admin-enabled":true}`, + "node4": `{"api-admin-enabled":false}`, + "node5": `{"api-admin-enabled":false}`, + "node6": `{"api-admin-enabled":false}`, + "node7": `{"api-admin-enabled":false}`, } numNodes = uint32(5) ) @@ -343,13 +343,13 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { color.Outf("{{green}}expected number of nodes up:{{/}} %q\n", len(customNodeConfigs)) color.Outf("{{green}}checking correct admin APIs are enabled resp. disabled") - // we have 7 nodes, 3 have the info API enabled, the other 4 disabled + // we have 7 nodes, 3 have the admin API enabled, the other 4 disabled // therefore we expect exactly 4 calls to fail and exactly 3 to succeed. ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second) errCnt := 0 for i := 0; i < len(uris); i++ { - cli := info.NewClient(uris[i]) - _, err := cli.GetNodeID(ctx) + cli := admin.NewClient(uris[i]) + err := cli.LockProfile(ctx) if err != nil { errCnt++ } From d56762048e606dac17f83f339d7a6737e52af32b Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 22 Jul 2022 12:56:09 -0300 Subject: [PATCH 05/36] avoid creating config file on server --- server/network.go | 95 +++-------- server/network_test.go | 153 ----------------- server/server.go | 19 +-- tests/e2e/e2e_test.go | 368 +++++++++++++++++++++-------------------- 4 files changed, 214 insertions(+), 421 deletions(-) delete mode 100644 server/network_test.go diff --git a/server/network.go b/server/network.go index ca95a30b..2ac25a97 100644 --- a/server/network.go +++ b/server/network.go @@ -21,15 +21,8 @@ import ( "github.com/ava-labs/avalanchego/network/peer" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/logging" - "go.uber.org/zap" ) -var ignoreFields = map[string]struct{}{ - "public-ip": {}, - "http-port": {}, - "staking-port": {}, -} - type localNetwork struct { logger logging.Logger @@ -143,6 +136,11 @@ func (lc *localNetwork) createConfig() error { } } + // set flags applied to all nodes + for k, v := range globalConfig { + cfg.Flags[k] = v + } + for i := range cfg.NodeConfigs { // NOTE: Naming convention for node names is currently `node` + number, i.e. `node1,node2,node3,...node101` nodeName := fmt.Sprintf("node%d", i+1) @@ -156,9 +154,15 @@ func (lc *localNetwork) createConfig() error { cfg.NodeConfigs[i].ChainConfigFiles[k] = v } - mergedConfig, err := mergeNodeConfig(local.GetDefaultFlags(), globalConfig, lc.options.customNodeConfigs[nodeName]) - if err != nil { - return fmt.Errorf("failed merging provided configs: %w", err) + // set flags applied to the specific node + var customNodeConfig map[string]interface{} + if lc.options.customNodeConfigs[nodeName] != "" { + if err := json.Unmarshal([]byte(lc.options.customNodeConfigs[nodeName]), &customNodeConfig); err != nil { + return err + } + } + for k, v := range customNodeConfig { + cfg.NodeConfigs[i].Flags[k] = v } // avalanchego expects buildDir (parent dir of pluginDir) to be provided at cmdline @@ -166,9 +170,14 @@ func (lc *localNetwork) createConfig() error { if err != nil { return err } - cfg.NodeConfigs[i].ConfigFile, err = createConfigFileString(mergedConfig, logDir, dbDir, buildDir, lc.options.whitelistedSubnets) - if err != nil { - return err + + cfg.NodeConfigs[i].Flags[config.LogsDirKey] = logDir + cfg.NodeConfigs[i].Flags[config.DBPathKey] = dbDir + if buildDir != "" { + cfg.NodeConfigs[i].Flags[config.BuildDirKey] = buildDir + } + if lc.options.whitelistedSubnets != "" { + cfg.NodeConfigs[i].Flags[config.WhitelistedSubnetsKey] = lc.options.whitelistedSubnets } cfg.NodeConfigs[i].BinaryPath = lc.options.execPath @@ -180,39 +189,6 @@ func (lc *localNetwork) createConfig() error { return nil } -// mergeAndCheckForIgnores takes two maps, merging the two and overriding the first with the second -// if common entries are found. -// It also skips some entries which are internal to the runner -func mergeAndCheckForIgnores(base, override map[string]interface{}) { - for k, v := range override { - if _, ok := ignoreFields[k]; ok { - continue - } - base[k] = v - } -} - -// mergeNodeConfig evaluates the final node config. -// defaultConfig: map of base config to be applied -// globalConfig: map of global config provided to be applied to all nodes. Overrides defaultConfig -// customConfig: a custom config provided to be applied to this node. Overrides globalConfig and defaultConfig -// returns final map of node config entries -func mergeNodeConfig(baseConfig map[string]interface{}, globalConfig map[string]interface{}, customConfig string) (map[string]interface{}, error) { - mergeAndCheckForIgnores(baseConfig, globalConfig) - - var jsonCustom map[string]interface{} - // merge, overwriting entries in default with the global ones - if customConfig != "" { - if err := json.Unmarshal([]byte(customConfig), &jsonCustom); err != nil { - return nil, err - } - // merge, overwriting entries in default with the custom ones - mergeAndCheckForIgnores(baseConfig, jsonCustom) - } - - return baseConfig, nil -} - // generates buildDir from pluginDir, and if not available, from execPath // returns error if pluginDir is non empty and invalid func getBuildDir(execPath string, pluginDir string) (string, error) { @@ -230,33 +206,6 @@ func getBuildDir(execPath string, pluginDir string) (string, error) { return buildDir, nil } -// createConfigFileString finalizes the config setup and returns the node config JSON string -func createConfigFileString(configFileMap map[string]interface{}, logDir string, dbDir string, buildDir string, whitelistedSubnets string) (string, error) { - // add (or overwrite, if given) the following entries - if configFileMap[config.LogsDirKey] != "" { - zap.L().Warn("ignoring config file entry provided; the network runner needs to set its own", zap.String("entry", config.LogsDirKey)) - } - configFileMap[config.LogsDirKey] = logDir - if configFileMap[config.DBPathKey] != "" { - zap.L().Warn("ignoring config file entry provided; the network runner needs to set its own", zap.String("entry", config.DBPathKey)) - } - configFileMap[config.DBPathKey] = dbDir - if buildDir != "" { - configFileMap[config.BuildDirKey] = buildDir - } - // need to whitelist subnet ID to create custom VM chain - // ref. vms/platformvm/createChain - if whitelistedSubnets != "" { - configFileMap[config.WhitelistedSubnetsKey] = whitelistedSubnets - } - - finalJSON, err := json.Marshal(configFileMap) - if err != nil { - return "", err - } - return string(finalJSON), nil -} - func (lc *localNetwork) start() error { if err := lc.createConfig(); err != nil { return err diff --git a/server/network_test.go b/server/network_test.go deleted file mode 100644 index 481d7840..00000000 --- a/server/network_test.go +++ /dev/null @@ -1,153 +0,0 @@ -package server - -import ( - "encoding/json" - "testing" - - "github.com/ava-labs/avalanche-network-runner/local" - "github.com/stretchr/testify/assert" -) - -func TestEvalConfig(t *testing.T) { - assert := assert.New(t) - - // test using the default config... - tLogDir := "/tmp/log" - tDbDir := "/tmp/db" - tWhitelistedSubnets := "someSubnet" - tPluginDir := "/tmp/plugins" - - var defaultConfig, globalConfig map[string]interface{} - - defaultConfig = local.GetDefaultFlags() - - config, err := mergeNodeConfig(defaultConfig, globalConfig, "") - assert.NoError(err) - finalJSON, err := createConfigFileString(config, tLogDir, tDbDir, tPluginDir, tWhitelistedSubnets) - assert.NoError(err) - - var controlMap map[string]interface{} - err = json.Unmarshal([]byte(finalJSON), &controlMap) - assert.NoError(err) - - var test1Map map[string]interface{} - test1Map = local.GetDefaultFlags() - // ...all default config entries should still be there... - for k, v := range test1Map { - assert.Equal(controlMap[k], v) - } - // ...as well as additional ones - assert.Equal(controlMap["log-level"], defaultConfig["log-level"]) - assert.Equal(controlMap["log-dir"], tLogDir) - assert.Equal(controlMap["db-dir"], tDbDir) - assert.Equal(controlMap["whitelisted-subnets"], tWhitelistedSubnets) - - // now test a global provided config - globalConfigJSON := `{ - "log-dir":"/home/user/logs", - "db-dir":"/home/user/db", - "plugin-dir":"/home/user/plugins", - "log-display-level":"debug", - "log-level":"debug", - "whitelisted-subnets":"otherSubNets", - "index-enabled":false, - "public-ip":"192.168.0.1", - "network-id":999, - "http-port":777, - "staking-port":555, - "tx-fee":9999999 - }` - - err = json.Unmarshal([]byte(globalConfigJSON), &globalConfig) - assert.NoError(err) - - config, err = mergeNodeConfig(defaultConfig, globalConfig, "") - assert.NoError(err) - finalJSON, err = createConfigFileString(config, tLogDir, tDbDir, tPluginDir, tWhitelistedSubnets) - assert.NoError(err) - - err = json.Unmarshal([]byte(finalJSON), &controlMap) - assert.NoError(err) - - // the custom ones should be there... - assert.Equal(controlMap["index-enabled"], false) - assert.Equal(controlMap["network-id"], float64(999)) - assert.Equal(controlMap["tx-fee"], float64(9999999)) - // ...as well as the common additional ones - assert.Equal(controlMap["log-level"], "debug") - assert.Equal(controlMap["log-dir"], tLogDir) - assert.Equal(controlMap["db-dir"], tDbDir) - assert.Equal(controlMap["whitelisted-subnets"], tWhitelistedSubnets) - - // these ones should be ignored as they are hard-set by the code and required by the runner - assert.Equal(controlMap["public-ip"], "127.0.0.1") - assert.NotEqual(controlMap["http-port"], 777) - assert.NotEqual(controlMap["staking-port"], 555) - // same test but as custom only - should have same effect - customConfigJSON := globalConfigJSON - config, err = mergeNodeConfig(defaultConfig, map[string]interface{}{}, customConfigJSON) - assert.NoError(err) - finalJSON, err = createConfigFileString(config, tLogDir, tDbDir, tPluginDir, tWhitelistedSubnets) - assert.NoError(err) - - err = json.Unmarshal([]byte(finalJSON), &controlMap) - assert.NoError(err) - - // the custom ones should be there... - assert.Equal(controlMap["index-enabled"], false) - assert.Equal(controlMap["network-id"], float64(999)) - assert.Equal(controlMap["tx-fee"], float64(9999999)) - // ...as well as the common additional ones - assert.Equal(controlMap["log-level"], "debug") - assert.Equal(controlMap["log-dir"], tLogDir) - assert.Equal(controlMap["db-dir"], tDbDir) - assert.Equal(controlMap["whitelisted-subnets"], tWhitelistedSubnets) - // these ones should be ignored as they are hard-set by the code and required by the runner - assert.Equal(controlMap["public-ip"], "127.0.0.1") - assert.NotEqual(controlMap["http-port"], 777) - assert.NotEqual(controlMap["staking-port"], 555) - - // finally a combined one with custom and global - // newGlobalConfigJSON represents the global config, globalConfigJSON the custom. custom should override global - newGlobalConfigJSON := `{ - "log-dir":"/home/user/logs", - "db-dir":"/home/user/db", - "plugin-dir":"/home/user/plugins", - "log-display-level":"debug", - "log-level":"info", - "whitelisted-subnets":"otherSubNets", - "index-enabled":false, - "public-ip":"192.168.2.111", - "network-id":888, - "tx-fee":9999999, - "staking-port":11111, - "http-port":5555, - "uptime-requirement":98.5 - }` - err = json.Unmarshal([]byte(newGlobalConfigJSON), &globalConfig) - assert.NoError(err) - - config, err = mergeNodeConfig(defaultConfig, globalConfig, customConfigJSON) - assert.NoError(err) - finalJSON, err = createConfigFileString(config, tLogDir, tDbDir, tPluginDir, tWhitelistedSubnets) - assert.NoError(err) - - err = json.Unmarshal([]byte(finalJSON), &controlMap) - assert.NoError(err) - - // the custom ones should be there... - assert.Equal(controlMap["index-enabled"], false) - assert.Equal(controlMap["network-id"], float64(999)) - assert.Equal(controlMap["tx-fee"], float64(9999999)) - // ...as well as the common additional ones - assert.Equal(controlMap["log-level"], "debug") - assert.Equal(controlMap["log-dir"], tLogDir) - assert.Equal(controlMap["db-dir"], tDbDir) - assert.Equal(controlMap["whitelisted-subnets"], tWhitelistedSubnets) - // ...as well as the ones only in the global config - assert.Equal(controlMap["uptime-requirement"], float64(98.5)) - // these ones should be ignored as they are hard-set by the code and required by the runner - assert.Equal(controlMap["public-ip"], "127.0.0.1") - assert.NotEqual(controlMap["staking-port"], float64(11111)) - assert.NotEqual(controlMap["http-port"], float64(5555)) -} diff --git a/server/server.go b/server/server.go index 868cc7d3..ea7d7727 100644 --- a/server/server.go +++ b/server/server.go @@ -20,7 +20,6 @@ import ( "sync" "time" - "github.com/ava-labs/avalanche-network-runner/local" "github.com/ava-labs/avalanche-network-runner/network/node" "github.com/ava-labs/avalanche-network-runner/rpcpb" "github.com/ava-labs/avalanche-network-runner/utils" @@ -824,22 +823,18 @@ func (s *server) RestartNode(ctx context.Context, req *rpcpb.RestartNodeRequest) nodeInfo.DbDir = filepath.Join(req.GetRootDataDir(), req.Name, "db-dir") } - defaultConfig := local.GetDefaultFlags() - buildDir, err := getBuildDir(nodeInfo.ExecPath, nodeInfo.PluginDir) if err != nil { return nil, err } - nodeConfig.ConfigFile, err = createConfigFileString( - defaultConfig, - nodeInfo.LogDir, - nodeInfo.DbDir, - buildDir, - nodeInfo.WhitelistedSubnets, - ) - if err != nil { - return nil, fmt.Errorf("failed to generate json node config string: %w", err) + nodeConfig.Flags[config.LogsDirKey] = nodeInfo.LogDir + nodeConfig.Flags[config.DBPathKey] = nodeInfo.DbDir + if buildDir != "" { + nodeConfig.Flags[config.BuildDirKey] = buildDir + } + if nodeInfo.WhitelistedSubnets != "" { + nodeConfig.Flags[config.WhitelistedSubnetsKey] = nodeInfo.WhitelistedSubnets } nodeConfig.BinaryPath = nodeInfo.ExecPath diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 33f3393a..3e719116 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -359,193 +359,195 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { }) }) - ginkgo.It("start with default network, for subsecuent steps", func() { - ginkgo.By("stopping network first", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Stop(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("starting", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - _, err := cli.Start(ctx, execPath1) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("wait for health", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Health(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - }) - - ginkgo.It("subnet creation", func() { - ginkgo.By("check subnets are 0", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - numSubnets := len(status.ClusterInfo.Subnets) - gomega.Ω(numSubnets).Should(gomega.Equal(0)) - }) - ginkgo.By("add 1 subnet", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - _, err := cli.CreateSubnets(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("wait for network to be healthy", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - var created bool - continueLoop := true - for continueLoop { - select { - case <-ctx.Done(): - continueLoop = false - case <-time.After(5 * time.Second): - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - created = status.ClusterInfo.CustomVmsHealthy - if created { + /* + ginkgo.It("start with default network, for subsecuent steps", func() { + ginkgo.By("stopping network first", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Stop(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("starting", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + _, err := cli.Start(ctx, execPath1) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("wait for health", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Health(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + }) + + ginkgo.It("subnet creation", func() { + ginkgo.By("check subnets are 0", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + numSubnets := len(status.ClusterInfo.Subnets) + gomega.Ω(numSubnets).Should(gomega.Equal(0)) + }) + ginkgo.By("add 1 subnet", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + _, err := cli.CreateSubnets(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("wait for network to be healthy", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + var created bool + continueLoop := true + for continueLoop { + select { + case <-ctx.Done(): continueLoop = false + case <-time.After(5 * time.Second): + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + created = status.ClusterInfo.CustomVmsHealthy + if created { + continueLoop = false + } } } - } - cancel() - gomega.Ω(created).Should(gomega.Equal(true)) - }) - ginkgo.By("check subnets are 1", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - numSubnets := len(status.ClusterInfo.Subnets) - gomega.Ω(numSubnets).Should(gomega.Equal(1)) - }) - }) - - ginkgo.It("snapshots + blockchain creation", func() { - var originalUris []string - var originalSubnets []string - ginkgo.By("get original URIs", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - var err error - originalUris, err = cli.URIs(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(len(originalUris)).Should(gomega.Equal(5)) - }) - ginkgo.By("get original subnets", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - numSubnets := len(status.ClusterInfo.Subnets) - gomega.Ω(numSubnets).Should(gomega.Equal(1)) - originalSubnets = status.ClusterInfo.Subnets - }) - ginkgo.By("check there are no snapshots", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - snapshotNames, err := cli.GetSnapshotNames(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(snapshotNames).Should(gomega.Equal([]string(nil))) - }) - ginkgo.By("can save snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.SaveSnapshot(ctx, "pepe") - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("wait fail for stopped network", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Health(ctx) - cancel() - gomega.Ω(err.Error()).Should(gomega.ContainSubstring("not bootstrapped")) - }) - ginkgo.By("load fail for unknown snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.LoadSnapshot(ctx, "papa") - cancel() - gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"papa\" does not exists")) - }) - ginkgo.By("can load snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.LoadSnapshot(ctx, "pepe") - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("wait for network to be healthy", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - var created bool - continueLoop := true - for continueLoop { - select { - case <-ctx.Done(): - continueLoop = false - case <-time.After(5 * time.Second): - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - created = status.ClusterInfo.CustomVmsHealthy - if created { + cancel() + gomega.Ω(created).Should(gomega.Equal(true)) + }) + ginkgo.By("check subnets are 1", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + numSubnets := len(status.ClusterInfo.Subnets) + gomega.Ω(numSubnets).Should(gomega.Equal(1)) + }) + }) + + ginkgo.It("snapshots + blockchain creation", func() { + var originalUris []string + var originalSubnets []string + ginkgo.By("get original URIs", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + var err error + originalUris, err = cli.URIs(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(len(originalUris)).Should(gomega.Equal(5)) + }) + ginkgo.By("get original subnets", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + numSubnets := len(status.ClusterInfo.Subnets) + gomega.Ω(numSubnets).Should(gomega.Equal(1)) + originalSubnets = status.ClusterInfo.Subnets + }) + ginkgo.By("check there are no snapshots", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + snapshotNames, err := cli.GetSnapshotNames(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(snapshotNames).Should(gomega.Equal([]string(nil))) + }) + ginkgo.By("can save snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.SaveSnapshot(ctx, "pepe") + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("wait fail for stopped network", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Health(ctx) + cancel() + gomega.Ω(err.Error()).Should(gomega.ContainSubstring("not bootstrapped")) + }) + ginkgo.By("load fail for unknown snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.LoadSnapshot(ctx, "papa") + cancel() + gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"papa\" does not exists")) + }) + ginkgo.By("can load snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.LoadSnapshot(ctx, "pepe") + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("wait for network to be healthy", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + var created bool + continueLoop := true + for continueLoop { + select { + case <-ctx.Done(): continueLoop = false + case <-time.After(5 * time.Second): + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + created = status.ClusterInfo.CustomVmsHealthy + if created { + continueLoop = false + } } } - } - cancel() - gomega.Ω(created).Should(gomega.Equal(true)) - }) - ginkgo.By("check URIs", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - var err error - uris, err := cli.URIs(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(uris).Should(gomega.Equal(originalUris)) - }) - ginkgo.By("check subnets", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(status.ClusterInfo.Subnets).Should(gomega.Equal(originalSubnets)) - }) - ginkgo.By("save fail for already saved snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.SaveSnapshot(ctx, "pepe") - cancel() - gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"pepe\" already exists")) - }) - ginkgo.By("check there is a snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - snapshotNames, err := cli.GetSnapshotNames(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(snapshotNames).Should(gomega.Equal([]string{"pepe"})) - }) - ginkgo.By("can remove snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.RemoveSnapshot(ctx, "pepe") - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("check there are no snapshots", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - snapshotNames, err := cli.GetSnapshotNames(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(snapshotNames).Should(gomega.Equal([]string(nil))) - }) - ginkgo.By("remove fail for unknown snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.RemoveSnapshot(ctx, "pepe") - cancel() - gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"pepe\" does not exists")) - }) - }) + cancel() + gomega.Ω(created).Should(gomega.Equal(true)) + }) + ginkgo.By("check URIs", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + var err error + uris, err := cli.URIs(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(uris).Should(gomega.Equal(originalUris)) + }) + ginkgo.By("check subnets", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(status.ClusterInfo.Subnets).Should(gomega.Equal(originalSubnets)) + }) + ginkgo.By("save fail for already saved snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.SaveSnapshot(ctx, "pepe") + cancel() + gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"pepe\" already exists")) + }) + ginkgo.By("check there is a snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + snapshotNames, err := cli.GetSnapshotNames(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(snapshotNames).Should(gomega.Equal([]string{"pepe"})) + }) + ginkgo.By("can remove snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.RemoveSnapshot(ctx, "pepe") + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("check there are no snapshots", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + snapshotNames, err := cli.GetSnapshotNames(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(snapshotNames).Should(gomega.Equal([]string(nil))) + }) + ginkgo.By("remove fail for unknown snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.RemoveSnapshot(ctx, "pepe") + cancel() + gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"pepe\" does not exists")) + }) + }) + */ }) From 06c168a29840be65055822d55ebf0464813740ad Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 22 Jul 2022 13:27:14 -0300 Subject: [PATCH 06/36] avoid nil error --- server/network.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/network.go b/server/network.go index 2ac25a97..5e7fe373 100644 --- a/server/network.go +++ b/server/network.go @@ -154,6 +154,10 @@ func (lc *localNetwork) createConfig() error { cfg.NodeConfigs[i].ChainConfigFiles[k] = v } + if cfg.NodeConfigs[i].Flags == nil { + cfg.NodeConfigs[i].Flags = map[string]interface{}{} + } + // set flags applied to the specific node var customNodeConfig map[string]interface{} if lc.options.customNodeConfigs[nodeName] != "" { From cc62f6c730707988949b08a5e1f8a57457723d25 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 22 Jul 2022 13:45:39 -0300 Subject: [PATCH 07/36] reenable all e2e --- tests/e2e/e2e_test.go | 368 +++++++++++++++++++++--------------------- 1 file changed, 183 insertions(+), 185 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 3e719116..33f3393a 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -359,195 +359,193 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { }) }) - /* - ginkgo.It("start with default network, for subsecuent steps", func() { - ginkgo.By("stopping network first", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Stop(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("starting", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - _, err := cli.Start(ctx, execPath1) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("wait for health", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Health(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - }) - - ginkgo.It("subnet creation", func() { - ginkgo.By("check subnets are 0", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - numSubnets := len(status.ClusterInfo.Subnets) - gomega.Ω(numSubnets).Should(gomega.Equal(0)) - }) - ginkgo.By("add 1 subnet", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - _, err := cli.CreateSubnets(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("wait for network to be healthy", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - var created bool - continueLoop := true - for continueLoop { - select { - case <-ctx.Done(): + ginkgo.It("start with default network, for subsecuent steps", func() { + ginkgo.By("stopping network first", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Stop(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("starting", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + _, err := cli.Start(ctx, execPath1) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("wait for health", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Health(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + }) + + ginkgo.It("subnet creation", func() { + ginkgo.By("check subnets are 0", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + numSubnets := len(status.ClusterInfo.Subnets) + gomega.Ω(numSubnets).Should(gomega.Equal(0)) + }) + ginkgo.By("add 1 subnet", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + _, err := cli.CreateSubnets(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("wait for network to be healthy", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + var created bool + continueLoop := true + for continueLoop { + select { + case <-ctx.Done(): + continueLoop = false + case <-time.After(5 * time.Second): + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + created = status.ClusterInfo.CustomVmsHealthy + if created { continueLoop = false - case <-time.After(5 * time.Second): - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - created = status.ClusterInfo.CustomVmsHealthy - if created { - continueLoop = false - } } } - cancel() - gomega.Ω(created).Should(gomega.Equal(true)) - }) - ginkgo.By("check subnets are 1", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - numSubnets := len(status.ClusterInfo.Subnets) - gomega.Ω(numSubnets).Should(gomega.Equal(1)) - }) - }) - - ginkgo.It("snapshots + blockchain creation", func() { - var originalUris []string - var originalSubnets []string - ginkgo.By("get original URIs", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - var err error - originalUris, err = cli.URIs(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(len(originalUris)).Should(gomega.Equal(5)) - }) - ginkgo.By("get original subnets", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - numSubnets := len(status.ClusterInfo.Subnets) - gomega.Ω(numSubnets).Should(gomega.Equal(1)) - originalSubnets = status.ClusterInfo.Subnets - }) - ginkgo.By("check there are no snapshots", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - snapshotNames, err := cli.GetSnapshotNames(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(snapshotNames).Should(gomega.Equal([]string(nil))) - }) - ginkgo.By("can save snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.SaveSnapshot(ctx, "pepe") - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("wait fail for stopped network", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.Health(ctx) - cancel() - gomega.Ω(err.Error()).Should(gomega.ContainSubstring("not bootstrapped")) - }) - ginkgo.By("load fail for unknown snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.LoadSnapshot(ctx, "papa") - cancel() - gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"papa\" does not exists")) - }) - ginkgo.By("can load snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.LoadSnapshot(ctx, "pepe") - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("wait for network to be healthy", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - var created bool - continueLoop := true - for continueLoop { - select { - case <-ctx.Done(): + } + cancel() + gomega.Ω(created).Should(gomega.Equal(true)) + }) + ginkgo.By("check subnets are 1", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + numSubnets := len(status.ClusterInfo.Subnets) + gomega.Ω(numSubnets).Should(gomega.Equal(1)) + }) + }) + + ginkgo.It("snapshots + blockchain creation", func() { + var originalUris []string + var originalSubnets []string + ginkgo.By("get original URIs", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + var err error + originalUris, err = cli.URIs(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(len(originalUris)).Should(gomega.Equal(5)) + }) + ginkgo.By("get original subnets", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + numSubnets := len(status.ClusterInfo.Subnets) + gomega.Ω(numSubnets).Should(gomega.Equal(1)) + originalSubnets = status.ClusterInfo.Subnets + }) + ginkgo.By("check there are no snapshots", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + snapshotNames, err := cli.GetSnapshotNames(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(snapshotNames).Should(gomega.Equal([]string(nil))) + }) + ginkgo.By("can save snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.SaveSnapshot(ctx, "pepe") + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("wait fail for stopped network", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.Health(ctx) + cancel() + gomega.Ω(err.Error()).Should(gomega.ContainSubstring("not bootstrapped")) + }) + ginkgo.By("load fail for unknown snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.LoadSnapshot(ctx, "papa") + cancel() + gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"papa\" does not exists")) + }) + ginkgo.By("can load snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.LoadSnapshot(ctx, "pepe") + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("wait for network to be healthy", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + var created bool + continueLoop := true + for continueLoop { + select { + case <-ctx.Done(): + continueLoop = false + case <-time.After(5 * time.Second): + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + created = status.ClusterInfo.CustomVmsHealthy + if created { continueLoop = false - case <-time.After(5 * time.Second): - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - created = status.ClusterInfo.CustomVmsHealthy - if created { - continueLoop = false - } } } - cancel() - gomega.Ω(created).Should(gomega.Equal(true)) - }) - ginkgo.By("check URIs", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - var err error - uris, err := cli.URIs(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(uris).Should(gomega.Equal(originalUris)) - }) - ginkgo.By("check subnets", func() { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) - status, err := cli.Status(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(status.ClusterInfo.Subnets).Should(gomega.Equal(originalSubnets)) - }) - ginkgo.By("save fail for already saved snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.SaveSnapshot(ctx, "pepe") - cancel() - gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"pepe\" already exists")) - }) - ginkgo.By("check there is a snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - snapshotNames, err := cli.GetSnapshotNames(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(snapshotNames).Should(gomega.Equal([]string{"pepe"})) - }) - ginkgo.By("can remove snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.RemoveSnapshot(ctx, "pepe") - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - }) - ginkgo.By("check there are no snapshots", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - snapshotNames, err := cli.GetSnapshotNames(ctx) - cancel() - gomega.Ω(err).Should(gomega.BeNil()) - gomega.Ω(snapshotNames).Should(gomega.Equal([]string(nil))) - }) - ginkgo.By("remove fail for unknown snapshot", func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - _, err := cli.RemoveSnapshot(ctx, "pepe") - cancel() - gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"pepe\" does not exists")) - }) - }) - */ + } + cancel() + gomega.Ω(created).Should(gomega.Equal(true)) + }) + ginkgo.By("check URIs", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + var err error + uris, err := cli.URIs(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(uris).Should(gomega.Equal(originalUris)) + }) + ginkgo.By("check subnets", func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + status, err := cli.Status(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(status.ClusterInfo.Subnets).Should(gomega.Equal(originalSubnets)) + }) + ginkgo.By("save fail for already saved snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.SaveSnapshot(ctx, "pepe") + cancel() + gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"pepe\" already exists")) + }) + ginkgo.By("check there is a snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + snapshotNames, err := cli.GetSnapshotNames(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(snapshotNames).Should(gomega.Equal([]string{"pepe"})) + }) + ginkgo.By("can remove snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.RemoveSnapshot(ctx, "pepe") + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + }) + ginkgo.By("check there are no snapshots", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + snapshotNames, err := cli.GetSnapshotNames(ctx) + cancel() + gomega.Ω(err).Should(gomega.BeNil()) + gomega.Ω(snapshotNames).Should(gomega.Equal([]string(nil))) + }) + ginkgo.By("remove fail for unknown snapshot", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + _, err := cli.RemoveSnapshot(ctx, "pepe") + cancel() + gomega.Ω(err.Error()).Should(gomega.ContainSubstring("snapshot \"pepe\" does not exists")) + }) + }) }) From 73e2e7712fb463ab611057609f83c44800f14b01 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 22 Jul 2022 13:58:27 -0300 Subject: [PATCH 08/36] avoid modifying snapshot flags --- local/network.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/local/network.go b/local/network.go index d65449fa..93bb27ad 100644 --- a/local/network.go +++ b/local/network.go @@ -867,10 +867,7 @@ func (ln *localNetwork) loadSnapshot( if err != nil { return fmt.Errorf("failure reading network config file from snapshot: %w", err) } - // set default flags for all nodes - networkConfig := network.Config{ - Flags: GetDefaultFlags(), - } + networkConfig := network.Config{} err = json.Unmarshal(networkConfigJSON, &networkConfig) if err != nil { return fmt.Errorf("failure unmarshaling network config from snapshot: %w", err) From 1b275bf476ceb9eeab0b2ad709ba8f1f32ec9b94 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 28 Jul 2022 16:11:25 -0300 Subject: [PATCH 09/36] address PR comments --- server/network.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/network.go b/server/network.go index 5e7fe373..146c2f1c 100644 --- a/server/network.go +++ b/server/network.go @@ -160,7 +160,7 @@ func (lc *localNetwork) createConfig() error { // set flags applied to the specific node var customNodeConfig map[string]interface{} - if lc.options.customNodeConfigs[nodeName] != "" { + if lc.options.customNodeConfigs != nil && lc.options.customNodeConfigs[nodeName] != "" { if err := json.Unmarshal([]byte(lc.options.customNodeConfigs[nodeName]), &customNodeConfig); err != nil { return err } From b4d0e1f854e3ca4c3582203dc717af4199a413f9 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 29 Jul 2022 13:12:01 -0300 Subject: [PATCH 10/36] add debug prints to follow up E2E problem --- server/server.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/server.go b/server/server.go index ea7d7727..879e7508 100644 --- a/server/server.go +++ b/server/server.go @@ -736,6 +736,7 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb var globalConfig map[string]interface{} if req.StartRequest.GetGlobalNodeConfig() != "" { if err := json.Unmarshal([]byte(req.StartRequest.GetGlobalNodeConfig()), &globalConfig); err != nil { + fmt.Printf("GLOBALNODECONFIG ERR %s %s\n", req.StartRequest.GetGlobalNodeConfig(), err) return nil, err } } else { @@ -757,6 +758,7 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb } _, err = s.network.nw.AddNode(nodeConfig) if err != nil { + fmt.Printf("ADDNODE ERR %#v %s\n", nodeConfig, err) return nil, err } From 4179bb2d561ee8b62a601f9046715ad8ffd57f83 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 29 Jul 2022 14:19:34 -0300 Subject: [PATCH 11/36] add more debug --- local/network.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/local/network.go b/local/network.go index 93bb27ad..f3dcf3a2 100644 --- a/local/network.go +++ b/local/network.go @@ -528,17 +528,23 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { } } + fmt.Println("HERE_0") + nodeData, err := ln.buildFlags(configFile, nodeDir, &nodeConfig) if err != nil { return nil, err } + fmt.Println("HERE_1") + // Parse this node's ID nodeID, err := utils.ToNodeID([]byte(nodeConfig.StakingKey), []byte(nodeConfig.StakingCert)) if err != nil { return nil, fmt.Errorf("couldn't get node ID: %w", err) } + fmt.Println("HERE_2") + // Start the AvalancheGo node and pass it the flags defined above nodeProcess, err := ln.nodeProcessCreator.NewNodeProcess(nodeConfig, ln.log, nodeData.flags...) if err != nil { @@ -549,6 +555,8 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { } ln.log.Debug("starting node %q with \"%s %s\"", nodeConfig.Name, nodeConfig.BinaryPath, nodeData.flags) + fmt.Println("HERE_3") + // Create a wrapper for this node so we can reference it later node := &localNode{ name: nodeConfig.Name, @@ -566,6 +574,7 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { httpHost: nodeData.httpHost, } ln.nodes[node.name] = node + fmt.Println("HERE_4") // If this node is a beacon, add its IP/ID to the beacon lists. // Note that we do this *after* we set this node's bootstrap IPs/IDs // so this node won't try to use itself as a beacon. @@ -575,6 +584,8 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { Port: nodeData.p2pPort, })) } + fmt.Println("HERE_5") + fmt.Println(err) return node, err } From 5e93a417ba124b926caf686a872637fd41621bec Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 29 Jul 2022 17:45:04 -0300 Subject: [PATCH 12/36] add a little more info --- client/client.go | 6 +++++- server/server.go | 1 + tests/e2e/e2e_test.go | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/client/client.go b/client/client.go index 527677c5..755fde4b 100644 --- a/client/client.go +++ b/client/client.go @@ -11,6 +11,7 @@ import ( "strings" "sync" "time" + "fmt" "github.com/ava-labs/avalanche-network-runner/local" "github.com/ava-labs/avalanche-network-runner/pkg/logutil" @@ -248,7 +249,10 @@ func (c *client) AddNode(ctx context.Context, name string, execPath string, opts req.StartRequest.ChainConfigs = ret.chainConfigs zap.L().Info("add node", zap.String("name", name)) - return c.controlc.AddNode(ctx, req) + r, err := c.controlc.AddNode(ctx, req) + fmt.Println(r) + fmt.Println(err) + return r, err } func (c *client) RemoveNode(ctx context.Context, name string) (*rpcpb.RemoveNodeResponse, error) { diff --git a/server/server.go b/server/server.go index 879e7508..ff317c9d 100644 --- a/server/server.go +++ b/server/server.go @@ -761,6 +761,7 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb fmt.Printf("ADDNODE ERR %#v %s\n", nodeConfig, err) return nil, err } + fmt.Println("ADDNODE CALL END") return &rpcpb.AddNodeResponse{ClusterInfo: s.clusterInfo}, nil } diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 33f3393a..120f7cea 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -7,6 +7,7 @@ package e2e_test import ( "context" "flag" + "fmt" "io/fs" "os" "path/filepath" @@ -285,6 +286,8 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { color.Outf("{{green}}calling 'add-node' with the valid binary path:{{/}} %q\n", execPath1) ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) resp, err := cli.AddNode(ctx, newNodeName, execPath1) + fmt.Println(resp) + fmt.Println(err) cancel() gomega.Ω(err).Should(gomega.BeNil()) color.Outf("{{green}}successfully started:{{/}} %+v\n", resp.ClusterInfo.NodeNames) From 3ec5326ba3b03fd7b56dd577cb92523173920329 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 29 Jul 2022 19:30:31 -0300 Subject: [PATCH 13/36] one more check --- server/server.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/server.go b/server/server.go index eec2cd71..67c842e5 100644 --- a/server/server.go +++ b/server/server.go @@ -762,10 +762,11 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb fmt.Printf("ADDNODE ERR %#v %s\n", nodeConfig, err) return nil, err } - fmt.Println("ADDNODE CALL END") if err := s.network.updateNodeInfo(); err != nil { + fmt.Println("UPDATENODEINFO FAIL") return nil, err } + fmt.Println("ADDNODE CALL END") return &rpcpb.AddNodeResponse{ClusterInfo: s.clusterInfo}, nil } From 6518c7ed3a678939994d1e082c5b9dedb1d9178f Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Fri, 29 Jul 2022 19:58:43 -0300 Subject: [PATCH 14/36] one more print, close to find it --- server/network.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server/network.go b/server/network.go index 86b7e206..7190451b 100644 --- a/server/network.go +++ b/server/network.go @@ -470,6 +470,7 @@ func (lc *localNetwork) updateNodeInfo() error { var whitelistedSubnets string var configFileMap map[string]interface{} if err := json.Unmarshal(configFile, &configFileMap); err != nil { + fmt.Printf("UNMARSHAL ERROR %s\n", string(configFile)) return err } whitelistedSubnetsIntf, ok := configFileMap[config.WhitelistedSubnetsKey] From cb78f2541e363254b66d46f6d6b9ba33832be0e9 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Mon, 1 Aug 2022 16:00:08 -0300 Subject: [PATCH 15/36] fix e2e --- client/client.go | 7 ++----- local/network.go | 11 ----------- local/node.go | 28 ++++++++++++++++++++++++++++ network/node/node.go | 2 ++ server/network.go | 14 ++------------ server/server.go | 4 ---- tests/e2e/e2e_test.go | 3 --- 7 files changed, 34 insertions(+), 35 deletions(-) diff --git a/client/client.go b/client/client.go index 755fde4b..f9f9653f 100644 --- a/client/client.go +++ b/client/client.go @@ -11,7 +11,6 @@ import ( "strings" "sync" "time" - "fmt" "github.com/ava-labs/avalanche-network-runner/local" "github.com/ava-labs/avalanche-network-runner/pkg/logutil" @@ -249,10 +248,8 @@ func (c *client) AddNode(ctx context.Context, name string, execPath string, opts req.StartRequest.ChainConfigs = ret.chainConfigs zap.L().Info("add node", zap.String("name", name)) - r, err := c.controlc.AddNode(ctx, req) - fmt.Println(r) - fmt.Println(err) - return r, err + r, err := c.controlc.AddNode(ctx, req) + return r, err } func (c *client) RemoveNode(ctx context.Context, name string) (*rpcpb.RemoveNodeResponse, error) { diff --git a/local/network.go b/local/network.go index abd6bfd4..62491b40 100644 --- a/local/network.go +++ b/local/network.go @@ -528,23 +528,17 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { } } - fmt.Println("HERE_0") - nodeData, err := ln.buildFlags(configFile, nodeDir, &nodeConfig) if err != nil { return nil, err } - fmt.Println("HERE_1") - // Parse this node's ID nodeID, err := utils.ToNodeID([]byte(nodeConfig.StakingKey), []byte(nodeConfig.StakingCert)) if err != nil { return nil, fmt.Errorf("couldn't get node ID: %w", err) } - fmt.Println("HERE_2") - // Start the AvalancheGo node and pass it the flags defined above nodeProcess, err := ln.nodeProcessCreator.NewNodeProcess(nodeConfig, ln.log, nodeData.flags...) if err != nil { @@ -555,8 +549,6 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { } ln.log.Debug("starting node %q with \"%s %s\"", nodeConfig.Name, nodeConfig.BinaryPath, nodeData.flags) - fmt.Println("HERE_3") - // Create a wrapper for this node so we can reference it later node := &localNode{ name: nodeConfig.Name, @@ -574,7 +566,6 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { httpHost: nodeData.httpHost, } ln.nodes[node.name] = node - fmt.Println("HERE_4") // If this node is a beacon, add its IP/ID to the beacon lists. // Note that we do this *after* we set this node's bootstrap IPs/IDs // so this node won't try to use itself as a beacon. @@ -584,8 +575,6 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { Port: nodeData.p2pPort, })) } - fmt.Println("HERE_5") - fmt.Println(err) return node, err } diff --git a/local/node.go b/local/node.go index d06458dc..dcba04f9 100644 --- a/local/node.go +++ b/local/node.go @@ -3,6 +3,7 @@ package local import ( "context" "crypto" + "encoding/json" "fmt" "net" "path/filepath" @@ -235,3 +236,30 @@ func (node *localNode) GetConfigFile() string { func (node *localNode) GetConfig() node.Config { return node.config } + +// See node.Node +func (node *localNode) GetFlag(k string) (string, error) { + var v string + if node.config.ConfigFile != "" { + var configFileMap map[string]interface{} + if err := json.Unmarshal([]byte(node.config.ConfigFile), &configFileMap); err != nil { + return "", err + } + vIntf, ok := configFileMap[k] + if ok { + v, ok = vIntf.(string) + if !ok { + return "", fmt.Errorf("unexpected type for %q expected string got %T", k, vIntf) + } + } + } else if node.config.Flags != nil { + vIntf, ok := node.config.Flags[k] + if ok { + v, ok = vIntf.(string) + if !ok { + return "", fmt.Errorf("unexpected type for %q expected string got %T", k, vIntf) + } + } + } + return v, nil +} diff --git a/network/node/node.go b/network/node/node.go index 6639ad9d..578a9c6c 100644 --- a/network/node/node.go +++ b/network/node/node.go @@ -49,6 +49,8 @@ type Node interface { GetConfigFile() string // Return this node's config GetConfig() Config + // Return this node's flag value + GetFlag(string) (string, error) } // Config encapsulates an avalanchego configuration diff --git a/server/network.go b/server/network.go index 7190451b..30f0ce62 100644 --- a/server/network.go +++ b/server/network.go @@ -465,21 +465,11 @@ func (lc *localNetwork) updateNodeInfo() error { lc.nodeInfos = make(map[string]*rpcpb.NodeInfo) for _, name := range lc.nodeNames { node := nodes[name] - configFile := []byte(node.GetConfigFile()) var pluginDir string - var whitelistedSubnets string - var configFileMap map[string]interface{} - if err := json.Unmarshal(configFile, &configFileMap); err != nil { - fmt.Printf("UNMARSHAL ERROR %s\n", string(configFile)) + whitelistedSubnets, err := node.GetFlag(config.WhitelistedSubnetsKey) + if err != nil { return err } - whitelistedSubnetsIntf, ok := configFileMap[config.WhitelistedSubnetsKey] - if ok { - whitelistedSubnets, ok = whitelistedSubnetsIntf.(string) - if !ok { - return fmt.Errorf("unexpected type for %q expected string got %T", config.WhitelistedSubnetsKey, whitelistedSubnetsIntf) - } - } buildDir := node.GetBuildDir() if buildDir != "" { pluginDir = filepath.Join(buildDir, "plugins") diff --git a/server/server.go b/server/server.go index 67c842e5..007ede3e 100644 --- a/server/server.go +++ b/server/server.go @@ -737,7 +737,6 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb var globalConfig map[string]interface{} if req.StartRequest.GetGlobalNodeConfig() != "" { if err := json.Unmarshal([]byte(req.StartRequest.GetGlobalNodeConfig()), &globalConfig); err != nil { - fmt.Printf("GLOBALNODECONFIG ERR %s %s\n", req.StartRequest.GetGlobalNodeConfig(), err) return nil, err } } else { @@ -759,14 +758,11 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb } _, err = s.network.nw.AddNode(nodeConfig) if err != nil { - fmt.Printf("ADDNODE ERR %#v %s\n", nodeConfig, err) return nil, err } if err := s.network.updateNodeInfo(); err != nil { - fmt.Println("UPDATENODEINFO FAIL") return nil, err } - fmt.Println("ADDNODE CALL END") return &rpcpb.AddNodeResponse{ClusterInfo: s.clusterInfo}, nil } diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 120f7cea..33f3393a 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -7,7 +7,6 @@ package e2e_test import ( "context" "flag" - "fmt" "io/fs" "os" "path/filepath" @@ -286,8 +285,6 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { color.Outf("{{green}}calling 'add-node' with the valid binary path:{{/}} %q\n", execPath1) ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) resp, err := cli.AddNode(ctx, newNodeName, execPath1) - fmt.Println(resp) - fmt.Println(err) cancel() gomega.Ω(err).Should(gomega.BeNil()) color.Outf("{{green}}successfully started:{{/}} %+v\n", resp.ClusterInfo.NodeNames) From 7bab6cef53433c6b65288e66019dfe4634af7b5e Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Tue, 2 Aug 2022 08:15:12 -0500 Subject: [PATCH 16/36] broken up network.go in smaller files --- local/helpers.go | 178 +++++++++++++++++ local/network.go | 451 ------------------------------------------ local/node_process.go | 50 ++++- local/snapshot.go | 253 ++++++++++++++++++++++++ 4 files changed, 480 insertions(+), 452 deletions(-) create mode 100644 local/helpers.go create mode 100644 local/snapshot.go diff --git a/local/helpers.go b/local/helpers.go new file mode 100644 index 00000000..b693fd81 --- /dev/null +++ b/local/helpers.go @@ -0,0 +1,178 @@ +package local + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/ava-labs/avalanche-network-runner/network/node" + "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/utils/logging" +) + +// writeFiles writes the files a node needs on startup. +// It returns flags used to point to those files. +func writeFiles(genesis []byte, nodeRootDir string, nodeConfig *node.Config) ([]string, error) { + type file struct { + pathKey string + flagValue string + path string + contents []byte + } + files := []file{ + { + flagValue: filepath.Join(nodeRootDir, stakingKeyFileName), + path: filepath.Join(nodeRootDir, stakingKeyFileName), + pathKey: config.StakingKeyPathKey, + contents: []byte(nodeConfig.StakingKey), + }, + { + flagValue: filepath.Join(nodeRootDir, stakingCertFileName), + path: filepath.Join(nodeRootDir, stakingCertFileName), + pathKey: config.StakingCertPathKey, + contents: []byte(nodeConfig.StakingCert), + }, + { + flagValue: filepath.Join(nodeRootDir, genesisFileName), + path: filepath.Join(nodeRootDir, genesisFileName), + pathKey: config.GenesisConfigFileKey, + contents: genesis, + }, + } + if len(nodeConfig.ConfigFile) != 0 { + files = append(files, file{ + flagValue: filepath.Join(nodeRootDir, configFileName), + path: filepath.Join(nodeRootDir, configFileName), + pathKey: config.ConfigFileKey, + contents: []byte(nodeConfig.ConfigFile), + }) + } + flags := []string{} + for _, f := range files { + flags = append(flags, fmt.Sprintf("--%s=%s", f.pathKey, f.flagValue)) + if err := createFileAndWrite(f.path, f.contents); err != nil { + return nil, fmt.Errorf("couldn't write file at %q: %w", f.path, err) + } + } + if nodeConfig.ChainConfigFiles != nil { + // only one flag and multiple files + chainConfigDir := filepath.Join(nodeRootDir, chainConfigSubDir) + flags = append(flags, fmt.Sprintf("--%s=%s", config.ChainConfigDirKey, chainConfigDir)) + for chainAlias, chainConfigFile := range nodeConfig.ChainConfigFiles { + chainConfigPath := filepath.Join(chainConfigDir, chainAlias, configFileName) + if err := createFileAndWrite(chainConfigPath, []byte(chainConfigFile)); err != nil { + return nil, fmt.Errorf("couldn't write file at %q: %w", chainConfigPath, err) + } + } + } + return flags, nil +} + +// getConfigEntry returns an entry in the config file if it is found, otherwise returns the default value +func getConfigEntry( + nodeConfigFlags map[string]interface{}, + configFile map[string]interface{}, + flag string, + defaultVal string, +) (string, error) { + var entry string + if val, ok := nodeConfigFlags[flag]; ok { + if entry, ok := val.(string); ok { + return entry, nil + } + return "", fmt.Errorf("expected node config flag %q to be string but got %T", flag, entry) + } + if val, ok := configFile[flag]; ok { + if entry, ok := val.(string); ok { + return entry, nil + } + return "", fmt.Errorf("expected config file flag %q to be string but got %T", flag, entry) + } + return defaultVal, nil +} + +// getPort looks up the port config in the config file, if there is none, it tries to get a random free port from the OS +func getPort( + flags map[string]interface{}, + configFile map[string]interface{}, + portKey string, +) (port uint16, err error) { + if portIntf, ok := flags[portKey]; ok { + if portFromFlags, ok := portIntf.(int); ok { + port = uint16(portFromFlags) + } else if portFromFlags, ok := portIntf.(float64); ok { + port = uint16(portFromFlags) + } else { + return 0, fmt.Errorf("expected flag %q to be int/float64 but got %T", portKey, portIntf) + } + } else if portIntf, ok := configFile[portKey]; ok { + if portFromConfigFile, ok := portIntf.(float64); ok { + port = uint16(portFromConfigFile) + } else { + return 0, fmt.Errorf("expected flag %q to be float64 but got %T", portKey, portIntf) + } + } else { + // Use a random free port. + // Note: it is possible but unlikely for getFreePort to return the same port multiple times. + port, err = getFreePort() + if err != nil { + return 0, fmt.Errorf("couldn't get free API port: %w", err) + } + } + return port, nil +} + +func makeNodeDir(log logging.Logger, rootDir, nodeName string) (string, error) { + if rootDir == "" { + log.Warn("no network root directory defined; will create this node's runtime directory in working directory") + } + // [nodeRootDir] is where this node's config file, C-Chain config file, + // staking key, staking certificate and genesis file will be written. + // (Other file locations are given in the node's config file.) + // TODO should we do this for other directories? Profiles? + nodeRootDir := filepath.Join(rootDir, nodeName) + if err := os.Mkdir(nodeRootDir, 0o755); err != nil { + if os.IsExist(err) { + log.Warn("node root directory %s already exists", nodeRootDir) + } else { + return "", fmt.Errorf("error creating temp dir: %w", err) + } + } + return nodeRootDir, nil +} + +// createFileAndWrite creates a file with the given path and +// writes the given contents +func createFileAndWrite(path string, contents []byte) error { + if err := os.MkdirAll(filepath.Dir(path), 0o750); err != nil { + return err + } + file, err := os.Create(path) + if err != nil { + return err + } + defer func() { + _ = file.Close() + }() + if _, err := file.Write(contents); err != nil { + return err + } + return nil +} + +// addNetworkFlags adds the flags in [networkFlags] to [nodeConfig.Flags]. +// [nodeFlags] must not be nil. +func addNetworkFlags(log logging.Logger, networkFlags map[string]interface{}, nodeFlags map[string]interface{}) { + for flagName, flagVal := range networkFlags { + // If the same flag is given in network config and node config, + // the flag in the node config takes precedence + if val, ok := nodeFlags[flagName]; !ok { + nodeFlags[flagName] = flagVal + } else { + log.Info( + "not overwriting node config flag %s (value %v) with network config flag (value %v)", + flagName, val, flagVal, + ) + } + } +} diff --git a/local/network.go b/local/network.go index d0ff2385..504a0fa9 100644 --- a/local/network.go +++ b/local/network.go @@ -6,14 +6,11 @@ import ( "encoding/json" "errors" "fmt" - "io" "io/fs" "net" "os" - "os/exec" "os/user" "path/filepath" - "strings" "sync" "time" @@ -26,11 +23,9 @@ import ( "github.com/ava-labs/avalanchego/network/peer" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils/beacon" - "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/wrappers" - dircopy "github.com/otiai10/copy" "go.uber.org/zap" "golang.org/x/sync/errgroup" ) @@ -200,52 +195,6 @@ func init() { defaultSnapshotsDir = filepath.Join(usr.HomeDir, snapshotsRelPath) } -// NodeProcessCreator is an interface for new node process creation -type NodeProcessCreator interface { - NewNodeProcess(config node.Config, log logging.Logger, args ...string) (NodeProcess, error) -} - -type nodeProcessCreator struct { - log logging.Logger - // If this node's stdout or stderr are redirected, [colorPicker] determines - // the color of logs printed to stdout and/or stderr - colorPicker utils.ColorPicker - // If this node's stdout is redirected, it will be to here. - // In practice this is usually os.Stdout, but for testing can be replaced. - stdout io.Writer - // If this node's stderr is redirected, it will be to here. - // In practice this is usually os.Stderr, but for testing can be replaced. - stderr io.Writer -} - -// NewNodeProcess creates a new process of the passed binary -// If the config has redirection set to `true` for either StdErr or StdOut, -// the output will be redirected and colored -func (npc *nodeProcessCreator) NewNodeProcess(config node.Config, log logging.Logger, args ...string) (NodeProcess, error) { - // Start the AvalancheGo node and pass it the flags defined above - cmd := exec.Command(config.BinaryPath, args...) - // assign a new color to this process (might not be used if the config isn't set for it) - color := npc.colorPicker.NextColor() - // Optionally redirect stdout and stderr - if config.RedirectStdout { - stdout, err := cmd.StdoutPipe() - if err != nil { - return nil, fmt.Errorf("couldn't create stdout pipe: %s", err) - } - // redirect stdout and assign a color to the text - utils.ColorAndPrepend(stdout, npc.stdout, config.Name, color) - } - if config.RedirectStderr { - stderr, err := cmd.StderrPipe() - if err != nil { - return nil, fmt.Errorf("couldn't create stderr pipe: %s", err) - } - // redirect stderr and assign a color to the text - utils.ColorAndPrepend(stderr, npc.stderr, config.Name, color) - } - return newNodeProcess(config.Name, npc.log, cmd) -} - // NewNetwork returns a new network that uses the given log. // Files (e.g. logs, databases) default to being written at directory [rootDir]. // If there isn't a directory at [dir] one will be created. @@ -316,35 +265,6 @@ func newNetwork( return net, nil } -// NewNetwork returns a new network from the given snapshot -func NewNetworkFromSnapshot( - log logging.Logger, - snapshotName string, - rootDir string, - snapshotsDir string, - binaryPath string, - buildDir string, - chainConfigs map[string]string, - flags map[string]interface{}, -) (network.Network, error) { - net, err := newNetwork( - log, - api.NewAPIClient, - &nodeProcessCreator{ - colorPicker: utils.NewColorPicker(), - stdout: os.Stdout, - stderr: os.Stderr, - }, - rootDir, - snapshotsDir, - ) - if err != nil { - return net, err - } - err = net.loadSnapshot(context.Background(), snapshotName, binaryPath, buildDir, chainConfigs, flags) - return net, err -} - // NewDefaultNetwork returns a new network using a pre-defined // network configuration. // The following addresses are pre-funded: @@ -713,210 +633,6 @@ func (ln *localNetwork) removeNode(ctx context.Context, nodeName string) error { return nil } -// Save network snapshot -// Network is stopped in order to do a safe preservation -func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) (string, error) { - ln.lock.Lock() - defer ln.lock.Unlock() - if ln.stopCalled() { - return "", network.ErrStopped - } - if len(snapshotName) == 0 { - return "", fmt.Errorf("invalid snapshotName %q", snapshotName) - } - // check if snapshot already exists - snapshotDir := filepath.Join(ln.snapshotsDir, snapshotPrefix+snapshotName) - _, err := os.Stat(snapshotDir) - if err == nil { - return "", fmt.Errorf("snapshot %q already exists", snapshotName) - } - // keep copy of node info that will be removed by stop - nodesConfig := map[string]node.Config{} - nodesDbDir := map[string]string{} - for nodeName, node := range ln.nodes { - nodeConfig := node.config - // depending on how the user generated the config, different nodes config flags - // may point to the same map, so we made a copy to avoid always modifying the same value - nodeConfigFlags := make(map[string]interface{}) - for fk, fv := range nodeConfig.Flags { - nodeConfigFlags[fk] = fv - } - nodeConfig.Flags = nodeConfigFlags - nodesConfig[nodeName] = nodeConfig - nodesDbDir[nodeName] = node.GetDbDir() - } - // we change nodeConfig.Flags so as to preserve in snapshot the current node ports - for nodeName, nodeConfig := range nodesConfig { - nodeConfig.Flags[config.HTTPPortKey] = ln.nodes[nodeName].GetAPIPort() - nodeConfig.Flags[config.StakingPortKey] = ln.nodes[nodeName].GetP2PPort() - } - // make copy of network flags - networkConfigFlags := make(map[string]interface{}) - for fk, fv := range ln.flags { - networkConfigFlags[fk] = fv - } - // remove all log dir references - delete(networkConfigFlags, config.LogsDirKey) - for nodeName, nodeConfig := range nodesConfig { - nodeConfig.ConfigFile, err = utils.SetJSONKey(nodeConfig.ConfigFile, config.LogsDirKey, "") - if err != nil { - return "", err - } - delete(nodeConfig.Flags, config.LogsDirKey) - nodesConfig[nodeName] = nodeConfig - } - - // stop network to safely save snapshot - if err := ln.stop(ctx); err != nil { - return "", err - } - // create main snapshot dirs - snapshotDbDir := filepath.Join(filepath.Join(snapshotDir, defaultDbSubdir)) - err = os.MkdirAll(snapshotDbDir, os.ModePerm) - if err != nil { - return "", err - } - // save db - for _, nodeConfig := range nodesConfig { - sourceDbDir, ok := nodesDbDir[nodeConfig.Name] - if !ok { - return "", fmt.Errorf("failure obtaining db path for node %q", nodeConfig.Name) - } - sourceDbDir = filepath.Join(sourceDbDir, constants.NetworkName(ln.networkID)) - targetDbDir := filepath.Join(filepath.Join(snapshotDbDir, nodeConfig.Name), constants.NetworkName(ln.networkID)) - if err := dircopy.Copy(sourceDbDir, targetDbDir); err != nil { - return "", fmt.Errorf("failure saving node %q db dir: %w", nodeConfig.Name, err) - } - } - // save network conf - networkConfig := network.Config{ - Genesis: string(ln.genesis), - Flags: networkConfigFlags, - NodeConfigs: []node.Config{}, - } - for _, nodeConfig := range nodesConfig { - // no need to save this, will be generated automatically on snapshot load - networkConfig.NodeConfigs = append(networkConfig.NodeConfigs, nodeConfig) - } - networkConfigJSON, err := json.MarshalIndent(networkConfig, "", " ") - if err != nil { - return "", err - } - err = createFileAndWrite(filepath.Join(snapshotDir, "network.json"), networkConfigJSON) - if err != nil { - return "", err - } - return snapshotDir, nil -} - -// start network from snapshot -func (ln *localNetwork) loadSnapshot( - ctx context.Context, - snapshotName string, - binaryPath string, - buildDir string, - chainConfigs map[string]string, - flags map[string]interface{}, -) error { - ln.lock.Lock() - defer ln.lock.Unlock() - snapshotDir := filepath.Join(ln.snapshotsDir, snapshotPrefix+snapshotName) - snapshotDbDir := filepath.Join(filepath.Join(snapshotDir, defaultDbSubdir)) - _, err := os.Stat(snapshotDir) - if err != nil { - if errors.Is(err, os.ErrNotExist) { - return ErrSnapshotNotFound - } else { - return fmt.Errorf("failure accessing snapshot %q: %w", snapshotName, err) - } - } - // load network config - networkConfigJSON, err := os.ReadFile(filepath.Join(snapshotDir, "network.json")) - if err != nil { - return fmt.Errorf("failure reading network config file from snapshot: %w", err) - } - networkConfig := network.Config{} - err = json.Unmarshal(networkConfigJSON, &networkConfig) - if err != nil { - return fmt.Errorf("failure unmarshaling network config from snapshot: %w", err) - } - // add flags - for i := range networkConfig.NodeConfigs { - for k, v := range flags { - networkConfig.NodeConfigs[i].Flags[k] = v - } - } - // load db - for _, nodeConfig := range networkConfig.NodeConfigs { - sourceDbDir := filepath.Join(snapshotDbDir, nodeConfig.Name) - targetDbDir := filepath.Join(filepath.Join(ln.rootDir, nodeConfig.Name), defaultDbSubdir) - if err := dircopy.Copy(sourceDbDir, targetDbDir); err != nil { - return fmt.Errorf("failure loading node %q db dir: %w", nodeConfig.Name, err) - } - nodeConfig.Flags[config.DBPathKey] = targetDbDir - } - // replace binary path - if binaryPath != "" { - for i := range networkConfig.NodeConfigs { - networkConfig.NodeConfigs[i].BinaryPath = binaryPath - } - } - // replace build dir - if buildDir != "" { - for i := range networkConfig.NodeConfigs { - networkConfig.NodeConfigs[i].Flags[config.BuildDirKey] = buildDir - } - } - // add chain configs - for i := range networkConfig.NodeConfigs { - if networkConfig.NodeConfigs[i].ChainConfigFiles == nil { - networkConfig.NodeConfigs[i].ChainConfigFiles = map[string]string{} - } - for k, v := range chainConfigs { - networkConfig.NodeConfigs[i].ChainConfigFiles[k] = v - } - } - return ln.loadConfig(ctx, networkConfig) -} - -// Remove network snapshot -func (ln *localNetwork) RemoveSnapshot(snapshotName string) error { - snapshotDir := filepath.Join(ln.snapshotsDir, snapshotPrefix+snapshotName) - _, err := os.Stat(snapshotDir) - if err != nil { - if errors.Is(err, os.ErrNotExist) { - return ErrSnapshotNotFound - } else { - return fmt.Errorf("failure accessing snapshot %q: %w", snapshotName, err) - } - } - if err := os.RemoveAll(snapshotDir); err != nil { - return fmt.Errorf("failure removing snapshot path %q: %w", snapshotDir, err) - } - return nil -} - -// Get network snapshots -func (ln *localNetwork) GetSnapshotNames() ([]string, error) { - _, err := os.Stat(ln.snapshotsDir) - if err != nil { - if errors.Is(err, os.ErrNotExist) { - return nil, fmt.Errorf("snapshots dir %q does not exists", ln.snapshotsDir) - } else { - return nil, fmt.Errorf("failure accessing snapshots dir %q: %w", ln.snapshotsDir, err) - } - } - matches, err := filepath.Glob(filepath.Join(ln.snapshotsDir, snapshotPrefix+"*")) - if err != nil { - return nil, err - } - snapshots := []string{} - for _, match := range matches { - snapshots = append(snapshots, strings.TrimPrefix(filepath.Base(match), snapshotPrefix)) - } - return snapshots, nil -} - // Returns whether Stop has been called. func (ln *localNetwork) stopCalled() bool { select { @@ -927,42 +643,6 @@ func (ln *localNetwork) stopCalled() bool { } } -// createFileAndWrite creates a file with the given path and -// writes the given contents -func createFileAndWrite(path string, contents []byte) error { - if err := os.MkdirAll(filepath.Dir(path), 0o750); err != nil { - return err - } - file, err := os.Create(path) - if err != nil { - return err - } - defer func() { - _ = file.Close() - }() - if _, err := file.Write(contents); err != nil { - return err - } - return nil -} - -// addNetworkFlags adds the flags in [networkFlags] to [nodeConfig.Flags]. -// [nodeFlags] must not be nil. -func addNetworkFlags(log logging.Logger, networkFlags map[string]interface{}, nodeFlags map[string]interface{}) { - for flagName, flagVal := range networkFlags { - // If the same flag is given in network config and node config, - // the flag in the node config takes precedence - if val, ok := nodeFlags[flagName]; !ok { - nodeFlags[flagName] = flagVal - } else { - log.Info( - "not overwriting node config flag %s (value %v) with network config flag (value %v)", - flagName, val, flagVal, - ) - } - } -} - // Set [nodeConfig].Name if it isn't given and assert it's unique. func (ln *localNetwork) setNodeName(nodeConfig *node.Config) error { // If no name was given, use default name pattern @@ -983,79 +663,6 @@ func (ln *localNetwork) setNodeName(nodeConfig *node.Config) error { return nil } -func makeNodeDir(log logging.Logger, rootDir, nodeName string) (string, error) { - if rootDir == "" { - log.Warn("no network root directory defined; will create this node's runtime directory in working directory") - } - // [nodeRootDir] is where this node's config file, C-Chain config file, - // staking key, staking certificate and genesis file will be written. - // (Other file locations are given in the node's config file.) - // TODO should we do this for other directories? Profiles? - nodeRootDir := filepath.Join(rootDir, nodeName) - if err := os.Mkdir(nodeRootDir, 0o755); err != nil { - if os.IsExist(err) { - log.Warn("node root directory %s already exists", nodeRootDir) - } else { - return "", fmt.Errorf("error creating temp dir: %w", err) - } - } - return nodeRootDir, nil -} - -// getConfigEntry returns an entry in the config file if it is found, otherwise returns the default value -func getConfigEntry( - nodeConfigFlags map[string]interface{}, - configFile map[string]interface{}, - flag string, - defaultVal string, -) (string, error) { - var entry string - if val, ok := nodeConfigFlags[flag]; ok { - if entry, ok := val.(string); ok { - return entry, nil - } - return "", fmt.Errorf("expected node config flag %q to be string but got %T", flag, entry) - } - if val, ok := configFile[flag]; ok { - if entry, ok := val.(string); ok { - return entry, nil - } - return "", fmt.Errorf("expected config file flag %q to be string but got %T", flag, entry) - } - return defaultVal, nil -} - -// getPort looks up the port config in the config file, if there is none, it tries to get a random free port from the OS -func getPort( - flags map[string]interface{}, - configFile map[string]interface{}, - portKey string, -) (port uint16, err error) { - if portIntf, ok := flags[portKey]; ok { - if portFromFlags, ok := portIntf.(int); ok { - port = uint16(portFromFlags) - } else if portFromFlags, ok := portIntf.(float64); ok { - port = uint16(portFromFlags) - } else { - return 0, fmt.Errorf("expected flag %q to be int/float64 but got %T", portKey, portIntf) - } - } else if portIntf, ok := configFile[portKey]; ok { - if portFromConfigFile, ok := portIntf.(float64); ok { - port = uint16(portFromConfigFile) - } else { - return 0, fmt.Errorf("expected flag %q to be float64 but got %T", portKey, portIntf) - } - } else { - // Use a random free port. - // Note: it is possible but unlikely for getFreePort to return the same port multiple times. - port, err = getFreePort() - if err != nil { - return 0, fmt.Errorf("couldn't get free API port: %w", err) - } - } - return port, nil -} - type buildFlagsReturn struct { flags []string apiPort uint16 @@ -1160,61 +767,3 @@ func (ln *localNetwork) buildFlags( httpHost: httpHost, }, nil } - -// writeFiles writes the files a node needs on startup. -// It returns flags used to point to those files. -func writeFiles(genesis []byte, nodeRootDir string, nodeConfig *node.Config) ([]string, error) { - type file struct { - pathKey string - flagValue string - path string - contents []byte - } - files := []file{ - { - flagValue: filepath.Join(nodeRootDir, stakingKeyFileName), - path: filepath.Join(nodeRootDir, stakingKeyFileName), - pathKey: config.StakingKeyPathKey, - contents: []byte(nodeConfig.StakingKey), - }, - { - flagValue: filepath.Join(nodeRootDir, stakingCertFileName), - path: filepath.Join(nodeRootDir, stakingCertFileName), - pathKey: config.StakingCertPathKey, - contents: []byte(nodeConfig.StakingCert), - }, - { - flagValue: filepath.Join(nodeRootDir, genesisFileName), - path: filepath.Join(nodeRootDir, genesisFileName), - pathKey: config.GenesisConfigFileKey, - contents: genesis, - }, - } - if len(nodeConfig.ConfigFile) != 0 { - files = append(files, file{ - flagValue: filepath.Join(nodeRootDir, configFileName), - path: filepath.Join(nodeRootDir, configFileName), - pathKey: config.ConfigFileKey, - contents: []byte(nodeConfig.ConfigFile), - }) - } - flags := []string{} - for _, f := range files { - flags = append(flags, fmt.Sprintf("--%s=%s", f.pathKey, f.flagValue)) - if err := createFileAndWrite(f.path, f.contents); err != nil { - return nil, fmt.Errorf("couldn't write file at %q: %w", f.path, err) - } - } - if nodeConfig.ChainConfigFiles != nil { - // only one flag and multiple files - chainConfigDir := filepath.Join(nodeRootDir, chainConfigSubDir) - flags = append(flags, fmt.Sprintf("--%s=%s", config.ChainConfigDirKey, chainConfigDir)) - for chainAlias, chainConfigFile := range nodeConfig.ChainConfigFiles { - chainConfigPath := filepath.Join(chainConfigDir, chainAlias, configFileName) - if err := createFileAndWrite(chainConfigPath, []byte(chainConfigFile)); err != nil { - return nil, fmt.Errorf("couldn't write file at %q: %w", chainConfigPath, err) - } - } - } - return flags, nil -} diff --git a/local/node_process.go b/local/node_process.go index 9e5775b5..a51be259 100644 --- a/local/node_process.go +++ b/local/node_process.go @@ -3,11 +3,14 @@ package local import ( "context" "fmt" + "io" "os" "os/exec" "sync" + "github.com/ava-labs/avalanche-network-runner/network/node" "github.com/ava-labs/avalanche-network-runner/network/node/status" + "github.com/ava-labs/avalanche-network-runner/utils" "github.com/ava-labs/avalanchego/utils/logging" "github.com/shirou/gopsutil/process" ) @@ -27,6 +30,52 @@ type NodeProcess interface { Status() status.Status } +// NodeProcessCreator is an interface for new node process creation +type NodeProcessCreator interface { + NewNodeProcess(config node.Config, log logging.Logger, args ...string) (NodeProcess, error) +} + +type nodeProcessCreator struct { + log logging.Logger + // If this node's stdout or stderr are redirected, [colorPicker] determines + // the color of logs printed to stdout and/or stderr + colorPicker utils.ColorPicker + // If this node's stdout is redirected, it will be to here. + // In practice this is usually os.Stdout, but for testing can be replaced. + stdout io.Writer + // If this node's stderr is redirected, it will be to here. + // In practice this is usually os.Stderr, but for testing can be replaced. + stderr io.Writer +} + +// NewNodeProcess creates a new process of the passed binary +// If the config has redirection set to `true` for either StdErr or StdOut, +// the output will be redirected and colored +func (npc *nodeProcessCreator) NewNodeProcess(config node.Config, log logging.Logger, args ...string) (NodeProcess, error) { + // Start the AvalancheGo node and pass it the flags defined above + cmd := exec.Command(config.BinaryPath, args...) + // assign a new color to this process (might not be used if the config isn't set for it) + color := npc.colorPicker.NextColor() + // Optionally redirect stdout and stderr + if config.RedirectStdout { + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, fmt.Errorf("couldn't create stdout pipe: %s", err) + } + // redirect stdout and assign a color to the text + utils.ColorAndPrepend(stdout, npc.stdout, config.Name, color) + } + if config.RedirectStderr { + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, fmt.Errorf("couldn't create stderr pipe: %s", err) + } + // redirect stderr and assign a color to the text + utils.ColorAndPrepend(stderr, npc.stderr, config.Name, color) + } + return newNodeProcess(config.Name, npc.log, cmd) +} + type nodeProcess struct { name string log logging.Logger @@ -125,7 +174,6 @@ func (p *nodeProcess) Stop(ctx context.Context) int { defer p.lock.RUnlock() return p.cmd.ProcessState.ExitCode() - } func (p *nodeProcess) Status() status.Status { diff --git a/local/snapshot.go b/local/snapshot.go new file mode 100644 index 00000000..c10e9678 --- /dev/null +++ b/local/snapshot.go @@ -0,0 +1,253 @@ +package local + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/ava-labs/avalanche-network-runner/api" + "github.com/ava-labs/avalanche-network-runner/network" + "github.com/ava-labs/avalanche-network-runner/network/node" + "github.com/ava-labs/avalanche-network-runner/utils" + "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" + dircopy "github.com/otiai10/copy" +) + +// NewNetwork returns a new network from the given snapshot +func NewNetworkFromSnapshot( + log logging.Logger, + snapshotName string, + rootDir string, + snapshotsDir string, + binaryPath string, + buildDir string, + chainConfigs map[string]string, + flags map[string]interface{}, +) (network.Network, error) { + net, err := newNetwork( + log, + api.NewAPIClient, + &nodeProcessCreator{ + colorPicker: utils.NewColorPicker(), + stdout: os.Stdout, + stderr: os.Stderr, + }, + rootDir, + snapshotsDir, + ) + if err != nil { + return net, err + } + err = net.loadSnapshot(context.Background(), snapshotName, binaryPath, buildDir, chainConfigs, flags) + return net, err +} + +// Save network snapshot +// Network is stopped in order to do a safe preservation +func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) (string, error) { + ln.lock.Lock() + defer ln.lock.Unlock() + if ln.stopCalled() { + return "", network.ErrStopped + } + if len(snapshotName) == 0 { + return "", fmt.Errorf("invalid snapshotName %q", snapshotName) + } + // check if snapshot already exists + snapshotDir := filepath.Join(ln.snapshotsDir, snapshotPrefix+snapshotName) + _, err := os.Stat(snapshotDir) + if err == nil { + return "", fmt.Errorf("snapshot %q already exists", snapshotName) + } + // keep copy of node info that will be removed by stop + nodesConfig := map[string]node.Config{} + nodesDbDir := map[string]string{} + for nodeName, node := range ln.nodes { + nodeConfig := node.config + // depending on how the user generated the config, different nodes config flags + // may point to the same map, so we made a copy to avoid always modifying the same value + nodeConfigFlags := make(map[string]interface{}) + for fk, fv := range nodeConfig.Flags { + nodeConfigFlags[fk] = fv + } + nodeConfig.Flags = nodeConfigFlags + nodesConfig[nodeName] = nodeConfig + nodesDbDir[nodeName] = node.GetDbDir() + } + // we change nodeConfig.Flags so as to preserve in snapshot the current node ports + for nodeName, nodeConfig := range nodesConfig { + nodeConfig.Flags[config.HTTPPortKey] = ln.nodes[nodeName].GetAPIPort() + nodeConfig.Flags[config.StakingPortKey] = ln.nodes[nodeName].GetP2PPort() + } + // make copy of network flags + networkConfigFlags := make(map[string]interface{}) + for fk, fv := range ln.flags { + networkConfigFlags[fk] = fv + } + // remove all log dir references + delete(networkConfigFlags, config.LogsDirKey) + for nodeName, nodeConfig := range nodesConfig { + nodeConfig.ConfigFile, err = utils.SetJSONKey(nodeConfig.ConfigFile, config.LogsDirKey, "") + if err != nil { + return "", err + } + delete(nodeConfig.Flags, config.LogsDirKey) + nodesConfig[nodeName] = nodeConfig + } + + // stop network to safely save snapshot + if err := ln.stop(ctx); err != nil { + return "", err + } + // create main snapshot dirs + snapshotDbDir := filepath.Join(filepath.Join(snapshotDir, defaultDbSubdir)) + err = os.MkdirAll(snapshotDbDir, os.ModePerm) + if err != nil { + return "", err + } + // save db + for _, nodeConfig := range nodesConfig { + sourceDbDir, ok := nodesDbDir[nodeConfig.Name] + if !ok { + return "", fmt.Errorf("failure obtaining db path for node %q", nodeConfig.Name) + } + sourceDbDir = filepath.Join(sourceDbDir, constants.NetworkName(ln.networkID)) + targetDbDir := filepath.Join(filepath.Join(snapshotDbDir, nodeConfig.Name), constants.NetworkName(ln.networkID)) + if err := dircopy.Copy(sourceDbDir, targetDbDir); err != nil { + return "", fmt.Errorf("failure saving node %q db dir: %w", nodeConfig.Name, err) + } + } + // save network conf + networkConfig := network.Config{ + Genesis: string(ln.genesis), + Flags: networkConfigFlags, + NodeConfigs: []node.Config{}, + } + for _, nodeConfig := range nodesConfig { + // no need to save this, will be generated automatically on snapshot load + networkConfig.NodeConfigs = append(networkConfig.NodeConfigs, nodeConfig) + } + networkConfigJSON, err := json.MarshalIndent(networkConfig, "", " ") + if err != nil { + return "", err + } + err = createFileAndWrite(filepath.Join(snapshotDir, "network.json"), networkConfigJSON) + if err != nil { + return "", err + } + return snapshotDir, nil +} + +// start network from snapshot +func (ln *localNetwork) loadSnapshot( + ctx context.Context, + snapshotName string, + binaryPath string, + buildDir string, + chainConfigs map[string]string, + flags map[string]interface{}, +) error { + ln.lock.Lock() + defer ln.lock.Unlock() + snapshotDir := filepath.Join(ln.snapshotsDir, snapshotPrefix+snapshotName) + snapshotDbDir := filepath.Join(filepath.Join(snapshotDir, defaultDbSubdir)) + _, err := os.Stat(snapshotDir) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return ErrSnapshotNotFound + } else { + return fmt.Errorf("failure accessing snapshot %q: %w", snapshotName, err) + } + } + // load network config + networkConfigJSON, err := os.ReadFile(filepath.Join(snapshotDir, "network.json")) + if err != nil { + return fmt.Errorf("failure reading network config file from snapshot: %w", err) + } + networkConfig := network.Config{} + err = json.Unmarshal(networkConfigJSON, &networkConfig) + if err != nil { + return fmt.Errorf("failure unmarshaling network config from snapshot: %w", err) + } + // add flags + for i := range networkConfig.NodeConfigs { + for k, v := range flags { + networkConfig.NodeConfigs[i].Flags[k] = v + } + } + // load db + for _, nodeConfig := range networkConfig.NodeConfigs { + sourceDbDir := filepath.Join(snapshotDbDir, nodeConfig.Name) + targetDbDir := filepath.Join(filepath.Join(ln.rootDir, nodeConfig.Name), defaultDbSubdir) + if err := dircopy.Copy(sourceDbDir, targetDbDir); err != nil { + return fmt.Errorf("failure loading node %q db dir: %w", nodeConfig.Name, err) + } + nodeConfig.Flags[config.DBPathKey] = targetDbDir + } + // replace binary path + if binaryPath != "" { + for i := range networkConfig.NodeConfigs { + networkConfig.NodeConfigs[i].BinaryPath = binaryPath + } + } + // replace build dir + if buildDir != "" { + for i := range networkConfig.NodeConfigs { + networkConfig.NodeConfigs[i].Flags[config.BuildDirKey] = buildDir + } + } + // add chain configs + for i := range networkConfig.NodeConfigs { + if networkConfig.NodeConfigs[i].ChainConfigFiles == nil { + networkConfig.NodeConfigs[i].ChainConfigFiles = map[string]string{} + } + for k, v := range chainConfigs { + networkConfig.NodeConfigs[i].ChainConfigFiles[k] = v + } + } + return ln.loadConfig(ctx, networkConfig) +} + +// Remove network snapshot +func (ln *localNetwork) RemoveSnapshot(snapshotName string) error { + snapshotDir := filepath.Join(ln.snapshotsDir, snapshotPrefix+snapshotName) + _, err := os.Stat(snapshotDir) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return ErrSnapshotNotFound + } else { + return fmt.Errorf("failure accessing snapshot %q: %w", snapshotName, err) + } + } + if err := os.RemoveAll(snapshotDir); err != nil { + return fmt.Errorf("failure removing snapshot path %q: %w", snapshotDir, err) + } + return nil +} + +// Get network snapshots +func (ln *localNetwork) GetSnapshotNames() ([]string, error) { + _, err := os.Stat(ln.snapshotsDir) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("snapshots dir %q does not exists", ln.snapshotsDir) + } else { + return nil, fmt.Errorf("failure accessing snapshots dir %q: %w", ln.snapshotsDir, err) + } + } + matches, err := filepath.Glob(filepath.Join(ln.snapshotsDir, snapshotPrefix+"*")) + if err != nil { + return nil, err + } + snapshots := []string{} + for _, match := range matches { + snapshots = append(snapshots, strings.TrimPrefix(filepath.Base(match), snapshotPrefix)) + } + return snapshots, nil +} From 9075504f27c82bc7f7674ee2a2b5eddbf8d8e6df Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Wed, 3 Aug 2022 09:31:23 -0500 Subject: [PATCH 17/36] fixed conflicts --- local/node_process.go | 4 ++-- local/snapshot.go | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/local/node_process.go b/local/node_process.go index a51be259..4c9788a1 100644 --- a/local/node_process.go +++ b/local/node_process.go @@ -32,7 +32,7 @@ type NodeProcess interface { // NodeProcessCreator is an interface for new node process creation type NodeProcessCreator interface { - NewNodeProcess(config node.Config, log logging.Logger, args ...string) (NodeProcess, error) + NewNodeProcess(config node.Config, args ...string) (NodeProcess, error) } type nodeProcessCreator struct { @@ -51,7 +51,7 @@ type nodeProcessCreator struct { // NewNodeProcess creates a new process of the passed binary // If the config has redirection set to `true` for either StdErr or StdOut, // the output will be redirected and colored -func (npc *nodeProcessCreator) NewNodeProcess(config node.Config, log logging.Logger, args ...string) (NodeProcess, error) { +func (npc *nodeProcessCreator) NewNodeProcess(config node.Config, args ...string) (NodeProcess, error) { // Start the AvalancheGo node and pass it the flags defined above cmd := exec.Command(config.BinaryPath, args...) // assign a new color to this process (might not be used if the config isn't set for it) diff --git a/local/snapshot.go b/local/snapshot.go index c10e9678..88cec678 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -35,6 +35,7 @@ func NewNetworkFromSnapshot( api.NewAPIClient, &nodeProcessCreator{ colorPicker: utils.NewColorPicker(), + log: log, stdout: os.Stdout, stderr: os.Stderr, }, From bbbdb212bff69ce63273fc27766fa3c7f9abccec Mon Sep 17 00:00:00 2001 From: Fabio Barone Date: Wed, 3 Aug 2022 09:42:32 -0500 Subject: [PATCH 18/36] finally resolved conflict --- local/network.go | 207 ----------------------------------------------- 1 file changed, 207 deletions(-) diff --git a/local/network.go b/local/network.go index 1032a7db..eab07b65 100644 --- a/local/network.go +++ b/local/network.go @@ -633,8 +633,6 @@ func (ln *localNetwork) removeNode(ctx context.Context, nodeName string) error { return nil } -<<<<<<< HEAD -======= // Restart [nodeName] using the same config, optionally changing [binaryPath], // [buildDir], [whitelistedSubnets], [dbDir] func (ln *localNetwork) RestartNode( @@ -678,211 +676,6 @@ func (ln *localNetwork) RestartNode( return nil } -// Save network snapshot -// Network is stopped in order to do a safe preservation -func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) (string, error) { - ln.lock.Lock() - defer ln.lock.Unlock() - if ln.stopCalled() { - return "", network.ErrStopped - } - if len(snapshotName) == 0 { - return "", fmt.Errorf("invalid snapshotName %q", snapshotName) - } - // check if snapshot already exists - snapshotDir := filepath.Join(ln.snapshotsDir, snapshotPrefix+snapshotName) - _, err := os.Stat(snapshotDir) - if err == nil { - return "", fmt.Errorf("snapshot %q already exists", snapshotName) - } - // keep copy of node info that will be removed by stop - nodesConfig := map[string]node.Config{} - nodesDbDir := map[string]string{} - for nodeName, node := range ln.nodes { - nodeConfig := node.config - // depending on how the user generated the config, different nodes config flags - // may point to the same map, so we made a copy to avoid always modifying the same value - nodeConfigFlags := make(map[string]interface{}) - for fk, fv := range nodeConfig.Flags { - nodeConfigFlags[fk] = fv - } - nodeConfig.Flags = nodeConfigFlags - nodesConfig[nodeName] = nodeConfig - nodesDbDir[nodeName] = node.GetDbDir() - } - // we change nodeConfig.Flags so as to preserve in snapshot the current node ports - for nodeName, nodeConfig := range nodesConfig { - nodeConfig.Flags[config.HTTPPortKey] = ln.nodes[nodeName].GetAPIPort() - nodeConfig.Flags[config.StakingPortKey] = ln.nodes[nodeName].GetP2PPort() - } - // make copy of network flags - networkConfigFlags := make(map[string]interface{}) - for fk, fv := range ln.flags { - networkConfigFlags[fk] = fv - } - // remove all log dir references - delete(networkConfigFlags, config.LogsDirKey) - for nodeName, nodeConfig := range nodesConfig { - nodeConfig.ConfigFile, err = utils.SetJSONKey(nodeConfig.ConfigFile, config.LogsDirKey, "") - if err != nil { - return "", err - } - delete(nodeConfig.Flags, config.LogsDirKey) - nodesConfig[nodeName] = nodeConfig - } - - // stop network to safely save snapshot - if err := ln.stop(ctx); err != nil { - return "", err - } - // create main snapshot dirs - snapshotDbDir := filepath.Join(filepath.Join(snapshotDir, defaultDbSubdir)) - err = os.MkdirAll(snapshotDbDir, os.ModePerm) - if err != nil { - return "", err - } - // save db - for _, nodeConfig := range nodesConfig { - sourceDbDir, ok := nodesDbDir[nodeConfig.Name] - if !ok { - return "", fmt.Errorf("failure obtaining db path for node %q", nodeConfig.Name) - } - sourceDbDir = filepath.Join(sourceDbDir, constants.NetworkName(ln.networkID)) - targetDbDir := filepath.Join(filepath.Join(snapshotDbDir, nodeConfig.Name), constants.NetworkName(ln.networkID)) - if err := dircopy.Copy(sourceDbDir, targetDbDir); err != nil { - return "", fmt.Errorf("failure saving node %q db dir: %w", nodeConfig.Name, err) - } - } - // save network conf - networkConfig := network.Config{ - Genesis: string(ln.genesis), - Flags: networkConfigFlags, - NodeConfigs: []node.Config{}, - } - for _, nodeConfig := range nodesConfig { - // no need to save this, will be generated automatically on snapshot load - networkConfig.NodeConfigs = append(networkConfig.NodeConfigs, nodeConfig) - } - networkConfigJSON, err := json.MarshalIndent(networkConfig, "", " ") - if err != nil { - return "", err - } - err = createFileAndWrite(filepath.Join(snapshotDir, "network.json"), networkConfigJSON) - if err != nil { - return "", err - } - return snapshotDir, nil -} - -// start network from snapshot -func (ln *localNetwork) loadSnapshot( - ctx context.Context, - snapshotName string, - binaryPath string, - buildDir string, - chainConfigs map[string]string, - flags map[string]interface{}, -) error { - ln.lock.Lock() - defer ln.lock.Unlock() - snapshotDir := filepath.Join(ln.snapshotsDir, snapshotPrefix+snapshotName) - snapshotDbDir := filepath.Join(filepath.Join(snapshotDir, defaultDbSubdir)) - _, err := os.Stat(snapshotDir) - if err != nil { - if errors.Is(err, os.ErrNotExist) { - return ErrSnapshotNotFound - } else { - return fmt.Errorf("failure accessing snapshot %q: %w", snapshotName, err) - } - } - // load network config - networkConfigJSON, err := os.ReadFile(filepath.Join(snapshotDir, "network.json")) - if err != nil { - return fmt.Errorf("failure reading network config file from snapshot: %w", err) - } - networkConfig := network.Config{} - err = json.Unmarshal(networkConfigJSON, &networkConfig) - if err != nil { - return fmt.Errorf("failure unmarshaling network config from snapshot: %w", err) - } - // add flags - for i := range networkConfig.NodeConfigs { - for k, v := range flags { - networkConfig.NodeConfigs[i].Flags[k] = v - } - } - // load db - for _, nodeConfig := range networkConfig.NodeConfigs { - sourceDbDir := filepath.Join(snapshotDbDir, nodeConfig.Name) - targetDbDir := filepath.Join(filepath.Join(ln.rootDir, nodeConfig.Name), defaultDbSubdir) - if err := dircopy.Copy(sourceDbDir, targetDbDir); err != nil { - return fmt.Errorf("failure loading node %q db dir: %w", nodeConfig.Name, err) - } - nodeConfig.Flags[config.DBPathKey] = targetDbDir - } - // replace binary path - if binaryPath != "" { - for i := range networkConfig.NodeConfigs { - networkConfig.NodeConfigs[i].BinaryPath = binaryPath - } - } - // replace build dir - if buildDir != "" { - for i := range networkConfig.NodeConfigs { - networkConfig.NodeConfigs[i].Flags[config.BuildDirKey] = buildDir - } - } - // add chain configs - for i := range networkConfig.NodeConfigs { - if networkConfig.NodeConfigs[i].ChainConfigFiles == nil { - networkConfig.NodeConfigs[i].ChainConfigFiles = map[string]string{} - } - for k, v := range chainConfigs { - networkConfig.NodeConfigs[i].ChainConfigFiles[k] = v - } - } - return ln.loadConfig(ctx, networkConfig) -} - -// Remove network snapshot -func (ln *localNetwork) RemoveSnapshot(snapshotName string) error { - snapshotDir := filepath.Join(ln.snapshotsDir, snapshotPrefix+snapshotName) - _, err := os.Stat(snapshotDir) - if err != nil { - if errors.Is(err, os.ErrNotExist) { - return ErrSnapshotNotFound - } else { - return fmt.Errorf("failure accessing snapshot %q: %w", snapshotName, err) - } - } - if err := os.RemoveAll(snapshotDir); err != nil { - return fmt.Errorf("failure removing snapshot path %q: %w", snapshotDir, err) - } - return nil -} - -// Get network snapshots -func (ln *localNetwork) GetSnapshotNames() ([]string, error) { - _, err := os.Stat(ln.snapshotsDir) - if err != nil { - if errors.Is(err, os.ErrNotExist) { - return nil, fmt.Errorf("snapshots dir %q does not exists", ln.snapshotsDir) - } else { - return nil, fmt.Errorf("failure accessing snapshots dir %q: %w", ln.snapshotsDir, err) - } - } - matches, err := filepath.Glob(filepath.Join(ln.snapshotsDir, snapshotPrefix+"*")) - if err != nil { - return nil, err - } - snapshots := []string{} - for _, match := range matches { - snapshots = append(snapshots, strings.TrimPrefix(filepath.Base(match), snapshotPrefix)) - } - return snapshots, nil -} - ->>>>>>> origin/main // Returns whether Stop has been called. func (ln *localNetwork) stopCalled() bool { select { From b9c4c894dcd3de43b6ee4fbc35e06ee65471871f Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Wed, 3 Aug 2022 16:59:33 -0300 Subject: [PATCH 19/36] go back to plugin-dir in RPC --- client/client.go | 14 +- cmd/control/control.go | 18 +- rpcpb/rpc.pb.go | 719 +++++++++++++++++++++-------------------- rpcpb/rpc.proto | 6 +- server/network.go | 50 ++- server/server.go | 24 +- 6 files changed, 430 insertions(+), 401 deletions(-) diff --git a/client/client.go b/client/client.go index 1c8f36df..71a059b1 100644 --- a/client/client.go +++ b/client/client.go @@ -117,8 +117,8 @@ func (c *client) Start(ctx context.Context, execPath string, opts ...OpOption) ( if ret.rootDataDir != "" { req.RootDataDir = &ret.rootDataDir } - if ret.buildDir != "" { - req.BuildDir = &ret.buildDir + if ret.pluginDir != "" { + req.PluginDir = &ret.pluginDir } if len(ret.blockchainSpecs) > 0 { req.BlockchainSpecs = ret.blockchainSpecs @@ -296,8 +296,8 @@ func (c *client) LoadSnapshot(ctx context.Context, snapshotName string, opts ... if ret.execPath != "" { req.ExecPath = &ret.execPath } - if ret.buildDir != "" { - req.BuildDir = &ret.buildDir + if ret.pluginDir != "" { + req.PluginDir = &ret.pluginDir } if ret.rootDataDir != "" { req.RootDataDir = &ret.rootDataDir @@ -335,7 +335,7 @@ type Op struct { whitelistedSubnets string globalNodeConfig string rootDataDir string - buildDir string + pluginDir string blockchainSpecs []*rpcpb.BlockchainSpec customNodeConfigs map[string]string numSubnets uint32 @@ -380,9 +380,9 @@ func WithRootDataDir(rootDataDir string) OpOption { } } -func WithBuildDir(buildDir string) OpOption { +func WithPluginDir(pluginDir string) OpOption { return func(op *Op) { - op.buildDir = buildDir + op.pluginDir = pluginDir } } diff --git a/cmd/control/control.go b/cmd/control/control.go index 177c5da1..00f8afde 100644 --- a/cmd/control/control.go +++ b/cmd/control/control.go @@ -74,7 +74,7 @@ func NewCommand() *cobra.Command { var ( avalancheGoBinPath string numNodes uint32 - buildDir string + pluginDir string globalNodeConfig string addNodeConfig string blockchainSpecsStr string @@ -104,10 +104,10 @@ func newStartCommand() *cobra.Command { "number of nodes of the network", ) cmd.PersistentFlags().StringVar( - &buildDir, - "build-dir", + &pluginDir, + "plugin-dir", "", - "[optional] build directory", + "[optional] plugin directory", ) cmd.PersistentFlags().StringVar( &rootDataDir, @@ -157,7 +157,7 @@ func startFunc(cmd *cobra.Command, args []string) error { opts := []client.OpOption{ client.WithNumNodes(numNodes), - client.WithBuildDir(buildDir), + client.WithPluginDir(pluginDir), client.WithWhitelistedSubnets(whitelistedSubnets), client.WithRootDataDir(rootDataDir), } @@ -765,10 +765,10 @@ func newLoadSnapshotCommand() *cobra.Command { "avalanchego binary path", ) cmd.PersistentFlags().StringVar( - &buildDir, - "build-dir", + &pluginDir, + "plugin-dir", "", - "build directory", + "plugin directory", ) cmd.PersistentFlags().StringVar( &rootDataDir, @@ -800,7 +800,7 @@ func loadSnapshotFunc(cmd *cobra.Command, args []string) error { opts := []client.OpOption{ client.WithExecPath(avalancheGoBinPath), - client.WithBuildDir(buildDir), + client.WithPluginDir(pluginDir), client.WithRootDataDir(rootDataDir), } diff --git a/rpcpb/rpc.pb.go b/rpcpb/rpc.pb.go index 79c4dc79..a768a26f 100644 --- a/rpcpb/rpc.pb.go +++ b/rpcpb/rpc.pb.go @@ -310,7 +310,7 @@ type NodeInfo struct { Id string `protobuf:"bytes,4,opt,name=id,proto3" json:"id,omitempty"` LogDir string `protobuf:"bytes,5,opt,name=log_dir,json=logDir,proto3" json:"log_dir,omitempty"` DbDir string `protobuf:"bytes,6,opt,name=db_dir,json=dbDir,proto3" json:"db_dir,omitempty"` - BuildDir string `protobuf:"bytes,7,opt,name=build_dir,json=buildDir,proto3" json:"build_dir,omitempty"` + PluginDir string `protobuf:"bytes,7,opt,name=plugin_dir,json=pluginDir,proto3" json:"plugin_dir,omitempty"` WhitelistedSubnets string `protobuf:"bytes,8,opt,name=whitelisted_subnets,json=whitelistedSubnets,proto3" json:"whitelisted_subnets,omitempty"` Config []byte `protobuf:"bytes,9,opt,name=config,proto3" json:"config,omitempty"` } @@ -389,9 +389,9 @@ func (x *NodeInfo) GetDbDir() string { return "" } -func (x *NodeInfo) GetBuildDir() string { +func (x *NodeInfo) GetPluginDir() string { if x != nil { - return x.BuildDir + return x.PluginDir } return "" } @@ -517,7 +517,7 @@ type StartRequest struct { RootDataDir *string `protobuf:"bytes,5,opt,name=root_data_dir,json=rootDataDir,proto3,oneof" json:"root_data_dir,omitempty"` // Build directory that contains the subdir 'plugins' from which to load all custom VM executables. // If not specified, will be derived from the exec_path (its basedir) - BuildDir *string `protobuf:"bytes,6,opt,name=build_dir,json=buildDir,proto3,oneof" json:"build_dir,omitempty"` + PluginDir *string `protobuf:"bytes,6,opt,name=plugin_dir,json=pluginDir,proto3,oneof" json:"plugin_dir,omitempty"` // The list of custom chain's VM name, genesis file path, and (optional) subnet id to use. // // subnet id must be always nil when using StartRequest, as the network is empty and has no preloaded @@ -607,9 +607,9 @@ func (x *StartRequest) GetRootDataDir() string { return "" } -func (x *StartRequest) GetBuildDir() string { - if x != nil && x.BuildDir != nil { - return *x.BuildDir +func (x *StartRequest) GetPluginDir() string { + if x != nil && x.PluginDir != nil { + return *x.PluginDir } return "" } @@ -2020,7 +2020,7 @@ type LoadSnapshotRequest struct { SnapshotName string `protobuf:"bytes,1,opt,name=snapshot_name,json=snapshotName,proto3" json:"snapshot_name,omitempty"` ExecPath *string `protobuf:"bytes,2,opt,name=exec_path,json=execPath,proto3,oneof" json:"exec_path,omitempty"` - BuildDir *string `protobuf:"bytes,3,opt,name=build_dir,json=buildDir,proto3,oneof" json:"build_dir,omitempty"` + PluginDir *string `protobuf:"bytes,3,opt,name=plugin_dir,json=pluginDir,proto3,oneof" json:"plugin_dir,omitempty"` RootDataDir *string `protobuf:"bytes,4,opt,name=root_data_dir,json=rootDataDir,proto3,oneof" json:"root_data_dir,omitempty"` ChainConfigs map[string]string `protobuf:"bytes,5,rep,name=chain_configs,json=chainConfigs,proto3" json:"chain_configs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` GlobalNodeConfig *string `protobuf:"bytes,6,opt,name=global_node_config,json=globalNodeConfig,proto3,oneof" json:"global_node_config,omitempty"` @@ -2072,9 +2072,9 @@ func (x *LoadSnapshotRequest) GetExecPath() string { return "" } -func (x *LoadSnapshotRequest) GetBuildDir() string { - if x != nil && x.BuildDir != nil { - return *x.BuildDir +func (x *LoadSnapshotRequest) GetPluginDir() string { + if x != nil && x.PluginDir != nil { + return *x.PluginDir } return "" } @@ -2378,7 +2378,7 @@ var file_rpcpb_rpc_proto_rawDesc = []byte{ 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0xf3, 0x01, 0x0a, 0x08, 0x4e, 0x6f, 0x64, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0xf5, 0x01, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, @@ -2387,366 +2387,367 @@ var file_rpcpb_rpc_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6c, 0x6f, 0x67, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x6f, 0x67, 0x44, 0x69, 0x72, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x62, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x64, 0x62, 0x44, 0x69, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x44, 0x69, 0x72, 0x12, 0x2f, 0x0a, 0x13, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, - 0x73, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x12, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x53, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x22, - 0x0a, 0x10, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x22, 0x47, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x66, 0x41, 0x74, 0x74, 0x61, - 0x63, 0x68, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x0a, 0x05, - 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x70, - 0x63, 0x70, 0x62, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x22, 0xcf, 0x05, 0x0a, 0x0c, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, - 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x65, 0x78, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x09, 0x6e, 0x75, 0x6d, - 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x08, - 0x6e, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a, 0x13, 0x77, - 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x12, 0x77, 0x68, 0x69, 0x74, - 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x88, 0x01, - 0x01, 0x12, 0x31, 0x0a, 0x12, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, - 0x10, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x88, 0x01, 0x01, 0x12, 0x27, 0x0a, 0x0d, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x61, 0x74, - 0x61, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x0b, 0x72, - 0x6f, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x44, 0x69, 0x72, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, - 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x04, 0x52, 0x08, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x69, 0x72, 0x88, 0x01, 0x01, 0x12, - 0x40, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x70, - 0x65, 0x63, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x70, - 0x62, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, - 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, - 0x73, 0x12, 0x5a, 0x0a, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6e, 0x6f, 0x64, 0x65, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, - 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x63, 0x75, 0x73, 0x74, - 0x6f, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x4a, 0x0a, - 0x0d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x09, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x1a, 0x44, 0x0a, 0x16, 0x43, 0x75, 0x73, - 0x74, 0x6f, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, - 0x3f, 0x0a, 0x11, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x42, 0x16, - 0x0a, 0x14, 0x5f, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x73, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, - 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x10, 0x0a, - 0x0e, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x64, 0x69, 0x72, 0x42, - 0x0c, 0x0a, 0x0a, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x69, 0x72, 0x22, 0x46, 0x0a, - 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, - 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x73, 0x0a, 0x0e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x17, 0x0a, 0x07, 0x76, 0x6d, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x6d, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x75, - 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, - 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, - 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x5c, 0x0a, 0x18, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x73, 0x22, 0x52, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, - 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x4c, 0x0a, 0x14, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0b, 0x6e, 0x75, 0x6d, 0x5f, 0x73, 0x75, 0x62, 0x6e, - 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0a, 0x6e, 0x75, 0x6d, - 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x6e, - 0x75, 0x6d, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x22, 0x4e, 0x0a, 0x15, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x09, 0x52, 0x05, 0x64, 0x62, 0x44, 0x69, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x44, 0x69, 0x72, 0x12, 0x2f, 0x0a, 0x13, 0x77, 0x68, 0x69, 0x74, 0x65, + 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, + 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x22, 0x22, 0x0a, 0x10, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x22, 0x47, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x66, 0x41, 0x74, + 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, + 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x50, 0x65, + 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x22, 0xd2, 0x05, + 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x65, 0x78, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x09, 0x6e, + 0x75, 0x6d, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, + 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a, + 0x13, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, + 0x6e, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x12, 0x77, 0x68, + 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, + 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x12, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, + 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x02, 0x52, 0x10, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x88, 0x01, 0x01, 0x12, 0x27, 0x0a, 0x0d, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, + 0x0b, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x44, 0x69, 0x72, 0x88, 0x01, 0x01, 0x12, + 0x22, 0x0a, 0x0a, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x09, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x44, 0x69, 0x72, + 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x53, 0x70, 0x65, 0x63, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x53, 0x70, 0x65, 0x63, 0x73, 0x12, 0x5a, 0x0a, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, + 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4e, 0x6f, + 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, + 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x73, 0x12, 0x4a, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, + 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x1a, 0x44, 0x0a, + 0x16, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x1a, 0x3f, 0x0a, 0x11, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x6e, 0x6f, 0x64, + 0x65, 0x73, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, + 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x64, 0x69, 0x72, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x64, + 0x69, 0x72, 0x22, 0x46, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x0f, 0x0a, 0x0d, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x47, 0x0a, 0x0e, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, - 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x0d, 0x0a, 0x0b, 0x55, 0x52, 0x49, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x22, 0x0a, 0x0c, 0x55, 0x52, 0x49, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x72, 0x69, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x04, 0x75, 0x72, 0x69, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x47, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x73, 0x0a, 0x0e, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x17, 0x0a, 0x07, + 0x76, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, + 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x12, + 0x20, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x88, 0x01, + 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x22, + 0x5c, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x10, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0f, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x73, 0x22, 0x52, 0x0a, + 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, - 0x6f, 0x22, 0x3a, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x75, 0x73, 0x68, - 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0c, 0x70, 0x75, 0x73, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0x4d, 0x0a, - 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, - 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xa6, 0x01, 0x0a, - 0x12, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x09, 0x65, 0x78, 0x65, 0x63, 0x5f, - 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x65, 0x78, - 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a, 0x13, 0x77, 0x68, 0x69, - 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x12, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, - 0x69, 0x73, 0x74, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x88, 0x01, 0x01, 0x42, - 0x0c, 0x0a, 0x0a, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x42, 0x16, 0x0a, - 0x14, 0x5f, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x75, - 0x62, 0x6e, 0x65, 0x74, 0x73, 0x22, 0x4c, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, - 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, - 0x6e, 0x66, 0x6f, 0x22, 0x27, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x4b, 0x0a, 0x12, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x6f, 0x22, 0x4c, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0b, 0x6e, 0x75, 0x6d, + 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, + 0x52, 0x0a, 0x6e, 0x75, 0x6d, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x88, 0x01, 0x01, 0x42, + 0x0e, 0x0a, 0x0c, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x22, + 0x4e, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, + 0x0f, 0x0a, 0x0d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0x47, 0x0a, 0x0e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x86, 0x02, 0x0a, 0x0e, 0x41, 0x64, - 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, - 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x88, 0x01, 0x01, 0x12, 0x4c, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x70, 0x63, - 0x70, 0x62, 0x2e, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x73, 0x1a, 0x3f, 0x0a, 0x11, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x22, 0x48, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x0d, 0x0a, 0x0b, 0x55, 0x52, 0x49, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x22, 0x0a, 0x0c, 0x55, 0x52, 0x49, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x72, 0x69, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x75, 0x72, 0x69, 0x73, 0x22, 0x0f, 0x0a, 0x0d, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x47, 0x0a, + 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x3a, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, + 0x0d, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x22, 0x4d, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, + 0x6f, 0x22, 0xa6, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x64, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x09, + 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x08, 0x65, 0x78, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x88, 0x01, 0x01, 0x12, 0x34, + 0x0a, 0x13, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x75, + 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x12, 0x77, + 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, + 0x73, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, + 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x22, 0x4c, 0x0a, 0x13, 0x52, 0x65, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x27, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x4b, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x86, + 0x02, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x65, 0x63, 0x50, 0x61, + 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x88, 0x01, 0x01, 0x12, 0x4c, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x1a, 0x3f, 0x0a, 0x11, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x48, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, + 0x6f, 0x22, 0x0d, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0x45, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x30, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x61, 0x63, + 0x68, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x12, 0x41, 0x74, + 0x74, 0x61, 0x63, 0x68, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x45, 0x0a, 0x12, 0x61, 0x74, 0x74, 0x61, 0x63, + 0x68, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x74, 0x74, 0x61, + 0x63, 0x68, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x61, 0x74, + 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x78, + 0x0a, 0x1a, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, + 0x6f, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0x31, 0x0a, 0x1b, 0x53, 0x65, 0x6e, 0x64, + 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x22, 0x3a, 0x0a, 0x13, 0x53, + 0x61, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, + 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3b, 0x0a, 0x14, 0x53, 0x61, 0x76, 0x65, 0x53, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, + 0x50, 0x61, 0x74, 0x68, 0x22, 0xb6, 0x03, 0x0a, 0x13, 0x4c, 0x6f, 0x61, 0x64, 0x53, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, + 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x20, 0x0a, 0x09, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x65, 0x78, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, + 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x64, 0x69, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x09, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x44, 0x69, 0x72, 0x88, 0x01, 0x01, 0x12, 0x27, 0x0a, 0x0d, 0x72, 0x6f, 0x6f, 0x74, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, + 0x52, 0x0b, 0x72, 0x6f, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x44, 0x69, 0x72, 0x88, 0x01, 0x01, + 0x12, 0x51, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, + 0x4c, 0x6f, 0x61, 0x64, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x73, 0x12, 0x31, 0x0a, 0x12, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, + 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x03, 0x52, 0x10, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x88, 0x01, 0x01, 0x1a, 0x3f, 0x0a, 0x11, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x65, 0x78, 0x65, 0x63, + 0x5f, 0x70, 0x61, 0x74, 0x68, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x5f, 0x64, 0x69, 0x72, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x5f, 0x64, 0x69, 0x72, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x4d, 0x0a, + 0x14, 0x4c, 0x6f, 0x61, 0x64, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x0d, 0x0a, 0x0b, - 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x45, 0x0a, 0x0c, 0x53, - 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, - 0x66, 0x6f, 0x22, 0x30, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x50, 0x65, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x12, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x50, - 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x45, 0x0a, 0x12, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x70, - 0x65, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x50, - 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, - 0x64, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x78, 0x0a, 0x1a, 0x53, 0x65, 0x6e, - 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x0e, 0x0a, - 0x02, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x14, 0x0a, - 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x22, 0x31, 0x0a, 0x1b, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x22, 0x3a, 0x0a, 0x13, 0x53, 0x61, 0x76, 0x65, 0x53, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, - 0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x22, 0x3b, 0x0a, 0x14, 0x53, 0x61, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, - 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x50, 0x61, 0x74, 0x68, 0x22, - 0xb3, 0x03, 0x0a, 0x13, 0x4c, 0x6f, 0x61, 0x64, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, - 0x68, 0x6f, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x09, - 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x00, 0x52, 0x08, 0x65, 0x78, 0x65, 0x63, 0x50, 0x61, 0x74, 0x68, 0x88, 0x01, 0x01, 0x12, 0x20, - 0x0a, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x01, 0x52, 0x08, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x69, 0x72, 0x88, 0x01, 0x01, - 0x12, 0x27, 0x0a, 0x0d, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x64, 0x69, - 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x0b, 0x72, 0x6f, 0x6f, 0x74, 0x44, - 0x61, 0x74, 0x61, 0x44, 0x69, 0x72, 0x88, 0x01, 0x01, 0x12, 0x51, 0x0a, 0x0d, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2c, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x53, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x68, 0x61, - 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x31, 0x0a, 0x12, - 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x10, 0x67, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x88, 0x01, 0x01, 0x1a, - 0x3f, 0x0a, 0x11, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x42, 0x0c, - 0x0a, 0x0a, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x69, 0x72, 0x42, 0x10, 0x0a, 0x0e, - 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x64, 0x69, 0x72, 0x42, 0x15, - 0x0a, 0x13, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x4d, 0x0a, 0x14, 0x4c, 0x6f, 0x61, 0x64, 0x53, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, - 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x3c, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, - 0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, - 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x0a, 0x17, - 0x47, 0x65, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x41, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x53, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x32, 0x53, 0x0a, 0x0b, 0x50, 0x69, - 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x04, 0x50, 0x69, 0x6e, - 0x67, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x50, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x0d, 0x22, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x69, 0x6e, 0x67, 0x3a, 0x01, 0x2a, 0x32, - 0xfa, 0x0d, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x50, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x13, 0x2e, 0x72, 0x70, - 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x11, - 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x80, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x1f, 0x2e, 0x72, 0x70, 0x63, - 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x70, - 0x63, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x70, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x22, 0x19, 0x2f, 0x76, 0x31, - 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x54, 0x0a, 0x06, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x70, - 0x62, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x3a, 0x01, 0x2a, 0x12, - 0x4c, 0x0a, 0x04, 0x55, 0x52, 0x49, 0x73, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, - 0x55, 0x52, 0x49, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, - 0x63, 0x70, 0x62, 0x2e, 0x55, 0x52, 0x49, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x22, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x75, 0x72, 0x69, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x54, 0x0a, - 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, - 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x12, 0x2f, 0x76, - 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x3a, 0x01, 0x2a, 0x12, 0x6e, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x1a, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3a, 0x01, - 0x2a, 0x30, 0x01, 0x12, 0x64, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, - 0x65, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, - 0x63, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x22, 0x16, - 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x72, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x58, 0x0a, 0x07, 0x41, 0x64, 0x64, - 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x64, 0x64, - 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, - 0x63, 0x70, 0x62, 0x2e, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x22, 0x13, 0x2f, 0x76, 0x31, - 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x61, 0x64, 0x64, 0x6e, 0x6f, 0x64, 0x65, - 0x3a, 0x01, 0x2a, 0x12, 0x68, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x6f, - 0x64, 0x65, 0x12, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, - 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x64, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x1c, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x72, - 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x4c, 0x0a, - 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, - 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x70, - 0x62, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x22, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x2f, 0x73, 0x74, 0x6f, 0x70, 0x3a, 0x01, 0x2a, 0x12, 0x64, 0x0a, 0x0a, 0x41, - 0x74, 0x74, 0x61, 0x63, 0x68, 0x50, 0x65, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x70, - 0x62, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x74, 0x74, 0x61, - 0x63, 0x68, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, + 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x3c, 0x0a, 0x15, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, + 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, + 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x41, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x32, 0x53, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x44, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, + 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, + 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x22, 0x08, 0x2f, 0x76, 0x31, 0x2f, + 0x70, 0x69, 0x6e, 0x67, 0x3a, 0x01, 0x2a, 0x32, 0xfa, 0x0d, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x50, 0x0a, 0x05, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, + 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x2f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x80, 0x01, 0x0a, + 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x73, 0x12, 0x1f, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x22, 0x1d, 0x2f, + 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x3a, 0x01, 0x2a, 0x12, + 0x70, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, + 0x12, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, + 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6e, + 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1e, 0x22, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x3a, 0x01, + 0x2a, 0x12, 0x54, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x14, 0x2e, 0x72, 0x70, + 0x63, 0x70, 0x62, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, + 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x68, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x3a, 0x01, 0x2a, 0x12, 0x4c, 0x0a, 0x04, 0x55, 0x52, 0x49, 0x73, 0x12, + 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x55, 0x52, 0x49, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x55, 0x52, 0x49, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, + 0x22, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x75, 0x72, + 0x69, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x54, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x14, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x17, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x6e, 0x0a, 0x0c, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x2e, 0x72, 0x70, + 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, 0x76, + 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3a, 0x01, 0x2a, 0x30, 0x01, 0x12, 0x64, 0x0a, 0x0a, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x70, + 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x22, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x2f, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x70, 0x65, 0x65, 0x72, 0x3a, 0x01, - 0x2a, 0x12, 0x88, 0x01, 0x0a, 0x13, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x2e, 0x72, 0x70, 0x63, 0x70, - 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, - 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x6c, 0x0a, 0x0c, - 0x53, 0x61, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x1a, 0x2e, 0x72, - 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, - 0x2e, 0x53, 0x61, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, - 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x73, 0x61, 0x76, 0x65, 0x73, - 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x6c, 0x0a, 0x0c, 0x4c, 0x6f, - 0x61, 0x64, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x1a, 0x2e, 0x72, 0x70, 0x63, - 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, - 0x6f, 0x61, 0x64, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, 0x76, 0x31, - 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x74, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x1c, 0x2e, 0x72, 0x70, 0x63, - 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, - 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x22, - 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x72, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x7c, - 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x22, 0x1c, 0x2f, 0x76, 0x31, - 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x67, 0x65, 0x74, 0x73, 0x6e, 0x61, 0x70, - 0x73, 0x68, 0x6f, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x42, 0x34, 0x5a, 0x32, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, - 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x2d, 0x6e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2d, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x72, 0x70, 0x63, - 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x6f, 0x6c, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x3a, 0x01, + 0x2a, 0x12, 0x58, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x2e, 0x72, + 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x64, 0x64, 0x4e, + 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x18, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x2f, 0x61, 0x64, 0x64, 0x6e, 0x6f, 0x64, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x68, 0x0a, 0x0b, 0x52, + 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x19, 0x2e, 0x72, 0x70, 0x63, + 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x52, 0x65, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x6e, 0x6f, + 0x64, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x4c, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x12, 0x2e, + 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x22, 0x10, + 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x73, 0x74, 0x6f, 0x70, + 0x3a, 0x01, 0x2a, 0x12, 0x64, 0x0a, 0x0a, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x50, 0x65, 0x65, + 0x72, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, + 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, + 0x63, 0x70, 0x62, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x22, 0x16, + 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x61, 0x74, 0x74, 0x61, + 0x63, 0x68, 0x70, 0x65, 0x65, 0x72, 0x3a, 0x01, 0x2a, 0x12, 0x88, 0x01, 0x0a, 0x13, 0x53, 0x65, + 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x21, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x75, + 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, + 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, + 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x73, 0x65, + 0x6e, 0x64, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x6c, 0x0a, 0x0c, 0x53, 0x61, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, + 0x73, 0x68, 0x6f, 0x74, 0x12, 0x1a, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x61, 0x76, + 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x53, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x2f, 0x73, 0x61, 0x76, 0x65, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x3a, + 0x01, 0x2a, 0x12, 0x6c, 0x0a, 0x0c, 0x4c, 0x6f, 0x61, 0x64, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, + 0x6f, 0x74, 0x12, 0x1a, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x53, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, + 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x53, 0x6e, 0x61, 0x70, 0x73, + 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x2f, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x3a, 0x01, 0x2a, + 0x12, 0x74, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, + 0x6f, 0x74, 0x12, 0x1c, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1d, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x22, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x6e, 0x61, 0x70, 0x73, + 0x68, 0x6f, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x7c, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x72, 0x70, 0x63, + 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x70, 0x63, + 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x21, 0x22, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x2f, 0x67, 0x65, 0x74, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x3a, 0x01, 0x2a, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x68, 0x65, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2d, 0x72, 0x75, + 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x72, 0x70, 0x63, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/rpcpb/rpc.proto b/rpcpb/rpc.proto index b380715e..77bd8b8f 100644 --- a/rpcpb/rpc.proto +++ b/rpcpb/rpc.proto @@ -184,7 +184,7 @@ message NodeInfo { string id = 4; string log_dir = 5; string db_dir = 6; - string build_dir = 7; + string plugin_dir = 7; string whitelisted_subnets = 8; bytes config = 9; } @@ -207,7 +207,7 @@ message StartRequest { // Build directory that contains the subdir 'plugins' from which to load all custom VM executables. // If not specified, will be derived from the exec_path (its basedir) - optional string build_dir = 6; + optional string plugin_dir = 6; // The list of custom chain's VM name, genesis file path, and (optional) subnet id to use. // @@ -362,7 +362,7 @@ message SaveSnapshotResponse { message LoadSnapshotRequest { string snapshot_name = 1; optional string exec_path = 2; - optional string build_dir = 3; + optional string plugin_dir = 3; optional string root_data_dir = 4; map chain_configs = 5; optional string global_node_config = 6; diff --git a/server/network.go b/server/network.go index f6e70adb..997e1dc5 100644 --- a/server/network.go +++ b/server/network.go @@ -43,8 +43,8 @@ var ignoreFields = map[string]struct{}{ type localNetwork struct { logger logging.Logger - execPath string - buildDir string + execPath string + pluginDir string cfg network.Config @@ -89,7 +89,7 @@ type localNetworkOptions struct { redirectNodesOutput bool globalNodeConfig string - buildDir string + pluginDir string customNodeConfigs map[string]string // chain configs to be added to the network, besides the ones in default config, or saved snapshot @@ -118,7 +118,7 @@ func newLocalNetwork(opts localNetworkOptions) (*localNetwork, error) { execPath: opts.execPath, - buildDir: getBuildDir(opts.execPath, opts.buildDir), + pluginDir: opts.pluginDir, options: opts, @@ -169,7 +169,13 @@ func (lc *localNetwork) createConfig() error { return fmt.Errorf("failed merging provided configs: %w", err) } - cfg.NodeConfigs[i].ConfigFile, err = createConfigFileString(mergedConfig, logDir, dbDir, lc.buildDir, lc.options.whitelistedSubnets) + // avalanchego expects buildDir (parent dir of pluginDir) to be provided at cmdline + buildDir, err := getBuildDir(lc.execPath, lc.pluginDir) + if err != nil { + return err + } + + cfg.NodeConfigs[i].ConfigFile, err = createConfigFileString(mergedConfig, logDir, dbDir, buildDir, lc.options.whitelistedSubnets) if err != nil { return err } @@ -216,17 +222,21 @@ func mergeNodeConfig(baseConfig map[string]interface{}, globalConfig map[string] return baseConfig, nil } -// if givenBuildDir is empty, generates it from execPath +// generates buildDir from pluginDir, and if not available, from execPath // returns error if pluginDir is non empty and invalid -func getBuildDir(execPath string, givenBuildDir string) string { +func getBuildDir(execPath string, pluginDir string) (string, error) { buildDir := "" if execPath != "" { buildDir = filepath.Dir(execPath) } - if givenBuildDir != "" { - buildDir = givenBuildDir + if pluginDir != "" { + pluginDir := filepath.Clean(pluginDir) + if filepath.Base(pluginDir) != "plugins" { + return "", fmt.Errorf("plugin dir %q is not named plugins", pluginDir) + } + buildDir = filepath.Dir(pluginDir) } - return buildDir + return buildDir, nil } // createConfigFileString finalizes the config setup and returns the node config JSON string @@ -394,6 +404,11 @@ func (lc *localNetwork) loadSnapshot( ) error { color.Outf("{{blue}}{{bold}}create and run local network from snapshot{{/}}\n") + buildDir, err := getBuildDir(lc.execPath, lc.pluginDir) + if err != nil { + return err + } + var globalNodeConfig map[string]interface{} if lc.options.globalNodeConfig != "" { if err := json.Unmarshal([]byte(lc.options.globalNodeConfig), &globalNodeConfig); err != nil { @@ -407,7 +422,7 @@ func (lc *localNetwork) loadSnapshot( lc.options.rootDataDir, lc.options.snapshotsDir, lc.execPath, - lc.buildDir, + buildDir, lc.options.chainConfigs, globalNodeConfig, ) @@ -508,6 +523,7 @@ func (lc *localNetwork) updateNodeInfo() error { for _, name := range lc.nodeNames { node := nodes[name] configFile := []byte(node.GetConfigFile()) + var pluginDir string var whitelistedSubnets string var configFileMap map[string]interface{} if err := json.Unmarshal(configFile, &configFileMap); err != nil { @@ -520,6 +536,10 @@ func (lc *localNetwork) updateNodeInfo() error { return fmt.Errorf("unexpected type for %q expected string got %T", config.WhitelistedSubnetsKey, whitelistedSubnetsIntf) } } + buildDir := node.GetBuildDir() + if buildDir != "" { + pluginDir = filepath.Join(buildDir, "plugins") + } lc.nodeInfos[name] = &rpcpb.NodeInfo{ Name: node.GetName(), @@ -529,16 +549,16 @@ func (lc *localNetwork) updateNodeInfo() error { LogDir: node.GetLogsDir(), DbDir: node.GetDbDir(), Config: []byte(node.GetConfigFile()), - BuildDir: node.GetBuildDir(), + PluginDir: pluginDir, WhitelistedSubnets: whitelistedSubnets, } - // update default exec and buildDir if empty (snapshots started without this params) + // update default exec and pluginDir if empty (snapshots started without this params) if lc.execPath == "" { lc.execPath = node.GetBinaryPath() } - if lc.buildDir == "" { - lc.buildDir = node.GetBuildDir() + if lc.pluginDir == "" { + lc.pluginDir = pluginDir } // update default chain configs if empty if lc.chainConfigs == nil { diff --git a/server/server.go b/server/server.go index 8cef010d..b1c0236e 100644 --- a/server/server.go +++ b/server/server.go @@ -249,8 +249,13 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta if err := utils.CheckExecPath(req.GetExecPath()); err != nil { return nil, err } - buildDir := getBuildDir(req.GetExecPath(), req.GetBuildDir()) - pluginDir := filepath.Join(buildDir, "plugins") + pluginDir := "" + if req.GetPluginDir() != "" { + pluginDir = req.GetPluginDir() + } + if pluginDir == "" { + pluginDir = filepath.Join(filepath.Dir(req.GetExecPath()), "plugins") + } chainSpecs := []network.BlockchainSpec{} if len(req.GetBlockchainSpecs()) > 0 { zap.L().Info("plugin dir", zap.String("plugin-dir", pluginDir)) @@ -327,7 +332,7 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta zap.String("whitelistedSubnets", whitelistedSubnets), zap.Int32("pid", pid), zap.String("rootDataDir", rootDataDir), - zap.String("buildDir", buildDir), + zap.String("pluginDir", pluginDir), zap.Any("chainConfigs", req.ChainConfigs), zap.String("defaultNodeConfig", globalNodeConfig), ) @@ -347,7 +352,7 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta numNodes: numNodes, whitelistedSubnets: whitelistedSubnets, redirectNodesOutput: s.cfg.RedirectNodesOutput, - buildDir: buildDir, + pluginDir: pluginDir, globalNodeConfig: globalNodeConfig, customNodeConfigs: customNodeConfigs, chainConfigs: req.ChainConfigs, @@ -442,7 +447,6 @@ func (s *server) CreateBlockchains(ctx context.Context, req *rpcpb.CreateBlockch return nil, ErrNoBlockchainSpec } - pluginDir := filepath.Join(s.network.buildDir, "plugins") chainSpecs := []network.BlockchainSpec{} for i := range req.GetBlockchainSpecs() { vmName := req.GetBlockchainSpecs()[i].VmName @@ -457,7 +461,7 @@ func (s *server) CreateBlockchains(ctx context.Context, req *rpcpb.CreateBlockch return nil, ErrInvalidVMName } if err := utils.CheckPluginPaths( - filepath.Join(pluginDir, vmID.String()), + filepath.Join(s.network.pluginDir, vmID.String()), vmGenesisFilePath, ); err != nil { return nil, err @@ -739,7 +743,11 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb // use same configs from other nodes whitelistedSubnets = s.network.options.whitelistedSubnets - buildDir := getBuildDir(execPath, s.network.buildDir) + buildDir, err := getBuildDir(execPath, s.network.pluginDir) + if err != nil { + return nil, err + } + rootDataDir := s.clusterInfo.RootDataDir logDir := filepath.Join(rootDataDir, req.Name, "log") @@ -1006,7 +1014,7 @@ func (s *server) LoadSnapshot(ctx context.Context, req *rpcpb.LoadSnapshotReques s.network, err = newLocalNetwork(localNetworkOptions{ execPath: req.GetExecPath(), - buildDir: req.GetBuildDir(), + pluginDir: req.GetPluginDir(), rootDataDir: rootDataDir, chainConfigs: req.ChainConfigs, globalNodeConfig: req.GetGlobalNodeConfig(), From a38dbd469bbdb9b501321194956059fd44a47065 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Wed, 3 Aug 2022 17:27:44 -0300 Subject: [PATCH 20/36] fix E2E --- tests/e2e/e2e_test.go | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 4fc3c863..01f2a6de 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -134,7 +134,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { ginkgo.By("start request with invalid custom VM path should fail", func() { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) _, err := cli.Start(ctx, execPath1, - client.WithBuildDir(os.TempDir()), + client.WithPluginDir(os.TempDir()), client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{ { VmName: "invalid", @@ -146,17 +146,14 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { }) ginkgo.By("start request with invalid custom VM name format should fail", func() { - pluginsPath := filepath.Join(os.TempDir(), "plugins") - err := os.MkdirAll(pluginsPath, fs.ModePerm) - gomega.Ω(err).Should(gomega.BeNil()) - f, err := os.CreateTemp(pluginsPath, strings.Repeat("a", 33)) + f, err := os.CreateTemp(os.TempDir(), strings.Repeat("a", 33)) gomega.Ω(err).Should(gomega.BeNil()) filePath := f.Name() gomega.Ω(f.Close()).Should(gomega.BeNil()) ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) _, err = cli.Start(ctx, execPath1, - client.WithBuildDir(filepath.Dir(filepath.Dir(filePath))), + client.WithPluginDir(filepath.Dir(filePath)), client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{ { VmName: filepath.Base(filePath), @@ -172,15 +169,12 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() { ginkgo.By("start request with invalid custom VM genesis path should fail", func() { vmID, err := utils.VMID("hello") gomega.Ω(err).Should(gomega.BeNil()) - pluginsPath := filepath.Join(os.TempDir(), "plugins") - err = os.MkdirAll(pluginsPath, fs.ModePerm) - gomega.Ω(err).Should(gomega.BeNil()) - filePath := filepath.Join(pluginsPath, vmID.String()) + filePath := filepath.Join(os.TempDir(), vmID.String()) gomega.Ω(os.WriteFile(filePath, []byte{0}, fs.ModePerm)).Should(gomega.BeNil()) ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) _, err = cli.Start(ctx, execPath1, - client.WithBuildDir(filepath.Dir(filepath.Dir(filePath))), + client.WithPluginDir(filepath.Dir(filePath)), client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{ { VmName: "hello", From 65e27168990daffc0eec079ac16b821f420b9e47 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Wed, 3 Aug 2022 18:07:46 -0300 Subject: [PATCH 21/36] fix lint --- local/snapshot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/local/snapshot.go b/local/snapshot.go index 88cec678..e652a060 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -88,7 +88,7 @@ func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) ( } // make copy of network flags networkConfigFlags := make(map[string]interface{}) - for fk, fv := range ln.flags { + for fk, fv := range ln.defaultNodeConfig.Flags { networkConfigFlags[fk] = fv } // remove all log dir references From 121b2e83c7c8d806df481bff14dc8fbd73a914e1 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 04:54:42 -0300 Subject: [PATCH 22/36] start passing binary exec and node conf to ANR for add node --- client/client.go | 9 ++++---- local/helpers.go | 2 +- local/network.go | 17 ++++++++++---- server/server.go | 59 +++++++++++++++++++++++------------------------- 4 files changed, 45 insertions(+), 42 deletions(-) diff --git a/client/client.go b/client/client.go index 78602afc..8cca43c1 100644 --- a/client/client.go +++ b/client/client.go @@ -233,12 +233,11 @@ func (c *client) AddNode(ctx context.Context, name string, execPath string, opts ret.applyOpts(opts) req := &rpcpb.AddNodeRequest{ - Name: name, - } - if ret.execPath != "" { - req.ExecPath = ret.execPath + Name: name, + ExecPath: execPath, + NodeConfig: &ret.globalNodeConfig, + ChainConfigs: ret.chainConfigs, } - req.ChainConfigs = ret.chainConfigs zap.L().Info("add node", zap.String("name", name)) r, err := c.controlc.AddNode(ctx, req) diff --git a/local/helpers.go b/local/helpers.go index b693fd81..4912cd4c 100644 --- a/local/helpers.go +++ b/local/helpers.go @@ -169,7 +169,7 @@ func addNetworkFlags(log logging.Logger, networkFlags map[string]interface{}, no if val, ok := nodeFlags[flagName]; !ok { nodeFlags[flagName] = flagVal } else { - log.Info( + log.Debug( "not overwriting node config flag %s (value %v) with network config flag (value %v)", flagName, val, flagVal, ) diff --git a/local/network.go b/local/network.go index 14721843..b0c57c04 100644 --- a/local/network.go +++ b/local/network.go @@ -391,6 +391,9 @@ func (ln *localNetwork) AddNode(nodeConfig node.Config) (node.Node, error) { // set defaults only if this is not the first node if ln.defaultNodeConfig != nil { + if nodeConfig.BinaryPath == "" { + nodeConfig.BinaryPath = ln.defaultNodeConfig.BinaryPath + } nodeConfig.Flags = ln.defaultNodeConfig.Flags nodeConfig.ChainConfigFiles = ln.defaultNodeConfig.ChainConfigFiles } @@ -408,6 +411,7 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { // this should therefore be running for the first node only if ln.defaultNodeConfig == nil { ln.defaultNodeConfig = &node.Config{ + BinaryPath: nodeConfig.BinaryPath, Flags: GetDefaultFlags(), ChainConfigFiles: map[string]string{}, } @@ -423,6 +427,7 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { ln.defaultNodeConfig.ChainConfigFiles[k] = v } } + // it shouldn't happen that just one is empty, most probably both, // but in any case if just one is empty it's unusable so we just assign a new one. if nodeConfig.StakingCert == "" || nodeConfig.StakingKey == "" { @@ -470,6 +475,12 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { nodeConfig.BinaryPath, nodeData.flags, err, ) } + + ln.log.Info( + "adding node %q with tmp dir at %s, logs at %s, DB at %s, P2P port %d, API port %d", + nodeConfig.Name, nodeDir, nodeData.logsDir, nodeData.dbDir, nodeData.p2pPort, nodeData.apiPort, + ) + ln.log.Debug("starting node %q with \"%s %s\"", nodeConfig.Name, nodeConfig.BinaryPath, nodeData.flags) // Create a wrapper for this node so we can reference it later @@ -731,11 +742,11 @@ func (ln *localNetwork) setNodeName(nodeConfig *node.Config) error { if len(nodeConfig.Name) == 0 { for { nodeConfig.Name = fmt.Sprintf("%s%d", defaultNodeNamePrefix, ln.nextNodeSuffix) - ln.nextNodeSuffix++ _, ok := ln.nodes[nodeConfig.Name] if !ok { break } + ln.nextNodeSuffix++ } } // Enforce name uniqueness @@ -835,10 +846,6 @@ func (ln *localNetwork) buildFlags( flags = append(flags, fmt.Sprintf("--%s=%v", flagName, flagVal)) } - ln.log.Info( - "adding node %q with tmp dir at %s, logs at %s, DB at %s, P2P port %d, API port %d", - nodeConfig.Name, nodeDir, logsDir, dbDir, p2pPort, apiPort, - ) return buildFlagsReturn{ flags: flags, apiPort: apiPort, diff --git a/server/server.go b/server/server.go index d3679d60..e2cb4385 100644 --- a/server/server.go +++ b/server/server.go @@ -10,7 +10,8 @@ import ( "errors" "fmt" "io" - "io/fs" + + //"io/fs" "net" "net/http" "os" @@ -721,45 +722,40 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb s.mu.Lock() defer s.mu.Unlock() - if _, exists := s.network.nodeInfos[req.Name]; exists { - return nil, fmt.Errorf("repeated node name %q", req.Name) - } + /* + // user can override bin path for this node... + execPath := req.ExecPath + if execPath == "" { + // ...or use the same binary as the rest of the network + execPath = s.network.execPath + } + _, err := os.Stat(execPath) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return nil, utils.ErrNotExists + } + return nil, fmt.Errorf("failed to stat exec %q (%w)", execPath, err) + } + */ - // user can override bin path for this node... - execPath := req.ExecPath - if execPath == "" { - // ...or use the same binary as the rest of the network - execPath = s.network.execPath - } - _, err := os.Stat(execPath) - if err != nil { - if errors.Is(err, fs.ErrNotExist) { - return nil, utils.ErrNotExists + nodeFlags := map[string]interface{}{} + if req.GetNodeConfig() != "" { + if err := json.Unmarshal([]byte(req.GetNodeConfig()), &nodeFlags); err != nil { + return nil, err } - return nil, fmt.Errorf("failed to stat exec %q (%w)", execPath, err) } // as execPath can be provided by this function, we might need a new `build-dir` - buildDir, err := getBuildDir(execPath, s.network.pluginDir) + buildDir, err := getBuildDir(req.ExecPath, s.network.pluginDir) if err != nil { return nil, err } - - var globalConfig map[string]interface{} - if req.GetNodeConfig() != "" { - if err := json.Unmarshal([]byte(req.GetNodeConfig()), &globalConfig); err != nil { - return nil, err - } - } else { - globalConfig = map[string]interface{}{} - } - - globalConfig[config.BuildDirKey] = buildDir + nodeFlags[config.BuildDirKey] = buildDir nodeConfig := node.Config{ Name: req.Name, - Flags: globalConfig, - BinaryPath: execPath, + Flags: nodeFlags, + BinaryPath: req.ExecPath, RedirectStdout: s.cfg.RedirectNodesOutput, RedirectStderr: s.cfg.RedirectNodesOutput, } @@ -767,10 +763,11 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb for k, v := range req.ChainConfigs { nodeConfig.ChainConfigFiles[k] = v } - _, err = s.network.nw.AddNode(nodeConfig) - if err != nil { + + if _, err := s.network.nw.AddNode(nodeConfig); err != nil { return nil, err } + if err := s.network.updateNodeInfo(); err != nil { return nil, err } From 0d40f984398aee58e68d9c3475620070ac043221 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 05:18:39 -0300 Subject: [PATCH 23/36] cleanup of server addnode, removenode, restartnode --- server/server.go | 59 ++++++++---------------------------------------- 1 file changed, 10 insertions(+), 49 deletions(-) diff --git a/server/server.go b/server/server.go index e2cb4385..9a25c57a 100644 --- a/server/server.go +++ b/server/server.go @@ -10,8 +10,6 @@ import ( "errors" "fmt" "io" - - //"io/fs" "net" "net/http" "os" @@ -25,7 +23,6 @@ import ( "github.com/ava-labs/avalanche-network-runner/network/node" "github.com/ava-labs/avalanche-network-runner/rpcpb" "github.com/ava-labs/avalanche-network-runner/utils" - "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/snow/networking/router" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" @@ -722,22 +719,6 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb s.mu.Lock() defer s.mu.Unlock() - /* - // user can override bin path for this node... - execPath := req.ExecPath - if execPath == "" { - // ...or use the same binary as the rest of the network - execPath = s.network.execPath - } - _, err := os.Stat(execPath) - if err != nil { - if errors.Is(err, fs.ErrNotExist) { - return nil, utils.ErrNotExists - } - return nil, fmt.Errorf("failed to stat exec %q (%w)", execPath, err) - } - */ - nodeFlags := map[string]interface{}{} if req.GetNodeConfig() != "" { if err := json.Unmarshal([]byte(req.GetNodeConfig()), &nodeFlags); err != nil { @@ -745,23 +726,13 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb } } - // as execPath can be provided by this function, we might need a new `build-dir` - buildDir, err := getBuildDir(req.ExecPath, s.network.pluginDir) - if err != nil { - return nil, err - } - nodeFlags[config.BuildDirKey] = buildDir - nodeConfig := node.Config{ - Name: req.Name, - Flags: nodeFlags, - BinaryPath: req.ExecPath, - RedirectStdout: s.cfg.RedirectNodesOutput, - RedirectStderr: s.cfg.RedirectNodesOutput, - } - nodeConfig.ChainConfigFiles = map[string]string{} - for k, v := range req.ChainConfigs { - nodeConfig.ChainConfigFiles[k] = v + Name: req.Name, + Flags: nodeFlags, + BinaryPath: req.ExecPath, + RedirectStdout: s.cfg.RedirectNodesOutput, + RedirectStderr: s.cfg.RedirectNodesOutput, + ChainConfigFiles: req.ChainConfigs, } if _, err := s.network.nw.AddNode(nodeConfig); err != nil { @@ -772,6 +743,9 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb return nil, err } + s.clusterInfo.NodeNames = s.network.nodeNames + s.clusterInfo.NodeInfos = s.network.nodeInfos + return &rpcpb.AddNodeResponse{ClusterInfo: s.clusterInfo}, nil } @@ -784,20 +758,14 @@ func (s *server) RemoveNode(ctx context.Context, req *rpcpb.RemoveNodeRequest) ( s.mu.Lock() defer s.mu.Unlock() - if _, ok := s.network.nodeInfos[req.Name]; !ok { - return nil, network.ErrNodeNotFound - } - if err := s.network.nw.RemoveNode(ctx, req.Name); err != nil { return nil, err } - zap.L().Info("waiting for local cluster readiness") - if err := s.network.waitForLocalClusterReady(ctx); err != nil { + if err := s.network.updateNodeInfo(); err != nil { return nil, err } - s.clusterInfo.Healthy = true s.clusterInfo.NodeNames = s.network.nodeNames s.clusterInfo.NodeInfos = s.network.nodeInfos @@ -826,15 +794,8 @@ func (s *server) RestartNode(ctx context.Context, req *rpcpb.RestartNodeRequest) return nil, err } - zap.L().Info("waiting for local cluster readiness") - if err := s.network.waitForLocalClusterReady(ctx); err != nil { - return nil, err - } - - // update with the new config s.clusterInfo.NodeNames = s.network.nodeNames s.clusterInfo.NodeInfos = s.network.nodeInfos - s.clusterInfo.Healthy = true return &rpcpb.RestartNodeResponse{ClusterInfo: s.clusterInfo}, nil } From 22d3ea20b14c4278badd93d4b26a2dbd64834698 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 05:27:32 -0300 Subject: [PATCH 24/36] fix unit tests --- local/network_test.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/local/network_test.go b/local/network_test.go index a68a5a13..a89ec614 100644 --- a/local/network_test.go +++ b/local/network_test.go @@ -1006,7 +1006,7 @@ func TestSetNodeName(t *testing.T) { config.Name = "" err = ln.setNodeName(config) assert.NoError(err) - assert.Equal("node2", config.Name) + assert.Equal("node1", config.Name) // Case: name given config.Name = "hi" @@ -1014,12 +1014,6 @@ func TestSetNodeName(t *testing.T) { assert.NoError(err) assert.Equal("hi", config.Name) - // Case: No name given again - config.Name = "" - err = ln.setNodeName(config) - assert.NoError(err) - assert.Equal("node3", config.Name) - // Case: name already present config.Name = "hi" ln.nodes = map[string]*localNode{"hi": nil} From 40e972c1f9c08cca1ebae74709d7cbd5b2e50d52 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 06:18:28 -0300 Subject: [PATCH 25/36] partial changes in config defs --- local/config.go | 13 ------------- local/default/{node3/config.json => flags.json} | 5 ++--- local/default/node0/config.json | 12 ------------ local/default/node0/flags.json | 3 +++ local/default/node1/config.json | 12 ------------ local/default/node1/flags.json | 3 +++ local/default/node2/config.json | 12 ------------ local/default/node2/flags.json | 3 +++ local/default/node3/flags.json | 3 +++ local/default/node4/config.json | 12 ------------ local/default/node4/flags.json | 3 +++ network/config.go | 4 ++++ 12 files changed, 21 insertions(+), 64 deletions(-) delete mode 100644 local/config.go rename local/default/{node3/config.json => flags.json} (85%) delete mode 100644 local/default/node0/config.json create mode 100644 local/default/node0/flags.json delete mode 100644 local/default/node1/config.json create mode 100644 local/default/node1/flags.json delete mode 100644 local/default/node2/config.json create mode 100644 local/default/node2/flags.json create mode 100644 local/default/node3/flags.json delete mode 100644 local/default/node4/config.json create mode 100644 local/default/node4/flags.json diff --git a/local/config.go b/local/config.go deleted file mode 100644 index e1b3fd0e..00000000 --- a/local/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package local - -func GetDefaultFlags() map[string]interface{} { - return map[string]interface{}{ - "network-peer-list-gossip-frequency": "250ms", - "network-max-reconnect-delay": "1s", - "public-ip": "127.0.0.1", - "health-check-frequency": "2s", - "api-admin-enabled": true, - "api-ipcs-enabled": true, - "index-enabled": true, - } -} diff --git a/local/default/node3/config.json b/local/default/flags.json similarity index 85% rename from local/default/node3/config.json rename to local/default/flags.json index 7d9fef52..f65c4a0a 100644 --- a/local/default/node3/config.json +++ b/local/default/flags.json @@ -1,12 +1,11 @@ { "network-peer-list-gossip-frequency":"250ms", "network-max-reconnect-delay":"1s", + "public-ip":"127.0.0.1", "health-check-frequency":"2s", "api-admin-enabled":true, "api-ipcs-enabled":true, "index-enabled":true, - "public-ip":"127.0.0.1", "log-display-level":"ERROR", - "log-level": "DEBUG", - "http-port": 9656 + "log-level": "DEBUG" } diff --git a/local/default/node0/config.json b/local/default/node0/config.json deleted file mode 100644 index 63ed5c39..00000000 --- a/local/default/node0/config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "network-peer-list-gossip-frequency":"250ms", - "network-max-reconnect-delay":"1s", - "health-check-frequency":"2s", - "api-admin-enabled":true, - "api-ipcs-enabled":true, - "index-enabled":true, - "public-ip":"127.0.0.1", - "log-display-level":"ERROR", - "log-level": "DEBUG", - "http-port": 9650 -} diff --git a/local/default/node0/flags.json b/local/default/node0/flags.json new file mode 100644 index 00000000..48dcf307 --- /dev/null +++ b/local/default/node0/flags.json @@ -0,0 +1,3 @@ +{ + "http-port": 9650 +} diff --git a/local/default/node1/config.json b/local/default/node1/config.json deleted file mode 100644 index c2ba7db0..00000000 --- a/local/default/node1/config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "network-peer-list-gossip-frequency":"250ms", - "network-max-reconnect-delay":"1s", - "health-check-frequency":"2s", - "api-admin-enabled":true, - "api-ipcs-enabled":true, - "index-enabled":true, - "public-ip":"127.0.0.1", - "log-display-level":"ERROR", - "log-level": "DEBUG", - "http-port": 9652 -} diff --git a/local/default/node1/flags.json b/local/default/node1/flags.json new file mode 100644 index 00000000..2f1a0783 --- /dev/null +++ b/local/default/node1/flags.json @@ -0,0 +1,3 @@ +{ + "http-port": 9652 +} diff --git a/local/default/node2/config.json b/local/default/node2/config.json deleted file mode 100644 index 2a3b67fc..00000000 --- a/local/default/node2/config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "network-peer-list-gossip-frequency":"250ms", - "network-max-reconnect-delay":"1s", - "health-check-frequency":"2s", - "api-admin-enabled":true, - "api-ipcs-enabled":true, - "index-enabled":true, - "public-ip":"127.0.0.1", - "log-display-level":"ERROR", - "log-level": "DEBUG", - "http-port": 9654 -} diff --git a/local/default/node2/flags.json b/local/default/node2/flags.json new file mode 100644 index 00000000..57fe3d94 --- /dev/null +++ b/local/default/node2/flags.json @@ -0,0 +1,3 @@ +{ + "http-port": 9654 +} diff --git a/local/default/node3/flags.json b/local/default/node3/flags.json new file mode 100644 index 00000000..4c3bf88f --- /dev/null +++ b/local/default/node3/flags.json @@ -0,0 +1,3 @@ +{ + "http-port": 9656 +} diff --git a/local/default/node4/config.json b/local/default/node4/config.json deleted file mode 100644 index ce2dc4c9..00000000 --- a/local/default/node4/config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "network-peer-list-gossip-frequency":"250ms", - "network-max-reconnect-delay":"1s", - "health-check-frequency":"2s", - "api-admin-enabled":true, - "api-ipcs-enabled":true, - "index-enabled":true, - "public-ip":"127.0.0.1", - "log-display-level":"ERROR", - "log-level": "DEBUG", - "http-port": 9658 -} diff --git a/local/default/node4/flags.json b/local/default/node4/flags.json new file mode 100644 index 00000000..7424fdd2 --- /dev/null +++ b/local/default/node4/flags.json @@ -0,0 +1,3 @@ +{ + "http-port": 9658 +} diff --git a/network/config.go b/network/config.go index bce7493c..3a47ae08 100644 --- a/network/config.go +++ b/network/config.go @@ -55,6 +55,10 @@ type Config struct { // and the node's config file has flag W set to Z, // then the node will be started with flag W set to Y. Flags map[string]interface{} `json:"flags"` + // Binary path to use per default, if not specified in node config + BinaryPath string `json:"binaryPath"` + // Chain config files to use per default, if not specified in node config + ChainConfigFiles map[string]string `json:"chainConfigFiles"` } // Validate returns an error if this config is invalid From 879ce37c021da6f7f7ea2e3b2c51ef1b72c4706b Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 06:21:56 -0300 Subject: [PATCH 26/36] unify cchain confs --- local/default/{node0 => }/cchain_config.json | 0 local/default/node0/flags.json | 3 - local/default/node0/staking.crt | 30 ------ local/default/node0/staking.key | 51 ---------- local/default/node1/cchain_config.json | 31 ------ local/default/node1/flags.json | 2 +- local/default/node1/staking.crt | 48 ++++----- local/default/node1/staking.key | 98 +++++++++--------- local/default/node2/cchain_config.json | 31 ------ local/default/node2/flags.json | 2 +- local/default/node2/staking.crt | 48 ++++----- local/default/node2/staking.key | 98 +++++++++--------- local/default/node3/cchain_config.json | 31 ------ local/default/node3/flags.json | 2 +- local/default/node3/staking.crt | 50 +++++----- local/default/node3/staking.key | 100 +++++++++---------- local/default/node4/cchain_config.json | 31 ------ local/default/node4/flags.json | 2 +- local/default/node4/staking.crt | 48 ++++----- local/default/node4/staking.key | 98 +++++++++--------- local/default/node5/flags.json | 3 + local/default/node5/staking.crt | 30 ++++++ local/default/node5/staking.key | 51 ++++++++++ 23 files changed, 382 insertions(+), 506 deletions(-) rename local/default/{node0 => }/cchain_config.json (100%) delete mode 100644 local/default/node0/flags.json delete mode 100644 local/default/node0/staking.crt delete mode 100644 local/default/node0/staking.key delete mode 100644 local/default/node1/cchain_config.json delete mode 100644 local/default/node2/cchain_config.json delete mode 100644 local/default/node3/cchain_config.json delete mode 100644 local/default/node4/cchain_config.json create mode 100644 local/default/node5/flags.json create mode 100644 local/default/node5/staking.crt create mode 100644 local/default/node5/staking.key diff --git a/local/default/node0/cchain_config.json b/local/default/cchain_config.json similarity index 100% rename from local/default/node0/cchain_config.json rename to local/default/cchain_config.json diff --git a/local/default/node0/flags.json b/local/default/node0/flags.json deleted file mode 100644 index 48dcf307..00000000 --- a/local/default/node0/flags.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "http-port": 9650 -} diff --git a/local/default/node0/staking.crt b/local/default/node0/staking.crt deleted file mode 100644 index b97df695..00000000 --- a/local/default/node0/staking.crt +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFNzCCAx8CCQC687XFxtDRSjANBgkqhkiG9w0BAQsFADB/MQswCQYDVQQGEwJV -UzELMAkGA1UECAwCTlkxDzANBgNVBAcMBkl0aGFjYTEQMA4GA1UECgwHQXZhbGFi -czEOMAwGA1UECwwFR2Vja28xDDAKBgNVBAMMA2F2YTEiMCAGCSqGSIb3DQEJARYT -c3RlcGhlbkBhdmFsYWJzLm9yZzAgFw0xOTA3MDIxNjEyMTVaGA8zMDE5MDcxMDE2 -MTIxNVowOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQKDAdBdmFs -YWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQDKYSRw/W0YpYH/MTQhiFrR0m89l6yTuzLpDtjudr/5RnhIPvtqk7YIGm/m9l29 -xwR4J5r7SZGs+70yBetkbS+h7PwJ2rmWDwbrdyJKvVBhqf8kSn+VU2LePSIcJj19 -3LDyWhV1H4lqNkUkcAR76Fh9qjMvA2p0vJ66+eDLXlph/RYapQx9HgOj/0BmAKMr -YCyo5BhRih+Ougg8aK4G9PQTIA5G2wTWW2QkHxM/QppFjZd/XwQeJ2H6ubWMFc5f -ttf6AzpJvFIDBu/JDCKWiCu5m8t4GL8w2OrIx8Js19lF4YYE2eojCreqgPi64S3o -cqwKsDoySTw6/5iKQ5BUYwUXX3z7EXOqD8SMHefUKeczj4WvAaZLzR27qXm55EgR -YQAIX4fhmY7NfSop3Wh0Eo62+JHoM/1g+UgOXlbnWpY95Mgd7/fwDSWLu4IxE0/u -q8VufIbfC4yrY8qlTVfAffI1ldRdvJjPJBPiQ0CNrOl60LVptpkGc9shH7wZ2bP0 -bEnYKTgLAfOzD8Ut71O2AOIa80A1GNFl4Yle/MSNJOcQOSpgtWdREzIUoenAjfuz -M4OeTr4cRg4+VYTAo9KHKriN1DuewNzGd8WjKAVHmcIMjqISLTlzMhdsdm+OmfQ6 -OvyX7v0GTOBbhP09NGcww5A0gCzXN18FS5oxnxe6OG9D0wIDAQABMA0GCSqGSIb3 -DQEBCwUAA4ICAQAqL1TWI1PTMm3JaXkhdTBe8tsk7+FsHAFzTcBVBsB8dkJNGhxb -dlu7XIm+AyGUn0j8siz8qojKbO+rEPV/ImTH5W7Q36rXSdgvNUWpKrKIC5S8PUF5 -T4pH+lpYIlQHnTaKMuqH3nO3I40IhEhPaa2wAwy2kDlz46fJcr6aMzj6Zg43J5UK -Zid+BQsiWAUau5V7CpC7GMCx4YdOZWWsT3dAsug9hvwTe81kK1JoTH0juwPTBH0t -xUgUVIWyuweM1UwYF3n8Hmwq6B46YmujhMDKT+3lgqZt7eZ1XvieLdBRlVQWzOa/ -6QYTkrqwPZioKIStrxVGYjk40qECNodCSCIwRDgbnQubRWrdslxiIyc5blJNuOV+ -jgv5d2EeUpwUjvpZuEV7FqPKGRgiG0jfl6Psms9gYUXd+y3ytG9HeoDNmLTSTBE4 -nCQXX935P2/xOuok6CpiGpP89DX7t8yiwk8LFNnY3rvv50nVy8kerVdnfHTmoMZ9 -/IBgojSIKov4lmPKdgzFfimzhbssVCa4DO/LIhTF7bQbH1ut/Oq7npdOpMjLYIBE -9lagvRVTVFwT/uwrCcXHCb21b/puwV94SNXVwt7BheFTFBdtxJrR4jjr2T5odLkX -6nQcY8V2OT7KOxn0KVc6pl3saJTLmL+H/3CtAao9NtmuUDapKINRSVNyvg== ------END CERTIFICATE----- diff --git a/local/default/node0/staking.key b/local/default/node0/staking.key deleted file mode 100644 index f4747a58..00000000 --- a/local/default/node0/staking.key +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY----- diff --git a/local/default/node1/cchain_config.json b/local/default/node1/cchain_config.json deleted file mode 100644 index 1817e410..00000000 --- a/local/default/node1/cchain_config.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "snowman-api-enabled": false, - "coreth-admin-api-enabled": false, - "coreth-admin-api-dir": "", - "eth-apis": ["public-eth", "public-eth-filter", "net", "web3", "internal-public-eth", "internal-public-blockchain", "internal-public-transaction-pool", "internal-public-account"], - "continuous-profiler-dir": "", - "continuous-profiler-frequency": 900000000000, - "continuous-profiler-max-files": 5, - "rpc-gas-cap": 50000000, - "rpc-tx-fee-cap": 100, - "preimages-enabled": false, - "pruning-enabled": true, - "snapshot-async": true, - "snapshot-verification-enabled": false, - "metrics-enabled": false, - "metrics-expensive-enabled": false, - "local-txs-enabled": false, - "api-max-duration": 0, - "ws-cpu-refill-rate": 0, - "ws-cpu-max-stored": 0, - "api-max-blocks-per-request": 0, - "allow-unfinalized-queries": false, - "allow-unprotected-txs": false, - "keystore-directory": "", - "keystore-external-signer": "", - "keystore-insecure-unlock-allowed": false, - "remote-tx-gossip-only-enabled": false, - "tx-regossip-frequency": 60000000000, - "tx-regossip-max-size": 15, - "log-level": "debug" -} diff --git a/local/default/node1/flags.json b/local/default/node1/flags.json index 2f1a0783..48dcf307 100644 --- a/local/default/node1/flags.json +++ b/local/default/node1/flags.json @@ -1,3 +1,3 @@ { - "http-port": 9652 + "http-port": 9650 } diff --git a/local/default/node1/staking.crt b/local/default/node1/staking.crt index a572af1d..b97df695 100644 --- a/local/default/node1/staking.crt +++ b/local/default/node1/staking.crt @@ -2,29 +2,29 @@ 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 -----END CERTIFICATE----- diff --git a/local/default/node1/staking.key b/local/default/node1/staking.key index c31bc808..f4747a58 100644 --- a/local/default/node1/staking.key +++ b/local/default/node1/staking.key @@ -1,51 +1,51 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/local/default/node2/cchain_config.json b/local/default/node2/cchain_config.json deleted file mode 100644 index 1817e410..00000000 --- a/local/default/node2/cchain_config.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "snowman-api-enabled": false, - "coreth-admin-api-enabled": false, - "coreth-admin-api-dir": "", - "eth-apis": ["public-eth", "public-eth-filter", "net", "web3", "internal-public-eth", "internal-public-blockchain", "internal-public-transaction-pool", "internal-public-account"], - "continuous-profiler-dir": "", - "continuous-profiler-frequency": 900000000000, - "continuous-profiler-max-files": 5, - "rpc-gas-cap": 50000000, - "rpc-tx-fee-cap": 100, - "preimages-enabled": false, - "pruning-enabled": true, - "snapshot-async": true, - "snapshot-verification-enabled": false, - "metrics-enabled": false, - "metrics-expensive-enabled": false, - "local-txs-enabled": false, - "api-max-duration": 0, - "ws-cpu-refill-rate": 0, - "ws-cpu-max-stored": 0, - "api-max-blocks-per-request": 0, - "allow-unfinalized-queries": false, - "allow-unprotected-txs": false, - "keystore-directory": "", - "keystore-external-signer": "", - "keystore-insecure-unlock-allowed": false, - "remote-tx-gossip-only-enabled": false, - "tx-regossip-frequency": 60000000000, - "tx-regossip-max-size": 15, - "log-level": "debug" -} diff --git a/local/default/node2/flags.json b/local/default/node2/flags.json index 57fe3d94..2f1a0783 100644 --- a/local/default/node2/flags.json +++ b/local/default/node2/flags.json @@ -1,3 +1,3 @@ { - "http-port": 9654 + "http-port": 9652 } diff --git a/local/default/node2/staking.crt b/local/default/node2/staking.crt index 65781b04..a572af1d 100644 --- a/local/default/node2/staking.crt +++ b/local/default/node2/staking.crt @@ -2,29 +2,29 @@ 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 -----END CERTIFICATE----- diff --git a/local/default/node2/staking.key b/local/default/node2/staking.key index 504cdfe3..c31bc808 100644 --- a/local/default/node2/staking.key +++ b/local/default/node2/staking.key @@ -1,51 +1,51 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/local/default/node3/cchain_config.json b/local/default/node3/cchain_config.json deleted file mode 100644 index 1817e410..00000000 --- a/local/default/node3/cchain_config.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "snowman-api-enabled": false, - "coreth-admin-api-enabled": false, - "coreth-admin-api-dir": "", - "eth-apis": ["public-eth", "public-eth-filter", "net", "web3", "internal-public-eth", "internal-public-blockchain", "internal-public-transaction-pool", "internal-public-account"], - "continuous-profiler-dir": "", - "continuous-profiler-frequency": 900000000000, - "continuous-profiler-max-files": 5, - "rpc-gas-cap": 50000000, - "rpc-tx-fee-cap": 100, - "preimages-enabled": false, - "pruning-enabled": true, - "snapshot-async": true, - "snapshot-verification-enabled": false, - "metrics-enabled": false, - "metrics-expensive-enabled": false, - "local-txs-enabled": false, - "api-max-duration": 0, - "ws-cpu-refill-rate": 0, - "ws-cpu-max-stored": 0, - "api-max-blocks-per-request": 0, - "allow-unfinalized-queries": false, - "allow-unprotected-txs": false, - "keystore-directory": "", - "keystore-external-signer": "", - "keystore-insecure-unlock-allowed": false, - "remote-tx-gossip-only-enabled": false, - "tx-regossip-frequency": 60000000000, - "tx-regossip-max-size": 15, - "log-level": "debug" -} diff --git a/local/default/node3/flags.json b/local/default/node3/flags.json index 4c3bf88f..57fe3d94 100644 --- a/local/default/node3/flags.json +++ b/local/default/node3/flags.json @@ -1,3 +1,3 @@ { - "http-port": 9656 + "http-port": 9654 } diff --git a/local/default/node3/staking.crt b/local/default/node3/staking.crt index f5debcc4..65781b04 100644 --- a/local/default/node3/staking.crt +++ b/local/default/node3/staking.crt @@ -2,29 +2,29 @@ MIIFNzCCAx8CCQC687XFxtDRSjANBgkqhkiG9w0BAQsFADB/MQswCQYDVQQGEwJV UzELMAkGA1UECAwCTlkxDzANBgNVBAcMBkl0aGFjYTEQMA4GA1UECgwHQXZhbGFi czEOMAwGA1UECwwFR2Vja28xDDAKBgNVBAMMA2F2YTEiMCAGCSqGSIb3DQEJARYT -c3RlcGhlbkBhdmFsYWJzLm9yZzAgFw0xOTA3MDIxNjEyMjVaGA8zMDE5MDcxMDE2 -MTIyNVowOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQKDAdBdmFs +c3RlcGhlbkBhdmFsYWJzLm9yZzAgFw0xOTA3MDIxNjEyMjJaGA8zMDE5MDcxMDE2 +MTIyMlowOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQKDAdBdmFs YWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQDZnDoDHE2nj82xDjH0Tb7OXMqQDHz+zbLidt6MSI1XB3vOAIEiPqrtenGnqRbV -Fcm5GZxvxh4YQD8CjKSk1qgZJczs0DPSiGQ8Efl4PGO4xnEbllgL3PURPWp7mEV3 -oh6fxICgQKTBlT671EnFzB5lyJWpumRzvA1vyhBMsY8aO+xdq5LUFltYzBdvpgLX -VaDwHZQ2PQEWtF0d0JO2N0WFFDGNmx6n8pKSeIAVDsTwZCZK+FCeeEyoGfXsINsc -0yCMQslawkfOMqA9yBV3Ji6QmFYKyGYt65MWGNqPA4XrIyliKwCCXwz9mjaWyN7r -Ayw9cWlLMODNmDORWzGRZ5290MEAEIZsqjYHVitRTM/RnNIadToZGO0y5uAkM14c -mTvnsK1CP92qtfSisq75W/I91drThoEtTK78UGOl/5Q1YBR08F+tSUWZWyHeI6UO -BUCGC2bCtmzKMl7vU25lG6mbCR1JuQi6RYpnfMjXH36lV4S7fTvSwwuR03h2F3H1 -eFkWNG2lbFrW0dzDCPg3lXwmFQ65hUcQhctznoBz5C1lF2eW03wuVgxinnuVlJHj -y/GrqmWsASn1PDuVs4k7k6DJfwyHAiA0uxXrGfxYvp7H8j4+2YOmWiWl5xYgrEDj -ur5n8Zx46PHQer2Avq3sbEGEe1MCtXJlj3drd5Him3m+NQIDAQABMA0GCSqGSIb3 -DQEBCwUAA4ICAQA40ax0dAMrbWikaJ5s6kjaGkPkYuxHNJbw047Do0hjw+ncXsxc -QDHmWcoHHpgMQCx0+vp8y+oKZ4pnqNfGSuOTo7/l05oQW/NbWw9mHwTiLMeI18/x -Ay+5LpOasw+omqWLbdbbWqL0o/RvtBdK2rkcHzTVzECgGSoxUFfZD+ck2odpH+aR -sQVu86AZVfclN2mjMyFSqMItqRcVw7rqr3Xy6FcgRQPykUnpguCEgcc9c54c1lQ9 -Zpddt4ezY7cTdk86oh7yA8QFchvtE9Zb5dJ5Vu9bdy9ig1kyscPTm+SeyhXRchUo -ql4H/czGBVMHUY41wY2VFz7HitECcTAIpS6QvcxxgYevGNjZZxyZvEA8SYpLMZyb -omk4enDTLd/xK1yF7VFodTDEyq63IAm0NTQZUVvIDfJeuzuNz55uxgdUq2RLpaJe -0bvrt9Obz+f5j2jonb2e0BuucwSdTyFXkUCxMW+piIUGkyrguAhlcHohDLEo2uB/ -iQ4fosGqqsl47b+TezT5pSSblkgUjiwz6eDpM4lQpx22MxsHVlxFHrcBNm0Td92v -FixrmllamAZbEz1tB//0bipKaOOZuhANJfrgN8BC6v2ahl4/SBuut09a0Azyxqpp -uCsyTnfNEd1W6c6noaq24s+7W7KKLIekuNn1NunnHqKqriEuH1xlxxPjYA== ------END CERTIFICATE----- \ No newline at end of file +AQC8mVDToHbkUF2gRdVfpydZLNKeQ38d6HZFkUM3U1dWLZFSZNvagN8hlQvY/tQu +3A40p19WgKbzWZre3tg1Akw8Jztdz9gl4RMn142IIO3CiwIptkE0JopbZhmG5fAC +2n/MXQtfieI3hzeR04LW4JgLKzf3Nn8xZdlBgJfBmL5qUUnE7O7IbJGGma6gSD3e +wetE6KQZtNtf0xRIv08doZKYwTl6ItkdGK76ufqq098GVwWvA1wSune4+MFgs9N4 +eFJj6Jyt85fiK/cwPx7KRdgYgBzrZQ4EPshRnwWrBTieOOaJvAA2RMxMEYzKRrJA +AsYI1zxtNyqIUaBTcxmaz+NXUGW+wHwITic0Gp/XQm2Lwr/lxIV6OnAlL3CgbSXi +rSnoG+eHQ+vDzBAcRDkTAgv/GUIzlfqT2StTK02uIBgJYzvFTG4plHitccRfy8wx +sh5Z8xG99lmPQQtLsnlQAV+Li06Cb8CH4hUVoiWiVs5QAahqWmv5fpoX0Es26RyU +HXGbjE202pyMMA7jUerUVKMijOoGZtcH6zB4p/dJ0TtToRwOgrA7NCI9AYVtqVXr +XG/udj8ur2r1bTVwIbHsOeTEP3gY0mHRWm2E/bLjt9vbYIRUxR8xWnLkbeBziNTw +g+36jdDF+6gu3cUz/nbSn8YY+Y1jjXuM3lqF8iMaAobhuwIDAQABMA0GCSqGSIb3 +DQEBCwUAA4ICAQAe2kC0HjKZU+dlnU2RlfBpB4QgzzrFE5N9A8F1MlE4vV3AzCg1 +RVdHPvniXzdNhDiiflK0l/cnrFv2X1TzYMrrA677/usHf2Bw0xjm/ipHOt5V+4TN +mZAIA4IPl09gP28IZLc9xSuq4FoHeM8OTxhttOlINhqpG9P5d6bPezW6ZzI3CdPP +CF69xK4GFlj/NQnAoFogid4ojYYNTj/cM4PYQU2KbrlzLyPuUk/CgwefXLMH87/H +e3kPDev80Tjv2Pm5nD937fZfgrEoyolKxiRVcfZVMxR7qhPhizjueD0DAkfQIs7L +YVSyx/qjEv2bBYaim5RQakUeHR1Xu5Xj/k5zr33t979ede50byQrcWm4H5JxnEpD +JxJnFfDOU6o14SKGHSrao5Z4C3dI55DM84WLASnlMI5BK4XtS3notLNzG8dfWWhT +9m0Hcry+wPNDcGr8Mtj1los/0bMDqMHC4jcFW1hrXCUUs9RYzE+N/xoqwCQSgN1P +E73uXTySWj5ovMR5TPF6PhcftLB/OziqO7FverEBpvGGHUAnUT61JtjodjXPbEdj +0VgyMOBY2y53HTXnx3dxeFZkUdRX/VZYy8tMK3MTY+7UIU5cWYnCZAo5LNcc0ukR +S6WS9+6eaQ6XRjhfNUjx9a7FzqapWdtTedpipmBP1Njap3g29iUuVnLQeg== +-----END CERTIFICATE----- diff --git a/local/default/node3/staking.key b/local/default/node3/staking.key index 03919b06..504cdfe3 100644 --- a/local/default/node3/staking.key +++ b/local/default/node3/staking.key @@ -1,51 +1,51 @@ -----BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY----- \ No newline at end of file +MIIJJwIBAAKCAgEAvJlQ06B25FBdoEXVX6cnWSzSnkN/Heh2RZFDN1NXVi2RUmTb +2oDfIZUL2P7ULtwONKdfVoCm81ma3t7YNQJMPCc7Xc/YJeETJ9eNiCDtwosCKbZB +NCaKW2YZhuXwAtp/zF0LX4niN4c3kdOC1uCYCys39zZ/MWXZQYCXwZi+alFJxOzu +yGyRhpmuoEg93sHrROikGbTbX9MUSL9PHaGSmME5eiLZHRiu+rn6qtPfBlcFrwNc +Erp3uPjBYLPTeHhSY+icrfOX4iv3MD8eykXYGIAc62UOBD7IUZ8FqwU4njjmibwA +NkTMTBGMykayQALGCNc8bTcqiFGgU3MZms/jV1BlvsB8CE4nNBqf10Jti8K/5cSF +ejpwJS9woG0l4q0p6Bvnh0Prw8wQHEQ5EwIL/xlCM5X6k9krUytNriAYCWM7xUxu +KZR4rXHEX8vMMbIeWfMRvfZZj0ELS7J5UAFfi4tOgm/Ah+IVFaIlolbOUAGoalpr ++X6aF9BLNukclB1xm4xNtNqcjDAO41Hq1FSjIozqBmbXB+sweKf3SdE7U6EcDoKw +OzQiPQGFbalV61xv7nY/Lq9q9W01cCGx7DnkxD94GNJh0VpthP2y47fb22CEVMUf +MVpy5G3gc4jU8IPt+o3QxfuoLt3FM/520p/GGPmNY417jN5ahfIjGgKG4bsCAwEA +AQKCAgA+uHIT3yKK7VslqPO7+tfwJSLqNSI6LQvgON30sUezRjY1A4vGD+OkxG+L +O7wO1Wn4As2G9AQRm/QQOGYIwvnda2Kn4S5N8psvPdU4t1K6xwXyH0Vx9Xs/yCWn +IiL+n/GuYicdH7rWoqZNXdz+XvTRig7zrPEB2ZA143EUlhqFOwFgdzc1+j0vWT6k +2UGSKkV2xjOExQvLw2PUiaLjBM++80uNHbe8oG/YvC7rzsg10Iz4VhKxu8eDAV82 +LLegMcucpEgu5XrWYa60Idm4hR/HjhuQASx3JvXxhwQYiwT4QY4Rsi8T3S9gANok +jvxKo2F+oS3cWGNRsGu0NOwH+yjsVyMYazcLOUesAAe85ttXgYr02+Z/uMnxqtOF +gjIHY3X5QZbD4l4gbwx+PLbjsj4KC6r3yZrr51PdLUrBvoqBhqwuCksdaMntWGME +u0V/ooJi4+uzCYzN06jFfAFXa2pWzVB5yKw1d6yYi9U/bPd4xn1phLUMHrC2bvdM +H8P18gAS6rkWn+ageiWRHmkf4uoKgv3PrMjijkBaGpf6xjv6+0Q393jdVIC7wgJV +8W0i1f1Awv68089mHBEarPTv3gz39251WFCPNQhEuSy79Li5zjwOprZXS0MnJXbm +B00IPTIw51KuaoueWzY1pA2IFQ/0sH3fo2JhD0pp1gI0Dde7EQKCAQEA7RVgNelk +3H3ZJsoOfOTFa03lnXuEfTAyxhEECRz64k54pSbEWV73PIeYByZvnsrKRydpYWUP +Cp/mKhAJH4UCf2hzY0GyO7/D6+HEKZdCg6a0DNKckAoFkBfeOlLJLjLVAW2eEVxz +tlFt+/WBE90GCvE5ovXuEhXGaPxCPp5giIN5phSzSD557bwwOyPwNKFZ7Ao77UNK +kz6EzcvQgqb205SRRKGpS8/T/9LcLsUYVkBfYQ/BayjffO+cQF4vH5rB4x/8/T7t +uUa79uY+LeGHgTSFIAui9LEK5ry//2hDJINsItYMks1Qo4Suu23pOuGerjiFTKWl +mOIoFmPmbebAcwKCAQEAy6WaJczPcKQQ/hqglQtxU6VfP49ZjUKkoi+OCmtvKDts +7pJfIkuluhnYGeqFfjnopw5bgZHNFm6Gccc5CwBtN6Wk1KnnOgDIg3kYCrfjtKy/ +BSSV3kLEBvhe9EJA56mFgP7RufMbHTXhXPGLkgE7JBZj2EKxp1qGYYVZesTMFwDM +KEHwzIGcFkyZsd2jptyLYqcfDKzTHmFGcw1mdtLWAUdpv3xrS3GvrCbUMqIodjRd +qkrg/d/kQpK7A3oLOWfa6eBQ2BXqaWB1x13bzJ2WlshxJAZ1p1ozKii5BQ9rvwWo +muI5vd7o6A9Xsl8QzluSSSPi+NhjZ64gMBrXciRvmQKCAQB/dB5k3TP71SwITle7 +jMEVDquCHgT7yA2DrWIeBBZb0xPItS6ZXRRM1hhEv8UB+MMFvYpJcarEa3Gw6y38 +Y+UT2XMuyQKoXE9XX+e09DwtylDBE/hW9wxGio5NjHPbAjjAq81uR+Vs/hnCehkK +NKgq+cOid9OkpVAk4Hg8cagzu3qKblZzYCLsS18ibA+WO6e73USaKLLOta1vdUKC ++n92/0eZPc9lkjTGMvVrr0mGFNUxuOaiVTbQU4AMmpV6yBezol6/RjVGhWBHOz/y +KmxOaY2nzJmuMf9KS+5rwAFYf86Ca9AWm4neXlYRLOVVYjWMM5Z1vhdoOSyT3ODj +9ElBAoIBAGCRPaBxF2j9k8U7ESy8CVg10g3MxxVSJcl2rW9JdKNqUoRqykvz/Tlb +afsYF4c8pJMbHs85OTxK2tv3MZiC8kdx99CUZL4/gtW9RWZHvuV9CPPCXoLPvC7l +9fjztd1kqJb7vq3jltbqJtyw+ZMZnFbHez8gmSeXqKNz3XN3AKRjz2vDoREI4OA+ +IJ+UTzcf28TDJNkY1t/QFt0V3KG55psipwWTVTmoRjpnCzabaH5s5IGNElWwpoff +FmlWpR3qnodKxGtDMS4Y/KC2ZDUKAU+s6uG/YmkiP6LdPqckod4qK8KORf1AR8dL +BzXhGJISIDMonkeMLM8MZd0JzWIl3vkCggEAPBkExd2j4VY5s+wQJdiMto5DDoci +kAEIvIkJY9I+Pt2lpinQKAcAAXbvueaJkJpq31f6Y66uok8QnD09bIQCABjjlIve +o7qQ+H8/iqHQX1nbHDzInaDdad3jYtkWUHjHPaKg2/ktyNkFtlSHskvvCEVw5aju +80Q3tRpQG9Pe4ZRjKEzNIpMXfQksFH0KwjwAVKwYJLqZxtNEYok4dpefSIsnH/rX +pwK/pyBrFqxU6PURULUJuLqRlaIRXAU31RmJsVs2JbmI7Cbtj2TmqAOxsLsi5UeJ +cZxcTAuYCNYMu88ktHul8YJdBF3rQKUOnsgW1cx7H6LGbuPZTpg8Sbyltw== +-----END RSA PRIVATE KEY----- diff --git a/local/default/node4/cchain_config.json b/local/default/node4/cchain_config.json deleted file mode 100644 index 1817e410..00000000 --- a/local/default/node4/cchain_config.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "snowman-api-enabled": false, - "coreth-admin-api-enabled": false, - "coreth-admin-api-dir": "", - "eth-apis": ["public-eth", "public-eth-filter", "net", "web3", "internal-public-eth", "internal-public-blockchain", "internal-public-transaction-pool", "internal-public-account"], - "continuous-profiler-dir": "", - "continuous-profiler-frequency": 900000000000, - "continuous-profiler-max-files": 5, - "rpc-gas-cap": 50000000, - "rpc-tx-fee-cap": 100, - "preimages-enabled": false, - "pruning-enabled": true, - "snapshot-async": true, - "snapshot-verification-enabled": false, - "metrics-enabled": false, - "metrics-expensive-enabled": false, - "local-txs-enabled": false, - "api-max-duration": 0, - "ws-cpu-refill-rate": 0, - "ws-cpu-max-stored": 0, - "api-max-blocks-per-request": 0, - "allow-unfinalized-queries": false, - "allow-unprotected-txs": false, - "keystore-directory": "", - "keystore-external-signer": "", - "keystore-insecure-unlock-allowed": false, - "remote-tx-gossip-only-enabled": false, - "tx-regossip-frequency": 60000000000, - "tx-regossip-max-size": 15, - "log-level": "debug" -} diff --git a/local/default/node4/flags.json b/local/default/node4/flags.json index 7424fdd2..4c3bf88f 100644 --- a/local/default/node4/flags.json +++ b/local/default/node4/flags.json @@ -1,3 +1,3 @@ { - "http-port": 9658 + "http-port": 9656 } diff --git a/local/default/node4/staking.crt b/local/default/node4/staking.crt index 95a826e2..f5debcc4 100644 --- a/local/default/node4/staking.crt +++ b/local/default/node4/staking.crt @@ -2,29 +2,29 @@ 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 -----END CERTIFICATE----- \ No newline at end of file diff --git a/local/default/node4/staking.key b/local/default/node4/staking.key index 461ec17c..03919b06 100644 --- a/local/default/node4/staking.key +++ b/local/default/node4/staking.key @@ -1,51 +1,51 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/local/default/node5/flags.json b/local/default/node5/flags.json new file mode 100644 index 00000000..7424fdd2 --- /dev/null +++ b/local/default/node5/flags.json @@ -0,0 +1,3 @@ +{ + "http-port": 9658 +} diff --git a/local/default/node5/staking.crt b/local/default/node5/staking.crt new file mode 100644 index 00000000..95a826e2 --- /dev/null +++ b/local/default/node5/staking.crt @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFNzCCAx8CCQC687XFxtDRSjANBgkqhkiG9w0BAQsFADB/MQswCQYDVQQGEwJV +UzELMAkGA1UECAwCTlkxDzANBgNVBAcMBkl0aGFjYTEQMA4GA1UECgwHQXZhbGFi +czEOMAwGA1UECwwFR2Vja28xDDAKBgNVBAMMA2F2YTEiMCAGCSqGSIb3DQEJARYT +c3RlcGhlbkBhdmFsYWJzLm9yZzAgFw0xOTA3MDIxNjEyMjlaGA8zMDE5MDcxMDE2 +MTIyOVowOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQKDAdBdmFs +YWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDgK5r5vdHtJFEgw7hGE/lzKaHcvwzr32armq0k9tYchJXfT3k1j1lXtBAdcUN3 +gSRKjgzH/vjbn0ea3AiDCUd2Mck/n0KcJZ43S5I7ZjP7rbav296bKCZ1Hr7r5gXY +Fhk+3aUsVfDUqAPBwyP8KeV31ARVA/s+WPeWqs69QXTdyJuBYE5pr40v1Sf+ebUI +nZ37uGY3kiO0Ex/JgcoQsGJzrWD/ztbRCFIvrdNJZd0pGvMlmTKp7XsMR3cpvqk7 +70//MLCdyGW/1IArTSuD1vd7mBX1JyVXKycYN0vIOtbgxPOFutUyqDOeP7o51q4i +PS3dCRgfmn/hWLwy+CtJe0BGKsb4tk0tKxo0se8v9JA8mUtnmzmMt4Y9jijOrCOB +7XwWKmJYEm8N5Ubcy6cp2oL8vQVtzz3PXrkFt+3cFt1jrjdpQYgH4jykkWDeOjEf +y1FCwzsNRudLTvLhfLn86/ZT4cLZ9JI7/WW0IPC8Fc7lhznJ+bIQUeEndaGdgVkx +uEg0MxdrMr0jU0IFoXySRXNRzcDWZShEjBTv7tnFxLmoNU+uJb/KpMH6sRYi3zs8 +5ecaMKNyG+LDmBahUlHx5hKAH49O8855+AMhsg91ONZJldjQX0oZrIKzK5BpsqeT +l4c2Yt/fALiZaeFk1pBEsvVeMOBCIuWE+b4UIEaLAOhxfwIDAQABMA0GCSqGSIb3 +DQEBCwUAA4ICAQB+2VXnqRqfG7H2/K0lgzxT+X9r1u+YDn0EaUGAG71s70Qnqbpn +X7tBmCKLN6XgPL0HrN933nwiYrmfb8S33zZ7kw8GJDvaTamLNyem4/8qTBQmnRwe +6rQ7SY2l73Ig87mR0WTi+rTnTTtc66+/jLtFeaj0Ycl9hBZXHKiULSGhsbUbwtkz +iuNlANhoNKXNIABRImUq6OwYhEQN0DwHXj79wkpyDYjKZwHuEZUknc8Pl2oQPBke +mil3tsrvGRkwhisnXX7tqh6rWKVZNJkO68hy7XO9aTXjbcB/7Y1K83ISNEyGPsH/ +pwFyd/j8O4modwh7Ulww1/hwcqnqiEFE3KzxX2pMh7VxeAmX2t5eXFZOlRx1lecM +XRkVu19lYDKQHGSrGxng+BFlSOB96e5kXIbuIXKpPAACoBQ/JZYbtHks9H8OtNYO +P2joqmnQ9wGkE5co1Ii//j2tuoCRCpK86mmbTlyNYvK+1/kkKcsaiiWXNrQsrIDZ +BFs0FwX5g24OP5+brxTlRZE01R6St8lQj4IUwAcIzG8fFmMCWaYavrCZTeYaEiyF +A0X2VA/vZ7x9D5P9Z5OakMhrMW+hJTYrpH1rm6KR7B26iU2kJRxTX7xQ9lrksqfB +7lX+q0iheeYA4cHbGJNWwWgd+FQsK/PTeiyr4rfqututdWA0IxoLRc3XFw== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/local/default/node5/staking.key b/local/default/node5/staking.key new file mode 100644 index 00000000..461ec17c --- /dev/null +++ b/local/default/node5/staking.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKQIBAAKCAgEA4Cua+b3R7SRRIMO4RhP5cymh3L8M699mq5qtJPbWHISV3095 +NY9ZV7QQHXFDd4EkSo4Mx/74259HmtwIgwlHdjHJP59CnCWeN0uSO2Yz+622r9ve +mygmdR6+6+YF2BYZPt2lLFXw1KgDwcMj/Cnld9QEVQP7Plj3lqrOvUF03cibgWBO +aa+NL9Un/nm1CJ2d+7hmN5IjtBMfyYHKELBic61g/87W0QhSL63TSWXdKRrzJZky +qe17DEd3Kb6pO+9P/zCwnchlv9SAK00rg9b3e5gV9SclVysnGDdLyDrW4MTzhbrV +Mqgznj+6OdauIj0t3QkYH5p/4Vi8MvgrSXtARirG+LZNLSsaNLHvL/SQPJlLZ5s5 +jLeGPY4ozqwjge18FipiWBJvDeVG3MunKdqC/L0Fbc89z165Bbft3BbdY643aUGI +B+I8pJFg3joxH8tRQsM7DUbnS07y4Xy5/Ov2U+HC2fSSO/1ltCDwvBXO5Yc5yfmy +EFHhJ3WhnYFZMbhINDMXazK9I1NCBaF8kkVzUc3A1mUoRIwU7+7ZxcS5qDVPriW/ +yqTB+rEWIt87POXnGjCjchviw5gWoVJR8eYSgB+PTvPOefgDIbIPdTjWSZXY0F9K +GayCsyuQabKnk5eHNmLf3wC4mWnhZNaQRLL1XjDgQiLlhPm+FCBGiwDocX8CAwEA +AQKCAgEApuMPrxmH7Xn6A+BxkYpRTVETNZnt7rQUZXDzse8pm3WBdgxeemdL5iUh +Uin+RjuYXwC9ty606hv8XOeuVo9T6kRKRNk157WBwjy6kwoVbSr4NJgFc5FCgDLx +hAFtHF/nT4wG6ajZcBfdJCU45wPx13G5/+jE5LerKzniS7ctX+d3Daw69CdDfva7 +nZHSGqXs9Xdkcb6UYf1SztuXKTGHOgM7kXXVKy18sg5AnAX/zhhIKBeTRjqMPqn9 +ptBQgVQ6RAtlkTGdvmBfQt1ipfYlrJee0THhdLGlmzufaWOUkSVO/qIHEn1yYD+l +TmXqoYbWXBXnJbAJwCQlh/SFlWDyiWWOxszxdwwT2ybw7OR3a0DEV0MbKJkUexyF +92Lr3qoBSZRFQnXVvBgjQOwnzEFph1ANuGY3odL8JSM1tHniIsCs4WhDPOsbAj+h +kwS51colMk3bNCZ3xeArjMLBVLgT7xLX/7ZYc7/oTEFWik+20TvSEWzdE1N/4gfJ +jEU/VqrnNjyev2w9Ak6bEkwZFLS6VZ9rTWTF9jk8C1aXj/RhfaaC33xXBbhn9HuX +lTu/JaLMp0Qc4aClqUYM6LlxIejH5b8fIxCNHJislXJDa6a6aQl85BiQODPFxVT5 +WCpQD4858EuLdX4BRW2fIGRY6DivR6uJRAmxLf+EwAg/rgTzUsECggEBAPSkHX5F +BhRgudF0MnwN+enj4SoXHhRG+DTorxO1Zh2qN9lnXO9nMKMCXVJLIVvGFuiMRSJ0 +VKf1u0UqaBF02MbIvbei7mzkkW0/74m04X37iyMmtnmooQ0GEV84oONwAt3DeeTg +vIpOtq9V26XHGaQDxcRFMFBuD02a2yf3JYkXj74i2scMP4xxMHMkJxGK9FSBOhnp +k/p0hMl3FVGfo5Ns5T1Rl3pMueEF3B5+BvrV1z14IN/0lwuhujrUUYS4Ew+Pk5zC +FSubfIQMqST1jvXXTaGgX0GPffa4lxgaDEATLewvL3Fjy27Xzl57i9ZvTNC4yFad +4okjr/eItHtKVHECggEBAOqUKww/6uiJMNvc2NxLUMxuzB07rqOZKT2VMBkG5Gzk +v81fDtlndD8cwHSqOLKscH/QKXD7WK3FCuvZSvMwCjEB4Pp1zgwJoBexuXvFDDbs +0T77Qiwe+2WmRIiYev5aRG3lnBMM8RDS/QPzEdoxHdzrFURYVl0rv5l/7rwB2Zd6 +xAYHcUpZc4ZaysEgqQCuZQqC7Mrq7qfByUthH28Yicz1978fpE3dx15ceqjU9jBQ +xUUwbeKT/UkQQvmYHdtgwEjhzVQL1OAAWkT6RssMqx2RAdi0SqWPFEhxNPHBpG9B +lKUDBBIM6du916On0Bjghh3WhxQKpTIzveNAiexbXO8CggEBANvJohGyc37VU7wg +18ZqTA/cwostD8IJ7K6kKb7cJy0Zo2l3mqAfJiwdULhBdWvdMPGmK+qDdxcbBy9h +pPOh9avJ5+BWyjwcsabkXRFr53ZnCp7/BcuRO3fW7r6Mwsby+DBCkX2Whuz/QNOP +oHF0yc138jKeMoTgDHGdYa2rNhbPiz24VLOlhmZnvq6DWXJCU7akDw3+swq9qhrS +GN4nPS+TEvUfG6ctzYWj3RmsAhtTCThZd7edKCK0HvsBi2dgdQdy55xbJefynlCI +i2IAF3s4/q7pxQrCntmNB3oI1N6wHH7n+Yi2rqsbyXVLK9vwTKPsj1h6Km8pF8ud +DwEBS5ECggEAMnq2FMnAbE/xgq6wwB85APUq2XOZbj0sYcMz+X7BMym6mKBHGsOn +gVlXlQN4dgKjpu2NrXF5MNPBOOWmulRxLQChgGRPdcmweMjXCGpr6XnmwW3iXIpC +QSqZfueJOCkGpruNbZAQZDVzGyF4iwKc0YiJKA72btBWR9r+7dhcEbvqaP27BGvh +b10kWpEDrVDaD3wDJtuNhe4uuhjpYcffB4s6yBcwDU2XdJfkEWban6UR/oSgcOy1 +yb5FG17/tdDJMCXfQKHXKmkJA+TzzQgp3o/w3MhXc+8pRzmNUiUAlKyBJ01R1+yN +eqsMt3wKTQAr/EnJAagUyovV5gxiYcl7YwKCAQAdOYcZx/l//O0Ftm6wpXGRjakN +IHFcP2i7mUW76Ewnj1iFa9Yv7pgbbBD9S1SMuetfIWcqSjDiUaymnDdA18NVYUYv +lhlUJ6kwdVusejqfcn+75Jf87BvWdIVGrNxPdB7Z/lmbWxFqyZi00R90UGBntaMu +zg/ibrLgatzA9SKgoWXm2bLt6bbXefmOgnZXyw8Qko70Xxtx5eBR1BDAQjDis81n +Lg96sJ3LOn7SXHfxJ3BtXshTJAoBFx6EpmulgNoPWIkJtd7XWYP6Yy22D+kK7OhH +Rq3CiYMtDmZoub/kVBL0MVdSm7hn1TSVTHjFoW6cwQ37iKHjkZVRwX1Kzt0B +-----END RSA PRIVATE KEY----- \ No newline at end of file From e065b039930fc4fa92d12a207c4c8643810f26bd Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 06:54:14 -0300 Subject: [PATCH 27/36] make the new defaults to work --- local/network.go | 113 +++++++++++++++++++++++----------------------- local/snapshot.go | 2 +- 2 files changed, 57 insertions(+), 58 deletions(-) diff --git a/local/network.go b/local/network.go index b0c57c04..575a1d72 100644 --- a/local/network.go +++ b/local/network.go @@ -93,8 +93,12 @@ type localNetwork struct { networkConfigFlags map[string]interface{} // directory where networks can be persistently saved snapshotsDir string - // config to apply to all nodes as default - defaultNodeConfig *node.Config + // flags to apply to all nodes per default + flags map[string]interface{} + // binary path to use per default + binaryPath string + // chain config files to use per default + chainConfigFiles map[string]string } var ( @@ -116,17 +120,11 @@ func init() { panic(err) } - defaultNetworkConfig = network.Config{ - NodeConfigs: make([]node.Config, DefaultNumNodes), - Flags: GetDefaultFlags(), - } - + // load genesis, updating validation start time genesis, err := fs.ReadFile(configsDir, "genesis.json") if err != nil { panic(err) } - - // update genesis validation start time var genesisMap map[string]interface{} if err = json.Unmarshal(genesis, &genesisMap); err != nil { panic(err) @@ -162,31 +160,51 @@ func init() { panic(err) } - defaultNetworkConfig.Genesis = string(updatedGenesis) + // load network flags + flagsBytes, err := fs.ReadFile(configsDir, "flags.json") + if err != nil { + panic(err) + } + flags := map[string]interface{}{} + if err = json.Unmarshal(flagsBytes, &flags); err != nil { + panic(err) + } + + // load chain config + cChainConfig, err := fs.ReadFile(configsDir, "cchain_config.json") + if err != nil { + panic(err) + } + + defaultNetworkConfig = network.Config{ + NodeConfigs: make([]node.Config, DefaultNumNodes), + Flags: flags, + Genesis: string(updatedGenesis), + ChainConfigFiles: map[string]string{ + "C": string(cChainConfig), + }, + } for i := 0; i < len(defaultNetworkConfig.NodeConfigs); i++ { - configFile, err := fs.ReadFile(configsDir, fmt.Sprintf("node%d/config.json", i)) + flagsBytes, err := fs.ReadFile(configsDir, fmt.Sprintf("node%d/flags.json", i+1)) if err != nil { panic(err) } - defaultNetworkConfig.NodeConfigs[i].ConfigFile = string(configFile) - stakingKey, err := fs.ReadFile(configsDir, fmt.Sprintf("node%d/staking.key", i)) - if err != nil { + flags := map[string]interface{}{} + if err = json.Unmarshal(flagsBytes, &flags); err != nil { panic(err) } - defaultNetworkConfig.NodeConfigs[i].StakingKey = string(stakingKey) - stakingCert, err := fs.ReadFile(configsDir, fmt.Sprintf("node%d/staking.crt", i)) + defaultNetworkConfig.NodeConfigs[i].Flags = flags + stakingKey, err := fs.ReadFile(configsDir, fmt.Sprintf("node%d/staking.key", i+1)) if err != nil { panic(err) } - defaultNetworkConfig.NodeConfigs[i].StakingCert = string(stakingCert) - cChainConfig, err := fs.ReadFile(configsDir, fmt.Sprintf("node%d/cchain_config.json", i)) + defaultNetworkConfig.NodeConfigs[i].StakingKey = string(stakingKey) + stakingCert, err := fs.ReadFile(configsDir, fmt.Sprintf("node%d/staking.crt", i+1)) if err != nil { panic(err) } - defaultNetworkConfig.NodeConfigs[i].ChainConfigFiles = map[string]string{ - "C": string(cChainConfig), - } + defaultNetworkConfig.NodeConfigs[i].StakingCert = string(stakingCert) defaultNetworkConfig.NodeConfigs[i].IsBeacon = true } @@ -298,12 +316,10 @@ func NewDefaultNetwork( // NewDefaultConfig creates a new default network config func NewDefaultConfig(binaryPath string) network.Config { config := defaultNetworkConfig + config.BinaryPath = binaryPath // Don't overwrite [DefaultNetworkConfig.NodeConfigs] config.NodeConfigs = make([]node.Config, len(defaultNetworkConfig.NodeConfigs)) copy(config.NodeConfigs, defaultNetworkConfig.NodeConfigs) - for i := 0; i < len(config.NodeConfigs); i++ { - config.NodeConfigs[i].BinaryPath = binaryPath - } return config } @@ -352,7 +368,9 @@ func (ln *localNetwork) loadConfig(ctx context.Context, networkConfig network.Co return fmt.Errorf("couldn't get network ID from genesis: %w", err) } - ln.networkConfigFlags = networkConfig.Flags + ln.flags = networkConfig.Flags + ln.binaryPath = networkConfig.BinaryPath + ln.chainConfigFiles = networkConfig.ChainConfigFiles // Sort node configs so beacons start first var nodeConfigs []node.Config @@ -389,44 +407,29 @@ func (ln *localNetwork) AddNode(nodeConfig node.Config) (node.Node, error) { return nil, network.ErrStopped } - // set defaults only if this is not the first node - if ln.defaultNodeConfig != nil { - if nodeConfig.BinaryPath == "" { - nodeConfig.BinaryPath = ln.defaultNodeConfig.BinaryPath - } - nodeConfig.Flags = ln.defaultNodeConfig.Flags - nodeConfig.ChainConfigFiles = ln.defaultNodeConfig.ChainConfigFiles - } - return ln.addNode(nodeConfig) } // Assumes [ln.lock] is held and [ln.Stop] hasn't been called. func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { if nodeConfig.Flags == nil { - nodeConfig.Flags = make(map[string]interface{}) + nodeConfig.Flags = map[string]interface{}{} + } + if nodeConfig.ChainConfigFiles == nil { + nodeConfig.ChainConfigFiles = map[string]string{} } - // init the default config if they haven't been initialized yet - // this should therefore be running for the first node only - if ln.defaultNodeConfig == nil { - ln.defaultNodeConfig = &node.Config{ - BinaryPath: nodeConfig.BinaryPath, - Flags: GetDefaultFlags(), - ChainConfigFiles: map[string]string{}, - } - // after the defaults, assign all the ones from the networkConfig - for k, v := range ln.networkConfigFlags { - ln.defaultNodeConfig.Flags[k] = v - } - if nodeConfig.Flags[config.WhitelistedSubnetsKey] != nil { - ln.defaultNodeConfig.Flags[config.WhitelistedSubnetsKey] = nodeConfig.Flags[config.WhitelistedSubnetsKey] - } - - for k, v := range nodeConfig.ChainConfigFiles { - ln.defaultNodeConfig.ChainConfigFiles[k] = v + // set defaults + if nodeConfig.BinaryPath == "" { + nodeConfig.BinaryPath = ln.binaryPath + } + for k, v := range ln.chainConfigFiles { + _, ok := nodeConfig.ChainConfigFiles[k] + if !ok { + nodeConfig.ChainConfigFiles[k] = v } } + addNetworkFlags(ln.log, ln.flags, nodeConfig.Flags) // it shouldn't happen that just one is empty, most probably both, // but in any case if just one is empty it's unusable so we just assign a new one. @@ -778,10 +781,6 @@ func (ln *localNetwork) buildFlags( nodeDir string, nodeConfig *node.Config, ) (buildFlagsReturn, error) { - // Add flags in [ln.Flags] to [nodeConfig.Flags] - // Assumes [nodeConfig.Flags] is non-nil - addNetworkFlags(ln.log, ln.defaultNodeConfig.Flags, nodeConfig.Flags) - // httpHost from all configs for node httpHost, err := getConfigEntry(nodeConfig.Flags, configFile, config.HTTPHostKey, "") if err != nil { diff --git a/local/snapshot.go b/local/snapshot.go index e652a060..88cec678 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -88,7 +88,7 @@ func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) ( } // make copy of network flags networkConfigFlags := make(map[string]interface{}) - for fk, fv := range ln.defaultNodeConfig.Flags { + for fk, fv := range ln.flags { networkConfigFlags[fk] = fv } // remove all log dir references From 5eff382dde96223fc908f30428ed9392cc4de9ea Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 06:59:28 -0300 Subject: [PATCH 28/36] fix unit tests --- local/network_test.go | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/local/network_test.go b/local/network_test.go index a89ec614..39c86700 100644 --- a/local/network_test.go +++ b/local/network_test.go @@ -160,11 +160,9 @@ func newLocalTestOneNodeCreator(assert *assert.Assertions, networkConfig network func (lt *localTestOneNodeCreator) NewNodeProcess(config node.Config, flags ...string) (NodeProcess, error) { lt.assert.True(config.IsBeacon) expectedConfig := lt.networkConfig.NodeConfigs[0] - // TODO without this the test FAILS, is this the correct way to fix it? - expectedConfig.Flags = GetDefaultFlags() - lt.assert.EqualValues(expectedConfig.ChainConfigFiles, config.ChainConfigFiles) + lt.assert.EqualValues(lt.networkConfig.ChainConfigFiles, config.ChainConfigFiles) lt.assert.EqualValues(expectedConfig.ConfigFile, config.ConfigFile) - lt.assert.EqualValues(expectedConfig.BinaryPath, config.BinaryPath) + lt.assert.EqualValues(lt.networkConfig.BinaryPath, config.BinaryPath) lt.assert.EqualValues(expectedConfig.IsBeacon, config.IsBeacon) lt.assert.EqualValues(expectedConfig.Name, config.Name) lt.assert.EqualValues(expectedConfig.StakingCert, config.StakingCert) @@ -722,9 +720,6 @@ func TestFlags(t *testing.T) { "test2-node-config-flag": "config", } - for k, v := range GetDefaultFlags() { - expectedFlags[k] = v - } nw, err := newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestFlagCheckProcessCreator{ // after creating the network, one flag should have been overridden by the node configs expectedFlags: expectedFlags, @@ -752,9 +747,6 @@ func TestFlags(t *testing.T) { v := &networkConfig.NodeConfigs[i] v.Flags = flags } - for k, v := range GetDefaultFlags() { - flags[k] = v - } nw, err = newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestFlagCheckProcessCreator{ // after creating the network, only node configs should exist expectedFlags: flags, @@ -781,9 +773,6 @@ func TestFlags(t *testing.T) { v := &networkConfig.NodeConfigs[i] v.Flags = nil } - for k, v := range GetDefaultFlags() { - flags[k] = v - } nw, err = newNetwork(logging.NoLog{}, newMockAPISuccessful, &localTestFlagCheckProcessCreator{ // after creating the network, only flags from the network config should exist expectedFlags: flags, From d4dbb3233b94767d58795630d5afd9b05d87b906 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 07:01:33 -0300 Subject: [PATCH 29/36] fix comments --- local/network.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/local/network.go b/local/network.go index 575a1d72..7d5b9574 100644 --- a/local/network.go +++ b/local/network.go @@ -368,6 +368,7 @@ func (ln *localNetwork) loadConfig(ctx context.Context, networkConfig network.Co return fmt.Errorf("couldn't get network ID from genesis: %w", err) } + // save node defaults ln.flags = networkConfig.Flags ln.binaryPath = networkConfig.BinaryPath ln.chainConfigFiles = networkConfig.ChainConfigFiles @@ -419,7 +420,7 @@ func (ln *localNetwork) addNode(nodeConfig node.Config) (node.Node, error) { nodeConfig.ChainConfigFiles = map[string]string{} } - // set defaults + // load node defaults if nodeConfig.BinaryPath == "" { nodeConfig.BinaryPath = ln.binaryPath } From de809c73ad9fa03e696ae503a773557dbd2cf2d8 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 07:11:39 -0300 Subject: [PATCH 30/36] make server creating again networks with new ports --- server/network.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server/network.go b/server/network.go index 3bd41b1f..39e37592 100644 --- a/server/network.go +++ b/server/network.go @@ -168,6 +168,7 @@ func (lc *localNetwork) createConfig() error { return err } + delete(cfg.NodeConfigs[i].Flags, config.HTTPPortKey) cfg.NodeConfigs[i].Flags[config.LogsDirKey] = logDir cfg.NodeConfigs[i].Flags[config.DBPathKey] = dbDir if buildDir != "" { From 4d0d850c56a64498b2a979678c10fc7ef282c850 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 07:40:49 -0300 Subject: [PATCH 31/36] fixes for config file not specified --- local/blockchain.go | 9 ++++----- local/snapshot.go | 8 +++++--- server/network.go | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/local/blockchain.go b/local/blockchain.go index db658c89..56159208 100644 --- a/local/blockchain.go +++ b/local/blockchain.go @@ -440,13 +440,12 @@ func (ln *localNetwork) restartNodesWithWhitelistedSubnets( zap.L().Info("restarting all nodes to whitelist subnet", zap.Strings("whitelisted-subnets", whitelistedSubnetIDs), ) + + // change default setting + ln.flags[config.WhitelistedSubnetsKey] = whitelistedSubnets + for nodeName, node := range ln.nodes { - // replace WhitelistedSubnetsKey flag nodeConfig := node.GetConfig() - nodeConfig.ConfigFile, err = utils.SetJSONKey(nodeConfig.ConfigFile, config.WhitelistedSubnetsKey, whitelistedSubnets) - if err != nil { - return err - } zap.L().Info("removing and adding back the node for whitelisted subnets", zap.String("node-name", nodeName)) if err := ln.removeNode(ctx, nodeName); err != nil { diff --git a/local/snapshot.go b/local/snapshot.go index 88cec678..45af2287 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -94,9 +94,11 @@ func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) ( // remove all log dir references delete(networkConfigFlags, config.LogsDirKey) for nodeName, nodeConfig := range nodesConfig { - nodeConfig.ConfigFile, err = utils.SetJSONKey(nodeConfig.ConfigFile, config.LogsDirKey, "") - if err != nil { - return "", err + if nodeConfig.ConfigFile != "" { + nodeConfig.ConfigFile, err = utils.SetJSONKey(nodeConfig.ConfigFile, config.LogsDirKey, "") + if err != nil { + return "", err + } } delete(nodeConfig.Flags, config.LogsDirKey) nodesConfig[nodeName] = nodeConfig diff --git a/server/network.go b/server/network.go index 39e37592..acf3d1cc 100644 --- a/server/network.go +++ b/server/network.go @@ -273,12 +273,12 @@ func (lc *localNetwork) createBlockchains( return } - if err := lc.waitForLocalClusterReady(ctx); err != nil { + if err := lc.updateNodeInfo(); err != nil { lc.startErrCh <- err return } - if err := lc.updateNodeInfo(); err != nil { + if err := lc.waitForLocalClusterReady(ctx); err != nil { lc.startErrCh <- err return } From 03dd203955e5f3d46553cb1569123289e0eb05fd Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 07:55:01 -0300 Subject: [PATCH 32/36] fix whitelisted subnets for more than one blockchain --- local/blockchain.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/local/blockchain.go b/local/blockchain.go index 56159208..4feba3f5 100644 --- a/local/blockchain.go +++ b/local/blockchain.go @@ -447,6 +447,9 @@ func (ln *localNetwork) restartNodesWithWhitelistedSubnets( for nodeName, node := range ln.nodes { nodeConfig := node.GetConfig() + // delete node specific flag so as to use default one + delete(nodeConfig.Flags, config.WhitelistedSubnetsKey) + zap.L().Info("removing and adding back the node for whitelisted subnets", zap.String("node-name", nodeName)) if err := ln.removeNode(ctx, nodeName); err != nil { return err From 4621bf337890be0f4ab61fac9dc1f000d25fe021 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 07:56:40 -0300 Subject: [PATCH 33/36] lint --- local/network.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/local/network.go b/local/network.go index 7d5b9574..2c092da3 100644 --- a/local/network.go +++ b/local/network.go @@ -89,8 +89,6 @@ type localNetwork struct { // rootDir is the root directory under which we write all node // logs, databases, etc. rootDir string - // flags from the networkConfig - networkConfigFlags map[string]interface{} // directory where networks can be persistently saved snapshotsDir string // flags to apply to all nodes per default From 2db301cb90216001c89e72d5a0b7d0baab6602be Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 08:13:28 -0300 Subject: [PATCH 34/36] keep copy of defaults in snapshot --- local/snapshot.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/local/snapshot.go b/local/snapshot.go index 45af2287..e8cbe19a 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -128,10 +128,13 @@ func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) ( } // save network conf networkConfig := network.Config{ - Genesis: string(ln.genesis), - Flags: networkConfigFlags, - NodeConfigs: []node.Config{}, + Genesis: string(ln.genesis), + Flags: networkConfigFlags, + NodeConfigs: []node.Config{}, + BinaryPath: ln.binaryPath, + ChainConfigFiles: ln.chainConfigFiles, } + for _, nodeConfig := range nodesConfig { // no need to save this, will be generated automatically on snapshot load networkConfig.NodeConfigs = append(networkConfig.NodeConfigs, nodeConfig) From fce28a8c5ea8ccf386f40e79b6960149a9b0c1b2 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 09:33:08 -0300 Subject: [PATCH 35/36] improve network config copy --- local/network.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/local/network.go b/local/network.go index 2c092da3..7229159f 100644 --- a/local/network.go +++ b/local/network.go @@ -311,6 +311,22 @@ func NewDefaultNetwork( return NewNetwork(log, config, "", "") } +func copyMapStringInterface(flags map[string]interface{}) map[string]interface{} { + outFlags := map[string]interface{}{} + for k, v := range flags { + outFlags[k] = v + } + return outFlags +} + +func copyMapStringString(flags map[string]string) map[string]string { + outFlags := map[string]string{} + for k, v := range flags { + outFlags[k] = v + } + return outFlags +} + // NewDefaultConfig creates a new default network config func NewDefaultConfig(binaryPath string) network.Config { config := defaultNetworkConfig @@ -318,6 +334,12 @@ func NewDefaultConfig(binaryPath string) network.Config { // Don't overwrite [DefaultNetworkConfig.NodeConfigs] config.NodeConfigs = make([]node.Config, len(defaultNetworkConfig.NodeConfigs)) copy(config.NodeConfigs, defaultNetworkConfig.NodeConfigs) + // copy maps + config.ChainConfigFiles = copyMapStringString(config.ChainConfigFiles) + config.Flags = copyMapStringInterface(config.Flags) + for i := range config.NodeConfigs { + config.NodeConfigs[i].Flags = copyMapStringInterface(config.NodeConfigs[i].Flags) + } return config } From 64283e0f8685d7c0b4091f0d9b3e8549442164af Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Thu, 4 Aug 2022 13:13:34 -0300 Subject: [PATCH 36/36] address PR comments --- client/client.go | 3 +-- server/network.go | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/client.go b/client/client.go index 8cca43c1..e351b471 100644 --- a/client/client.go +++ b/client/client.go @@ -240,8 +240,7 @@ func (c *client) AddNode(ctx context.Context, name string, execPath string, opts } zap.L().Info("add node", zap.String("name", name)) - r, err := c.controlc.AddNode(ctx, req) - return r, err + return c.controlc.AddNode(ctx, req) } func (c *client) RemoveNode(ctx context.Context, name string) (*rpcpb.RemoveNodeResponse, error) { diff --git a/server/network.go b/server/network.go index acf3d1cc..7bb25e7b 100644 --- a/server/network.go +++ b/server/network.go @@ -168,7 +168,10 @@ func (lc *localNetwork) createConfig() error { return err } + // remove http port defined in local network config, to get dynamic port + // generation when creating a new network delete(cfg.NodeConfigs[i].Flags, config.HTTPPortKey) + cfg.NodeConfigs[i].Flags[config.LogsDirKey] = logDir cfg.NodeConfigs[i].Flags[config.DBPathKey] = dbDir if buildDir != "" {