Skip to content

Commit 814b1d7

Browse files
committed
[tmpnet] Switch FlagsMap from map[string]any to map[string]string
`map[string]any` complicates comparison of values converted to strings (e.g. when node configuration is provided as env vars to a kube pod) to their original golang form. Switching `FlagsMap` to use `map[string]string` forces the decision of how to serialize on the developer to ensure that all subsequent usage will be consistent. This change also updates chain and monitor configuration to stop using FlagsMap in favor of locally-appropriate maps.
1 parent 62f6308 commit 814b1d7

File tree

13 files changed

+76
-147
lines changed

13 files changed

+76
-147
lines changed

tests/antithesis/compose.go

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"fmt"
99
"os"
1010
"path/filepath"
11-
"strconv"
1211

1312
"github.com/compose-spec/compose-go/types"
1413
"gopkg.in/yaml.v3"
@@ -97,10 +96,7 @@ func initComposeConfig(
9796
targetPath string,
9897
) error {
9998
// Generate a compose project for the specified network
100-
project, err := newComposeProject(network, nodeImageName, workloadImageName)
101-
if err != nil {
102-
return fmt.Errorf("failed to create compose project: %w", err)
103-
}
99+
project := newComposeProject(network, nodeImageName, workloadImageName)
104100

105101
absPath, err := filepath.Abs(targetPath)
106102
if err != nil {
@@ -135,7 +131,7 @@ func initComposeConfig(
135131

136132
// Create a new docker compose project for an antithesis test setup
137133
// for the provided network configuration.
138-
func newComposeProject(network *tmpnet.Network, nodeImageName string, workloadImageName string) (*types.Project, error) {
134+
func newComposeProject(network *tmpnet.Network, nodeImageName string, workloadImageName string) *types.Project {
139135
networkName := "avalanche-testnet"
140136
baseNetworkAddress := "10.0.20"
141137

@@ -148,18 +144,9 @@ func newComposeProject(network *tmpnet.Network, nodeImageName string, workloadIm
148144
for i, node := range network.Nodes {
149145
address := fmt.Sprintf("%s.%d", baseNetworkAddress, 3+i)
150146

151-
tlsKey, err := node.Flags.GetStringVal(config.StakingTLSKeyContentKey)
152-
if err != nil {
153-
return nil, err
154-
}
155-
tlsCert, err := node.Flags.GetStringVal(config.StakingCertContentKey)
156-
if err != nil {
157-
return nil, err
158-
}
159-
signerKey, err := node.Flags.GetStringVal(config.StakingSignerKeyContentKey)
160-
if err != nil {
161-
return nil, err
162-
}
147+
tlsKey := node.Flags[config.StakingTLSKeyContentKey]
148+
tlsCert := node.Flags[config.StakingCertContentKey]
149+
signerKey := node.Flags[config.StakingSignerKeyContentKey]
163150

164151
env := types.Mapping{
165152
config.NetworkNameKey: constants.LocalName,
@@ -175,14 +162,7 @@ func newComposeProject(network *tmpnet.Network, nodeImageName string, workloadIm
175162

176163
// Apply configuration appropriate to a test network
177164
for k, v := range tmpnet.DefaultTestFlags() {
178-
switch value := v.(type) {
179-
case string:
180-
env[k] = value
181-
case bool:
182-
env[k] = strconv.FormatBool(value)
183-
default:
184-
return nil, fmt.Errorf("unable to convert unsupported type %T to string", v)
185-
}
165+
env[k] = v
186166
}
187167

188168
serviceName := getServiceName(i)
@@ -195,10 +175,7 @@ func newComposeProject(network *tmpnet.Network, nodeImageName string, workloadIm
195175
},
196176
}
197177

198-
trackSubnets, err := node.Flags.GetStringVal(config.TrackSubnetsKey)
199-
if err != nil {
200-
return nil, err
201-
}
178+
trackSubnets := node.Flags[config.TrackSubnetsKey]
202179
if len(trackSubnets) > 0 {
203180
env[config.TrackSubnetsKey] = trackSubnets
204181
if i == bootstrapIndex {
@@ -282,7 +259,7 @@ func newComposeProject(network *tmpnet.Network, nodeImageName string, workloadIm
282259
},
283260
},
284261
Services: services,
285-
}, nil
262+
}
286263
}
287264

288265
// Convert a mapping of avalanche config keys to a mapping of env vars

tests/e2e/p/interchain_workflow.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"time"
99

1010
"github.com/onsi/ginkgo/v2"
11-
"github.com/spf13/cast"
1211
"github.com/stretchr/testify/require"
1312

1413
"github.com/ava-labs/avalanchego/api/info"
@@ -44,8 +43,7 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL
4443
)
4544

4645
tc.By("checking that the network has a compatible minimum stake duration", func() {
47-
minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey])
48-
require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration)
46+
require.Equal(tmpnet.DefaultMinStakeDuration, network.DefaultFlags[config.MinStakeDurationKey])
4947
})
5048

5149
tc.By("creating wallet with a funded key to send from and recipient key to deliver to")

tests/e2e/p/staking_rewards.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88

99
"github.com/mitchellh/mapstructure"
1010
"github.com/onsi/ginkgo/v2"
11-
"github.com/spf13/cast"
1211
"github.com/stretchr/testify/require"
1312
"go.uber.org/zap"
1413

@@ -50,8 +49,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() {
5049
)
5150

5251
tc.By("checking that the network has a compatible minimum stake duration", func() {
53-
minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey])
54-
require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration)
52+
require.Equal(tmpnet.DefaultMinStakeDuration, network.DefaultFlags[config.MinStakeDurationKey])
5553
})
5654

