github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/cmd/swarm/swarm-smoke/upload_and_sync.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2018 Go Ethereum作者 10 //此文件是Go以太坊的一部分。 11 // 12 //Go以太坊是免费软件:您可以重新发布和/或修改它 13 //根据GNU通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊的分布希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU通用公共许可证了解更多详细信息。 21 // 22 //你应该已经收到一份GNU通用公共许可证的副本 23 //一起去以太坊吧。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package main 26 27 import ( 28 "bytes" 29 "crypto/md5" 30 "crypto/rand" 31 "fmt" 32 "io" 33 "io/ioutil" 34 "net/http" 35 "os" 36 "os/exec" 37 "strings" 38 "sync" 39 "time" 40 41 "github.com/ethereum/go-ethereum/log" 42 "github.com/pborman/uuid" 43 44 cli "gopkg.in/urfave/cli.v1" 45 ) 46 47 func generateEndpoints(scheme string, cluster string, from int, to int) { 48 if cluster == "prod" { 49 cluster = "" 50 } else { 51 cluster = cluster + "." 52 } 53 54 for port := from; port <= to; port++ { 55 endpoints = append(endpoints, fmt.Sprintf("%s://%v.%sswarm gateways.net“,方案,端口,群集) 56 } 57 58 if includeLocalhost { 59 endpoints = append(endpoints, "http://本地主机:8500“) 60 } 61 } 62 63 func cliUploadAndSync(c *cli.Context) error { 64 defer func(now time.Time) { log.Info("total time", "time", time.Since(now), "size", filesize) }(time.Now()) 65 66 generateEndpoints(scheme, cluster, from, to) 67 68 log.Info("uploading to " + endpoints[0] + " and syncing") 69 70 f, cleanup := generateRandomFile(filesize * 1000000) 71 defer cleanup() 72 73 hash, err := upload(f, endpoints[0]) 74 if err != nil { 75 log.Error(err.Error()) 76 return err 77 } 78 79 fhash, err := digest(f) 80 if err != nil { 81 log.Error(err.Error()) 82 return err 83 } 84 85 log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fhash)) 86 87 if filesize < 10 { 88 time.Sleep(35 * time.Second) 89 } else { 90 time.Sleep(15 * time.Second) 91 time.Sleep(2 * time.Duration(filesize) * time.Second) 92 } 93 94 wg := sync.WaitGroup{} 95 for _, endpoint := range endpoints { 96 endpoint := endpoint 97 ruid := uuid.New()[:8] 98 wg.Add(1) 99 go func(endpoint string, ruid string) { 100 for { 101 err := fetch(hash, endpoint, fhash, ruid) 102 if err != nil { 103 continue 104 } 105 106 wg.Done() 107 return 108 } 109 }(endpoint, ruid) 110 } 111 wg.Wait() 112 log.Info("all endpoints synced random file successfully") 113 114 return nil 115 } 116 117 // 118 func fetch(hash string, endpoint string, original []byte, ruid string) error { 119 log.Trace("sleeping", "ruid", ruid) 120 time.Sleep(5 * time.Second) 121 122 log.Trace("http get request", "ruid", ruid, "api", endpoint, "hash", hash) 123 res, err := http.Get(endpoint + "/bzz:/" + hash + "/") 124 if err != nil { 125 log.Warn(err.Error(), "ruid", ruid) 126 return err 127 } 128 log.Trace("http get response", "ruid", ruid, "api", endpoint, "hash", hash, "code", res.StatusCode, "len", res.ContentLength) 129 130 if res.StatusCode != 200 { 131 err := fmt.Errorf("expected status code %d, got %v", 200, res.StatusCode) 132 log.Warn(err.Error(), "ruid", ruid) 133 return err 134 } 135 136 defer res.Body.Close() 137 138 rdigest, err := digest(res.Body) 139 if err != nil { 140 log.Warn(err.Error(), "ruid", ruid) 141 return err 142 } 143 144 if !bytes.Equal(rdigest, original) { 145 err := fmt.Errorf("downloaded imported file md5=%x is not the same as the generated one=%x", rdigest, original) 146 log.Warn(err.Error(), "ruid", ruid) 147 return err 148 } 149 150 log.Trace("downloaded file matches random file", "ruid", ruid, "len", res.ContentLength) 151 152 return nil 153 } 154 155 //upload正在通过“swarm up”命令将文件“f”上载到“endpoint” 156 func upload(f *os.File, endpoint string) (string, error) { 157 var out bytes.Buffer 158 cmd := exec.Command("swarm", "--bzzapi", endpoint, "up", f.Name()) 159 cmd.Stdout = &out 160 err := cmd.Run() 161 if err != nil { 162 return "", err 163 } 164 hash := strings.TrimRight(out.String(), "\r\n") 165 return hash, nil 166 } 167 168 func digest(r io.Reader) ([]byte, error) { 169 h := md5.New() 170 _, err := io.Copy(h, r) 171 if err != nil { 172 return nil, err 173 } 174 return h.Sum(nil), nil 175 } 176 177 //GenerateRandomFile正在创建具有请求字节大小的临时文件 178 func generateRandomFile(size int) (f *os.File, teardown func()) { 179 //创建tmp文件 180 tmp, err := ioutil.TempFile("", "swarm-test") 181 if err != nil { 182 panic(err) 183 } 184 185 //tmp文件清理回调 186 teardown = func() { 187 tmp.Close() 188 os.Remove(tmp.Name()) 189 } 190 191 buf := make([]byte, size) 192 _, err = rand.Read(buf) 193 if err != nil { 194 panic(err) 195 } 196 ioutil.WriteFile(tmp.Name(), buf, 0755) 197 198 return tmp, teardown 199 }