@@ -24,10 +24,14 @@ import (
24
24
"github.com/ava-labs/avalanchego/utils/set"
25
25
)
26
26
27
- // This interval was chosen to avoid spamming node APIs during
28
- // startup, as smaller intervals (e.g. 50ms) seemed to noticeably
29
- // increase the time for a network's nodes to be seen as healthy.
30
- const networkHealthCheckInterval = 200 * time .Millisecond
27
+ const (
28
+ // This interval was chosen to avoid spamming node APIs during
29
+ // startup, as smaller intervals (e.g. 50ms) seemed to noticeably
30
+ // increase the time for a network's nodes to be seen as healthy.
31
+ networkHealthCheckInterval = 200 * time .Millisecond
32
+
33
+ defaultEphemeralDirName = "ephemeral"
34
+ )
31
35
32
36
var (
33
37
errInvalidNodeCount = errors .New ("failed to populate local network config: non-zero node count is only valid for a network without nodes" )
@@ -102,16 +106,26 @@ func (ln *LocalNetwork) GetNodes() []testnet.Node {
102
106
return nodes
103
107
}
104
108
105
- // Adds a backend-agnostic node to the network
106
- func (ln * LocalNetwork ) AddNode (w io.Writer , flags testnet.FlagsMap ) (testnet.Node , error ) {
109
+ // Internal method supporting AddNode and AddEphemeralNode in creating a backend-agnostic node.
110
+ func (ln * LocalNetwork ) addNode (w io.Writer , flags testnet.FlagsMap , isEphemeral bool ) (testnet.Node , error ) {
107
111
if flags == nil {
108
112
flags = testnet.FlagsMap {}
109
113
}
110
114
return ln .AddLocalNode (w , & LocalNode {
111
115
NodeConfig : testnet.NodeConfig {
112
116
Flags : flags ,
113
117
},
114
- })
118
+ }, isEphemeral )
119
+ }
120
+
121
+ // Adds a backend-agnostic node to the network
122
+ func (ln * LocalNetwork ) AddNode (w io.Writer , flags testnet.FlagsMap ) (testnet.Node , error ) {
123
+ return ln .addNode (w , flags , false /* isEphemeral */ )
124
+ }
125
+
126
+ // Adds a backend-agnostic ephemeral node to the network
127
+ func (ln * LocalNetwork ) AddEphemeralNode (w io.Writer , flags testnet.FlagsMap ) (testnet.Node , error ) {
128
+ return ln .addNode (w , flags , true /* isEphemeral */ )
115
129
}
116
130
117
131
// Starts a new network stored under the provided root dir. Required
@@ -278,17 +292,18 @@ func (ln *LocalNetwork) PopulateLocalNetworkConfig(networkID uint32, nodeCount i
278
292
for _ , node := range ln .Nodes {
279
293
// Ensure the node is configured for use with the network and
280
294
// knows where to write its configuration.
281
- if err := ln .PopulateNodeConfig (node ); err != nil {
295
+ if err := ln .PopulateNodeConfig (node , ln . Dir ); err != nil {
282
296
return err
283
297
}
284
298
}
285
299
286
300
return nil
287
301
}
288
302
289
- // Ensure the provided node has the configuration it needs to
290
- // start. Requires that the network has valid genesis data.
291
- func (ln * LocalNetwork ) PopulateNodeConfig (node * LocalNode ) error {
303
+ // Ensure the provided node has the configuration it needs to start. If the data dir is
304
+ // not set, it will be defaulted to [nodeParentDir]/[node ID]. Requires that the
305
+ // network has valid genesis data.
306
+ func (ln * LocalNetwork ) PopulateNodeConfig (node * LocalNode , nodeParentDir string ) error {
292
307
flags := node .Flags
293
308
294
309
// Set values common to all nodes
@@ -310,7 +325,7 @@ func (ln *LocalNetwork) PopulateNodeConfig(node *LocalNode) error {
310
325
dataDir := node .GetDataDir ()
311
326
if len (dataDir ) == 0 {
312
327
// NodeID will have been set by EnsureKeys
313
- dataDir = filepath .Join (ln . Dir , node .NodeID .String ())
328
+ dataDir = filepath .Join (nodeParentDir , node .NodeID .String ())
314
329
flags [config .DataDirKey ] = dataDir
315
330
}
316
331
@@ -645,15 +660,30 @@ func (ln *LocalNetwork) ReadAll() error {
645
660
return ln .ReadNodes ()
646
661
}
647
662
648
- func (ln * LocalNetwork ) AddLocalNode (w io.Writer , node * LocalNode ) (* LocalNode , error ) {
663
+ func (ln * LocalNetwork ) AddLocalNode (w io.Writer , node * LocalNode , isEphemeral bool ) (* LocalNode , error ) {
649
664
// Assume network configuration has been written to disk and is current in memory
650
665
651
666
if node == nil {
652
667
// Set an empty data dir so that PopulateNodeConfig will know
653
668
// to set the default of `[network dir]/[node id]`.
654
669
node = NewLocalNode ("" )
655
670
}
656
- if err := ln .PopulateNodeConfig (node ); err != nil {
671
+
672
+ // Default to a data dir of [network-dir]/[node-ID]
673
+ nodeParentDir := ln .Dir
674
+ if isEphemeral {
675
+ // For an ephemeral node, default to a data dir of [network-dir]/[ephemeral-dir][node-ID]
676
+ // to provide a clear separation between nodes that are expected to expose stable API
677
+ // endpoints and those that will live for only a short time (e.g. a node started by a test
678
+ // and stopped on test teardown).
679
+ //
680
+ // The data for an ephemeral node is still in the file tree rooted at the network dir to
681
+ // ensure that archiving the network dir in CI will collect all node data used for a test
682
+ // run. Otherwise the data dir of ephemeral nodes could be stored in a random temp dir.
683
+ nodeParentDir = filepath .Join (ln .Dir , defaultEphemeralDirName )
684
+ }
685
+
686
+ if err := ln .PopulateNodeConfig (node , nodeParentDir ); err != nil {
657
687
return nil , err
658
688
}
659
689
0 commit comments