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