github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/cmd/swarm/swarm-smoke/sliding_window.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "bytes" 21 "fmt" 22 "math/rand" 23 "time" 24 25 "github.com/ethereum/go-ethereum/log" 26 "github.com/ethereum/go-ethereum/metrics" 27 "github.com/ethereum/go-ethereum/swarm/testutil" 28 "github.com/pborman/uuid" 29 cli "gopkg.in/urfave/cli.v1" 30 ) 31 32 type uploadResult struct { 33 hash string 34 digest []byte 35 } 36 37 func slidingWindowCmd(ctx *cli.Context, tuid string) error { 38 errc := make(chan error) 39 40 go func() { 41 errc <- slidingWindow(ctx, tuid) 42 }() 43 44 select { 45 case err := <-errc: 46 if err != nil { 47 metrics.GetOrRegisterCounter(fmt.Sprintf("%s.fail", commandName), nil).Inc(1) 48 } 49 return err 50 case <-time.After(time.Duration(timeout) * time.Second): 51 metrics.GetOrRegisterCounter(fmt.Sprintf("%s.timeout", commandName), nil).Inc(1) 52 53 return fmt.Errorf("timeout after %v sec", timeout) 54 } 55 } 56 57 func slidingWindow(ctx *cli.Context, tuid string) error { 58 hashes := []uploadResult{} //swarm hashes of the uploads 59 nodes := len(hosts) 60 const iterationTimeout = 30 * time.Second 61 log.Info("sliding window test started", "tuid", tuid, "nodes", nodes, "filesize(kb)", filesize, "timeout", timeout) 62 uploadedBytes := 0 63 networkDepth := 0 64 errored := false 65 66 outer: 67 for { 68 log.Info("uploading to "+httpEndpoint(hosts[0])+" and syncing", "seed", seed) 69 70 t1 := time.Now() 71 72 randomBytes := testutil.RandomBytes(seed, filesize*1000) 73 74 hash, err := upload(randomBytes, httpEndpoint(hosts[0])) 75 if err != nil { 76 log.Error(err.Error()) 77 return err 78 } 79 80 metrics.GetOrRegisterResettingTimer("sliding-window.upload-time", nil).UpdateSince(t1) 81 82 fhash, err := digest(bytes.NewReader(randomBytes)) 83 if err != nil { 84 log.Error(err.Error()) 85 return err 86 } 87 88 log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fhash), "sleeping", syncDelay) 89 hashes = append(hashes, uploadResult{hash: hash, digest: fhash}) 90 time.Sleep(time.Duration(syncDelay) * time.Second) 91 uploadedBytes += filesize * 1000 92 93 for i, v := range hashes { 94 timeout := time.After(time.Duration(timeout) * time.Second) 95 errored = false 96 97 inner: 98 for { 99 select { 100 case <-timeout: 101 errored = true 102 log.Error("error retrieving hash. timeout", "hash idx", i, "err", err) 103 metrics.GetOrRegisterCounter("sliding-window.single.error", nil).Inc(1) 104 break inner 105 default: 106 idx := 1 + rand.Intn(len(hosts)-1) 107 ruid := uuid.New()[:8] 108 start := time.Now() 109 err := fetch(v.hash, httpEndpoint(hosts[idx]), v.digest, ruid, "") 110 if err != nil { 111 continue inner 112 } 113 metrics.GetOrRegisterResettingTimer("sliding-window.single.fetch-time", nil).UpdateSince(start) 114 break inner 115 } 116 } 117 118 if errored { 119 break outer 120 } 121 networkDepth = i 122 metrics.GetOrRegisterGauge("sliding-window.network-depth", nil).Update(int64(networkDepth)) 123 } 124 } 125 126 log.Info("sliding window test finished", "errored?", errored, "networkDepth", networkDepth, "networkDepth(kb)", networkDepth*filesize) 127 log.Info("stats", "uploadedFiles", len(hashes), "uploadedKb", uploadedBytes/1000, "filesizeKb", filesize) 128 129 return nil 130 }