5755
tc.By("adding alpha node, whose uptime should result in a staking reward")

tests/fixture/subnet/xsvm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func NewXSVMOrPanic(name string, key *secp256k1.PrivateKey, nodes ...*tmpnet.Nod
3333

3434
return &tmpnet.Subnet{
3535
Name: name,
36-
Config: tmpnet.FlagsMap{
36+
Config: map[string]any{
3737
// Reducing this from the 1s default speeds up tx acceptance
3838
"proposerMinBlockDelay": 0,
3939
},

tests/fixture/tmpnet/check_monitoring.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,7 @@ func getSelectors(networkUUID string) (string, error) {
273273
selectors := []string{}
274274
githubLabels := githubLabelsFromEnv()
275275
for label := range githubLabels {
276-
value, err := githubLabels.GetStringVal(label)
277-
if err != nil {
278-
return "", err
279-
}
276+
value := githubLabels[label]
280277
if len(value) == 0 {
281278
continue
282279
}

tests/fixture/tmpnet/defaults.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const (
3030
DefaultPreFundedKeyCount = 50
3131

3232
// A short minimum stake duration enables testing of staking logic.
33-
DefaultMinStakeDuration = time.Second
33+
DefaultMinStakeDuration = "1s"
3434

3535
defaultConfigFilename = "config.json"
3636
)
@@ -41,8 +41,8 @@ func DefaultTestFlags() FlagsMap {
4141
config.NetworkPeerListPullGossipFreqKey: "250ms",
4242
config.NetworkMaxReconnectDelayKey: "1s",
4343
config.HealthCheckFreqKey: "2s",
44-
config.AdminAPIEnabledKey: true,
45-
config.IndexEnabledKey: true,
44+
config.AdminAPIEnabledKey: "true",
45+
config.IndexEnabledKey: "true",
4646
}
4747
}
4848

@@ -60,23 +60,27 @@ func DefaultTmpnetFlags() FlagsMap {
6060
config.LogDisplayLevelKey: logging.Off.String(), // Display logging not needed since nodes run headless
6161
config.LogLevelKey: logging.Debug.String(),
6262
// Specific to e2e testing
63-
config.ProposerVMUseCurrentHeightKey: true,
63+
config.ProposerVMUseCurrentHeightKey: "true",
6464
// Reducing this from the 1s default speeds up tx acceptance
6565
config.ProposerVMMinBlockDelayKey: "0s",
6666
}
6767
flags.SetDefaults(DefaultTestFlags())
6868
return flags
6969
}
7070

71+
// Chain config values need to be any to enable unmarshaling to golang
72+
// (vs flags which are parsed with viper).
73+
type ChainConfigMap map[string]any
74+
7175
// A set of chain configurations appropriate for testing.
72-
func DefaultChainConfigs() map[string]FlagsMap {
73-
return map[string]FlagsMap{
76+
func DefaultChainConfigs() map[string]ChainConfigMap {
77+
return map[string]ChainConfigMap{
7478
// Supply only non-default configuration to ensure that default
7579
// values will be used. Available C-Chain configuration options are
7680
// defined in the `github.com/ava-labs/coreth/evm` package.
7781
"C": {
7882
"warp-api-enabled": true,
79-
"log-level": "trace",
83+
"log-level": logging.Trace.String(),
8084
},
8185
}
8286
}

tests/fixture/tmpnet/flags.go

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ import (
88
"fmt"
99
"os"
1010

11-
"github.com/spf13/cast"
12-
1311
"github.com/ava-labs/avalanchego/utils/perms"
1412
)
1513

1614
// Defines a mapping of flag keys to values intended to be supplied to
1715
// an invocation of an AvalancheGo node.
18-
type FlagsMap map[string]interface{}
16+
type FlagsMap map[string]string
1917

2018
// Utility function simplifying construction of a FlagsMap from a file.
2119
func ReadFlagsMap(path string, description string) (FlagsMap, error) {
@@ -32,7 +30,7 @@ func ReadFlagsMap(path string, description string) (FlagsMap, error) {
3230

3331
// SetDefault ensures the effectiveness of a flag override by only
3432
// setting a value supplied whose key is not already explicitly set.
35-
func (f FlagsMap) SetDefault(key string, value any) {
33+
func (f FlagsMap) SetDefault(key string, value string) {
3634
if _, ok := f[key]; !ok {
3735
f[key] = value
3836
}
@@ -47,34 +45,6 @@ func (f FlagsMap) SetDefaults(defaults FlagsMap) {
4745
}
4846
}
4947

50-
// GetStringVal simplifies retrieving a map value as a string.
51-
func (f FlagsMap) GetStringVal(key string) (string, error) {
52-
rawVal, ok := f[key]
53-
if !ok {
54-
return "", nil
55-
}
56-
57-
val, err := cast.ToStringE(rawVal)
58-
if err != nil {
59-
return "", fmt.Errorf("failed to cast value for %q: %w", key, err)
60-
}
61-
return val, nil
62-
}
63-
64-
// GetBoolVal simplifies retrieving a map value as a bool.
65-
func (f FlagsMap) GetBoolVal(key string, defaultVal bool) (bool, error) {
66-
rawVal, ok := f[key]
67-
if !ok {
68-
return defaultVal, nil
69-
}
70-
71-
val, err := cast.ToBoolE(rawVal)
72-
if err != nil {
73-
return false, fmt.Errorf("failed to cast value for %q: %w", key, err)
74-
}
75-
return val, nil
76-
}
77-
7848
// Write simplifies writing a FlagsMap to the provided path. The
7949
// description is used in error messages.
8050
func (f FlagsMap) Write(path string, description string) error {

tests/fixture/tmpnet/network.go

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ type Network struct {
107107
Genesis *genesis.UnparsedConfig
108108

109109
// Configuration for primary subnets
110-
PrimarySubnetConfig FlagsMap
110+
PrimarySubnetConfig map[string]any
111111

112112
// Configuration for primary network chains (P, X, C)
113-
PrimaryChainConfigs map[string]FlagsMap
113+
PrimaryChainConfigs map[string]ChainConfigMap
114114

115115
// Default configuration to use when creating new nodes
116116
DefaultFlags FlagsMap
@@ -229,14 +229,19 @@ func (n *Network) EnsureDefaultConfig(log logging.Logger) error {
229229

230230
// Ensure primary chains are configured
231231
if n.PrimaryChainConfigs == nil {
232-
n.PrimaryChainConfigs = map[string]FlagsMap{}
232+
n.PrimaryChainConfigs = map[string]ChainConfigMap{}
233233
}
234234
defaultChainConfigs := DefaultChainConfigs()
235-
for alias, chainConfig := range defaultChainConfigs {
235+
for alias, defaultChainConfig := range defaultChainConfigs {
236236
if _, ok := n.PrimaryChainConfigs[alias]; !ok {
237-
n.PrimaryChainConfigs[alias] = FlagsMap{}
237+
n.PrimaryChainConfigs[alias] = ChainConfigMap{}
238+
}
239+
primaryChainConfig := n.PrimaryChainConfigs[alias]
240+
for key, value := range defaultChainConfig {
241+
if _, ok := primaryChainConfig[key]; !ok {
242+
primaryChainConfig[key] = value
243+
}
238244
}
239-
n.PrimaryChainConfigs[alias].SetDefaults(chainConfig)
240245
}
241246

242247
return nil
@@ -377,8 +382,8 @@ func (n *Network) Bootstrap(ctx context.Context, log logging.Logger) error {
377382
// The node that will be used to create subnets and bootstrap the network
378383
bootstrapNode := n.Nodes[0]
379384

380-
// Whether sybil protection will need to be re-enabled after subnet creation
381-
reEnableSybilProtection := false
385+
// An existing sybil protection value that may need to be restored after subnet creation
386+
var existingSybilProtectionValue *string
382387

383388
if len(n.Nodes) > 1 {
384389
// Reduce the cost of subnet creation for a network of multiple nodes by
@@ -389,14 +394,11 @@ func (n *Network) Bootstrap(ctx context.Context, log logging.Logger) error {
389394
log.Info("starting a single-node network with sybil protection disabled for quicker subnet creation")
390395

391396
// If sybil protection is enabled, it should be re-enabled before the node is used to bootstrap the other nodes
392-
var err error
393-
reEnableSybilProtection, err = bootstrapNode.Flags.GetBoolVal(config.SybilProtectionEnabledKey, true)
394-
if err != nil {
395-
return fmt.Errorf("failed to read sybil protection flag: %w", err)
397+
if value, ok := bootstrapNode.Flags[config.SybilProtectionEnabledKey]; ok {
398+
existingSybilProtectionValue = &value
396399
}
397-
398400
// Ensure sybil protection is disabled for the bootstrap node.
399-
bootstrapNode.Flags[config.SybilProtectionEnabledKey] = false
401+
bootstrapNode.Flags[config.SybilProtectionEnabledKey] = "false"
400402
}
401403

402404
if err := n.StartNodes(ctx, log, bootstrapNode); err != nil {
@@ -413,11 +415,17 @@ func (n *Network) Bootstrap(ctx context.Context, log logging.Logger) error {
413415
return err
414416
}
415417

416-
if reEnableSybilProtection {
418+
if existingSybilProtectionValue == nil {
417419
log.Info("re-enabling sybil protection",
418420
zap.Stringer("nodeID", bootstrapNode.NodeID),
419421
)
420422
delete(bootstrapNode.Flags, config.SybilProtectionEnabledKey)
423+
} else {
424+
log.Info("restoring previous sybil protection value",
425+
zap.Stringer("nodeID", bootstrapNode.NodeID),
426+
zap.String("sybilProtectionEnabled", *existingSybilProtectionValue),
427+
)
428+
bootstrapNode.Flags[config.SybilProtectionEnabledKey] = *existingSybilProtectionValue
421429
}
422430

423431
log.Info("restarting bootstrap node",
@@ -640,10 +648,7 @@ func (n *Network) CreateSubnets(ctx context.Context, log logging.Logger, apiURI
640648

641649
reconfiguredNodes := []*Node{}
642650
for _, node := range n.Nodes {
643-
existingTrackedSubnets, err := node.Flags.GetStringVal(config.TrackSubnetsKey)
644-
if err != nil {
645-
return err
646-
}
651+
existingTrackedSubnets := node.Flags[config.TrackSubnetsKey]
647652
trackedSubnets := n.TrackedSubnetsForNode(node.NodeID)
648653
if existingTrackedSubnets == trackedSubnets {
649654
continue
@@ -801,7 +806,7 @@ func (n *Network) GetGenesisFileContent() (string, error) {
801806
// GetSubnetConfigContent returns the base64-encoded and
802807
// JSON-marshaled map of subnetID to subnet configuration.
803808
func (n *Network) GetSubnetConfigContent() (string, error) {
804-
subnetConfigs := map[ids.ID]FlagsMap{}
809+
subnetConfigs := map[ids.ID]map[string]any{}
805810

806811
if len(n.PrimarySubnetConfig) > 0 {
807812
subnetConfigs[constants.PrimaryNetworkID] = n.PrimarySubnetConfig
@@ -894,7 +899,7 @@ func (n *Network) writeNodeFlags(log logging.Logger, node *Node) error {
894899
isSingleNodeNetwork := (len(n.Nodes) == 1 && len(n.Genesis.InitialStakers) == 1)
895900
if isSingleNodeNetwork {
896901
log.Info("defaulting to sybil protection disabled to enable a single-node network to start")
897-
flags.SetDefault(config.SybilProtectionEnabledKey, false)
902+
flags.SetDefault(config.SybilProtectionEnabledKey, "false")
898903
}
899904
}
900905

tests/fixture/tmpnet/network_config.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,13 @@ func (n *Network) readConfig() error {
150150

151151
// The subset of network fields to store in the network config file.
152152
type serializedNetworkConfig struct {
153-
UUID string `json:"uuid,omitempty"`
154-
Owner string `json:"owner,omitempty"`
155-
PrimarySubnetConfig FlagsMap `json:"primarySubnetConfig,omitempty"`
156-
PrimaryChainConfigs map[string]FlagsMap `json:"primaryChainConfigs,omitempty"`
157-
DefaultFlags FlagsMap `json:"defaultFlags,omitempty"`
158-
DefaultRuntimeConfig NodeRuntimeConfig `json:"defaultRuntimeConfig,omitempty"`
159-
PreFundedKeys []*secp256k1.PrivateKey `json:"preFundedKeys,omitempty"`
153+
UUID string `json:"uuid,omitempty"`
154+
Owner string `json:"owner,omitempty"`
155+
PrimarySubnetConfig map[string]any `json:"primarySubnetConfig,omitempty"`
156+
PrimaryChainConfigs map[string]ChainConfigMap `json:"primaryChainConfigs,omitempty"`
157+
DefaultFlags FlagsMap `json:"defaultFlags,omitempty"`
158+
DefaultRuntimeConfig NodeRuntimeConfig `json:"defaultRuntimeConfig,omitempty"`
159+
PreFundedKeys []*secp256k1.PrivateKey `json:"preFundedKeys,omitempty"`
160160
}
161161

162162
func (n *Network) writeNetworkConfig() error {

0 commit comments

Comments
 (0)