You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
2.9 KiB

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