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  }