@@ -9,17 +9,17 @@ import (
9
9
"errors"
10
10
"fmt"
11
11
"io"
12
- "io/fs"
13
12
"os"
14
13
"path/filepath"
15
14
"strconv"
16
15
"strings"
17
16
"time"
18
17
18
+ "github.com/google/uuid"
19
+
19
20
"github.com/ava-labs/avalanchego/config"
20
21
"github.com/ava-labs/avalanchego/genesis"
21
22
"github.com/ava-labs/avalanchego/ids"
22
- "github.com/ava-labs/avalanchego/utils/constants"
23
23
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
24
24
"github.com/ava-labs/avalanchego/utils/perms"
25
25
"github.com/ava-labs/avalanchego/utils/set"
@@ -40,6 +40,9 @@ const (
40
40
// increase the time for a network's nodes to be seen as healthy.
41
41
networkHealthCheckInterval = 200 * time .Millisecond
42
42
43
+ // All temporary networks will use this arbitrary network ID by default.
44
+ defaultNetworkID = 88888
45
+
43
46
// eth address: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC
44
47
HardHatKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027"
45
48
)
@@ -61,6 +64,16 @@ func init() {
61
64
62
65
// Collects the configuration for running a temporary avalanchego network
63
66
type Network struct {
67
+ // Uniquely identifies the temporary network for metrics
68
+ // collection. Distinct from avalanchego's concept of network ID
69
+ // since the utility of special network ID values (e.g. to trigger
70
+ // specific fork behavior in a given network) precludes requiring
71
+ // unique network ID values across all temporary networks.
72
+ UUID string
73
+
74
+ // A string identifying the entity that started or maintains this network.
75
+ Owner string
76
+
64
77
// Path where network configuration and data is stored
65
78
Dir string
66
79
@@ -150,6 +163,11 @@ func (n *Network) EnsureDefaultConfig(w io.Writer, avalancheGoPath string, plugi
150
163
return err
151
164
}
152
165
166
+ // A UUID supports centralized metrics collection
167
+ if len (n .UUID ) == 0 {
168
+ n .UUID = uuid .NewString ()
169
+ }
170
+
153
171
// Ensure default flags
154
172
if n .DefaultFlags == nil {
155
173
n .DefaultFlags = FlagsMap {}
@@ -206,8 +224,9 @@ func (n *Network) EnsureDefaultConfig(w io.Writer, avalancheGoPath string, plugi
206
224
return nil
207
225
}
208
226
209
- // Creates the network on disk, choosing its network id and generating its genesis in the process.
227
+ // Creates the network on disk, generating its genesis and configuring its nodes in the process.
210
228
func (n * Network ) Create (rootDir string ) error {
229
+ // Ensure creation of the root dir
211
230
if len (rootDir ) == 0 {
212
231
// Use the default root dir
213
232
var err error
@@ -216,48 +235,34 @@ func (n *Network) Create(rootDir string) error {
216
235
return err
217
236
}
218
237
}
219
-
220
- // Ensure creation of the root dir
221
238
if err := os .MkdirAll (rootDir , perms .ReadWriteExecute ); err != nil {
222
239
return fmt .Errorf ("failed to create root network dir: %w" , err )
223
240
}
224
241
225
- // Determine the network path and ID
226
- var (
227
- networkDir string
228
- networkID uint32
229
- )
230
- if n .Genesis != nil && n .Genesis .NetworkID > 0 {
231
- // Use the network ID defined in the provided genesis
232
- networkID = n .Genesis .NetworkID
242
+ // A time-based name ensures consistent directory ordering
243
+ dirName := time .Now ().Format ("20060102-150405.999999" )
244
+ if len (n .Owner ) > 0 {
245
+ // Include the owner to differentiate networks created at similar times
246
+ dirName = fmt .Sprintf ("%s-%s" , dirName , n .Owner )
233
247
}
234
- if networkID > 0 {
235
- // Use a directory with a random suffix
236
- var err error
237
- networkDir , err = os .MkdirTemp (rootDir , fmt .Sprintf ("%d." , n .Genesis .NetworkID ))
238
- if err != nil {
239
- return fmt .Errorf ("failed to create network dir: %w" , err )
240
- }
241
- } else {
242
- // Find the next available network ID based on the contents of the root dir
243
- var err error
244
- networkID , networkDir , err = findNextNetworkID (rootDir )
245
- if err != nil {
246
- return err
247
- }
248
+
249
+ // Ensure creation of the network dir
250
+ networkDir := filepath .Join (rootDir , dirName )
251
+ if err := os .MkdirAll (networkDir , perms .ReadWriteExecute ); err != nil {
252
+ return fmt .Errorf ("failed to create network dir: %w" , err )
248
253
}
249
254
canonicalDir , err := toCanonicalDir (networkDir )
250
255
if err != nil {
251
256
return err
252
257
}
253
258
n .Dir = canonicalDir
254
259
260
+ // Ensure the existence of the plugin directory or nodes won't be able to start.
255
261
pluginDir , err := n .DefaultFlags .GetStringVal (config .PluginDirKey )
256
262
if err != nil {
257
263
return err
258
264
}
259
265
if len (pluginDir ) > 0 {
260
- // Ensure the existence of the plugin directory or nodes won't be able to start.
261
266
if err := os .MkdirAll (pluginDir , perms .ReadWriteExecute ); err != nil {
262
267
return fmt .Errorf ("failed to create plugin dir: %w" , err )
263
268
}
@@ -275,7 +280,7 @@ func (n *Network) Create(rootDir string) error {
275
280
}
276
281
keysToFund = append (keysToFund , n .PreFundedKeys ... )
277
282
278
- genesis , err := NewTestGenesis (networkID , n .Nodes , keysToFund )
283
+ genesis , err := NewTestGenesis (defaultNetworkID , n .Nodes , keysToFund )
279
284
if err != nil {
280
285
return err
281
286
}
@@ -296,7 +301,7 @@ func (n *Network) Create(rootDir string) error {
296
301
297
302
// Starts all nodes in the network
298
303
func (n * Network ) Start (ctx context.Context , w io.Writer ) error {
299
- if _ , err := fmt .Fprintf (w , "Starting network %d @ %s\n " , n .Genesis . NetworkID , n .Dir ); err != nil {
304
+ if _ , err := fmt .Fprintf (w , "Starting network %s (UUID: %s) \n " , n .Dir , n .UUID ); err != nil {
300
305
return err
301
306
}
302
307
@@ -313,7 +318,7 @@ func (n *Network) Start(ctx context.Context, w io.Writer) error {
313
318
if err := n .WaitForHealthy (ctx , w ); err != nil {
314
319
return err
315
320
}
316
- if _ , err := fmt .Fprintf (w , "\n Started network %d @ %s\n " , n .Genesis . NetworkID , n .Dir ); err != nil {
321
+ if _ , err := fmt .Fprintf (w , "\n Started network %s (UUID: %s) \n " , n .Dir , n .UUID ); err != nil {
317
322
return err
318
323
}
319
324
@@ -676,33 +681,3 @@ func getDefaultRootDir() (string, error) {
676
681
}
677
682
return filepath .Join (homeDir , ".tmpnet" , "networks" ), nil
678
683
}
679
-
680
- // Finds the next available network ID by attempting to create a
681
- // directory numbered from 1000 until creation succeeds. Returns the
682
- // network id and the full path of the created directory.
683
- func findNextNetworkID (rootDir string ) (uint32 , string , error ) {
684
- var (
685
- networkID uint32 = 1000
686
- dirPath string
687
- )
688
- for {
689
- _ , reserved := constants .NetworkIDToNetworkName [networkID ]
690
- if reserved {
691
- networkID ++
692
- continue
693
- }
694
-
695
- dirPath = filepath .Join (rootDir , strconv .FormatUint (uint64 (networkID ), 10 ))
696
- err := os .Mkdir (dirPath , perms .ReadWriteExecute )
697
- if err == nil {
698
- return networkID , dirPath , nil
699
- }
700
-
701
- if ! errors .Is (err , fs .ErrExist ) {
702
- return 0 , "" , fmt .Errorf ("failed to create network directory: %w" , err )
703
- }
704
-
705
- // Directory already exists, keep iterating
706
- networkID ++
707
- }
708
- }
0 commit comments