gitlab.com/jokerrs1/Sia@v1.3.2/node/api/ecosystem_test.go (about) 1 package api 2 3 // ecosystem_test.go provides tests for whole-ecosystem testing, consisting of 4 // multiple full, non-state-sharing nodes connected in various arrangements and 5 // performing various full-ecosystem tasks. 6 // 7 // To the absolute greatest extent possible, nodes are queried and updated 8 // exclusively through the API. 9 10 import ( 11 "testing" 12 "time" 13 14 "github.com/NebulousLabs/Sia/build" 15 "github.com/NebulousLabs/Sia/types" 16 ) 17 18 // TestHostPoorConnectivity creates several full server testers and links them 19 // together in a way that might mimic a full host ecosystem with a renter, and 20 // then isolates one of the hosts from the network, denying the host proper 21 // transaction propagation. The renters performed chained contract forming and 22 // uploading in the same manner that might happen in the wild, and then the 23 // host must get a file contract to the blockchain despite not getting any of 24 // the dependencies into the transaction pool from the flood network. 25 func TestHostPoorConnectivity(t *testing.T) { 26 if testing.Short() || !build.VLONG { 27 t.SkipNow() 28 } 29 t.Parallel() 30 31 // Create the various nodes that will be forming the simulated ecosystem of 32 // this test. 33 stLeader, err := createServerTester(t.Name()) 34 if err != nil { 35 t.Fatal(err) 36 } 37 defer stLeader.panicClose() 38 stHost1, err := blankServerTester(t.Name() + " - Host 1") 39 if err != nil { 40 t.Fatal(err) 41 } 42 defer stHost1.panicClose() 43 stHost2, err := blankServerTester(t.Name() + " - Host 2") 44 if err != nil { 45 t.Fatal(err) 46 } 47 defer stHost2.panicClose() 48 stHost3, err := blankServerTester(t.Name() + " - Host 3") 49 if err != nil { 50 t.Fatal(err) 51 } 52 defer stHost3.panicClose() 53 stHost4, err := blankServerTester(t.Name() + " - Host 4") 54 if err != nil { 55 t.Fatal(err) 56 } 57 defer stHost4.panicClose() 58 stRenter1, err := blankServerTester(t.Name() + " - Renter 1") 59 if err != nil { 60 t.Fatal(err) 61 } 62 defer stRenter1.panicClose() 63 stRenter2, err := blankServerTester(t.Name() + " - Renter 2") 64 if err != nil { 65 t.Fatal(err) 66 } 67 defer stRenter2.panicClose() 68 69 // Fetch all of the addresses of the nodes that got created. 70 var ggSTL, ggSTH1, ggSTH2, ggSTH3, ggSTH4, ggSTR1, ggSTR2 GatewayGET 71 err = stLeader.getAPI("/gateway", &ggSTL) 72 if err != nil { 73 t.Fatal(err) 74 } 75 err = stHost1.getAPI("/gateway", &ggSTH1) 76 if err != nil { 77 t.Fatal(err) 78 } 79 err = stHost2.getAPI("/gateway", &ggSTH2) 80 if err != nil { 81 t.Fatal(err) 82 } 83 err = stHost3.getAPI("/gateway", &ggSTH3) 84 if err != nil { 85 t.Fatal(err) 86 } 87 err = stHost4.getAPI("/gateway", &ggSTH4) 88 if err != nil { 89 t.Fatal(err) 90 } 91 err = stRenter1.getAPI("/gateway", &ggSTR1) 92 if err != nil { 93 t.Fatal(err) 94 } 95 err = stRenter2.getAPI("/gateway", &ggSTR2) 96 if err != nil { 97 t.Fatal(err) 98 } 99 100 // Connect all of the peers in a circle, so that everyone is connected but 101 // there are a lot of hops. 102 err = stLeader.stdPostAPI("/gateway/connect/"+string(ggSTH1.NetAddress), nil) 103 if err != nil { 104 t.Fatal(err) 105 } 106 err = stHost1.stdPostAPI("/gateway/connect/"+string(ggSTH2.NetAddress), nil) 107 if err != nil { 108 t.Fatal(err) 109 } 110 err = stHost2.stdPostAPI("/gateway/connect/"+string(ggSTH3.NetAddress), nil) 111 if err != nil { 112 t.Fatal(err) 113 } 114 err = stHost3.stdPostAPI("/gateway/connect/"+string(ggSTH4.NetAddress), nil) 115 if err != nil { 116 t.Fatal(err) 117 } 118 err = stHost4.stdPostAPI("/gateway/connect/"+string(ggSTR1.NetAddress), nil) 119 if err != nil { 120 t.Fatal(err) 121 } 122 err = stRenter1.stdPostAPI("/gateway/connect/"+string(ggSTR2.NetAddress), nil) 123 if err != nil { 124 t.Fatal(err) 125 } 126 err = stRenter2.stdPostAPI("/gateway/connect/"+string(ggSTL.NetAddress), nil) 127 if err != nil { 128 t.Fatal(err) 129 } 130 131 // Connectivity check - all nodes should be synchronized to the leader's 132 // chain, which should have been the longest. 133 allTesters := []*serverTester{stLeader, stHost1, stHost2, stHost3, stHost4, stRenter1, stRenter2} 134 chainTip, err := synchronizationCheck(allTesters) 135 if err != nil { 136 t.Fatal(err) 137 } 138 139 // Mine a block from each node, to give the node money in the wallet that 140 // is recognized by the shared chain. 141 for i := range allTesters { 142 // Wait until the current tester has 'chainTip' as its current 143 // block, to make sure the network is building a community chain 144 // instead of creating orphans. 145 var cg ConsensusGET 146 success := false 147 for j := 0; j < 100; j++ { 148 err = allTesters[i].getAPI("/consensus", &cg) 149 if err != nil { 150 t.Fatal(err) 151 } 152 if cg.CurrentBlock == chainTip { 153 success = true 154 break 155 } 156 time.Sleep(time.Millisecond * 100) 157 } 158 if !success { 159 t.Fatal("nodes do not seem to be synchronizing") 160 } 161 err := allTesters[i].cs.Flush() 162 if err != nil { 163 t.Fatal(err) 164 } 165 166 // Mine a block for this node. The next iteration will wait for 167 // synchronization before mining the block for the next node. 168 block, err := allTesters[i].miner.AddBlock() 169 if err != nil { 170 t.Fatal(err, i) 171 } 172 chainTip = block.ID() 173 } 174 175 // Wait until the leader has the most recent block. 176 var cg ConsensusGET 177 success := false 178 for i := 0; i < 100; i++ { 179 err = allTesters[0].getAPI("/consensus", &cg) 180 if err != nil { 181 t.Fatal(err) 182 } 183 if cg.CurrentBlock == chainTip { 184 success = true 185 break 186 } 187 time.Sleep(time.Millisecond * 100) 188 } 189 if !success { 190 t.Fatal("nodes do not seem to be synchronizing") 191 } 192 193 // Make sure that everyone has the most recent block. 194 _, err = synchronizationCheck(allTesters) 195 if err != nil { 196 t.Fatal(err) 197 } 198 199 // Mine blocks from the leader until everyone's miner payouts have matured 200 // and become spendable. 201 for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { 202 _, err := stLeader.miner.AddBlock() 203 if err != nil { 204 t.Fatal(err) 205 } 206 } 207 _, err = synchronizationCheck(allTesters) 208 if err != nil { 209 t.Fatal(err) 210 } 211 }