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 }