From d0c209421a98f69d37fbef1659705f20bdbcf02c Mon Sep 17 00:00:00 2001 From: Darioush Jalali Date: Thu, 20 Jun 2024 18:22:06 -0700 Subject: [PATCH 1/6] bump protobuf (fixes some build issues) (#3142) --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 34d9c6cfacde..cf4ca86ee324 100644 --- a/go.mod +++ b/go.mod @@ -65,7 +65,7 @@ require ( gonum.org/v1/gonum v0.11.0 google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 google.golang.org/grpc v1.62.0 - google.golang.org/protobuf v1.33.0 + google.golang.org/protobuf v1.34.2 gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -108,7 +108,7 @@ require ( github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect diff --git a/go.sum b/go.sum index 79f7b0d77e36..f969c7512b4f 100644 --- a/go.sum +++ b/go.sum @@ -269,8 +269,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -1027,8 +1027,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From cafd71c8c3f433faf92c207164e4a1e8548ce1e9 Mon Sep 17 00:00:00 2001 From: marun Date: Fri, 21 Jun 2024 20:26:01 +0200 Subject: [PATCH 2/6] Emit version in JSON format for --json-version (#3129) --- config/flags.go | 1 + config/keys.go | 1 + main/main.go | 19 ++++++++++++++- version/string.go | 53 +++++++++++++++++++++++------------------- version/string_test.go | 23 ++++++++++++++++++ 5 files changed, 72 insertions(+), 25 deletions(-) create mode 100644 version/string_test.go diff --git a/config/flags.go b/config/flags.go index 661eb9e84e66..3fb99e5f03e3 100644 --- a/config/flags.go +++ b/config/flags.go @@ -69,6 +69,7 @@ func deprecateFlags(fs *pflag.FlagSet) error { func addProcessFlags(fs *pflag.FlagSet) { // If true, print the version and quit. fs.Bool(VersionKey, false, "If true, print version and quit") + fs.Bool(VersionJSONKey, false, "If true, print version in JSON format and quit") } func addNodeFlags(fs *pflag.FlagSet) { diff --git a/config/keys.go b/config/keys.go index 25348ae54c8d..289c83170614 100644 --- a/config/keys.go +++ b/config/keys.go @@ -13,6 +13,7 @@ const ( ConfigContentKey = "config-file-content" ConfigContentTypeKey = "config-file-content-type" VersionKey = "version" + VersionJSONKey = "version-json" GenesisFileKey = "genesis-file" GenesisFileContentKey = "genesis-file-content" NetworkNameKey = "network-id" diff --git a/main/main.go b/main/main.go index 5651bf61940f..88de72dadbbe 100644 --- a/main/main.go +++ b/main/main.go @@ -4,6 +4,7 @@ package main import ( + "encoding/json" "errors" "fmt" "os" @@ -29,8 +30,24 @@ func main() { os.Exit(1) } + if v.GetBool(config.VersionJSONKey) && v.GetBool(config.VersionKey) { + fmt.Println("can't print both JSON and human readable versions") + os.Exit(1) + } + + if v.GetBool(config.VersionJSONKey) { + versions := version.GetVersions() + jsonBytes, err := json.MarshalIndent(versions, "", " ") + if err != nil { + fmt.Printf("couldn't marshal versions: %s\n", err) + os.Exit(1) + } + fmt.Println(string(jsonBytes)) + os.Exit(0) + } + if v.GetBool(config.VersionKey) { - fmt.Print(version.String) + fmt.Println(version.GetVersions().String()) os.Exit(0) } diff --git a/version/string.go b/version/string.go index 9abe555bcebb..80df9bea697a 100644 --- a/version/string.go +++ b/version/string.go @@ -9,32 +9,37 @@ import ( "strings" ) -var ( - // String is displayed when CLI arg --version is used - String string +// GitCommit is set in the build script at compile time +var GitCommit string - // GitCommit is set in the build script at compile time - GitCommit string -) +// Versions contains the versions relevant to a build of avalanchego. In +// addition to supporting construction of the string displayed by +// --version, it is used to produce the output of --version-json and can +// be used to unmarshal that output. +type Versions struct { + Application string `json:"application"` + Database string `json:"database"` + RPCChainVM uint64 `json:"rpcchainvm"` + // Commit may be empty if GitCommit was not set at compile time + Commit string `json:"commit"` + Go string `json:"go"` +} -func init() { - format := "%s [database=%s, rpcchainvm=%d" - args := []interface{}{ - CurrentApp, - CurrentDatabase, - RPCChainVMProtocol, - } - if GitCommit != "" { - format += ", commit=%s" - args = append(args, GitCommit) +func GetVersions() *Versions { + return &Versions{ + Application: CurrentApp.String(), + Database: CurrentDatabase.String(), + RPCChainVM: uint64(RPCChainVMProtocol), + Commit: GitCommit, + Go: strings.TrimPrefix(runtime.Version(), "go"), } +} - // add golang version - goVersion := runtime.Version() - goVersionNumber := strings.TrimPrefix(goVersion, "go") - format += ", go=%s" - args = append(args, goVersionNumber) - - format += "]\n" - String = fmt.Sprintf(format, args...) +func (v *Versions) String() string { + // This format maintains consistency with previous --version output + versionString := fmt.Sprintf("%s [database=%s, rpcchainvm=%d, ", v.Application, v.Database, v.RPCChainVM) + if len(v.Commit) > 0 { + versionString += fmt.Sprintf("commit=%s, ", v.Commit) + } + return versionString + fmt.Sprintf("go=%s]", v.Go) } diff --git a/version/string_test.go b/version/string_test.go new file mode 100644 index 000000000000..58f44668b3e0 --- /dev/null +++ b/version/string_test.go @@ -0,0 +1,23 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package version + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestVersionsGetString(t *testing.T) { + versions := Versions{ + Application: "1", + Database: "2", + RPCChainVM: 3, + Commit: "4", + Go: "5", + } + require.Equal(t, "1 [database=2, rpcchainvm=3, commit=4, go=5]", versions.String()) + versions.Commit = "" + require.Equal(t, "1 [database=2, rpcchainvm=3, go=5]", versions.String()) +} From 6eef08fe19e657e930d3824bdce87e315f4a4f1a Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 21 Jun 2024 20:27:30 +0200 Subject: [PATCH 3/6] Repackaged NextBlockTime and GetNextStakerChangeTime (#3134) --- vms/platformvm/block/builder/builder.go | 4 +- vms/platformvm/block/executor/manager.go | 2 +- .../block/executor/proposal_block_test.go | 2 +- vms/platformvm/block/executor/verifier.go | 2 +- vms/platformvm/state/chain_time_helpers.go | 70 +++++++++++++++++++ .../txs/executor/proposal_tx_executor.go | 2 +- .../staker_tx_verification_helpers.go | 34 --------- vms/platformvm/txs/executor/state_changes.go | 25 ------- 8 files changed, 76 insertions(+), 65 deletions(-) create mode 100644 vms/platformvm/state/chain_time_helpers.go diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 1a7f2f0556e6..a445bb52cb1b 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -171,7 +171,7 @@ func (b *builder) durationToSleep() (time.Duration, error) { return 0, fmt.Errorf("%w: %s", errMissingPreferredState, preferredID) } - nextStakerChangeTime, err := txexecutor.GetNextStakerChangeTime(preferredState) + nextStakerChangeTime, err := state.GetNextStakerChangeTime(preferredState) if err != nil { return 0, fmt.Errorf("%w of %s: %w", errCalculatingNextStakerTime, preferredID, err) } @@ -216,7 +216,7 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { return nil, fmt.Errorf("%w: %s", state.ErrMissingParentState, preferredID) } - timestamp, timeWasCapped, err := txexecutor.NextBlockTime(preferredState, b.txExecutorBackend.Clk) + timestamp, timeWasCapped, err := state.NextBlockTime(preferredState, b.txExecutorBackend.Clk) if err != nil { return nil, fmt.Errorf("could not calculate next staker change time: %w", err) } diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index ecc07f579815..80e3e4503139 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -132,7 +132,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - nextBlkTime, _, err := executor.NextBlockTime(stateDiff, m.txExecutorBackend.Clk) + nextBlkTime, _, err := state.NextBlockTime(stateDiff, m.txExecutorBackend.Clk) if err != nil { return err } diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 3a3f45fd7c0d..f0037754d06a 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -1436,7 +1436,7 @@ func TestAddValidatorProposalBlock(t *testing.T) { // Advance time until next staker change time is [validatorEndTime] for { - nextStakerChangeTime, err := executor.GetNextStakerChangeTime(env.state) + nextStakerChangeTime, err := state.GetNextStakerChangeTime(env.state) require.NoError(err) if nextStakerChangeTime.Equal(validatorEndTime) { break diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index c56abc45e3c1..3feccf4e4c96 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -266,7 +266,7 @@ func (v *verifier) banffNonOptionBlock(b block.BanffBlock) error { ) } - nextStakerChangeTime, err := executor.GetNextStakerChangeTime(parentState) + nextStakerChangeTime, err := state.GetNextStakerChangeTime(parentState) if err != nil { return fmt.Errorf("could not verify block timestamp: %w", err) } diff --git a/vms/platformvm/state/chain_time_helpers.go b/vms/platformvm/state/chain_time_helpers.go new file mode 100644 index 000000000000..036eb168d73d --- /dev/null +++ b/vms/platformvm/state/chain_time_helpers.go @@ -0,0 +1,70 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package state + +import ( + "fmt" + "time" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/utils/timer/mockable" +) + +func NextBlockTime(state Chain, clk *mockable.Clock) (time.Time, bool, error) { + var ( + timestamp = clk.Time() + parentTime = state.GetTimestamp() + ) + if parentTime.After(timestamp) { + timestamp = parentTime + } + // [timestamp] = max(now, parentTime) + + nextStakerChangeTime, err := GetNextStakerChangeTime(state) + if err != nil { + return time.Time{}, false, fmt.Errorf("failed getting next staker change time: %w", err) + } + + // timeWasCapped means that [timestamp] was reduced to [nextStakerChangeTime] + timeWasCapped := !timestamp.Before(nextStakerChangeTime) + if timeWasCapped { + timestamp = nextStakerChangeTime + } + // [timestamp] = min(max(now, parentTime), nextStakerChangeTime) + return timestamp, timeWasCapped, nil +} + +// GetNextStakerChangeTime returns the next time a staker will be either added +// or removed to/from the current validator set. +func GetNextStakerChangeTime(state Chain) (time.Time, error) { + currentStakerIterator, err := state.GetCurrentStakerIterator() + if err != nil { + return time.Time{}, err + } + defer currentStakerIterator.Release() + + pendingStakerIterator, err := state.GetPendingStakerIterator() + if err != nil { + return time.Time{}, err + } + defer pendingStakerIterator.Release() + + hasCurrentStaker := currentStakerIterator.Next() + hasPendingStaker := pendingStakerIterator.Next() + switch { + case hasCurrentStaker && hasPendingStaker: + nextCurrentTime := currentStakerIterator.Value().NextTime + nextPendingTime := pendingStakerIterator.Value().NextTime + if nextCurrentTime.Before(nextPendingTime) { + return nextCurrentTime, nil + } + return nextPendingTime, nil + case hasCurrentStaker: + return currentStakerIterator.Value().NextTime, nil + case hasPendingStaker: + return pendingStakerIterator.Value().NextTime, nil + default: + return time.Time{}, database.ErrNotFound + } +} diff --git a/vms/platformvm/txs/executor/proposal_tx_executor.go b/vms/platformvm/txs/executor/proposal_tx_executor.go index 294e01486a17..c54b8207fb06 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor.go @@ -269,7 +269,7 @@ func (e *ProposalTxExecutor) AdvanceTimeTx(tx *txs.AdvanceTimeTx) error { // Only allow timestamp to move forward as far as the time of next staker // set change time - nextStakerChangeTime, err := GetNextStakerChangeTime(e.OnCommitState) + nextStakerChangeTime, err := state.GetNextStakerChangeTime(e.OnCommitState) if err != nil { return err } diff --git a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go index 3a74cea28696..eb18c6609299 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go @@ -94,40 +94,6 @@ func getDelegatorRules( }, nil } -// GetNextStakerChangeTime returns the next time a staker will be either added -// or removed to/from the current validator set. -func GetNextStakerChangeTime(state state.Chain) (time.Time, error) { - currentStakerIterator, err := state.GetCurrentStakerIterator() - if err != nil { - return time.Time{}, err - } - defer currentStakerIterator.Release() - - pendingStakerIterator, err := state.GetPendingStakerIterator() - if err != nil { - return time.Time{}, err - } - defer pendingStakerIterator.Release() - - hasCurrentStaker := currentStakerIterator.Next() - hasPendingStaker := pendingStakerIterator.Next() - switch { - case hasCurrentStaker && hasPendingStaker: - nextCurrentTime := currentStakerIterator.Value().NextTime - nextPendingTime := pendingStakerIterator.Value().NextTime - if nextCurrentTime.Before(nextPendingTime) { - return nextCurrentTime, nil - } - return nextPendingTime, nil - case hasCurrentStaker: - return currentStakerIterator.Value().NextTime, nil - case hasPendingStaker: - return pendingStakerIterator.Value().NextTime, nil - default: - return time.Time{}, database.ErrNotFound - } -} - // GetValidator returns information about the given validator, which may be a // current validator or pending validator. func GetValidator(state state.Chain, subnetID ids.ID, nodeID ids.NodeID) (*state.Staker, error) { diff --git a/vms/platformvm/txs/executor/state_changes.go b/vms/platformvm/txs/executor/state_changes.go index 36981b095e8c..3086358304a3 100644 --- a/vms/platformvm/txs/executor/state_changes.go +++ b/vms/platformvm/txs/executor/state_changes.go @@ -10,7 +10,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -58,30 +57,6 @@ func VerifyNewChainTime( return nil } -func NextBlockTime(state state.Chain, clk *mockable.Clock) (time.Time, bool, error) { - var ( - timestamp = clk.Time() - parentTime = state.GetTimestamp() - ) - if parentTime.After(timestamp) { - timestamp = parentTime - } - // [timestamp] = max(now, parentTime) - - nextStakerChangeTime, err := GetNextStakerChangeTime(state) - if err != nil { - return time.Time{}, false, fmt.Errorf("failed getting next staker change time: %w", err) - } - - // timeWasCapped means that [timestamp] was reduced to [nextStakerChangeTime] - timeWasCapped := !timestamp.Before(nextStakerChangeTime) - if timeWasCapped { - timestamp = nextStakerChangeTime - } - // [timestamp] = min(max(now, parentTime), nextStakerChangeTime) - return timestamp, timeWasCapped, nil -} - // AdvanceTimeTo applies all state changes to [parentState] resulting from // advancing the chain time to [newChainTime]. // Returns true iff the validator set changed. From 1a9bc457d8c7a2c9b1336fdac67e9103898a696a Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 24 Jun 2024 05:21:18 -0700 Subject: [PATCH 4/6] [vms/platformvm] Cleanup execution config tests (#3137) --- .../config/execution_config_test.go | 117 ++++-------------- 1 file changed, 27 insertions(+), 90 deletions(-) diff --git a/vms/platformvm/config/execution_config_test.go b/vms/platformvm/config/execution_config_test.go index 4c4f4ba9dc96..f3fe8e4c6082 100644 --- a/vms/platformvm/config/execution_config_test.go +++ b/vms/platformvm/config/execution_config_test.go @@ -4,6 +4,8 @@ package config import ( + "encoding/json" + "reflect" "testing" "time" @@ -12,6 +14,23 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/network" ) +// Requires all values in a struct to be initialized +func verifyInitializedStruct(tb testing.TB, s interface{}) { + tb.Helper() + + require := require.New(tb) + + structType := reflect.TypeOf(s) + require.Equal(reflect.Struct, structType.Kind()) + + v := reflect.ValueOf(s) + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + require.True(field.IsValid(), "invalid field: ", structType.Field(i).Name) + require.False(field.IsZero(), "zero field: ", structType.Field(i).Name) + } +} + func TestExecutionConfigUnmarshal(t *testing.T) { t.Run("default values from empty json", func(t *testing.T) { require := require.New(t) @@ -41,39 +60,7 @@ func TestExecutionConfigUnmarshal(t *testing.T) { t.Run("all values extracted from json", func(t *testing.T) { require := require.New(t) - b := []byte(`{ - "network": { - "max-validator-set-staleness": 1, - "target-gossip-size": 2, - "push-gossip-percent-stake": 0.3, - "push-gossip-num-validators": 4, - "push-gossip-num-peers": 5, - "push-regossip-num-validators": 6, - "push-regossip-num-peers": 7, - "push-gossip-discarded-cache-size": 8, - "push-gossip-max-regossip-frequency": 9, - "push-gossip-frequency": 10, - "pull-gossip-poll-size": 11, - "pull-gossip-frequency": 12, - "pull-gossip-throttling-period": 13, - "pull-gossip-throttling-limit": 14, - "expected-bloom-filter-elements": 15, - "expected-bloom-filter-false-positive-probability": 16, - "max-bloom-filter-false-positive-probability": 17 - }, - "block-cache-size": 1, - "tx-cache-size": 2, - "transformed-subnet-tx-cache-size": 3, - "reward-utxos-cache-size": 5, - "chain-cache-size": 6, - "chain-db-cache-size": 7, - "block-id-cache-size": 8, - "fx-owner-cache-size": 9, - "checksums-enabled": true, - "mempool-prune-frequency": 60000000000 - }`) - ec, err := GetExecutionConfig(b) - require.NoError(err) + expected := &ExecutionConfig{ Network: network.Config{ MaxValidatorSetStaleness: 1, @@ -105,64 +92,14 @@ func TestExecutionConfigUnmarshal(t *testing.T) { ChecksumsEnabled: true, MempoolPruneFrequency: time.Minute, } - require.Equal(expected, ec) - }) + verifyInitializedStruct(t, *expected) + verifyInitializedStruct(t, expected.Network) - t.Run("default values applied correctly", func(t *testing.T) { - require := require.New(t) - b := []byte(`{ - "network": { - "max-validator-set-staleness": 1, - "target-gossip-size": 2, - "push-gossip-discarded-cache-size": 1024, - "push-gossip-max-regossip-frequency": 10000000000, - "pull-gossip-poll-size": 3, - "pull-gossip-frequency": 4, - "pull-gossip-throttling-period": 5 - }, - "block-cache-size": 1, - "tx-cache-size": 2, - "transformed-subnet-tx-cache-size": 3, - "reward-utxos-cache-size": 5, - "chain-cache-size": 6, - "chain-db-cache-size": 7, - "block-id-cache-size": 8, - "fx-owner-cache-size": 9, - "checksums-enabled": true - }`) - ec, err := GetExecutionConfig(b) + b, err := json.Marshal(expected) require.NoError(err) - expected := &ExecutionConfig{ - Network: network.Config{ - MaxValidatorSetStaleness: 1, - TargetGossipSize: 2, - PushGossipPercentStake: DefaultExecutionConfig.Network.PushGossipPercentStake, - PushGossipNumValidators: DefaultExecutionConfig.Network.PushGossipNumValidators, - PushGossipNumPeers: DefaultExecutionConfig.Network.PushGossipNumPeers, - PushRegossipNumValidators: DefaultExecutionConfig.Network.PushRegossipNumValidators, - PushRegossipNumPeers: DefaultExecutionConfig.Network.PushRegossipNumPeers, - PushGossipDiscardedCacheSize: 1024, - PushGossipMaxRegossipFrequency: 10 * time.Second, - PushGossipFrequency: DefaultExecutionConfig.Network.PushGossipFrequency, - PullGossipPollSize: 3, - PullGossipFrequency: 4, - PullGossipThrottlingPeriod: 5, - PullGossipThrottlingLimit: DefaultExecutionConfig.Network.PullGossipThrottlingLimit, - ExpectedBloomFilterElements: DefaultExecutionConfig.Network.ExpectedBloomFilterElements, - ExpectedBloomFilterFalsePositiveProbability: DefaultExecutionConfig.Network.ExpectedBloomFilterFalsePositiveProbability, - MaxBloomFilterFalsePositiveProbability: DefaultExecutionConfig.Network.MaxBloomFilterFalsePositiveProbability, - }, - BlockCacheSize: 1, - TxCacheSize: 2, - TransformedSubnetTxCacheSize: 3, - RewardUTXOsCacheSize: 5, - ChainCacheSize: 6, - ChainDBCacheSize: 7, - BlockIDCacheSize: 8, - FxOwnerCacheSize: 9, - ChecksumsEnabled: true, - MempoolPruneFrequency: 30 * time.Minute, - } - require.Equal(expected, ec) + + actual, err := GetExecutionConfig(b) + require.NoError(err) + require.Equal(expected, actual) }) } From 318da000780e3c165eb0c01b05da315c19309971 Mon Sep 17 00:00:00 2001 From: marun Date: Tue, 25 Jun 2024 17:35:11 +0200 Subject: [PATCH 5/6] [tmpnet] Enable bootstrap of subnets with disjoint validator sets (#3138) Co-authored-by: Alberto Benegiamo --- tests/e2e/vms/xsvm.go | 53 +++++++++++++++++++++++++-------- tests/fixture/tmpnet/network.go | 6 ++-- tests/fixture/tmpnet/subnet.go | 4 +-- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/tests/e2e/vms/xsvm.go b/tests/e2e/vms/xsvm.go index 71eeb7936c43..5d3557acd405 100644 --- a/tests/e2e/vms/xsvm.go +++ b/tests/e2e/vms/xsvm.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/tests/fixture/subnet" @@ -35,9 +36,17 @@ func XSVMSubnetsOrPanic(nodes ...*tmpnet.Node) []*tmpnet.Subnet { if err != nil { panic(err) } + subnetANodes := nodes + subnetBNodes := nodes + if len(nodes) > 1 { + // Validate tmpnet bootstrap of a disjoint validator set + midpoint := len(nodes) / 2 + subnetANodes = nodes[:midpoint] + subnetBNodes = nodes[midpoint:] + } return []*tmpnet.Subnet{ - subnet.NewXSVMOrPanic(subnetAName, key, nodes...), - subnet.NewXSVMOrPanic(subnetBName, key, nodes...), + subnet.NewXSVMOrPanic(subnetAName, key, subnetANodes...), + subnet.NewXSVMOrPanic(subnetBName, key, subnetBNodes...), } } @@ -55,14 +64,21 @@ var _ = ginkgo.Describe("[XSVM]", func() { sourceChain := sourceSubnet.Chains[0] destinationChain := destinationSubnet.Chains[0] - apiNode := network.Nodes[0] - tests.Outf(" issuing transactions on %s (%s)\n", apiNode.NodeID, apiNode.URI) + sourceValidators := getNodesForIDs(network.Nodes, sourceSubnet.ValidatorIDs) + require.NotEmpty(sourceValidators) + sourceAPINode := sourceValidators[0] + tests.Outf(" issuing transactions for source subnet on %s (%s)\n", sourceAPINode.NodeID, sourceAPINode.URI) + + destinationValidators := getNodesForIDs(network.Nodes, destinationSubnet.ValidatorIDs) + require.NotEmpty(destinationValidators) + destinationAPINode := destinationValidators[0] + tests.Outf(" issuing transactions for destination subnet on %s (%s)\n", destinationAPINode.NodeID, destinationAPINode.URI) destinationKey, err := secp256k1.NewPrivateKey() require.NoError(err) ginkgo.By("checking that the funded key has sufficient funds for the export") - sourceClient := api.NewClient(apiNode.URI, sourceChain.ChainID.String()) + sourceClient := api.NewClient(sourceAPINode.URI, sourceChain.ChainID.String()) initialSourcedBalance, err := sourceClient.Balance( e2e.DefaultContext(), sourceChain.PreFundedKey.Address(), @@ -75,7 +91,7 @@ var _ = ginkgo.Describe("[XSVM]", func() { exportTxStatus, err := export.Export( e2e.DefaultContext(), &export.Config{ - URI: apiNode.URI, + URI: sourceAPINode.URI, SourceChainID: sourceChain.ChainID, DestinationChainID: destinationChain.ChainID, Amount: units.Schmeckle, @@ -87,7 +103,7 @@ var _ = ginkgo.Describe("[XSVM]", func() { tests.Outf(" issued transaction with ID: %s\n", exportTxStatus.TxID) ginkgo.By("checking that the export transaction has been accepted on all nodes") - for _, node := range network.Nodes[1:] { + for _, node := range sourceValidators[1:] { require.NoError(api.AwaitTxAccepted( e2e.DefaultContext(), api.NewClient(node.URI, sourceChain.ChainID.String()), @@ -104,7 +120,7 @@ var _ = ginkgo.Describe("[XSVM]", func() { transferTxStatus, err := transfer.Transfer( e2e.DefaultContext(), &transfer.Config{ - URI: apiNode.URI, + URI: destinationAPINode.URI, ChainID: destinationChain.ChainID, AssetID: destinationChain.ChainID, Amount: units.Schmeckle, @@ -116,14 +132,14 @@ var _ = ginkgo.Describe("[XSVM]", func() { tests.Outf(" issued transaction with ID: %s\n", transferTxStatus.TxID) ginkgo.By(fmt.Sprintf("importing to blockchain %s on subnet %s", destinationChain.ChainID, destinationSubnet.SubnetID)) - sourceURIs := make([]string, len(network.Nodes)) - for i, node := range network.Nodes { + sourceURIs := make([]string, len(sourceValidators)) + for i, node := range sourceValidators { sourceURIs[i] = node.URI } importTxStatus, err := importtx.Import( e2e.DefaultContext(), &importtx.Config{ - URI: apiNode.URI, + URI: destinationAPINode.URI, SourceURIs: sourceURIs, SourceChainID: sourceChain.ChainID.String(), DestinationChainID: destinationChain.ChainID.String(), @@ -140,9 +156,22 @@ var _ = ginkgo.Describe("[XSVM]", func() { require.GreaterOrEqual(initialSourcedBalance-units.Schmeckle, sourceBalance) ginkgo.By("checking that the balance of the destination key is non-zero") - destinationClient := api.NewClient(apiNode.URI, destinationChain.ChainID.String()) + destinationClient := api.NewClient(destinationAPINode.URI, destinationChain.ChainID.String()) destinationBalance, err := destinationClient.Balance(e2e.DefaultContext(), destinationKey.Address(), sourceChain.ChainID) require.NoError(err) require.Equal(units.Schmeckle, destinationBalance) }) }) + +// Retrieve the nodes corresponding to the provided IDs +func getNodesForIDs(nodes []*tmpnet.Node, nodeIDs []ids.NodeID) []*tmpnet.Node { + desiredNodes := make([]*tmpnet.Node, 0, len(nodeIDs)) + for _, node := range nodes { + for _, nodeID := range nodeIDs { + if node.NodeID == nodeID { + desiredNodes = append(desiredNodes, node) + } + } + } + return desiredNodes +} diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index 97e6a9a48c21..63796be267a4 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -409,7 +409,7 @@ func (n *Network) Bootstrap(ctx context.Context, w io.Writer) error { } // Don't restart the node during subnet creation since it will always be restarted afterwards. - if err := n.CreateSubnets(ctx, w, false /* restartRequired */); err != nil { + if err := n.CreateSubnets(ctx, w, bootstrapNode.URI, false /* restartRequired */); err != nil { return err } @@ -646,7 +646,7 @@ func (n *Network) GetSubnet(name string) *Subnet { // Ensure that each subnet on the network is created. If restartRequired is false, node restart // to pick up configuration changes becomes the responsibility of the caller. -func (n *Network) CreateSubnets(ctx context.Context, w io.Writer, restartRequired bool) error { +func (n *Network) CreateSubnets(ctx context.Context, w io.Writer, apiURI string, restartRequired bool) error { createdSubnets := make([]*Subnet, 0, len(n.Subnets)) for _, subnet := range n.Subnets { if len(subnet.ValidatorIDs) == 0 { @@ -748,7 +748,7 @@ func (n *Network) CreateSubnets(ctx context.Context, w io.Writer, restartRequire validatorNodes = append(validatorNodes, node) } - if err := subnet.AddValidators(ctx, w, validatorNodes...); err != nil { + if err := subnet.AddValidators(ctx, w, apiURI, validatorNodes...); err != nil { return err } } diff --git a/tests/fixture/tmpnet/subnet.go b/tests/fixture/tmpnet/subnet.go index eb07536ba7d3..9e4d30f83f7f 100644 --- a/tests/fixture/tmpnet/subnet.go +++ b/tests/fixture/tmpnet/subnet.go @@ -155,9 +155,7 @@ func (s *Subnet) CreateChains(ctx context.Context, w io.Writer, uri string) erro } // Add validators to the subnet -func (s *Subnet) AddValidators(ctx context.Context, w io.Writer, nodes ...*Node) error { - apiURI := nodes[0].URI - +func (s *Subnet) AddValidators(ctx context.Context, w io.Writer, apiURI string, nodes ...*Node) error { wallet, err := s.GetWallet(ctx, apiURI) if err != nil { return err From e7caabe532fc99e9a6b7eda02dbd2bfc3dc04647 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 25 Jun 2024 11:41:15 -0400 Subject: [PATCH 6/6] nit --- snow/engine/snowman/transitive.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index 7f5d67bb5bed..fa9be05a803f 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -686,7 +686,7 @@ func (t *Transitive) buildBlocks(ctx context.Context) error { // TODO: Technically this may incorrectly log a warning if the block // that was just built caused votes to be applied such that the block - // was rejected or was accepted along with one of it's children. This + // was rejected or was accepted along with one of its children. This // should be cleaned up to never produce an invalid warning. if t.canIssueChildOn(blk.ID()) { t.Ctx.Log.Verbo("successfully issued new block from the VM")