github.com/XinFinOrg/xdcchain@v1.1.0/cmd/swarm/swarm-smoke/feed_upload_and_sync.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "crypto/md5" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "os" 10 "os/exec" 11 "strings" 12 "sync" 13 "time" 14 15 "github.com/ethereum/go-ethereum/common/hexutil" 16 "github.com/ethereum/go-ethereum/crypto" 17 "github.com/ethereum/go-ethereum/log" 18 "github.com/ethereum/go-ethereum/metrics" 19 "github.com/ethereum/go-ethereum/swarm/storage/feed" 20 "github.com/ethereum/go-ethereum/swarm/testutil" 21 "github.com/pborman/uuid" 22 cli "gopkg.in/urfave/cli.v1" 23 ) 24 25 const ( 26 feedRandomDataLength = 8 27 ) 28 29 func feedUploadAndSyncCmd(ctx *cli.Context, tuid string) error { 30 errc := make(chan error) 31 32 go func() { 33 errc <- feedUploadAndSync(ctx, tuid) 34 }() 35 36 select { 37 case err := <-errc: 38 if err != nil { 39 metrics.GetOrRegisterCounter(fmt.Sprintf("%s.fail", commandName), nil).Inc(1) 40 } 41 return err 42 case <-time.After(time.Duration(timeout) * time.Second): 43 metrics.GetOrRegisterCounter(fmt.Sprintf("%s.timeout", commandName), nil).Inc(1) 44 45 return fmt.Errorf("timeout after %v sec", timeout) 46 } 47 } 48 49 func feedUploadAndSync(c *cli.Context, tuid string) error { 50 log.Info("generating and uploading feeds to " + httpEndpoint(hosts[0]) + " and syncing") 51 52 // create a random private key to sign updates with and derive the address 53 pkFile, err := ioutil.TempFile("", "swarm-feed-smoke-test") 54 if err != nil { 55 return err 56 } 57 defer pkFile.Close() 58 defer os.Remove(pkFile.Name()) 59 60 privkeyHex := "0000000000000000000000000000000000000000000000000000000000001976" 61 privKey, err := crypto.HexToECDSA(privkeyHex) 62 if err != nil { 63 return err 64 } 65 user := crypto.PubkeyToAddress(privKey.PublicKey) 66 userHex := hexutil.Encode(user.Bytes()) 67 68 // save the private key to a file 69 _, err = io.WriteString(pkFile, privkeyHex) 70 if err != nil { 71 return err 72 } 73 74 // keep hex strings for topic and subtopic 75 var topicHex string 76 var subTopicHex string 77 78 // and create combination hex topics for bzz-feed retrieval 79 // xor'ed with topic (zero-value topic if no topic) 80 var subTopicOnlyHex string 81 var mergedSubTopicHex string 82 83 // generate random topic and subtopic and put a hex on them 84 topicBytes, err := generateRandomData(feed.TopicLength) 85 topicHex = hexutil.Encode(topicBytes) 86 subTopicBytes, err := generateRandomData(8) 87 subTopicHex = hexutil.Encode(subTopicBytes) 88 if err != nil { 89 return err 90 } 91 mergedSubTopic, err := feed.NewTopic(subTopicHex, topicBytes) 92 if err != nil { 93 return err 94 } 95 mergedSubTopicHex = hexutil.Encode(mergedSubTopic[:]) 96 subTopicOnlyBytes, err := feed.NewTopic(subTopicHex, nil) 97 if err != nil { 98 return err 99 } 100 subTopicOnlyHex = hexutil.Encode(subTopicOnlyBytes[:]) 101 102 // create feed manifest, topic only 103 var out bytes.Buffer 104 cmd := exec.Command("swarm", "--bzzapi", httpEndpoint(hosts[0]), "feed", "create", "--topic", topicHex, "--user", userHex) 105 cmd.Stdout = &out 106 log.Debug("create feed manifest topic cmd", "cmd", cmd) 107 err = cmd.Run() 108 if err != nil { 109 return err 110 } 111 manifestWithTopic := strings.TrimRight(out.String(), string([]byte{0x0a})) 112 if len(manifestWithTopic) != 64 { 113 return fmt.Errorf("unknown feed create manifest hash format (topic): (%d) %s", len(out.String()), manifestWithTopic) 114 } 115 log.Debug("create topic feed", "manifest", manifestWithTopic) 116 out.Reset() 117 118 // create feed manifest, subtopic only 119 cmd = exec.Command("swarm", "--bzzapi", httpEndpoint(hosts[0]), "feed", "create", "--name", subTopicHex, "--user", userHex) 120 cmd.Stdout = &out 121 log.Debug("create feed manifest subtopic cmd", "cmd", cmd) 122 err = cmd.Run() 123 if err != nil { 124 return err 125 } 126 manifestWithSubTopic := strings.TrimRight(out.String(), string([]byte{0x0a})) 127 if len(manifestWithSubTopic) != 64 { 128 return fmt.Errorf("unknown feed create manifest hash format (subtopic): (%d) %s", len(out.String()), manifestWithSubTopic) 129 } 130 log.Debug("create subtopic feed", "manifest", manifestWithTopic) 131 out.Reset() 132 133 // create feed manifest, merged topic 134 cmd = exec.Command("swarm", "--bzzapi", httpEndpoint(hosts[0]), "feed", "create", "--topic", topicHex, "--name", subTopicHex, "--user", userHex) 135 cmd.Stdout = &out 136 log.Debug("create feed manifest mergetopic cmd", "cmd", cmd) 137 err = cmd.Run() 138 if err != nil { 139 log.Error(err.Error()) 140 return err 141 } 142 manifestWithMergedTopic := strings.TrimRight(out.String(), string([]byte{0x0a})) 143 if len(manifestWithMergedTopic) != 64 { 144 return fmt.Errorf("unknown feed create manifest hash format (mergedtopic): (%d) %s", len(out.String()), manifestWithMergedTopic) 145 } 146 log.Debug("create mergedtopic feed", "manifest", manifestWithMergedTopic) 147 out.Reset() 148 149 // create test data 150 data, err := generateRandomData(feedRandomDataLength) 151 if err != nil { 152 return err 153 } 154 h := md5.New() 155 h.Write(data) 156 dataHash := h.Sum(nil) 157 dataHex := hexutil.Encode(data) 158 159 // update with topic 160 cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--topic", topicHex, dataHex) 161 cmd.Stdout = &out 162 log.Debug("update feed manifest topic cmd", "cmd", cmd) 163 err = cmd.Run() 164 if err != nil { 165 return err 166 } 167 log.Debug("feed update topic", "out", out) 168 out.Reset() 169 170 // update with subtopic 171 cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--name", subTopicHex, dataHex) 172 cmd.Stdout = &out 173 log.Debug("update feed manifest subtopic cmd", "cmd", cmd) 174 err = cmd.Run() 175 if err != nil { 176 return err 177 } 178 log.Debug("feed update subtopic", "out", out) 179 out.Reset() 180 181 // update with merged topic 182 cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--topic", topicHex, "--name", subTopicHex, dataHex) 183 cmd.Stdout = &out 184 log.Debug("update feed manifest merged topic cmd", "cmd", cmd) 185 err = cmd.Run() 186 if err != nil { 187 return err 188 } 189 log.Debug("feed update mergedtopic", "out", out) 190 out.Reset() 191 192 time.Sleep(3 * time.Second) 193 194 // retrieve the data 195 wg := sync.WaitGroup{} 196 for _, host := range hosts { 197 // raw retrieve, topic only 198 for _, hex := range []string{topicHex, subTopicOnlyHex, mergedSubTopicHex} { 199 wg.Add(1) 200 ruid := uuid.New()[:8] 201 go func(hex string, endpoint string, ruid string) { 202 for { 203 err := fetchFeed(hex, userHex, httpEndpoint(host), dataHash, ruid) 204 if err != nil { 205 continue 206 } 207 208 wg.Done() 209 return 210 } 211 }(hex, httpEndpoint(host), ruid) 212 } 213 } 214 wg.Wait() 215 log.Info("all endpoints synced random data successfully") 216 217 // upload test file 218 log.Info("feed uploading to "+httpEndpoint(hosts[0])+" and syncing", "seed", seed) 219 220 randomBytes := testutil.RandomBytes(seed, filesize*1000) 221 222 hash, err := upload(randomBytes, httpEndpoint(hosts[0])) 223 if err != nil { 224 return err 225 } 226 hashBytes, err := hexutil.Decode("0x" + hash) 227 if err != nil { 228 return err 229 } 230 multihashHex := hexutil.Encode(hashBytes) 231 fileHash := h.Sum(nil) 232 233 log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fileHash)) 234 235 // update file with topic 236 cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--topic", topicHex, multihashHex) 237 cmd.Stdout = &out 238 err = cmd.Run() 239 if err != nil { 240 return err 241 } 242 log.Debug("feed update topic", "out", out) 243 out.Reset() 244 245 // update file with subtopic 246 cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--name", subTopicHex, multihashHex) 247 cmd.Stdout = &out 248 err = cmd.Run() 249 if err != nil { 250 return err 251 } 252 log.Debug("feed update subtopic", "out", out) 253 out.Reset() 254 255 // update file with merged topic 256 cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--topic", topicHex, "--name", subTopicHex, multihashHex) 257 cmd.Stdout = &out 258 err = cmd.Run() 259 if err != nil { 260 return err 261 } 262 log.Debug("feed update mergedtopic", "out", out) 263 out.Reset() 264 265 time.Sleep(3 * time.Second) 266 267 for _, host := range hosts { 268 269 // manifest retrieve, topic only 270 for _, url := range []string{manifestWithTopic, manifestWithSubTopic, manifestWithMergedTopic} { 271 wg.Add(1) 272 ruid := uuid.New()[:8] 273 go func(url string, endpoint string, ruid string) { 274 for { 275 err := fetch(url, endpoint, fileHash, ruid, "") 276 if err != nil { 277 continue 278 } 279 280 wg.Done() 281 return 282 } 283 }(url, httpEndpoint(host), ruid) 284 } 285 286 } 287 wg.Wait() 288 log.Info("all endpoints synced random file successfully") 289 290 return nil 291 }