Skip to content

Commit

Permalink
[tmpnet] Enable single node networks (#3003)
Browse files Browse the repository at this point in the history
Co-authored-by: Alberto Benegiamo <[email protected]>
  • Loading branch information
maru-ava and abi87 authored May 21, 2024
1 parent 551f8d3 commit 34e7b2f
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 35 deletions.
4 changes: 1 addition & 3 deletions tests/e2e/c/dynamic_fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ var _ = e2e.DescribeCChain("[Dynamic Fees]", func() {

ginkgo.It("should ensure that the gas price is affected by load", func() {
ginkgo.By("creating a new private network to ensure isolation from other tests")
privateNetwork := &tmpnet.Network{
Owner: "avalanchego-e2e-dynamic-fees",
}
privateNetwork := tmpnet.NewDefaultNetwork("avalanchego-e2e-dynamic-fees")
e2e.Env.StartPrivateNetwork(privateNetwork)

ginkgo.By("allocating a pre-funded key")
Expand Down
6 changes: 1 addition & 5 deletions tests/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"testing"

"github.com/onsi/gomega"
"github.com/stretchr/testify/require"

// ensure test packages are scanned by ginkgo
_ "github.com/ava-labs/avalanchego/tests/e2e/banff"
Expand Down Expand Up @@ -38,11 +37,8 @@ func init() {
var _ = ginkgo.SynchronizedBeforeSuite(func() []byte {
// Run only once in the first ginkgo process

nodes, err := tmpnet.NewNodes(tmpnet.DefaultNodeCount)
require.NoError(ginkgo.GinkgoT(), err)

nodes := tmpnet.NewNodesOrPanic(flagVars.NodeCount())
subnets := vms.XSVMSubnets(nodes...)

return e2e.NewTestEnvironment(
flagVars,
&tmpnet.Network{
Expand Down
11 changes: 11 additions & 0 deletions tests/fixture/e2e/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type FlagVars struct {
reuseNetwork bool
networkShutdownDelay time.Duration
stopNetwork bool
nodeCount int
}

func (v *FlagVars) AvalancheGoExecPath() string {
Expand Down Expand Up @@ -51,6 +52,10 @@ func (v *FlagVars) StopNetwork() bool {
return v.stopNetwork
}

func (v *FlagVars) NodeCount() int {
return v.nodeCount
}

func RegisterFlags() *FlagVars {
vars := FlagVars{}
flag.StringVar(
Expand Down Expand Up @@ -89,6 +94,12 @@ func RegisterFlags() *FlagVars {
false,
"[optional] stop an existing network and exit without executing any tests.",
)
flag.IntVar(
&vars.nodeCount,
"node-count",
tmpnet.DefaultNodeCount,
"number of nodes the network should initially consist of",
)

return &vars
}
1 change: 0 additions & 1 deletion tests/fixture/e2e/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ func StartNetwork(
DefaultNetworkDir,
avalancheGoExecPath,
pluginDir,
tmpnet.DefaultNodeCount,
),
)

Expand Down
5 changes: 3 additions & 2 deletions tests/fixture/tmpnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ A temporary network can be managed by the `tmpnetctl` cli tool:
# Build the tmpnetctl binary
$ ./scripts/build_tmpnetctl.sh

# Start a new network
# Start a new network. Possible to specify the number of nodes (> 1) with --node-count.
$ ./build/tmpnetctl start-network --avalanchego-path=/path/to/avalanchego
...
Started network /home/me/.tmpnet/networks/20240306-152305.924531 (UUID: abaab590-b375-44f6-9ca5-f8a6dc061725)
Expand Down Expand Up @@ -87,6 +87,7 @@ network := &tmpnet.Network{ // Configure non-default values fo
DefaultFlags: tmpnet.FlagsMap{
config.LogLevelKey: "INFO", // Change one of the network's defaults
},
Nodes: tmpnet.NewNodesOrPanic(5), // Number of initial validating nodes
Subnets: []*tmpnet.Subnet{ // Subnets to create on the new network once it is running
{
Name: "xsvm-a", // User-defined name used to reference subnet in code and on disk
Expand All @@ -97,6 +98,7 @@ network := &tmpnet.Network{ // Configure non-default values fo
PreFundedKey: <key>, // (Optional) A private key that is funded in the genesis bytes
},
},
ValidatorIDs: <node ids>, // The IDs of nodes that validate the subnet
},
},
}
Expand All @@ -108,7 +110,6 @@ _ := tmpnet.StartNewNetwork( // Start the network
"", // Empty string uses the default network path (~/tmpnet/networks)
"/path/to/avalanchego", // The path to the binary that nodes will execute
"/path/to/plugins", // The path nodes will use for plugin binaries (suggested value ~/.avalanchego/plugins)
5, // Number of initial validating nodes
)

uris := network.GetNodeURIs()
Expand Down
2 changes: 1 addition & 1 deletion tests/fixture/tmpnet/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func main() {

network := &tmpnet.Network{
Owner: networkOwner,
Nodes: tmpnet.NewNodesOrPanic(int(nodeCount)),
}

// Extreme upper bound, should never take this long
Expand All @@ -80,7 +81,6 @@ func main() {
rootDir,
avalancheGoPath,
pluginDir,
int(nodeCount),
)
if err != nil {
return err
Expand Down
39 changes: 24 additions & 15 deletions tests/fixture/tmpnet/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ const (
HardHatKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027"
)

// HardhatKey is a legacy used for hardhat testing in subnet-evm
// TODO(marun) Remove when no longer needed.
var HardhatKey *secp256k1.PrivateKey
var (
// Key expected to be funded for subnet-evm hardhat testing
// TODO(marun) Remove when subnet-evm configures the genesis with this key.
HardhatKey *secp256k1.PrivateKey

errInsufficientNodes = errors.New("network needs at least one node to start")
)

func init() {
hardhatKeyBytes, err := hex.DecodeString(HardHatKeyStr)
Expand Down Expand Up @@ -105,6 +109,13 @@ type Network struct {
Subnets []*Subnet
}

func NewDefaultNetwork(owner string) *Network {
return &Network{
Owner: owner,
Nodes: NewNodesOrPanic(DefaultNodeCount),
}
}

// Ensure a real and absolute network dir so that node
// configuration that embeds the network path will continue to
// work regardless of symlink and working directory changes.
Expand All @@ -123,9 +134,11 @@ func StartNewNetwork(
rootNetworkDir string,
avalancheGoExecPath string,
pluginDir string,
nodeCount int,
) error {
if err := network.EnsureDefaultConfig(w, avalancheGoExecPath, pluginDir, nodeCount); err != nil {
if len(network.Nodes) == 0 {
return errInsufficientNodes
}
if err := network.EnsureDefaultConfig(w, avalancheGoExecPath, pluginDir); err != nil {
return err
}
if err := network.Create(rootNetworkDir); err != nil {
Expand Down Expand Up @@ -171,7 +184,7 @@ func ReadNetwork(dir string) (*Network, error) {
}

// Initializes a new network with default configuration.
func (n *Network) EnsureDefaultConfig(w io.Writer, avalancheGoPath string, pluginDir string, nodeCount int) error {
func (n *Network) EnsureDefaultConfig(w io.Writer, avalancheGoPath string, pluginDir string) error {
if _, err := fmt.Fprintf(w, "Preparing configuration for new network with %s\n", avalancheGoPath); err != nil {
return err
}
Expand All @@ -187,6 +200,11 @@ func (n *Network) EnsureDefaultConfig(w io.Writer, avalancheGoPath string, plugi
}
n.DefaultFlags.SetDefaults(DefaultFlags())

if len(n.Nodes) == 1 {
// Sybil protection needs to be disabled for a single node network to start
n.DefaultFlags[config.SybilProtectionEnabledKey] = false
}

// Only configure the plugin dir with a non-empty value to ensure
// the use of the default value (`[datadir]/plugins`) when
// no plugin dir is configured.
Expand Down Expand Up @@ -222,15 +240,6 @@ func (n *Network) EnsureDefaultConfig(w io.Writer, avalancheGoPath string, plugi
n.DefaultRuntimeConfig.AvalancheGoPath = avalancheGoPath
}

// Ensure nodes are created
if len(n.Nodes) == 0 {
nodes, err := NewNodes(nodeCount)
if err != nil {
return err
}
n.Nodes = nodes
}

// Ensure nodes are configured
for i := range n.Nodes {
if err := n.EnsureNodeConfig(n.Nodes[i]); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions tests/fixture/tmpnet/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ func TestNetworkSerialization(t *testing.T) {

tmpDir := t.TempDir()

network := &Network{}
require.NoError(network.EnsureDefaultConfig(&bytes.Buffer{}, "/path/to/avalanche/go", "", 1))
network := NewDefaultNetwork("testnet")
require.NoError(network.EnsureDefaultConfig(&bytes.Buffer{}, "/path/to/avalanche/go", ""))
require.NoError(network.Create(tmpDir))
// Ensure node runtime is initialized
require.NoError(network.readNodes())
Expand Down
6 changes: 3 additions & 3 deletions tests/fixture/tmpnet/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,16 @@ func NewEphemeralNode(flags FlagsMap) *Node {
}

// Initializes the specified number of nodes.
func NewNodes(count int) ([]*Node, error) {
func NewNodesOrPanic(count int) []*Node {
nodes := make([]*Node, count)
for i := range nodes {
node := NewNode("")
if err := node.EnsureKeys(); err != nil {
return nil, err
panic(err)
}
nodes[i] = node
}
return nodes, nil
return nodes
}

// Reads a node's configuration from the specified directory.
Expand Down
4 changes: 1 addition & 3 deletions tests/upgrade/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ var _ = ginkgo.Describe("[Upgrade]", func() {
require := require.New(ginkgo.GinkgoT())

ginkgo.It("can upgrade versions", func() {
network := &tmpnet.Network{
Owner: "avalanchego-upgrade",
}
network := tmpnet.NewDefaultNetwork("avalanchego-upgrade")
e2e.StartNetwork(network, avalancheGoExecPath, "" /* pluginDir */, 0 /* shutdownDelay */, false /* reuseNetwork */)

ginkgo.By(fmt.Sprintf("restarting all nodes with %q binary", avalancheGoExecPathToUpgradeTo))
Expand Down

0 comments on commit 34e7b2f

Please sign in to comment.