github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/test/e2e/runner/start.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"sort"
     7  	"time"
     8  
     9  	"github.com/ari-anchor/sei-tendermint/libs/log"
    10  	e2e "github.com/ari-anchor/sei-tendermint/test/e2e/pkg"
    11  )
    12  
    13  func Start(ctx context.Context, logger log.Logger, testnet *e2e.Testnet) error {
    14  	if len(testnet.Nodes) == 0 {
    15  		return fmt.Errorf("no nodes in testnet")
    16  	}
    17  
    18  	// Nodes are already sorted by name. Sort them by name then startAt,
    19  	// which gives the overall order startAt, mode, name.
    20  	nodeQueue := testnet.Nodes
    21  	sort.SliceStable(nodeQueue, func(i, j int) bool {
    22  		a, b := nodeQueue[i], nodeQueue[j]
    23  		switch {
    24  		case a.Mode == b.Mode:
    25  			return false
    26  		case a.Mode == e2e.ModeSeed:
    27  			return true
    28  		case a.Mode == e2e.ModeValidator && b.Mode == e2e.ModeFull:
    29  			return true
    30  		}
    31  		return false
    32  	})
    33  
    34  	sort.SliceStable(nodeQueue, func(i, j int) bool {
    35  		return nodeQueue[i].StartAt < nodeQueue[j].StartAt
    36  	})
    37  
    38  	if nodeQueue[0].StartAt > 0 {
    39  		return fmt.Errorf("no initial nodes in testnet")
    40  	}
    41  
    42  	// Start initial nodes (StartAt: 0)
    43  	logger.Info("Starting initial network nodes...")
    44  	for len(nodeQueue) > 0 && nodeQueue[0].StartAt == 0 {
    45  		node := nodeQueue[0]
    46  		nodeQueue = nodeQueue[1:]
    47  		if err := execCompose(testnet.Dir, "up", "-d", node.Name); err != nil {
    48  			return err
    49  		}
    50  
    51  		if err := func() error {
    52  			ctx, cancel := context.WithTimeout(ctx, time.Minute)
    53  			defer cancel()
    54  
    55  			_, err := waitForNode(ctx, logger, node, 0)
    56  			return err
    57  		}(); err != nil {
    58  			return err
    59  		}
    60  		node.HasStarted = true
    61  		logger.Info(fmt.Sprintf("Node %v up on http://127.0.0.1:%v", node.Name, node.ProxyPort))
    62  	}
    63  
    64  	networkHeight := testnet.InitialHeight
    65  
    66  	// Wait for initial height
    67  	logger.Info("Waiting for initial height",
    68  		"height", networkHeight,
    69  		"nodes", len(testnet.Nodes)-len(nodeQueue),
    70  		"pending", len(nodeQueue))
    71  
    72  	block, blockID, err := waitForHeight(ctx, testnet, networkHeight)
    73  	if err != nil {
    74  		return err
    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  			logger.Info("Waiting for network to advance to height",
    87  				"node", node.Name,
    88  				"last_height", networkHeight,
    89  				"waiting_for", node.StartAt,
    90  				"size", len(testnet.Nodes)-len(nodeQueue),
    91  				"pending", len(nodeQueue))
    92  
    93  			networkHeight = node.StartAt
    94  
    95  			block, blockID, err = waitForHeight(ctx, testnet, networkHeight)
    96  			if err != nil {
    97  				return err
    98  			}
    99  		}
   100  
   101  		// Update any state sync nodes with a trusted height and hash
   102  		if node.StateSync != e2e.StateSyncDisabled || node.Mode == e2e.ModeLight {
   103  			err = UpdateConfigStateSync(node, block.Height, blockID.Hash.Bytes())
   104  			if err != nil {
   105  				return err
   106  			}
   107  		}
   108  
   109  		if err := execCompose(testnet.Dir, "up", "-d", node.Name); err != nil {
   110  			return err
   111  		}
   112  
   113  		wctx, wcancel := context.WithTimeout(ctx, 8*time.Minute)
   114  		status, err := waitForNode(wctx, logger, node, node.StartAt)
   115  		if err != nil {
   116  			wcancel()
   117  			return err
   118  		}
   119  		wcancel()
   120  
   121  		node.HasStarted = true
   122  
   123  		var lastNodeHeight int64
   124  
   125  		// If the node is a light client, we fetch its current height
   126  		if node.Mode == e2e.ModeLight {
   127  			lastNodeHeight = status.LightClientInfo.LastTrustedHeight
   128  		} else {
   129  			lastNodeHeight = status.SyncInfo.LatestBlockHeight
   130  		}
   131  		logger.Info(fmt.Sprintf("Node %v up on http://127.0.0.1:%v at height %v",
   132  			node.Name, node.ProxyPort, lastNodeHeight))
   133  	}
   134  
   135  	return nil
   136  }