@@ -10,7 +10,6 @@ import (
1010 "os"
1111 "path/filepath"
1212 "runtime"
13- "strconv"
1413 "time"
1514
1615 "github.com/go-yaml/yaml"
@@ -30,10 +29,11 @@ const (
3029 DockerComposeFile = "./docker-compose.nodes.yml"
3130 DockerComposeFileVersion = "3.7"
3231 PrometheusTargetsFile = "./targets.nodes.json"
33- DefaultObserverName = "observer"
32+ PortMapFile = "./ports.nodes.json"
33+ DefaultObserverRole = "observer"
3434 DefaultLogLevel = "DEBUG"
3535 DefaultGOMAXPROCS = 8
36- DefaultMaxObservers = 1000
36+ DefaultMaxObservers = 100
3737 DefaultCollectionCount = 3
3838 DefaultConsensusCount = 3
3939 DefaultExecutionCount = 1
@@ -48,15 +48,6 @@ const (
4848 DefaultExtensiveTracing = false
4949 DefaultConsensusDelay = 800 * time .Millisecond
5050 DefaultCollectionDelay = 950 * time .Millisecond
51- AccessAPIPort = 3569
52- AccessPubNetworkPort = 1234
53- ExecutionAPIPort = 3600
54- MetricsPort = 8080
55- RPCPort = 9000
56- SecuredRPCPort = 9001
57- AdminToolPort = 9002
58- AdminToolLocalPort = 3700
59- HTTPPort = 8000
6051)
6152
6253var (
7869 consensusDelay time.Duration
7970 collectionDelay time.Duration
8071 logLevel string
72+
73+ ports * PortAllocator
8174)
8275
8376func init () {
@@ -119,6 +112,9 @@ func generateBootstrapData(flowNetworkConf testnet.NetworkConfig) []testnet.Cont
119112func main () {
120113 flag .Parse ()
121114
115+ // Allocate blocks of IPs for each node
116+ ports = NewPortAllocator ()
117+
122118 // Prepare test node configurations of each type, access, execution, verification, etc
123119 flowNodes := prepareFlowNodes ()
124120
@@ -155,8 +151,12 @@ func main() {
155151 panic (err )
156152 }
157153
154+ if err = ports .WriteMappingConfig (); err != nil {
155+ panic (err )
156+ }
157+
158158 fmt .Print ("Bootstrapping success!\n \n " )
159- displayPortAssignments ()
159+ ports . Print ()
160160 fmt .Println ()
161161
162162 fmt .Println ("Run \" make start\" to re-build images and launch the network." )
@@ -171,20 +171,6 @@ func displayFlowNetworkConf(flowNetworkConf testnet.NetworkConfig) {
171171 fmt .Printf ("- DKG Phase Length: %d\n " , flowNetworkConf .ViewsInDKGPhase )
172172}
173173
174- func displayPortAssignments () {
175- for i := 0 ; i < accessCount ; i ++ {
176- fmt .Printf ("Access %d Flow API will be accessible at localhost:%d\n " , i + 1 , AccessAPIPort + i )
177- fmt .Printf ("Access %d public libp2p access will be accessible at localhost:%d\n \n " , i + 1 , AccessPubNetworkPort + i )
178- }
179- for i := 0 ; i < executionCount ; i ++ {
180- fmt .Printf ("Execution API %d will be accessible at localhost:%d\n " , i + 1 , ExecutionAPIPort + i )
181- }
182- fmt .Println ()
183- for i := 0 ; i < observerCount ; i ++ {
184- fmt .Printf ("Observer %d Flow API will be accessible at localhost:%d\n " , i + 1 , (accessCount * 2 )+ (AccessAPIPort )+ 2 * i )
185- }
186- }
187-
188174func prepareCommonHostFolders () {
189175 for _ , dir := range []string {BootstrapDir , ProfilerDir , DataDir , TrieDir } {
190176 if err := os .RemoveAll (dir ); err != nil && ! errors .Is (err , fs .ErrNotExist ) {
@@ -245,6 +231,14 @@ type Service struct {
245231 Volumes []string
246232 Ports []string `yaml:"ports,omitempty"`
247233 Labels map [string ]string
234+
235+ name string // don't export
236+ }
237+
238+ func (s * Service ) AddExposedPorts (containerPorts ... string ) {
239+ for _ , port := range containerPorts {
240+ s .Ports = append (s .Ports , fmt .Sprintf ("%s:%s" , ports .HostPort (s .name , port ), port ))
241+ }
248242}
249243
250244// Build ...
@@ -321,7 +315,7 @@ func prepareServiceDirs(role string, nodeId string) (string, string) {
321315func prepareService (container testnet.ContainerConfig , i int , n int ) Service {
322316 dataDir , profilerDir := prepareServiceDirs (container .Role .String (), container .NodeID .String ())
323317
324- service := defaultService (container .Role .String (), dataDir , profilerDir , i )
318+ service := defaultService (container .ContainerName , container . Role .String (), dataDir , profilerDir , i )
325319 service .Command = append (service .Command ,
326320 fmt .Sprintf ("--nodeid=%s" , container .NodeID ),
327321 )
@@ -341,8 +335,7 @@ func prepareConsensusService(container testnet.ContainerConfig, i int, n int) Se
341335 service := prepareService (container , i , n )
342336
343337 timeout := 1200 * time .Millisecond + consensusDelay
344- service .Command = append (
345- service .Command ,
338+ service .Command = append (service .Command ,
346339 fmt .Sprintf ("--block-rate-delay=%s" , consensusDelay ),
347340 fmt .Sprintf ("--hotstuff-min-timeout=%s" , timeout ),
348341 "--chunk-alpha=1" ,
@@ -351,25 +344,16 @@ func prepareConsensusService(container testnet.ContainerConfig, i int, n int) Se
351344 "--access-node-ids=*" ,
352345 )
353346
354- service .Ports = []string {
355- fmt .Sprintf ("%d:%d" , AdminToolLocalPort + n , AdminToolPort ),
356- }
357-
358347 return service
359348}
360349
361350func prepareVerificationService (container testnet.ContainerConfig , i int , n int ) Service {
362351 service := prepareService (container , i , n )
363352
364- service .Command = append (
365- service .Command ,
353+ service .Command = append (service .Command ,
366354 "--chunk-alpha=1" ,
367355 )
368356
369- service .Ports = []string {
370- fmt .Sprintf ("%d:%d" , AdminToolLocalPort + n , AdminToolPort ),
371- }
372-
373357 return service
374358}
375359
@@ -378,19 +362,14 @@ func prepareCollectionService(container testnet.ContainerConfig, i int, n int) S
378362 service := prepareService (container , i , n )
379363
380364 timeout := 1200 * time .Millisecond + collectionDelay
381- service .Command = append (
382- service .Command ,
365+ service .Command = append (service .Command ,
383366 fmt .Sprintf ("--block-rate-delay=%s" , collectionDelay ),
384367 fmt .Sprintf ("--hotstuff-min-timeout=%s" , timeout ),
385- fmt .Sprintf ("--ingress-addr=%s:%d " , container .ContainerName , RPCPort ),
368+ fmt .Sprintf ("--ingress-addr=%s:%s " , container .ContainerName , testnet . GRPCPort ),
386369 "--insecure-access-api=false" ,
387370 "--access-node-ids=*" ,
388371 )
389372
390- service .Ports = []string {
391- fmt .Sprintf ("%d:%d" , AdminToolLocalPort + n , AdminToolPort ),
392- }
393-
394373 return service
395374}
396375
@@ -411,25 +390,19 @@ func prepareExecutionService(container testnet.ContainerConfig, i int, n int) Se
411390 panic (err )
412391 }
413392
414- service .Command = append (
415- service .Command ,
393+ service .Command = append (service .Command ,
416394 "--triedir=/trie" ,
417- fmt .Sprintf ("--rpc-addr=%s:%d " , container .ContainerName , RPCPort ),
395+ fmt .Sprintf ("--rpc-addr=%s:%s " , container .ContainerName , testnet . GRPCPort ),
418396 fmt .Sprintf ("--cadence-tracing=%t" , cadenceTracing ),
419397 fmt .Sprintf ("--extensive-tracing=%t" , extesiveTracing ),
420398 "--execution-data-dir=/data/execution-data" ,
421399 )
422400
423- service .Volumes = append (
424- service .Volumes ,
401+ service .Volumes = append (service .Volumes ,
425402 fmt .Sprintf ("%s:/trie:z" , trieDir ),
426403 )
427404
428- service .Ports = []string {
429- fmt .Sprintf ("%d:%d" , ExecutionAPIPort + 2 * i , RPCPort ),
430- fmt .Sprintf ("%d:%d" , ExecutionAPIPort + (2 * i + 1 ), SecuredRPCPort ),
431- fmt .Sprintf ("%d:%d" , AdminToolLocalPort + n , AdminToolPort ),
432- }
405+ service .AddExposedPorts (testnet .GRPCPort )
433406
434407 return service
435408}
@@ -438,25 +411,29 @@ func prepareAccessService(container testnet.ContainerConfig, i int, n int) Servi
438411 service := prepareService (container , i , n )
439412
440413 service .Command = append (service .Command ,
441- fmt .Sprintf ("--rpc-addr=%s:%d" , container .ContainerName , RPCPort ),
442- fmt .Sprintf ("--secure-rpc-addr=%s:%d" , container .ContainerName , SecuredRPCPort ),
443- fmt .Sprintf ("--http-addr=%s:%d" , container .ContainerName , HTTPPort ),
444- fmt .Sprintf ("--collection-ingress-port=%d" , RPCPort ),
414+ fmt .Sprintf ("--rpc-addr=%s:%s" , container .ContainerName , testnet .GRPCPort ),
415+ fmt .Sprintf ("--secure-rpc-addr=%s:%s" , container .ContainerName , testnet .GRPCSecurePort ),
416+ fmt .Sprintf ("--http-addr=%s:%s" , container .ContainerName , testnet .GRPCWebPort ),
417+ fmt .Sprintf ("--rest-addr=%s:%s" , container .ContainerName , testnet .RESTPort ),
418+ fmt .Sprintf ("--state-stream-addr=%s:%s" , container .ContainerName , testnet .ExecutionStatePort ),
419+ fmt .Sprintf ("--collection-ingress-port=%s" , testnet .GRPCPort ),
445420 "--supports-observer=true" ,
446- fmt .Sprintf ("--public-network-address=%s:%d " , container .ContainerName , AccessPubNetworkPort ),
421+ fmt .Sprintf ("--public-network-address=%s:%s " , container .ContainerName , testnet . PublicNetworkPort ),
447422 "--log-tx-time-to-finalized" ,
448423 "--log-tx-time-to-executed" ,
449424 "--log-tx-time-to-finalized-executed" ,
450425 "--execution-data-sync-enabled=true" ,
451426 "--execution-data-dir=/data/execution-data" ,
452427 )
453428
454- service .Ports = []string {
455- fmt .Sprintf ("%d:%d" , AccessPubNetworkPort + i , AccessPubNetworkPort ),
456- fmt .Sprintf ("%d:%d" , AccessAPIPort + 2 * i , RPCPort ),
457- fmt .Sprintf ("%d:%d" , AccessAPIPort + (2 * i + 1 ), SecuredRPCPort ),
458- fmt .Sprintf ("%d:%d" , AdminToolLocalPort + n , AdminToolPort ),
459- }
429+ service .AddExposedPorts (
430+ testnet .GRPCPort ,
431+ testnet .GRPCSecurePort ,
432+ testnet .GRPCWebPort ,
433+ testnet .RESTPort ,
434+ testnet .ExecutionStatePort ,
435+ testnet .PublicNetworkPort ,
436+ )
460437
461438 return service
462439}
@@ -465,35 +442,41 @@ func prepareObserverService(i int, observerName string, agPublicKey string) Serv
465442 // Observers have a unique naming scheme omitting node id being on the public network
466443 dataDir , profilerDir := prepareServiceDirs (observerName , "" )
467444
468- observerService := defaultService (DefaultObserverName , dataDir , profilerDir , i )
469- observerService .Command = append (observerService .Command ,
470- fmt .Sprintf ("--bootstrap-node-addresses=%s:%d " , testnet .PrimaryAN , AccessPubNetworkPort ),
445+ service := defaultService (observerName , DefaultObserverRole , dataDir , profilerDir , i )
446+ service .Command = append (service .Command ,
447+ fmt .Sprintf ("--bootstrap-node-addresses=%s:%s " , testnet .PrimaryAN , testnet . PublicNetworkPort ),
471448 fmt .Sprintf ("--bootstrap-node-public-keys=%s" , agPublicKey ),
472- fmt .Sprintf ("--upstream-node-addresses=%s:%d " , testnet .PrimaryAN , SecuredRPCPort ),
449+ fmt .Sprintf ("--upstream-node-addresses=%s:%s " , testnet .PrimaryAN , testnet . GRPCSecurePort ),
473450 fmt .Sprintf ("--upstream-node-public-keys=%s" , agPublicKey ),
474451 fmt .Sprintf ("--observer-networking-key-path=/bootstrap/private-root-information/%s_key" , observerName ),
475452 "--bind=0.0.0.0:0" ,
476- fmt .Sprintf ("--rpc-addr=%s:%d" , observerName , RPCPort ),
477- fmt .Sprintf ("--secure-rpc-addr=%s:%d" , observerName , SecuredRPCPort ),
478- fmt .Sprintf ("--http-addr=%s:%d" , observerName , HTTPPort ),
453+ fmt .Sprintf ("--rpc-addr=%s:%s" , observerName , testnet .GRPCPort ),
454+ fmt .Sprintf ("--secure-rpc-addr=%s:%s" , observerName , testnet .GRPCSecurePort ),
455+ fmt .Sprintf ("--http-addr=%s:%s" , observerName , testnet .GRPCWebPort ),
456+ )
457+
458+ service .AddExposedPorts (
459+ testnet .GRPCPort ,
460+ testnet .GRPCSecurePort ,
461+ testnet .GRPCWebPort ,
462+ testnet .AdminPort ,
479463 )
480464
481465 // observer services rely on the access gateway
482- observerService .DependsOn = append (observerService .DependsOn , testnet .PrimaryAN )
483- observerService .Ports = []string {
484- // Flow API ports come in pairs, open and secure. While the guest port is always
485- // the same from the guest's perspective, the host port numbering accounts for the presence
486- // of multiple pairs of listeners on the host to avoid port collisions. Observer listener pairs
487- // are numbered just after the Access listeners on the host network by prior convention
488- fmt .Sprintf ("%d:%d" , (accessCount * 2 )+ AccessAPIPort + (2 * i ), RPCPort ),
489- fmt .Sprintf ("%d:%d" , (accessCount * 2 )+ AccessAPIPort + (2 * i )+ 1 , SecuredRPCPort ),
490- }
491- return observerService
466+ service .DependsOn = append (service .DependsOn , testnet .PrimaryAN )
467+
468+ return service
492469}
493470
494- func defaultService (role , dataDir , profilerDir string , i int ) Service {
471+ func defaultService (name , role , dataDir , profilerDir string , i int ) Service {
472+ err := ports .AllocatePorts (name , role )
473+ if err != nil {
474+ panic (err )
475+ }
476+
495477 num := fmt .Sprintf ("%03d" , i + 1 )
496478 service := Service {
479+ name : name ,
497480 Image : fmt .Sprintf ("localnet-%s" , role ),
498481 Command : []string {
499482 "--bootstrapdir=/bootstrap" ,
@@ -505,7 +488,7 @@ func defaultService(role, dataDir, profilerDir string, i int) Service {
505488 fmt .Sprintf ("--tracer-enabled=%t" , tracing ),
506489 "--profiler-dir=/profiler" ,
507490 "--profiler-interval=2m" ,
508- fmt .Sprintf ("--admin-addr=0.0.0.0:%d " , AdminToolPort ),
491+ fmt .Sprintf ("--admin-addr=0.0.0.0:%s " , testnet . AdminPort ),
509492 },
510493 Volumes : []string {
511494 fmt .Sprintf ("%s:/bootstrap:z" , BootstrapDir ),
@@ -525,6 +508,8 @@ func defaultService(role, dataDir, profilerDir string, i int) Service {
525508 },
526509 }
527510
511+ service .AddExposedPorts (testnet .AdminPort )
512+
528513 if i == 0 {
529514 // only specify build config for first service of each role
530515 service .Build = Build {
@@ -553,6 +538,7 @@ func writeDockerComposeConfig(services Services) error {
553538 if err != nil {
554539 return err
555540 }
541+ defer f .Close ()
556542
557543 network := Network {
558544 Version : DockerComposeFileVersion ,
@@ -585,7 +571,7 @@ func prepareServiceDiscovery(containers []testnet.ContainerConfig) PrometheusSer
585571 for _ , container := range containers {
586572 counters [container .Role ]++
587573 pt := PrometheusTarget {
588- Targets : []string {net .JoinHostPort (container .ContainerName , strconv . Itoa ( MetricsPort ) )},
574+ Targets : []string {net .JoinHostPort (container .ContainerName , testnet . MetricsPort )},
589575 Labels : map [string ]string {
590576 "job" : "flow" ,
591577 "role" : container .Role .String (),
@@ -604,6 +590,7 @@ func writePrometheusConfig(serviceDisc PrometheusServiceDiscovery) error {
604590 if err != nil {
605591 return err
606592 }
593+ defer f .Close ()
607594
608595 enc := json .NewEncoder (f )
609596
@@ -670,7 +657,7 @@ func prepareObserverServices(dockerServices Services, flowNodeContainerConfigs [
670657 }
671658
672659 for i := 0 ; i < observerCount ; i ++ {
673- observerName := fmt .Sprintf ("%s_%d" , DefaultObserverName , i + 1 )
660+ observerName := fmt .Sprintf ("%s_%d" , DefaultObserverRole , i + 1 )
674661 observerService := prepareObserverService (i , observerName , agPublicKey )
675662
676663 // Add a docker container for this named Observer
0 commit comments