Merge branch 'main' into move-restart-to-local

This commit is contained in:
Felipe Madero
2022-08-02 20:10:24 -03:00
10 changed files with 573 additions and 573 deletions
+5 -5
View File
@@ -389,7 +389,7 @@ avalanche-network-runner control add-node \
--avalanchego-path ${AVALANCHEGO_EXEC_PATH}
```
You can also provide additional flags that specify the node's config, and what custom VMs it supports:
You can also provide additional flags that specify the node's config:
```
--node-config '{"index-enabled":false, "api-admin-enabled":true,"network-peer-list-gossip-frequency":"300ms"}'
@@ -460,7 +460,7 @@ avalanche-network-runner server \
curl -X POST -k http://localhost:8081/v1/ping -d ''
```
To start the cluster with custom VMs:
To start the cluster with custom chains:
```bash
# or download from https://github.com/ava-labs/subnet-cli/releases
@@ -490,7 +490,7 @@ find ${HOME}/go/src/github.com/ava-labs/avalanchego/build
# .../build/plugins/evm
# .../build/avalanchego
# generate the genesis for the custom VM
# generate the genesis for the custom chain
export CHAIN_ID=99999
export GENESIS_ADDRESS="0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"
cat <<EOF > /tmp/subnet-evm.genesis.json
@@ -574,7 +574,7 @@ avalanche-network-runner server \
curl -X POST -k http://localhost:8081/v1/ping -d ''
```
To start the cluster with custom VMs:
To start the cluster with custom chains:
```bash
# or download from https://github.com/ava-labs/subnet-cli/releases
@@ -603,7 +603,7 @@ find ${HOME}/go/src/github.com/ava-labs/avalanchego/build
# .../build/plugins/evm
# .../build/avalanchego
# generate the genesis for the custom VM
# generate the genesis for the custom chain
cd ${HOME}/go/src/github.com/ava-labs/blobvm
go install -v ./cmd/blob-cli
echo "[]" > /tmp/alloc.json
+7 -7
View File
@@ -117,8 +117,8 @@ func (c *client) Start(ctx context.Context, execPath string, opts ...OpOption) (
if ret.rootDataDir != "" {
req.RootDataDir = &ret.rootDataDir
}
if ret.pluginDir != "" {
req.PluginDir = &ret.pluginDir
if ret.buildDir != "" {
req.BuildDir = &ret.buildDir
}
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.pluginDir != "" {
req.PluginDir = &ret.pluginDir
if ret.buildDir != "" {
req.BuildDir = &ret.buildDir
}
if ret.rootDataDir != "" {
req.RootDataDir = &ret.rootDataDir
@@ -335,7 +335,7 @@ type Op struct {
whitelistedSubnets string
globalNodeConfig string
rootDataDir string
pluginDir string
buildDir string
blockchainSpecs []*rpcpb.BlockchainSpec
customNodeConfigs map[string]string
numSubnets uint32
@@ -380,9 +380,9 @@ func WithRootDataDir(rootDataDir string) OpOption {
}
}
func WithPluginDir(pluginDir string) OpOption {
func WithBuildDir(buildDir string) OpOption {
return func(op *Op) {
op.pluginDir = pluginDir
op.buildDir = buildDir
}
}
+9 -9
View File
@@ -74,7 +74,7 @@ func NewCommand() *cobra.Command {
var (
avalancheGoBinPath string
numNodes uint32
pluginDir string
buildDir string
globalNodeConfig string
addNodeConfig string
blockchainSpecsStr string
@@ -104,10 +104,10 @@ func newStartCommand() *cobra.Command {
"number of nodes of the network",
)
cmd.PersistentFlags().StringVar(
&pluginDir,
"plugin-dir",
&buildDir,
"build-dir",
"",
"[optional] plugin directory",
"[optional] build directory",
)
cmd.PersistentFlags().StringVar(
&rootDataDir,
@@ -157,7 +157,7 @@ func startFunc(cmd *cobra.Command, args []string) error {
opts := []client.OpOption{
client.WithNumNodes(numNodes),
client.WithPluginDir(pluginDir),
client.WithBuildDir(buildDir),
client.WithWhitelistedSubnets(whitelistedSubnets),
client.WithRootDataDir(rootDataDir),
}
@@ -765,10 +765,10 @@ func newLoadSnapshotCommand() *cobra.Command {
"avalanchego binary path",
)
cmd.PersistentFlags().StringVar(
&pluginDir,
"plugin-dir",
&buildDir,
"build-dir",
"",
"plugin directory",
"build directory",
)
cmd.PersistentFlags().StringVar(
&rootDataDir,
@@ -800,7 +800,7 @@ func loadSnapshotFunc(cmd *cobra.Command, args []string) error {
opts := []client.OpOption{
client.WithExecPath(avalancheGoBinPath),
client.WithPluginDir(pluginDir),
client.WithBuildDir(buildDir),
client.WithRootDataDir(rootDataDir),
}
+16 -14
View File
@@ -38,7 +38,7 @@ const (
validationDuration = 365 * 24 * time.Hour
// weight assigned to subnet validators
subnetValidatorsWeight = 1000
// check period for blockchain logs while waiting for custom VMs to be ready
// check period for blockchain logs while waiting for custom chains to be ready
blockchainLogPullFrequency = time.Second
// check period while waiting for all validators to be ready
waitForValidatorsPullFrequency = time.Second
@@ -50,7 +50,7 @@ var (
)
type blockchainInfo struct {
vmName string
chainName string
vmID ids.ID
subnetID ids.ID
blockchainID ids.ID
@@ -79,12 +79,12 @@ func (ln *localNetwork) CreateBlockchains(
) error {
ln.lock.Lock()
defer ln.lock.Unlock()
chainInfos, err := ln.installCustomVMs(ctx, chainSpecs)
chainInfos, err := ln.installCustomChains(ctx, chainSpecs)
if err != nil {
return err
}
if err := ln.waitForCustomVMsReady(ctx, chainInfos); err != nil {
if err := ln.waitForCustomChainsReady(ctx, chainInfos); err != nil {
return err
}
return nil
@@ -102,14 +102,14 @@ func (ln *localNetwork) CreateSubnets(
return nil
}
// provisions local cluster and install custom VMs if applicable
// provisions local cluster and install custom chains if applicable
// assumes the local cluster is already set up and healthy
func (ln *localNetwork) installCustomVMs(
func (ln *localNetwork) installCustomChains(
ctx context.Context,
chainSpecs []network.BlockchainSpec,
) ([]blockchainInfo, error) {
println()
color.Outf("{{blue}}{{bold}}create and install custom VMs{{/}}\n")
color.Outf("{{blue}}{{bold}}create and install custom chains{{/}}\n")
clientURI, err := ln.getClientURI()
if err != nil {
@@ -215,7 +215,9 @@ func (ln *localNetwork) installCustomVMs(
return nil, err
}
chainInfos[i] = blockchainInfo{
vmName: chainSpec.VmName,
// we keep a record of VM name in blockchain name field,
// as there is no way to recover VM name from VM ID
chainName: chainSpec.VmName,
vmID: vmID,
subnetID: subnetID,
blockchainID: blockchainIDs[i],
@@ -324,12 +326,12 @@ func (ln *localNetwork) installSubnets(
return subnetIDs, nil
}
func (ln *localNetwork) waitForCustomVMsReady(
func (ln *localNetwork) waitForCustomChainsReady(
ctx context.Context,
chainInfos []blockchainInfo,
) error {
println()
color.Outf("{{blue}}{{bold}}waiting for custom VMs to report healthy...{{/}}\n")
color.Outf("{{blue}}{{bold}}waiting for custom chains to report healthy...{{/}}\n")
if err := ln.healthy(ctx); err != nil {
return err
@@ -349,7 +351,7 @@ func (ln *localNetwork) waitForCustomVMsReady(
}
for nodeName, node := range ln.nodes {
zap.L().Info("inspecting node log directory for custom VM logs",
zap.L().Info("inspecting node log directory for custom chain logs",
zap.String("node-name", nodeName),
zap.String("log-dir", node.GetLogsDir()),
)
@@ -387,10 +389,10 @@ func (ln *localNetwork) waitForCustomVMsReady(
}
println()
color.Outf("{{green}}{{bold}}all custom VMs are running!!!{{/}}\n")
color.Outf("{{green}}{{bold}}all custom chains are running!!!{{/}}\n")
println()
color.Outf("{{green}}{{bold}}all custom VMs are ready on RPC server-side -- network-runner RPC client can poll and query the cluster status{{/}}\n")
color.Outf("{{green}}{{bold}}all custom chains are ready on RPC server-side -- network-runner RPC client can poll and query the cluster status{{/}}\n")
return nil
}
@@ -728,7 +730,7 @@ func createBlockchains(
testKeyAddr ids.ShortID,
) ([]ids.ID, error) {
println()
color.Outf("{{green}}creating blockchain for each custom VM{{/}}\n")
color.Outf("{{green}}creating each custom chain{{/}}\n")
blockchainIDs := make([]ids.ID, len(chainSpecs))
for i, chainSpec := range chainSpecs {
vmName := chainSpec.VmName
+417 -410
View File
File diff suppressed because it is too large Load Diff
+22 -16
View File
@@ -152,15 +152,18 @@ message ClusterInfo {
// Maps from the node ID to its attached peer infos.
map<string, ListOfAttachedPeerInfo> attached_peer_infos = 6;
// Set to "true" once custom VMs are ready.
bool custom_vms_healthy = 7;
// The map of custom VM IDs in "ids.ID" format to its VM information.
map<string, CustomVmInfo> custom_vms = 8;
// Set to "true" once custom blockchains are ready.
bool custom_chains_healthy = 7;
// The map of blockchain IDs in "ids.ID" format to its blockchain information.
map<string, CustomChainInfo> custom_chains = 8;
repeated string subnets = 9;
}
message CustomVmInfo {
string vm_name = 1;
message CustomChainInfo {
// Blockchain name given to the create blockchain TX
// Currently used to keep a record of the VM name,
// which is not saved anywhere and can't be recovered from VM ID
string chain_name = 1;
// VM ID in "ids.ID" format.
string vm_id = 2;
@@ -170,8 +173,8 @@ message CustomVmInfo {
string subnet_id = 3;
// Create blockchain transaction ID -- blockchain ID>
// The blockchain ID is used for RPC endpoints for the custom VM.
string blockchain_id = 4;
// The blockchain ID is used for RPC endpoints.
string chain_id = 4;
}
message NodeInfo {
@@ -181,7 +184,7 @@ message NodeInfo {
string id = 4;
string log_dir = 5;
string db_dir = 6;
string plugin_dir = 7;
string build_dir = 7;
string whitelisted_subnets = 8;
bytes config = 9;
}
@@ -202,18 +205,21 @@ message StartRequest {
// Used for both database and log files.
optional string root_data_dir = 5;
// Plugin directory to load all custom VM executables.
// Must be non-empty to install custom VMs.
optional string plugin_dir = 6;
// 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;
// The list of custom VM name, its genesis file path, and (optional) subnet id to use.
// 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
// subnet ids available.
//
// The matching file with the name in "ids.ID" format must exist.
// e.g., ids.ToID(hashing.ComputeHash256("subnetevm")).String()
// e.g., subnet-cli create VMID subnetevm
//
// If this field is set to none (by default), the node/network-runner
// does not install the custom VM and does not create the subnet,
// does not install the custom chain and does not create the subnet,
// even if the VM binary exists on the local plugins directory.
repeated BlockchainSpec blockchain_specs = 7;
@@ -238,7 +244,7 @@ message BlockchainSpec {
}
message CreateBlockchainsRequest {
// The list of custom VM name, its genesis file path, and (optional) subnet id to use.
// The list of custom chain's VM name, genesis file path, and (optional) subnet id to use.
//
// The matching file with the name in "ids.ID" format must exist.
// e.g., ids.ToID(hashing.ComputeHash256("subnetevm")).String()
@@ -356,7 +362,7 @@ message SaveSnapshotResponse {
message LoadSnapshotRequest {
string snapshot_name = 1;
optional string exec_path = 2;
optional string plugin_dir = 3;
optional string build_dir = 3;
optional string root_data_dir = 4;
map<string, string> chain_configs = 5;
optional string global_node_config = 6;
+19 -12
View File
@@ -3,24 +3,31 @@ set -e
export RUN_E2E="true"
# e.g.,
# ./scripts/tests.e2e.sh 1.7.9 1.7.10
# ./scripts/tests.e2e.sh 1.7.12 1.7.13
if ! [[ "$0" =~ scripts/tests.e2e.sh ]]; then
echo "must be run from repository root"
exit 255
fi
VERSION_1=$1
if [[ -z "${VERSION_1}" ]]; then
echo "Missing version argument!"
echo "Usage: ${0} [VERSION_1] [VERSION_2]" >> /dev/stderr
exit 255
fi
DEFAULT_VERSION_1=1.7.12
DEFAULT_VERSION_2=1.7.13
VERSION_2=$2
if [[ -z "${VERSION_2}" ]]; then
echo "Missing version argument!"
echo "Usage: ${0} [VERSION_1] [VERSION_2]" >> /dev/stderr
exit 255
if [ $# == 0 ]; then
VERSION_1=$DEFAULT_VERSION_1
VERSION_2=$DEFAULT_VERSION_2
else
VERSION_1=$1
if [[ -z "${VERSION_1}" ]]; then
echo "Missing version argument!"
echo "Usage: ${0} [VERSION_1] [VERSION_2]" >> /dev/stderr
exit 255
fi
VERSION_2=$2
if [[ -z "${VERSION_2}" ]]; then
echo "Missing version argument!"
echo "Usage: ${0} [VERSION_1] [VERSION_2]" >> /dev/stderr
exit 255
fi
fi
echo "Running e2e tests with:"
+33 -52
View File
@@ -43,8 +43,8 @@ var ignoreFields = map[string]struct{}{
type localNetwork struct {
logger logging.Logger
execPath string
pluginDir string
execPath string
buildDir string
cfg network.Config
@@ -57,9 +57,9 @@ type localNetwork struct {
options localNetworkOptions
// map from blockchain ID to blockchain info
customVMBlockchainIDToInfo map[ids.ID]vmInfo
customChainIDToInfo map[ids.ID]chainInfo
customVMRestartMu *sync.RWMutex
customChainRestartMu *sync.RWMutex
stopCh chan struct{}
startDoneCh chan struct{}
@@ -75,8 +75,8 @@ type localNetwork struct {
chainConfigs map[string]string
}
type vmInfo struct {
info *rpcpb.CustomVmInfo
type chainInfo struct {
info *rpcpb.CustomChainInfo
subnetID ids.ID
blockchainID ids.ID
}
@@ -89,13 +89,13 @@ type localNetworkOptions struct {
redirectNodesOutput bool
globalNodeConfig string
pluginDir string
buildDir string
customNodeConfigs map[string]string
// chain configs to be added to the network, besides the ones in default config, or saved snapshot
chainConfigs map[string]string
// to block racey restart while installing custom VMs
// to block racey restart while installing custom chains
restartMu *sync.RWMutex
snapshotsDir string
@@ -118,12 +118,12 @@ func newLocalNetwork(opts localNetworkOptions) (*localNetwork, error) {
execPath: opts.execPath,
pluginDir: opts.pluginDir,
buildDir: getBuildDir(opts.execPath, opts.buildDir),
options: opts,
customVMBlockchainIDToInfo: make(map[ids.ID]vmInfo),
customVMRestartMu: opts.restartMu,
customChainIDToInfo: make(map[ids.ID]chainInfo),
customChainRestartMu: opts.restartMu,
stopCh: make(chan struct{}),
startDoneCh: make(chan struct{}),
@@ -169,17 +169,12 @@ func (lc *localNetwork) createConfig() error {
return fmt.Errorf("failed merging provided configs: %w", err)
}
// 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)
cfg.NodeConfigs[i].ConfigFile, err = createConfigFileString(mergedConfig, logDir, dbDir, lc.buildDir, lc.options.whitelistedSubnets)
if err != nil {
return err
}
cfg.NodeConfigs[i].BinaryPath = lc.options.execPath
cfg.NodeConfigs[i].BinaryPath = lc.execPath
cfg.NodeConfigs[i].RedirectStdout = lc.options.redirectNodesOutput
cfg.NodeConfigs[i].RedirectStderr = lc.options.redirectNodesOutput
}
@@ -221,21 +216,17 @@ func mergeNodeConfig(baseConfig map[string]interface{}, globalConfig map[string]
return baseConfig, nil
}
// generates buildDir from pluginDir, and if not available, from execPath
// if givenBuildDir is empty, generates it from execPath
// returns error if pluginDir is non empty and invalid
func getBuildDir(execPath string, pluginDir string) (string, error) {
func getBuildDir(execPath string, givenBuildDir string) string {
buildDir := ""
if execPath != "" {
buildDir = filepath.Dir(execPath)
}
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)
if givenBuildDir != "" {
buildDir = givenBuildDir
}
return buildDir, nil
return buildDir
}
// createConfigFileString finalizes the config setup and returns the node config JSON string
@@ -252,7 +243,7 @@ func createConfigFileString(configFileMap map[string]interface{}, logDir string,
if buildDir != "" {
configFileMap[config.BuildDirKey] = buildDir
}
// need to whitelist subnet ID to create custom VM chain
// need to whitelist subnet ID to create custom chain
// ref. vms/platformvm/createChain
if whitelistedSubnets != "" {
configFileMap[config.WhitelistedSubnetsKey] = whitelistedSubnets
@@ -320,7 +311,7 @@ func (lc *localNetwork) createBlockchains(
ctx, lc.startCtxCancel = context.WithCancel(argCtx)
if len(chainSpecs) == 0 {
color.Outf("{{orange}}{{bold}}custom VM not specified, skipping installation and its health checks...{{/}}\n")
color.Outf("{{orange}}{{bold}}custom chain not specified, skipping installation and its health checks...{{/}}\n")
return
}
@@ -403,11 +394,6 @@ 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 {
@@ -421,7 +407,7 @@ func (lc *localNetwork) loadSnapshot(
lc.options.rootDataDir,
lc.options.snapshotsDir,
lc.execPath,
buildDir,
lc.buildDir,
lc.options.chainConfigs,
globalNodeConfig,
)
@@ -462,12 +448,12 @@ func (lc *localNetwork) updateSubnetInfo(ctx context.Context) error {
}
for _, blockchain := range blockchains {
if blockchain.Name != "C-Chain" && blockchain.Name != "X-Chain" {
lc.customVMBlockchainIDToInfo[blockchain.ID] = vmInfo{
info: &rpcpb.CustomVmInfo{
VmName: blockchain.Name,
VmId: blockchain.VMID.String(),
SubnetId: blockchain.SubnetID.String(),
BlockchainId: blockchain.ID.String(),
lc.customChainIDToInfo[blockchain.ID] = chainInfo{
info: &rpcpb.CustomChainInfo{
ChainName: blockchain.Name,
VmId: blockchain.VMID.String(),
SubnetId: blockchain.SubnetID.String(),
ChainId: blockchain.ID.String(),
},
subnetID: blockchain.SubnetID,
blockchainID: blockchain.ID,
@@ -486,8 +472,8 @@ func (lc *localNetwork) updateSubnetInfo(ctx context.Context) error {
}
for _, nodeName := range lc.nodeNames {
nodeInfo := lc.nodeInfos[nodeName]
for blockchainID, vmInfo := range lc.customVMBlockchainIDToInfo {
color.Outf("{{blue}}{{bold}}[blockchain RPC for %q] \"%s/ext/bc/%s\"{{/}}\n", vmInfo.info.VmId, nodeInfo.GetUri(), blockchainID)
for chainID, chainInfo := range lc.customChainIDToInfo {
color.Outf("{{blue}}{{bold}}[blockchain RPC for %q] \"%s/ext/bc/%s\"{{/}}\n", chainInfo.info.VmId, nodeInfo.GetUri(), chainID)
}
}
return nil
@@ -522,7 +508,6 @@ 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 {
@@ -535,10 +520,6 @@ 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(),
@@ -548,16 +529,16 @@ func (lc *localNetwork) updateNodeInfo() error {
LogDir: node.GetLogsDir(),
DbDir: node.GetDbDir(),
Config: []byte(node.GetConfigFile()),
PluginDir: pluginDir,
BuildDir: node.GetBuildDir(),
WhitelistedSubnets: whitelistedSubnets,
}
// update default exec and pluginDir if empty (snapshots started without this params)
// update default exec and buildDir if empty (snapshots started without this params)
if lc.execPath == "" {
lc.execPath = node.GetBinaryPath()
}
if lc.pluginDir == "" {
lc.pluginDir = pluginDir
if lc.buildDir == "" {
lc.buildDir = node.GetBuildDir()
}
// update default chain configs if empty
if lc.chainConfigs == nil {
+32 -41
View File
@@ -72,17 +72,16 @@ type server struct {
}
var (
ErrInvalidVMName = errors.New("invalid VM name")
ErrInvalidPort = errors.New("invalid port")
ErrClosed = errors.New("server closed")
ErrPluginDirEmptyButCustomVMsNotEmpty = errors.New("empty plugin-dir but non-empty custom VMs")
ErrPluginDirNonEmptyButCustomVMsEmpty = errors.New("non-empty plugin-dir but empty custom VM")
ErrNotEnoughNodesForStart = errors.New("not enough nodes specified for start")
ErrAlreadyBootstrapped = errors.New("already bootstrapped")
ErrNotBootstrapped = errors.New("not bootstrapped")
ErrPeerNotFound = errors.New("peer not found")
ErrStatusCanceled = errors.New("gRPC stream status canceled")
ErrNoBlockchainSpec = errors.New("no blockchain spec was provided")
ErrInvalidVMName = errors.New("invalid VM name")
ErrInvalidPort = errors.New("invalid port")
ErrClosed = errors.New("server closed")
ErrNotEnoughNodesForStart = errors.New("not enough nodes specified for start")
ErrAlreadyBootstrapped = errors.New("already bootstrapped")
ErrNotBootstrapped = errors.New("not bootstrapped")
ErrNodeNotFound = errors.New("node not found")
ErrPeerNotFound = errors.New("peer not found")
ErrStatusCanceled = errors.New("gRPC stream status canceled")
ErrNoBlockchainSpec = errors.New("no blockchain spec was provided")
)
const (
@@ -250,13 +249,8 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta
if err := utils.CheckExecPath(req.GetExecPath()); err != nil {
return nil, err
}
pluginDir := ""
if req.GetPluginDir() != "" {
pluginDir = req.GetPluginDir()
}
if pluginDir == "" {
pluginDir = filepath.Join(filepath.Dir(req.GetExecPath()), "plugins")
}
buildDir := getBuildDir(req.GetExecPath(), req.GetBuildDir())
pluginDir := filepath.Join(buildDir, "plugins")
chainSpecs := []network.BlockchainSpec{}
if len(req.GetBlockchainSpecs()) > 0 {
zap.L().Info("plugin dir", zap.String("plugin-dir", pluginDir))
@@ -267,7 +261,7 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta
}
vmName := spec.VmName
vmGenesisFilePath := spec.Genesis
zap.L().Info("checking custom VM ID before installation", zap.String("vm-id", vmName))
zap.L().Info("checking custom chain's VM ID before installation", zap.String("vm-id", vmName))
vmID, err := utils.VMID(vmName)
if err != nil {
zap.L().Warn("failed to convert VM name to VM ID",
@@ -333,7 +327,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("pluginDir", pluginDir),
zap.String("buildDir", buildDir),
zap.Any("chainConfigs", req.ChainConfigs),
zap.String("defaultNodeConfig", globalNodeConfig),
)
@@ -353,7 +347,7 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta
numNodes: numNodes,
whitelistedSubnets: whitelistedSubnets,
redirectNodesOutput: s.cfg.RedirectNodesOutput,
pluginDir: pluginDir,
buildDir: buildDir,
globalNodeConfig: globalNodeConfig,
customNodeConfigs: customNodeConfigs,
chainConfigs: req.ChainConfigs,
@@ -378,7 +372,7 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta
return nil, err
}
// start non-blocking to install local cluster + custom VMs (if applicable)
// start non-blocking to install local cluster + custom chains (if applicable)
// the user is expected to poll cluster status
readyCh := make(chan struct{})
go s.network.startWait(ctx, chainSpecs, readyCh)
@@ -389,9 +383,9 @@ func (s *server) Start(ctx context.Context, req *rpcpb.StartRequest) (*rpcpb.Sta
go func() {
s.waitChAndUpdateClusterInfo("waiting for local cluster readiness", readyCh, false)
if len(req.GetBlockchainSpecs()) == 0 {
zap.L().Info("no custom VM installation request, skipping its readiness check")
zap.L().Info("no custom chain installation request, skipping its readiness check")
} else {
s.waitChAndUpdateClusterInfo("waiting for custom VMs readiness", readyCh, true)
s.waitChAndUpdateClusterInfo("waiting for custom chains readiness", readyCh, true)
}
}()
@@ -417,10 +411,10 @@ func (s *server) waitChAndUpdateClusterInfo(waitMsg string, readyCh chan struct{
s.clusterInfo.NodeNames = s.network.nodeNames
s.clusterInfo.NodeInfos = s.network.nodeInfos
if updateCustomVmsInfo {
s.clusterInfo.CustomVmsHealthy = true
s.clusterInfo.CustomVms = make(map[string]*rpcpb.CustomVmInfo)
for blockchainID, vmInfo := range s.network.customVMBlockchainIDToInfo {
s.clusterInfo.CustomVms[blockchainID.String()] = vmInfo.info
s.clusterInfo.CustomChainsHealthy = true
s.clusterInfo.CustomChains = make(map[string]*rpcpb.CustomChainInfo)
for chainID, chainInfo := range s.network.customChainIDToInfo {
s.clusterInfo.CustomChains[chainID.String()] = chainInfo.info
}
s.clusterInfo.Subnets = s.network.subnets
}
@@ -448,11 +442,12 @@ 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
vmGenesisFilePath := req.GetBlockchainSpecs()[i].Genesis
zap.L().Info("checking custom VM ID before installation", zap.String("vm-id", vmName))
zap.L().Info("checking custom chain's VM ID before installation", zap.String("vm-id", vmName))
vmID, err := utils.VMID(vmName)
if err != nil {
zap.L().Warn("failed to convert VM name to VM ID",
@@ -462,7 +457,7 @@ func (s *server) CreateBlockchains(ctx context.Context, req *rpcpb.CreateBlockch
return nil, ErrInvalidVMName
}
if err := utils.CheckPluginPaths(
filepath.Join(s.network.pluginDir, vmID.String()),
filepath.Join(pluginDir, vmID.String()),
vmGenesisFilePath,
); err != nil {
return nil, err
@@ -503,9 +498,9 @@ func (s *server) CreateBlockchains(ctx context.Context, req *rpcpb.CreateBlockch
}
}
s.clusterInfo.CustomVmsHealthy = false
s.clusterInfo.CustomChainsHealthy = false
// start non-blocking to install custom VMs (if applicable)
// start non-blocking to install custom chains (if applicable)
// the user is expected to poll cluster status
readyCh := make(chan struct{})
go s.network.createBlockchains(ctx, chainSpecs, readyCh)
@@ -514,7 +509,7 @@ func (s *server) CreateBlockchains(ctx context.Context, req *rpcpb.CreateBlockch
// the user is expected to poll this latest information
// to decide cluster/subnet readiness
go func() {
s.waitChAndUpdateClusterInfo("waiting for custom VMs readiness", readyCh, true)
s.waitChAndUpdateClusterInfo("waiting for custom chains readiness", readyCh, true)
}()
return &rpcpb.CreateBlockchainsResponse{ClusterInfo: s.clusterInfo}, nil
@@ -552,7 +547,7 @@ func (s *server) CreateSubnets(ctx context.Context, req *rpcpb.CreateSubnetsRequ
defer s.mu.Unlock()
s.clusterInfo.Healthy = false
s.clusterInfo.CustomVmsHealthy = false
s.clusterInfo.CustomChainsHealthy = false
// start non-blocking to add subnets
// the user is expected to poll cluster status
@@ -563,7 +558,7 @@ func (s *server) CreateSubnets(ctx context.Context, req *rpcpb.CreateSubnetsRequ
// the user is expected to poll this latest information
// to decide cluster/subnet readiness
go func() {
s.waitChAndUpdateClusterInfo("waiting for custom VMs readiness", readyCh, true)
s.waitChAndUpdateClusterInfo("waiting for custom chains readiness", readyCh, true)
}()
return &rpcpb.CreateSubnetsResponse{ClusterInfo: s.clusterInfo}, nil
@@ -744,11 +739,7 @@ func (s *server) AddNode(ctx context.Context, req *rpcpb.AddNodeRequest) (*rpcpb
// use same configs from other nodes
whitelistedSubnets = s.network.options.whitelistedSubnets
buildDir, err := getBuildDir(execPath, s.network.pluginDir)
if err != nil {
return nil, err
}
buildDir := getBuildDir(execPath, s.network.buildDir)
rootDataDir := s.clusterInfo.RootDataDir
logDir := filepath.Join(rootDataDir, req.Name, "log")
@@ -1015,7 +1006,7 @@ func (s *server) LoadSnapshot(ctx context.Context, req *rpcpb.LoadSnapshotReques
s.network, err = newLocalNetwork(localNetworkOptions{
execPath: req.GetExecPath(),
pluginDir: req.GetPluginDir(),
buildDir: req.GetBuildDir(),
rootDataDir: rootDataDir,
chainConfigs: req.ChainConfigs,
globalNodeConfig: req.GetGlobalNodeConfig(),
+13 -7
View File
@@ -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.WithPluginDir(os.TempDir()),
client.WithBuildDir(os.TempDir()),
client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{
{
VmName: "invalid",
@@ -146,14 +146,17 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
})
ginkgo.By("start request with invalid custom VM name format should fail", func() {
f, err := os.CreateTemp(os.TempDir(), strings.Repeat("a", 33))
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))
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.WithPluginDir(filepath.Dir(filePath)),
client.WithBuildDir(filepath.Dir(filepath.Dir(filePath))),
client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{
{
VmName: filepath.Base(filePath),
@@ -169,12 +172,15 @@ 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())
filePath := filepath.Join(os.TempDir(), vmID.String())
pluginsPath := filepath.Join(os.TempDir(), "plugins")
err = os.MkdirAll(pluginsPath, fs.ModePerm)
gomega.Ω(err).Should(gomega.BeNil())
filePath := filepath.Join(pluginsPath, 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.WithPluginDir(filepath.Dir(filePath)),
client.WithBuildDir(filepath.Dir(filepath.Dir(filePath))),
client.WithBlockchainSpecs([]*rpcpb.BlockchainSpec{
{
VmName: "hello",
@@ -422,7 +428,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
status, err := cli.Status(ctx)
cancel()
gomega.Ω(err).Should(gomega.BeNil())
created = status.ClusterInfo.CustomVmsHealthy
created = status.ClusterInfo.CustomChainsHealthy
if created {
continueLoop = false
}
@@ -505,7 +511,7 @@ var _ = ginkgo.Describe("[Start/Remove/Restart/Add/Stop]", func() {
status, err := cli.Status(ctx)
cancel()
gomega.Ω(err).Should(gomega.BeNil())
created = status.ClusterInfo.CustomVmsHealthy
created = status.ClusterInfo.CustomChainsHealthy
if created {
continueLoop = false
}