github.com/consideritdone/landslidecore@v0.0.0-20230718131026-a8b21c5cf8a7/test/e2e/runner/start.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"time"
     7  
     8  	e2e "github.com/consideritdone/landslidecore/test/e2e/pkg"
     9  )
    10  
    11  func Start(testnet *e2e.Testnet) error {
    12  	if len(testnet.Nodes) == 0 {
    13  		return fmt.Errorf("no nodes in testnet")
    14  	}
    15  
    16  	// Nodes are already sorted by name. Sort them by name then startAt,
    17  	// which gives the overall order startAt, mode, name.
    18  	nodeQueue := testnet.Nodes
    19  	sort.SliceStable(nodeQueue, func(i, j int) bool {
    20  		a, b := nodeQueue[i], nodeQueue[j]
    21  		switch {
    22  		case a.Mode == b.Mode:
    23  			return false
    24  		case a.Mode == e2e.ModeSeed:
    25  			return true
    26  		case a.Mode == e2e.ModeValidator && b.Mode == e2e.ModeFull:
    27  			return true
    28  		}
    29  		return false
    30  	})
    31  
    32  	sort.SliceStable(nodeQueue, func(i, j int) bool {
    33  		return nodeQueue[i].StartAt < nodeQueue[j].StartAt
    34  	})
    35  
    36  	if nodeQueue[0].StartAt > 0 {
    37  		return fmt.Errorf("no initial nodes in testnet")
    38  	}
    39  
    40  	// Start initial nodes (StartAt: 0)
    41  	logger.Info("Starting initial network nodes...")
    42  	for len(nodeQueue) > 0 && nodeQueue[0].StartAt == 0 {
    43  		node := nodeQueue[0]
    44  		nodeQueue = nodeQueue[1:]
    45  		if err := execCompose(testnet.Dir, "up", "-d", node.Name); err != nil {
    46  			return err
    47  		}
    48  		if _, err := waitForNode(node, 0, 15*time.Second); err != nil {
    49  			return err
    50  		}
    51  		logger.Info(fmt.Sprintf("Node %v up on http://127.0.0.1:%v", node.Name, node.ProxyPort))
    52  	}
    53  
    54  	networkHeight := testnet.InitialHeight
    55  
    56  	// Wait for initial height
    57  	logger.Info("Waiting for initial height",
    58  		"height", networkHeight,
    59  		"nodes", len(testnet.Nodes)-len(nodeQueue),
    60  		"pending", len(nodeQueue))
    61  
    62  	block, blockID, err := waitForHeight(testnet, networkHeight)
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	// Update any state sync nodes with a trusted height and hash
    68  	for _, node := range nodeQueue {
    69  		if node.StateSync || node.Mode == e2e.ModeLight {
    70  			err = UpdateConfigStateSync(node, block.Height, blockID.Hash.Bytes())
    71  			if err != nil {
    72  				return err
    73  			}
    74  		}
    75  	}
    76  
    77  	for _, node := range nodeQueue {
    78  		if node.StartAt > networkHeight {
    79  			// if we're starting a node that's ahead of
    80  			// the last known height of the network, then
    81  			// we should make sure that the rest of the
    82  			// network has reached at least the height
    83  			// that this node will start at before we
    84  			// start the node.
    85  
    86  			networkHeight = node.StartAt
    87  
    88  			logger.Info("Waiting for network to advance before starting catch up node",
    89  				"node", node.Name,
    90  				"height", networkHeight)
    91  
    92  			if _, _, err := waitForHeight(testnet, networkHeight); err != nil {
    93  				return err
    94  			}
    95  		}
    96  
    97  		logger.Info("Starting catch up node", "node", node.Name, "height", node.StartAt)
    98  
    99  		if err := execCompose(testnet.Dir, "up", "-d", node.Name); err != nil {
   100  			return err
   101  		}
   102  		status, err := waitForNode(node, node.StartAt, 3*time.Minute)
   103  		if err != nil {
   104  			return err
   105  		}
   106  		logger.Info(fmt.Sprintf("Node %v up on http://127.0.0.1:%v at height %v",
   107  			node.Name, node.ProxyPort, status.SyncInfo.LatestBlockHeight))
   108  	}
   109  
   110  	return nil
   111  }