From ea4f2b1161454f0ebda4b9e7381f0a4e75c7d8b2 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Wed, 10 Apr 2024 16:59:02 -0300 Subject: [PATCH 1/5] set snapshot removal and list to not depend on bootstrapped network --- local/network.go | 8 ++++---- local/snapshot.go | 22 +++++++++++++++------- server/server.go | 17 +++++++---------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/local/network.go b/local/network.go index 5fa3c139..22536a64 100644 --- a/local/network.go +++ b/local/network.go @@ -135,7 +135,7 @@ var ( deprecatedFlagsSupportBytes []byte deprecatedFlagsSupport []deprecatedFlagEsp // snapshots directory - defaultSnapshotsDir string + DefaultSnapshotsDir string ) // populate default network config from embedded default directory @@ -149,14 +149,14 @@ func init() { if err != nil { panic(err) } - defaultSnapshotsDir = filepath.Join(usr.HomeDir, snapshotsRelPath) + DefaultSnapshotsDir = filepath.Join(usr.HomeDir, snapshotsRelPath) } // 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. // If len([dir]) == 0, files will be written underneath a new temporary directory. -// Snapshots are saved to snapshotsDir, defaults to defaultSnapshotsDir if not given +// Snapshots are saved to snapshotsDir, defaults to DefaultSnapshotsDir if not given func NewNetwork( log logging.Logger, networkConfig network.Config, @@ -214,7 +214,7 @@ func newNetwork( } } if snapshotsDir == "" { - snapshotsDir = defaultSnapshotsDir + snapshotsDir = DefaultSnapshotsDir } // create the snapshots dir if not present err = os.MkdirAll(snapshotsDir, os.ModePerm) diff --git a/local/snapshot.go b/local/snapshot.go index a840ccd7..6191baee 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -334,7 +334,16 @@ func (ln *localNetwork) loadSnapshot( // Remove network snapshot func (ln *localNetwork) RemoveSnapshot(snapshotName string) error { - snapshotDir := filepath.Join(ln.snapshotsDir, snapshotPrefix+snapshotName) + return RemoveSnapshot(ln.snapshotsDir, snapshotName) +} + +// Get network snapshots +func (ln *localNetwork) GetSnapshotNames() ([]string, error) { + return GetSnapshotNames(ln.snapshotsDir) +} + +func RemoveSnapshot(snapshotsDir string, snapshotName string) error { + snapshotDir := filepath.Join(snapshotsDir, snapshotPrefix+snapshotName) _, err := os.Stat(snapshotDir) if err != nil { if errors.Is(err, os.ErrNotExist) { @@ -349,17 +358,16 @@ func (ln *localNetwork) RemoveSnapshot(snapshotName string) error { return nil } -// Get network snapshots -func (ln *localNetwork) GetSnapshotNames() ([]string, error) { - _, err := os.Stat(ln.snapshotsDir) +func GetSnapshotNames(snapshotsDir string) ([]string, error) { + _, err := os.Stat(snapshotsDir) if err != nil { if errors.Is(err, os.ErrNotExist) { - return nil, fmt.Errorf("snapshots dir %q does not exists", ln.snapshotsDir) + return nil, fmt.Errorf("snapshots dir %q does not exists", snapshotsDir) } else { - return nil, fmt.Errorf("failure accessing snapshots dir %q: %w", ln.snapshotsDir, err) + return nil, fmt.Errorf("failure accessing snapshots dir %q: %w", snapshotsDir, err) } } - matches, err := filepath.Glob(filepath.Join(ln.snapshotsDir, snapshotPrefix+"*")) + matches, err := filepath.Glob(filepath.Join(snapshotsDir, snapshotPrefix+"*")) if err != nil { return nil, err } diff --git a/server/server.go b/server/server.go index 4feecadf..e944f1ed 100644 --- a/server/server.go +++ b/server/server.go @@ -21,6 +21,7 @@ import ( "go.uber.org/multierr" + "github.com/ava-labs/avalanche-network-runner/local" "github.com/ava-labs/avalanche-network-runner/network" "github.com/ava-labs/avalanche-network-runner/network/node" "github.com/ava-labs/avalanche-network-runner/rpcpb" @@ -133,6 +134,10 @@ func New(cfg Config, log logging.Logger) (Server, error) { return nil, err } + if cfg.SnapshotsDir == "" { + cfg.SnapshotsDir = local.DefaultSnapshotsDir + } + s := &server{ cfg: cfg, log: log, @@ -1412,11 +1417,7 @@ func (s *server) RemoveSnapshot(_ context.Context, req *rpcpb.RemoveSnapshotRequ s.log.Info("RemoveSnapshot", zap.String("snapshot-name", req.SnapshotName)) - if s.network == nil { - return nil, ErrNotBootstrapped - } - - if err := s.network.nw.RemoveSnapshot(req.SnapshotName); err != nil { + if err := local.RemoveSnapshot(s.cfg.SnapshotsDir, req.SnapshotName); err != nil { s.log.Warn("snapshot remove failed to complete", zap.Error(err)) return nil, err } @@ -1429,11 +1430,7 @@ func (s *server) GetSnapshotNames(context.Context, *rpcpb.GetSnapshotNamesReques s.log.Info("GetSnapshotNames") - if s.network == nil { - return nil, ErrNotBootstrapped - } - - snapshotNames, err := s.network.nw.GetSnapshotNames() + snapshotNames, err := local.GetSnapshotNames(s.cfg.SnapshotsDir) if err != nil { return nil, err } From 20146263d6b83c53dde5c158b638cb26074f9364 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Wed, 10 Apr 2024 17:18:05 -0300 Subject: [PATCH 2/5] add aliases when loading snapshot --- local/snapshot.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/local/snapshot.go b/local/snapshot.go index 6191baee..a91bad1f 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -329,7 +329,28 @@ func (ln *localNetwork) loadSnapshot( ln.subnetID2ElasticSubnetID[subnetID] = elasticSubnetID } } - return ln.loadConfig(ctx, networkConfig) + if err := ln.loadConfig(ctx, networkConfig); err != nil { + return err + } + if err := ln.healthy(ctx); err != nil { + return err + } + node := ln.getNode() + blockchains, err := node.GetAPIClient().PChainAPI().GetBlockchains(ctx) + if err != nil { + return err + } + for _, blockchain := range blockchains { + if blockchain.Name == "C-Chain" || blockchain.Name == "X-Chain" { + continue + } + for nodeName, node := range ln.nodes { + if err := node.client.AdminAPI().AliasChain(ctx, blockchain.ID.String(), blockchain.Name); err != nil { + return fmt.Errorf("failure to register blockchain alias %v on node %v: %w", blockchain.Name, nodeName, err) + } + } + } + return nil } // Remove network snapshot From f99df511bc9558a6eb631143a8249376928d6774 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Wed, 10 Apr 2024 20:53:51 -0300 Subject: [PATCH 3/5] nit --- local/blockchain.go | 32 +++++++++++++++++++++++--------- local/network.go | 3 +++ local/snapshot.go | 20 ++++++++++++++++---- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/local/blockchain.go b/local/blockchain.go index 26527e58..f5741108 100644 --- a/local/blockchain.go +++ b/local/blockchain.go @@ -142,17 +142,31 @@ func (ln *localNetwork) RegisterBlockchainAliases( continue } blockchainAlias := chainSpec.BlockchainAlias - chainID := chainInfos[i].blockchainID.String() + blockchainID := chainInfos[i].blockchainID.String() ln.log.Info("registering blockchain alias", zap.String("alias", blockchainAlias), - zap.String("chain-id", chainID)) - for nodeName, node := range ln.nodes { - if node.paused { - continue - } - if err := node.client.AdminAPI().AliasChain(ctx, chainID, blockchainAlias); err != nil { - return fmt.Errorf("failure to register blockchain alias %v on node %v: %w", blockchainAlias, nodeName, err) - } + zap.String("chain-id", blockchainID)) + if err := ln.setBlockchainAlias(ctx, blockchainID, blockchainAlias); err != nil { + return err + } + ln.blockchainAliases[blockchainID] = append(ln.blockchainAliases[blockchainID], blockchainAlias) + } + return nil +} + +func (ln *localNetwork) setBlockchainAlias(ctx context.Context, blockchainID string, blockchainAlias string) error { + for nodeName, node := range ln.nodes { + if node.paused { + continue + } + if err := node.client.AdminAPI().AliasChain(ctx, blockchainID, blockchainAlias); err != nil { + return fmt.Errorf( + "failure to register blockchain alias %s for blockchain ID %s on node %s: %w", + blockchainAlias, + blockchainID, + nodeName, + err, + ) } } return nil diff --git a/local/network.go b/local/network.go index 22536a64..10208173 100644 --- a/local/network.go +++ b/local/network.go @@ -119,6 +119,8 @@ type localNetwork struct { redirectStderr bool // map from subnet id to elastic subnet tx id subnetID2ElasticSubnetID map[ids.ID]ids.ID + // map from blockchain id to blockchain aliases + blockchainAliases map[string][]string } type deprecatedFlagEsp struct { @@ -236,6 +238,7 @@ func newNetwork( redirectStdout: redirectStdout, redirectStderr: redirectStderr, subnetID2ElasticSubnetID: map[ids.ID]ids.ID{}, + blockchainAliases: map[string][]string{}, } return net, nil } diff --git a/local/snapshot.go b/local/snapshot.go index a91bad1f..5b290d5e 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -30,6 +30,8 @@ const ( type NetworkState struct { // Map from subnet id to elastic subnet tx id SubnetID2ElasticSubnetID map[string]string `json:"subnetID2ElasticSubnetID"` + // Map from blockchain id to blockchain aliases + BlockchainAliases map[string][]string `json:"blockchainAliases"` } // snapshots generated using older ANR versions may contain deprecated avago flags @@ -203,6 +205,7 @@ func (ln *localNetwork) SaveSnapshot(ctx context.Context, snapshotName string) ( } networkState := NetworkState{ SubnetID2ElasticSubnetID: subnetID2ElasticSubnetID, + BlockchainAliases: ln.blockchainAliases, } networkStateJSON, err := json.MarshalIndent(networkState, "", " ") if err != nil { @@ -328,6 +331,7 @@ func (ln *localNetwork) loadSnapshot( } ln.subnetID2ElasticSubnetID[subnetID] = elasticSubnetID } + ln.blockchainAliases = networkState.BlockchainAliases } if err := ln.loadConfig(ctx, networkConfig); err != nil { return err @@ -335,6 +339,15 @@ func (ln *localNetwork) loadSnapshot( if err := ln.healthy(ctx); err != nil { return err } + // add aliases included in the snapshot state + for blockchainID, blockchainAliases := range ln.blockchainAliases { + for _, blockchainAlias := range blockchainAliases { + if err := ln.setBlockchainAlias(ctx, blockchainID, blockchainAlias); err != nil { + return err + } + } + } + // add aliases for blockchain names node := ln.getNode() blockchains, err := node.GetAPIClient().PChainAPI().GetBlockchains(ctx) if err != nil { @@ -344,10 +357,9 @@ func (ln *localNetwork) loadSnapshot( if blockchain.Name == "C-Chain" || blockchain.Name == "X-Chain" { continue } - for nodeName, node := range ln.nodes { - if err := node.client.AdminAPI().AliasChain(ctx, blockchain.ID.String(), blockchain.Name); err != nil { - return fmt.Errorf("failure to register blockchain alias %v on node %v: %w", blockchain.Name, nodeName, err) - } + if err := ln.setBlockchainAlias(ctx, blockchain.ID.String(), blockchain.Name); err != nil { + // non fatal error: not required by user + ln.log.Warn(err.Error()) } } return nil From a133f6265b10cf105e249c71db0f9b38ca12888a Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Wed, 10 Apr 2024 21:43:33 -0300 Subject: [PATCH 4/5] fix panic --- local/snapshot.go | 4 +++- utils/utils.go | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/local/snapshot.go b/local/snapshot.go index 5b290d5e..ef968f1c 100644 --- a/local/snapshot.go +++ b/local/snapshot.go @@ -331,7 +331,9 @@ func (ln *localNetwork) loadSnapshot( } ln.subnetID2ElasticSubnetID[subnetID] = elasticSubnetID } - ln.blockchainAliases = networkState.BlockchainAliases + for k, v := range networkState.BlockchainAliases { + ln.blockchainAliases[k] = v + } } if err := ln.loadConfig(ctx, networkConfig); err != nil { return err diff --git a/utils/utils.go b/utils/utils.go index 9fdf402c..1dbe18a0 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -6,6 +6,7 @@ import ( "fmt" "io/fs" "os" + "path/filepath" "time" rpcb "github.com/ava-labs/avalanche-network-runner/rpcpb" @@ -90,7 +91,7 @@ func CheckPluginPath(pluginExec string) error { var err error if _, err = os.Stat(pluginExec); err != nil { if errors.Is(err, fs.ErrNotExist) { - return ErrNotExistsPlugin + return fmt.Errorf("%s: %w", filepath.Base(pluginExec), ErrNotExistsPlugin) } return fmt.Errorf("failed to stat plugin exec %q (%w)", pluginExec, err) } From bdafb60289598ecc949603c3ecc33b4b0c722627 Mon Sep 17 00:00:00 2001 From: Felipe Madero Date: Wed, 10 Apr 2024 21:50:56 -0300 Subject: [PATCH 5/5] fix unit test --- utils/utils.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utils/utils.go b/utils/utils.go index 1dbe18a0..9fdf402c 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -6,7 +6,6 @@ import ( "fmt" "io/fs" "os" - "path/filepath" "time" rpcb "github.com/ava-labs/avalanche-network-runner/rpcpb" @@ -91,7 +90,7 @@ func CheckPluginPath(pluginExec string) error { var err error if _, err = os.Stat(pluginExec); err != nil { if errors.Is(err, fs.ErrNotExist) { - return fmt.Errorf("%s: %w", filepath.Base(pluginExec), ErrNotExistsPlugin) + return ErrNotExistsPlugin } return fmt.Errorf("failed to stat plugin exec %q (%w)", pluginExec, err) }