github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/cmd/swarm/swarm-snapshot/create.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 19:16:33</date> 10 //</624450071756279808> 11 12 13 package main 14 15 import ( 16 "context" 17 "encoding/json" 18 "errors" 19 "fmt" 20 "io/ioutil" 21 "os" 22 "path" 23 "path/filepath" 24 "strings" 25 "sync" 26 "time" 27 28 "github.com/ethereum/go-ethereum/log" 29 "github.com/ethereum/go-ethereum/node" 30 "github.com/ethereum/go-ethereum/p2p/simulations" 31 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 32 "github.com/ethereum/go-ethereum/swarm/network" 33 "github.com/ethereum/go-ethereum/swarm/network/simulation" 34 cli "gopkg.in/urfave/cli.v1" 35 ) 36 37 //create用作“create”app命令的输入函数。 38 func create(ctx *cli.Context) error { 39 log.PrintOrigins(true) 40 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(ctx.Int("verbosity")), log.StreamHandler(os.Stdout, log.TerminalFormat(true)))) 41 42 if len(ctx.Args()) < 1 { 43 return errors.New("argument should be the filename to verify or write-to") 44 } 45 filename, err := touchPath(ctx.Args()[0]) 46 if err != nil { 47 return err 48 } 49 return createSnapshot(filename, ctx.Int("nodes"), strings.Split(ctx.String("services"), ",")) 50 } 51 52 //createSnapshot使用提供的文件名在文件系统上创建新的快照, 53 //节点数和服务名。 54 func createSnapshot(filename string, nodes int, services []string) (err error) { 55 log.Debug("create snapshot", "filename", filename, "nodes", nodes, "services", services) 56 57 sim := simulation.New(map[string]simulation.ServiceFunc{ 58 "bzz": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) { 59 addr := network.NewAddr(ctx.Config.Node()) 60 kad := network.NewKademlia(addr.Over(), network.NewKadParams()) 61 hp := network.NewHiveParams() 62 hp.KeepAliveInterval = time.Duration(200) * time.Millisecond 63 hp.Discovery = true //创建快照时必须启用发现 64 65 config := &network.BzzConfig{ 66 OverlayAddr: addr.Over(), 67 UnderlayAddr: addr.Under(), 68 HiveParams: hp, 69 } 70 return network.NewBzz(config, kad, nil, nil, nil), nil, nil 71 }, 72 }) 73 defer sim.Close() 74 75 _, err = sim.AddNodes(nodes) 76 if err != nil { 77 return fmt.Errorf("add nodes: %v", err) 78 } 79 80 err = sim.Net.ConnectNodesRing(nil) 81 if err != nil { 82 return fmt.Errorf("connect nodes: %v", err) 83 } 84 85 ctx, cancelSimRun := context.WithTimeout(context.Background(), 2*time.Minute) 86 defer cancelSimRun() 87 if _, err := sim.WaitTillHealthy(ctx); err != nil { 88 return fmt.Errorf("wait for healthy kademlia: %v", err) 89 } 90 91 var snap *simulations.Snapshot 92 if len(services) > 0 { 93 //如果提供了服务名称,请在快照中包含它们。 94 //但是,检查“bzz”服务是否不在其中以删除它 95 //在创建快照时形成快照。 96 var removeServices []string 97 var wantBzz bool 98 for _, s := range services { 99 if s == "bzz" { 100 wantBzz = true 101 break 102 } 103 } 104 if !wantBzz { 105 removeServices = []string{"bzz"} 106 } 107 snap, err = sim.Net.SnapshotWithServices(services, removeServices) 108 } else { 109 snap, err = sim.Net.Snapshot() 110 } 111 if err != nil { 112 return fmt.Errorf("create snapshot: %v", err) 113 } 114 jsonsnapshot, err := json.Marshal(snap) 115 if err != nil { 116 return fmt.Errorf("json encode snapshot: %v", err) 117 } 118 return ioutil.WriteFile(filename, jsonsnapshot, 0666) 119 } 120 121 // 122 //不见了。 123 func touchPath(filename string) (string, error) { 124 if path.IsAbs(filename) { 125 if _, err := os.Stat(filename); err == nil { 126 //路径存在,覆盖 127 return filename, nil 128 } 129 } 130 131 d, f := path.Split(filename) 132 dir, err := filepath.Abs(filepath.Dir(os.Args[0])) 133 if err != nil { 134 return "", err 135 } 136 137 _, err = os.Stat(path.Join(dir, filename)) 138 if err == nil { 139 //路径存在,覆盖 140 return filename, nil 141 } 142 143 dirPath := path.Join(dir, d) 144 filePath := path.Join(dirPath, f) 145 if d != "" { 146 err = os.MkdirAll(dirPath, os.ModeDir) 147 if err != nil { 148 return "", err 149 } 150 } 151 152 return filePath, nil 153 } 154