From 1f3746e54611d0dea59f52db1801365d91ea3c6b Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Wed, 29 Jan 2025 23:56:24 +0000 Subject: [PATCH 1/5] [tmpnet] Minimize duration of tx acceptance for e2e testing - Enable configuration of min block delay for primary subnet with the addition of node flag `--proposer-min-block-delay` - Configure tmpnet to default the block delay to zero for all subnets - Reduce the wallet poll interval from 100ms to 10ms - Remove unnecessary sleep in virtuous test --- config/config.go | 2 +- config/flags.go | 4 ++++ config/keys.go | 1 + tests/e2e/x/transfer/virtuous.go | 1 - tests/fixture/e2e/helpers.go | 2 ++ tests/fixture/tmpnet/defaults.go | 10 ++++++++++ tests/fixture/tmpnet/network.go | 6 ++++++ 7 files changed, 24 insertions(+), 2 deletions(-) diff --git a/config/config.go b/config/config.go index d3c3a136f11a..68bbfc4b3fc1 100644 --- a/config/config.go +++ b/config/config.go @@ -1132,7 +1132,7 @@ func getDefaultSubnetConfig(v *viper.Viper) subnets.Config { return subnets.Config{ ConsensusParameters: getConsensusConfig(v), ValidatorOnly: false, - ProposerMinBlockDelay: proposervm.DefaultMinBlockDelay, + ProposerMinBlockDelay: v.GetDuration(ProposerMinBlockDelayKey), ProposerNumHistoricalBlocks: proposervm.DefaultNumHistoricalBlocks, } } diff --git a/config/flags.go b/config/flags.go index fc53770fdb89..f54a97df4398 100644 --- a/config/flags.go +++ b/config/flags.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/utils/ulimit" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/gas" + "github.com/ava-labs/avalanchego/vms/proposervm" ) const ( @@ -384,6 +385,9 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.StringToString(TracingHeadersKey, map[string]string{}, "The headers to provide the trace indexer") fs.String(ProcessContextFileKey, defaultProcessContextPath, "The path to write process context to (including PID, API URI, and staking address).") + + // Primary Subnet Config + fs.Duration(ProposerMinBlockDelayKey, proposervm.DefaultMinBlockDelay, "Minimum delay to enforce when building a snowman++ block for the primary subnet") } // BuildFlagSet returns a complete set of flags for avalanchego diff --git a/config/keys.go b/config/keys.go index 760bee97fd77..2cb6a6ddc11a 100644 --- a/config/keys.go +++ b/config/keys.go @@ -208,4 +208,5 @@ const ( TracingExporterTypeKey = "tracing-exporter-type" TracingHeadersKey = "tracing-headers" ProcessContextFileKey = "process-context-file" + ProposerMinBlockDelayKey = "proposer-min-block-delay" ) diff --git a/tests/e2e/x/transfer/virtuous.go b/tests/e2e/x/transfer/virtuous.go index b17922ae8601..bcb4138fdd8e 100644 --- a/tests/e2e/x/transfer/virtuous.go +++ b/tests/e2e/x/transfer/virtuous.go @@ -299,7 +299,6 @@ var _ = e2e.DescribeXChainSerial("[Virtuous Transfer Tx AVAX]", func() { for i := 0; i < totalRounds; i++ { runFunc(i) - time.Sleep(time.Second) } _ = e2e.CheckBootstrapIsPossible(tc, env.GetNetwork()) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 1b6367c6eed4..3097e4260cb0 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -84,6 +84,8 @@ func NewWallet(tc tests.TestContext, keychain *secp256k1fx.Keychain, nodeURI tmp ) }, ), + // Reducing the default from 100ms speeds up detection of tx acceptance + common.WithPollFrequency(10*time.Millisecond), ) OutputWalletBalances(tc, wallet) return wallet diff --git a/tests/fixture/tmpnet/defaults.go b/tests/fixture/tmpnet/defaults.go index c5dbfeeebc96..8652b6373862 100644 --- a/tests/fixture/tmpnet/defaults.go +++ b/tests/fixture/tmpnet/defaults.go @@ -59,6 +59,8 @@ func DefaultTmpnetFlags() FlagsMap { // Specific to e2e testing config.MinStakeDurationKey: DefaultMinStakeDuration.String(), config.ProposerVMUseCurrentHeightKey: true, + // Reducing this from the 1s default speeds up tx acceptance + config.ProposerMinBlockDelayKey: "0s", } flags.SetDefaults(DefaultTestFlags()) return flags @@ -76,3 +78,11 @@ func DefaultChainConfigs() map[string]FlagsMap { }, } } + +// A set of subnet configuration appropriate for testing. +func DefaultSubnetConfig() FlagsMap { + return FlagsMap{ + // Reducing this from the 1s default speeds up tx acceptance + "proposerMinBlockDelay": 0, // Needs to be a number to be valid in subnet configuration + } +} diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index 2a9fdb4327a4..af2fccf190d7 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -679,6 +679,12 @@ func (n *Network) CreateSubnets(ctx context.Context, log logging.Logger, apiURI zap.String("name", subnet.Name), ) + // Apply tmpnet defaults + if subnet.Config == nil { + subnet.Config = FlagsMap{} + } + subnet.Config.SetDefaults(DefaultSubnetConfig()) + if subnet.OwningKey == nil { // Allocate a pre-funded key and remove it from the network so it won't be used for // other purposes From 4c662c56f59c9fa13ab9dcf0a64d1877a3b0b471 Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Thu, 30 Jan 2025 10:33:08 -0800 Subject: [PATCH 2/5] fixup: Respond to review feedback --- config/flags.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/flags.go b/config/flags.go index f54a97df4398..50369345241a 100644 --- a/config/flags.go +++ b/config/flags.go @@ -322,6 +322,9 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.Int(SnowMaxProcessingKey, snowball.DefaultParameters.MaxOutstandingItems, "Maximum number of processing items to be considered healthy") fs.Duration(SnowMaxTimeProcessingKey, snowball.DefaultParameters.MaxItemProcessingTime, "Maximum amount of time an item should be processing and still be healthy") + // Primary Network Config + fs.Duration(ProposerMinBlockDelayKey, proposervm.DefaultMinBlockDelay, "Minimum delay to enforce when building a snowman++ block for the primary network chains") + // ProposerVM fs.Bool(ProposerVMUseCurrentHeightKey, false, "Have the ProposerVM always report the last accepted P-chain block height") @@ -386,8 +389,6 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.String(ProcessContextFileKey, defaultProcessContextPath, "The path to write process context to (including PID, API URI, and staking address).") - // Primary Subnet Config - fs.Duration(ProposerMinBlockDelayKey, proposervm.DefaultMinBlockDelay, "Minimum delay to enforce when building a snowman++ block for the primary subnet") } // BuildFlagSet returns a complete set of flags for avalanchego From d12db28acc83dfbff5f7ad39adc6db7bc6cf9d2c Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Thu, 30 Jan 2025 11:01:28 -0800 Subject: [PATCH 3/5] fixup: lint --- config/flags.go | 1 - 1 file changed, 1 deletion(-) diff --git a/config/flags.go b/config/flags.go index 50369345241a..e9bb866ea977 100644 --- a/config/flags.go +++ b/config/flags.go @@ -388,7 +388,6 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.StringToString(TracingHeadersKey, map[string]string{}, "The headers to provide the trace indexer") fs.String(ProcessContextFileKey, defaultProcessContextPath, "The path to write process context to (including PID, API URI, and staking address).") - } // BuildFlagSet returns a complete set of flags for avalanchego From 579d425aab0cb39a15f6c2a69267347de27a9dca Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Mon, 3 Feb 2025 21:16:53 -0800 Subject: [PATCH 4/5] fixup: Respond to reviewer feedback --- chains/manager.go | 20 ++++++++------------ config/config.go | 15 +++++++++------ config/config.md | 6 ++++++ config/flags.go | 4 +--- config/keys.go | 2 +- tests/fixture/tmpnet/defaults.go | 10 +--------- tests/fixture/tmpnet/network.go | 6 ------ 7 files changed, 26 insertions(+), 37 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index 42cbf32c9380..d3216d750b42 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -752,13 +752,11 @@ func (m *manager) createAvalancheChain( // Initialize the ProposerVM and the vm wrapped inside it var ( - minBlockDelay = proposervm.DefaultMinBlockDelay - numHistoricalBlocks = proposervm.DefaultNumHistoricalBlocks - ) - if subnetCfg, ok := m.SubnetConfigs[ctx.SubnetID]; ok { - minBlockDelay = subnetCfg.ProposerMinBlockDelay + // A default subnet configuration will be present if explicit configuration is not provided + subnetCfg = m.SubnetConfigs[ctx.SubnetID] + minBlockDelay = subnetCfg.ProposerMinBlockDelay numHistoricalBlocks = subnetCfg.ProposerNumHistoricalBlocks - } + ) m.Log.Info("creating proposervm wrapper", zap.Time("activationTime", m.Upgrades.ApricotPhase4Time), zap.Uint64("minPChainHeight", m.Upgrades.ApricotPhase4MinPChainHeight), @@ -1150,13 +1148,11 @@ func (m *manager) createSnowmanChain( } var ( - minBlockDelay = proposervm.DefaultMinBlockDelay - numHistoricalBlocks = proposervm.DefaultNumHistoricalBlocks - ) - if subnetCfg, ok := m.SubnetConfigs[ctx.SubnetID]; ok { - minBlockDelay = subnetCfg.ProposerMinBlockDelay + // A default subnet configuration will be present if explicit configuration is not provided + subnetCfg = m.SubnetConfigs[ctx.SubnetID] + minBlockDelay = subnetCfg.ProposerMinBlockDelay numHistoricalBlocks = subnetCfg.ProposerNumHistoricalBlocks - } + ) m.Log.Info("creating proposervm wrapper", zap.Time("activationTime", m.Upgrades.ApricotPhase4Time), zap.Uint64("minPChainHeight", m.Upgrades.ApricotPhase4MinPChainHeight), diff --git a/config/config.go b/config/config.go index 68bbfc4b3fc1..54376c17052a 100644 --- a/config/config.go +++ b/config/config.go @@ -1054,8 +1054,9 @@ func getSubnetConfigsFromFlags(v *viper.Viper, subnetIDs []ids.ID) (map[ids.ID]s res := make(map[ids.ID]subnets.Config) for _, subnetID := range subnetIDs { + config := getDefaultSubnetConfig(v) + if rawSubnetConfigBytes, ok := subnetConfigs[subnetID]; ok { - config := getDefaultSubnetConfig(v) if err := json.Unmarshal(rawSubnetConfigBytes, &config); err != nil { return nil, err } @@ -1068,9 +1069,9 @@ func getSubnetConfigsFromFlags(v *viper.Viper, subnetIDs []ids.ID) (map[ids.ID]s if err := config.Valid(); err != nil { return nil, err } - - res[subnetID] = config } + + res[subnetID] = config } return res, nil } @@ -1090,11 +1091,14 @@ func getSubnetConfigsFromDir(v *viper.Viper, subnetIDs []ids.ID) (map[ids.ID]sub // reads subnet config files from a path and given subnetIDs and returns a map. for _, subnetID := range subnetIDs { + config := getDefaultSubnetConfig(v) + filePath := filepath.Join(subnetConfigPath, subnetID.String()+subnetConfigFileExt) fileInfo, err := os.Stat(filePath) switch { case errors.Is(err, os.ErrNotExist): - // this subnet config does not exist, move to the next one + // this subnet config does not exist, use the default configuration + subnetConfigs[subnetID] = config continue case err != nil: return nil, err @@ -1108,7 +1112,6 @@ func getSubnetConfigsFromDir(v *viper.Viper, subnetIDs []ids.ID) (map[ids.ID]sub return nil, err } - config := getDefaultSubnetConfig(v) if err := json.Unmarshal(file, &config); err != nil { return nil, fmt.Errorf("%w: %w", errUnmarshalling, err) } @@ -1132,7 +1135,7 @@ func getDefaultSubnetConfig(v *viper.Viper) subnets.Config { return subnets.Config{ ConsensusParameters: getConsensusConfig(v), ValidatorOnly: false, - ProposerMinBlockDelay: v.GetDuration(ProposerMinBlockDelayKey), + ProposerMinBlockDelay: v.GetDuration(ProposerVMMinBlockDelayKey), ProposerNumHistoricalBlocks: proposervm.DefaultNumHistoricalBlocks, } } diff --git a/config/config.md b/config/config.md index 1d8f22384919..14eededa019d 100644 --- a/config/config.md +++ b/config/config.md @@ -953,6 +953,12 @@ The value must be greater than `0`. Defaults to `2m`. Have the ProposerVM always report the last accepted P-chain block height. Defaults to `false`. +### `--proposervm-min-block-duration` (duration) + +The minimum delay to enforce when building a snowman++ block for the primary network +chains and the default minimum delay for subnets. Defaults to `1s`. A non-default +value is only suggested for non-production nodes. + ### Continuous Profiling You can configure your node to continuously run memory/CPU profiles and save the diff --git a/config/flags.go b/config/flags.go index e9bb866ea977..826aa25947c4 100644 --- a/config/flags.go +++ b/config/flags.go @@ -322,11 +322,9 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.Int(SnowMaxProcessingKey, snowball.DefaultParameters.MaxOutstandingItems, "Maximum number of processing items to be considered healthy") fs.Duration(SnowMaxTimeProcessingKey, snowball.DefaultParameters.MaxItemProcessingTime, "Maximum amount of time an item should be processing and still be healthy") - // Primary Network Config - fs.Duration(ProposerMinBlockDelayKey, proposervm.DefaultMinBlockDelay, "Minimum delay to enforce when building a snowman++ block for the primary network chains") - // ProposerVM fs.Bool(ProposerVMUseCurrentHeightKey, false, "Have the ProposerVM always report the last accepted P-chain block height") + fs.Duration(ProposerVMMinBlockDelayKey, proposervm.DefaultMinBlockDelay, "Minimum delay to enforce when building a snowman++ block for the primary network chains and the default minimum delay for subnets") // Metrics fs.Bool(MeterVMsEnabledKey, true, "Enable Meter VMs to track VM performance with more granularity") diff --git a/config/keys.go b/config/keys.go index 2cb6a6ddc11a..90f8fc9973b4 100644 --- a/config/keys.go +++ b/config/keys.go @@ -152,6 +152,7 @@ const ( ConsensusShutdownTimeoutKey = "consensus-shutdown-timeout" ConsensusFrontierPollFrequencyKey = "consensus-frontier-poll-frequency" ProposerVMUseCurrentHeightKey = "proposervm-use-current-height" + ProposerVMMinBlockDelayKey = "proposervm-min-block-delay" FdLimitKey = "fd-limit" IndexEnabledKey = "index-enabled" IndexAllowIncompleteKey = "index-allow-incomplete" @@ -208,5 +209,4 @@ const ( TracingExporterTypeKey = "tracing-exporter-type" TracingHeadersKey = "tracing-headers" ProcessContextFileKey = "process-context-file" - ProposerMinBlockDelayKey = "proposer-min-block-delay" ) diff --git a/tests/fixture/tmpnet/defaults.go b/tests/fixture/tmpnet/defaults.go index 8652b6373862..2f9ab62d14d9 100644 --- a/tests/fixture/tmpnet/defaults.go +++ b/tests/fixture/tmpnet/defaults.go @@ -60,7 +60,7 @@ func DefaultTmpnetFlags() FlagsMap { config.MinStakeDurationKey: DefaultMinStakeDuration.String(), config.ProposerVMUseCurrentHeightKey: true, // Reducing this from the 1s default speeds up tx acceptance - config.ProposerMinBlockDelayKey: "0s", + config.ProposerVMMinBlockDelayKey: "0s", } flags.SetDefaults(DefaultTestFlags()) return flags @@ -78,11 +78,3 @@ func DefaultChainConfigs() map[string]FlagsMap { }, } } - -// A set of subnet configuration appropriate for testing. -func DefaultSubnetConfig() FlagsMap { - return FlagsMap{ - // Reducing this from the 1s default speeds up tx acceptance - "proposerMinBlockDelay": 0, // Needs to be a number to be valid in subnet configuration - } -} diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index af2fccf190d7..2a9fdb4327a4 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -679,12 +679,6 @@ func (n *Network) CreateSubnets(ctx context.Context, log logging.Logger, apiURI zap.String("name", subnet.Name), ) - // Apply tmpnet defaults - if subnet.Config == nil { - subnet.Config = FlagsMap{} - } - subnet.Config.SetDefaults(DefaultSubnetConfig()) - if subnet.OwningKey == nil { // Allocate a pre-funded key and remove it from the network so it won't be used for // other purposes From a2ee6c0e7ab9d70387f5c1db4297540d509ee3a6 Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Tue, 4 Feb 2025 08:36:33 -0800 Subject: [PATCH 5/5] fixup: Fix unit tests --- config/config_test.go | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/config/config_test.go b/config/config_test.go index 68847ca4f6d5..1862787cc760 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -382,19 +382,16 @@ func TestGetSubnetConfigsFromFile(t *testing.T) { }, expectedErr: errUnmarshalling, }, - "subnet is not tracked": { - fileName: "Gmt4fuNsGJAd2PX86LBvycGaBpgCYKbuULdCLZs3SEs1Jx1LU.json", - givenJSON: `{"validatorOnly": true}`, - testF: func(require *require.Assertions, given map[ids.ID]subnets.Config) { - require.Empty(given) - }, - expectedErr: nil, - }, - "wrong extension": { + "default config when incorrect extension used": { fileName: "2Ctt6eGAeo4MLqTmGa7AdRecuVMPGWEX9wSsCLBYrLhX4a394i.yaml", givenJSON: `{"validatorOnly": true}`, testF: func(require *require.Assertions, given map[ids.ID]subnets.Config) { - require.Empty(given) + v := setupViperFlags() + defaultConfig := getDefaultSubnetConfig(v) + expected := map[ids.ID]subnets.Config{ + subnetID: defaultConfig, + } + require.Equal(expected, given) }, expectedErr: nil, }, @@ -455,10 +452,15 @@ func TestGetSubnetConfigsFromFlags(t *testing.T) { testF func(*require.Assertions, map[ids.ID]subnets.Config) expectedErr error }{ - "no configs": { + "default config used when no config provided": { givenJSON: `{}`, testF: func(require *require.Assertions, given map[ids.ID]subnets.Config) { - require.Empty(given) + v := setupViperFlags() + defaultConfig := getDefaultSubnetConfig(v) + expected := map[ids.ID]subnets.Config{ + subnetID: defaultConfig, + } + require.Equal(expected, given) }, expectedErr: nil, }, @@ -474,13 +476,6 @@ func TestGetSubnetConfigsFromFlags(t *testing.T) { }, expectedErr: nil, }, - "subnet is not tracked": { - givenJSON: `{"Gmt4fuNsGJAd2PX86LBvycGaBpgCYKbuULdCLZs3SEs1Jx1LU":{"validatorOnly":true}}`, - testF: func(require *require.Assertions, given map[ids.ID]subnets.Config) { - require.Empty(given) - }, - expectedErr: nil, - }, "invalid consensus parameters": { givenJSON: `{ "2Ctt6eGAeo4MLqTmGa7AdRecuVMPGWEX9wSsCLBYrLhX4a394i": {