github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/cmd/swarm/manifest.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 //版权所有2017 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 // 26 package main 27 28 import ( 29 "fmt" 30 "os" 31 "strings" 32 33 "github.com/ethereum/go-ethereum/cmd/utils" 34 "github.com/ethereum/go-ethereum/swarm/api" 35 swarm "github.com/ethereum/go-ethereum/swarm/api/client" 36 "gopkg.in/urfave/cli.v1" 37 ) 38 39 // 40 //最后一个参数new entry hash必须是清单的hash 41 // 42 // 43 func manifestAdd(ctx *cli.Context) { 44 args := ctx.Args() 45 if len(args) != 3 { 46 utils.Fatalf("Need exactly three arguments <MHASH> <path> <HASH>") 47 } 48 49 var ( 50 mhash = args[0] 51 path = args[1] 52 hash = args[2] 53 ) 54 55 bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") 56 client := swarm.NewClient(bzzapi) 57 58 m, _, err := client.DownloadManifest(hash) 59 if err != nil { 60 utils.Fatalf("Error downloading manifest to add: %v", err) 61 } 62 l := len(m.Entries) 63 if l == 0 { 64 utils.Fatalf("No entries in manifest %s", hash) 65 } else if l > 1 { 66 utils.Fatalf("Too many entries in manifest %s", hash) 67 } 68 69 newManifest := addEntryToManifest(client, mhash, path, m.Entries[0]) 70 fmt.Println(newManifest) 71 } 72 73 //清单更新将替换给定路径上清单的现有条目。 74 //最后一个参数new entry hash必须是清单的hash 75 //只有一个条目,这些元数据将添加到原始清单中。 76 //成功后,此函数将打印更新清单的哈希。 77 func manifestUpdate(ctx *cli.Context) { 78 args := ctx.Args() 79 if len(args) != 3 { 80 utils.Fatalf("Need exactly three arguments <MHASH> <path> <HASH>") 81 } 82 83 var ( 84 mhash = args[0] 85 path = args[1] 86 hash = args[2] 87 ) 88 89 bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") 90 client := swarm.NewClient(bzzapi) 91 92 m, _, err := client.DownloadManifest(hash) 93 if err != nil { 94 utils.Fatalf("Error downloading manifest to update: %v", err) 95 } 96 l := len(m.Entries) 97 if l == 0 { 98 utils.Fatalf("No entries in manifest %s", hash) 99 } else if l > 1 { 100 utils.Fatalf("Too many entries in manifest %s", hash) 101 } 102 103 newManifest, _, defaultEntryUpdated := updateEntryInManifest(client, mhash, path, m.Entries[0], true) 104 if defaultEntryUpdated { 105 // 106 // 107 // 108 fmt.Fprintln(os.Stderr, "Manifest default entry is updated, too") 109 } 110 fmt.Println(newManifest) 111 } 112 113 //manifestremove删除给定路径上清单的现有条目。 114 //成功后,此函数将打印清单的哈希,但该哈希没有 115 // 116 func manifestRemove(ctx *cli.Context) { 117 args := ctx.Args() 118 if len(args) != 2 { 119 utils.Fatalf("Need exactly two arguments <MHASH> <path>") 120 } 121 122 var ( 123 mhash = args[0] 124 path = args[1] 125 ) 126 127 bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") 128 client := swarm.NewClient(bzzapi) 129 130 newManifest := removeEntryFromManifest(client, mhash, path) 131 fmt.Println(newManifest) 132 } 133 134 func addEntryToManifest(client *swarm.Client, mhash, path string, entry api.ManifestEntry) string { 135 var longestPathEntry = api.ManifestEntry{} 136 137 mroot, isEncrypted, err := client.DownloadManifest(mhash) 138 if err != nil { 139 utils.Fatalf("Manifest download failed: %v", err) 140 } 141 142 //看看我们的道路是否在这张清单中,或者我们需要更深入地挖掘 143 for _, e := range mroot.Entries { 144 if path == e.Path { 145 utils.Fatalf("Path %s already present, not adding anything", path) 146 } else { 147 if e.ContentType == api.ManifestType { 148 prfxlen := strings.HasPrefix(path, e.Path) 149 if prfxlen && len(path) > len(longestPathEntry.Path) { 150 longestPathEntry = e 151 } 152 } 153 } 154 } 155 156 if longestPathEntry.Path != "" { 157 // 158 newPath := path[len(longestPathEntry.Path):] 159 newHash := addEntryToManifest(client, longestPathEntry.Hash, newPath, entry) 160 161 //替换父清单的哈希 162 newMRoot := &api.Manifest{} 163 for _, e := range mroot.Entries { 164 if longestPathEntry.Path == e.Path { 165 e.Hash = newHash 166 } 167 newMRoot.Entries = append(newMRoot.Entries, e) 168 } 169 mroot = newMRoot 170 } else { 171 // 172 entry.Path = path 173 mroot.Entries = append(mroot.Entries, entry) 174 } 175 176 newManifestHash, err := client.UploadManifest(mroot, isEncrypted) 177 if err != nil { 178 utils.Fatalf("Manifest upload failed: %v", err) 179 } 180 return newManifestHash 181 } 182 183 // 184 // 185 // 186 // 187 // 188 // 189 func updateEntryInManifest(client *swarm.Client, mhash, path string, entry api.ManifestEntry, isRoot bool) (newManifestHash, oldHash string, defaultEntryUpdated bool) { 190 var ( 191 newEntry = api.ManifestEntry{} 192 longestPathEntry = api.ManifestEntry{} 193 ) 194 195 mroot, isEncrypted, err := client.DownloadManifest(mhash) 196 if err != nil { 197 utils.Fatalf("Manifest download failed: %v", err) 198 } 199 200 //看看我们的道路是否在这张清单中,或者我们需要更深入地挖掘 201 for _, e := range mroot.Entries { 202 if path == e.Path { 203 newEntry = e 204 // 205 // 206 oldHash = e.Hash 207 } else { 208 if e.ContentType == api.ManifestType { 209 prfxlen := strings.HasPrefix(path, e.Path) 210 if prfxlen && len(path) > len(longestPathEntry.Path) { 211 longestPathEntry = e 212 } 213 } 214 } 215 } 216 217 if longestPathEntry.Path == "" && newEntry.Path == "" { 218 utils.Fatalf("Path %s not present in the Manifest, not setting anything", path) 219 } 220 221 if longestPathEntry.Path != "" { 222 // 223 newPath := path[len(longestPathEntry.Path):] 224 var newHash string 225 newHash, oldHash, _ = updateEntryInManifest(client, longestPathEntry.Hash, newPath, entry, false) 226 227 //替换父清单的哈希 228 newMRoot := &api.Manifest{} 229 for _, e := range mroot.Entries { 230 if longestPathEntry.Path == e.Path { 231 e.Hash = newHash 232 } 233 newMRoot.Entries = append(newMRoot.Entries, e) 234 235 } 236 mroot = newMRoot 237 } 238 239 // 240 //检查是否应更新默认条目 241 if newEntry.Path != "" || isRoot { 242 //替换叶清单的哈希 243 newMRoot := &api.Manifest{} 244 for _, e := range mroot.Entries { 245 if newEntry.Path == e.Path { 246 entry.Path = e.Path 247 newMRoot.Entries = append(newMRoot.Entries, entry) 248 } else if isRoot && e.Path == "" && e.Hash == oldHash { 249 entry.Path = e.Path 250 newMRoot.Entries = append(newMRoot.Entries, entry) 251 defaultEntryUpdated = true 252 } else { 253 newMRoot.Entries = append(newMRoot.Entries, e) 254 } 255 } 256 mroot = newMRoot 257 } 258 259 newManifestHash, err = client.UploadManifest(mroot, isEncrypted) 260 if err != nil { 261 utils.Fatalf("Manifest upload failed: %v", err) 262 } 263 return newManifestHash, oldHash, defaultEntryUpdated 264 } 265 266 func removeEntryFromManifest(client *swarm.Client, mhash, path string) string { 267 var ( 268 entryToRemove = api.ManifestEntry{} 269 longestPathEntry = api.ManifestEntry{} 270 ) 271 272 mroot, isEncrypted, err := client.DownloadManifest(mhash) 273 if err != nil { 274 utils.Fatalf("Manifest download failed: %v", err) 275 } 276 277 //看看我们的道路是否在这张清单中,或者我们需要更深入地挖掘 278 for _, entry := range mroot.Entries { 279 if path == entry.Path { 280 entryToRemove = entry 281 } else { 282 if entry.ContentType == api.ManifestType { 283 prfxlen := strings.HasPrefix(path, entry.Path) 284 if prfxlen && len(path) > len(longestPathEntry.Path) { 285 longestPathEntry = entry 286 } 287 } 288 } 289 } 290 291 if longestPathEntry.Path == "" && entryToRemove.Path == "" { 292 utils.Fatalf("Path %s not present in the Manifest, not removing anything", path) 293 } 294 295 if longestPathEntry.Path != "" { 296 // 297 newPath := path[len(longestPathEntry.Path):] 298 newHash := removeEntryFromManifest(client, longestPathEntry.Hash, newPath) 299 300 //替换父清单的哈希 301 newMRoot := &api.Manifest{} 302 for _, entry := range mroot.Entries { 303 if longestPathEntry.Path == entry.Path { 304 entry.Hash = newHash 305 } 306 newMRoot.Entries = append(newMRoot.Entries, entry) 307 } 308 mroot = newMRoot 309 } 310 311 if entryToRemove.Path != "" { 312 //删除此清单中的条目 313 newMRoot := &api.Manifest{} 314 for _, entry := range mroot.Entries { 315 if entryToRemove.Path != entry.Path { 316 newMRoot.Entries = append(newMRoot.Entries, entry) 317 } 318 } 319 mroot = newMRoot 320 } 321 322 newManifestHash, err := client.UploadManifest(mroot, isEncrypted) 323 if err != nil { 324 utils.Fatalf("Manifest upload failed: %v", err) 325 } 326 return newManifestHash 327 }