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