github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/simulations/discovery/discovery_test.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  //
    10  //
    11  //
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  
    25  package discovery
    26  
    27  import (
    28  	"context"
    29  	"encoding/json"
    30  	"errors"
    31  	"flag"
    32  	"fmt"
    33  	"io/ioutil"
    34  	"math/rand"
    35  	"os"
    36  	"path"
    37  	"strings"
    38  	"sync"
    39  	"testing"
    40  	"time"
    41  
    42  	"github.com/ethereum/go-ethereum/common"
    43  	"github.com/ethereum/go-ethereum/log"
    44  	"github.com/ethereum/go-ethereum/node"
    45  	"github.com/ethereum/go-ethereum/p2p"
    46  	"github.com/ethereum/go-ethereum/p2p/discover"
    47  	"github.com/ethereum/go-ethereum/p2p/simulations"
    48  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    49  	"github.com/ethereum/go-ethereum/swarm/network"
    50  	"github.com/ethereum/go-ethereum/swarm/state"
    51  	colorable "github.com/mattn/go-colorable"
    52  )
    53  
    54  //
    55  //
    56  const serviceName = "discovery"
    57  const testMinProxBinSize = 2
    58  const discoveryPersistenceDatadir = "discovery_persistence_test_store"
    59  
    60  var discoveryPersistencePath = path.Join(os.TempDir(), discoveryPersistenceDatadir)
    61  var discoveryEnabled = true
    62  var persistenceEnabled = false
    63  
    64  var services = adapters.Services{
    65  	serviceName: newService,
    66  }
    67  
    68  func cleanDbStores() error {
    69  	entries, err := ioutil.ReadDir(os.TempDir())
    70  	if err != nil {
    71  		return err
    72  	}
    73  
    74  	for _, f := range entries {
    75  		if strings.HasPrefix(f.Name(), discoveryPersistenceDatadir) {
    76  			os.RemoveAll(path.Join(os.TempDir(), f.Name()))
    77  		}
    78  	}
    79  	return nil
    80  
    81  }
    82  
    83  func getDbStore(nodeID string) (*state.DBStore, error) {
    84  	if _, err := os.Stat(discoveryPersistencePath + "_" + nodeID); os.IsNotExist(err) {
    85  		log.Info(fmt.Sprintf("directory for nodeID %s does not exist. creating...", nodeID))
    86  		ioutil.TempDir("", discoveryPersistencePath+"_"+nodeID)
    87  	}
    88  	log.Info(fmt.Sprintf("opening storage directory for nodeID %s", nodeID))
    89  	store, err := state.NewDBStore(discoveryPersistencePath + "_" + nodeID)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	return store, nil
    94  }
    95  
    96  var (
    97  	nodeCount    = flag.Int("nodes", 10, "number of nodes to create (default 10)")
    98  	initCount    = flag.Int("conns", 1, "number of originally connected peers	 (default 1)")
    99  	snapshotFile = flag.String("snapshot", "", "create snapshot")
   100  	loglevel     = flag.Int("loglevel", 3, "verbosity of logs")
   101  	rawlog       = flag.Bool("rawlog", false, "remove terminal formatting from logs")
   102  )
   103  
   104  func init() {
   105  	flag.Parse()
   106  //
   107  //
   108  	adapters.RegisterServices(services)
   109  
   110  	log.PrintOrigins(true)
   111  	log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(!*rawlog))))
   112  }
   113  
   114  //
   115  //
   116  func BenchmarkDiscovery_8_1(b *testing.B)   { benchmarkDiscovery(b, 8, 1) }
   117  func BenchmarkDiscovery_16_1(b *testing.B)  { benchmarkDiscovery(b, 16, 1) }
   118  func BenchmarkDiscovery_32_1(b *testing.B)  { benchmarkDiscovery(b, 32, 1) }
   119  func BenchmarkDiscovery_64_1(b *testing.B)  { benchmarkDiscovery(b, 64, 1) }
   120  func BenchmarkDiscovery_128_1(b *testing.B) { benchmarkDiscovery(b, 128, 1) }
   121  func BenchmarkDiscovery_256_1(b *testing.B) { benchmarkDiscovery(b, 256, 1) }
   122  
   123  func BenchmarkDiscovery_8_2(b *testing.B)   { benchmarkDiscovery(b, 8, 2) }
   124  func BenchmarkDiscovery_16_2(b *testing.B)  { benchmarkDiscovery(b, 16, 2) }
   125  func BenchmarkDiscovery_32_2(b *testing.B)  { benchmarkDiscovery(b, 32, 2) }
   126  func BenchmarkDiscovery_64_2(b *testing.B)  { benchmarkDiscovery(b, 64, 2) }
   127  func BenchmarkDiscovery_128_2(b *testing.B) { benchmarkDiscovery(b, 128, 2) }
   128  func BenchmarkDiscovery_256_2(b *testing.B) { benchmarkDiscovery(b, 256, 2) }
   129  
   130  func BenchmarkDiscovery_8_4(b *testing.B)   { benchmarkDiscovery(b, 8, 4) }
   131  func BenchmarkDiscovery_16_4(b *testing.B)  { benchmarkDiscovery(b, 16, 4) }
   132  func BenchmarkDiscovery_32_4(b *testing.B)  { benchmarkDiscovery(b, 32, 4) }
   133  func BenchmarkDiscovery_64_4(b *testing.B)  { benchmarkDiscovery(b, 64, 4) }
   134  func BenchmarkDiscovery_128_4(b *testing.B) { benchmarkDiscovery(b, 128, 4) }
   135  func BenchmarkDiscovery_256_4(b *testing.B) { benchmarkDiscovery(b, 256, 4) }
   136  
   137  func TestDiscoverySimulationDockerAdapter(t *testing.T) {
   138  	testDiscoverySimulationDockerAdapter(t, *nodeCount, *initCount)
   139  }
   140  
   141  func testDiscoverySimulationDockerAdapter(t *testing.T, nodes, conns int) {
   142  	adapter, err := adapters.NewDockerAdapter()
   143  	if err != nil {
   144  		if err == adapters.ErrLinuxOnly {
   145  			t.Skip(err)
   146  		} else {
   147  			t.Fatal(err)
   148  		}
   149  	}
   150  	testDiscoverySimulation(t, nodes, conns, adapter)
   151  }
   152  
   153  func TestDiscoverySimulationExecAdapter(t *testing.T) {
   154  	testDiscoverySimulationExecAdapter(t, *nodeCount, *initCount)
   155  }
   156  
   157  func testDiscoverySimulationExecAdapter(t *testing.T, nodes, conns int) {
   158  	baseDir, err := ioutil.TempDir("", "swarm-test")
   159  	if err != nil {
   160  		t.Fatal(err)
   161  	}
   162  	defer os.RemoveAll(baseDir)
   163  	testDiscoverySimulation(t, nodes, conns, adapters.NewExecAdapter(baseDir))
   164  }
   165  
   166  func TestDiscoverySimulationSimAdapter(t *testing.T) {
   167  	testDiscoverySimulationSimAdapter(t, *nodeCount, *initCount)
   168  }
   169  
   170  func TestDiscoveryPersistenceSimulationSimAdapter(t *testing.T) {
   171  	testDiscoveryPersistenceSimulationSimAdapter(t, *nodeCount, *initCount)
   172  }
   173  
   174  func testDiscoveryPersistenceSimulationSimAdapter(t *testing.T, nodes, conns int) {
   175  	testDiscoveryPersistenceSimulation(t, nodes, conns, adapters.NewSimAdapter(services))
   176  }
   177  
   178  func testDiscoverySimulationSimAdapter(t *testing.T, nodes, conns int) {
   179  	testDiscoverySimulation(t, nodes, conns, adapters.NewSimAdapter(services))
   180  }
   181  
   182  func testDiscoverySimulation(t *testing.T, nodes, conns int, adapter adapters.NodeAdapter) {
   183  	startedAt := time.Now()
   184  	result, err := discoverySimulation(nodes, conns, adapter)
   185  	if err != nil {
   186  		t.Fatalf("Setting up simulation failed: %v", err)
   187  	}
   188  	if result.Error != nil {
   189  		t.Fatalf("Simulation failed: %s", result.Error)
   190  	}
   191  	t.Logf("Simulation with %d nodes passed in %s", nodes, result.FinishedAt.Sub(result.StartedAt))
   192  	var min, max time.Duration
   193  	var sum int
   194  	for _, pass := range result.Passes {
   195  		duration := pass.Sub(result.StartedAt)
   196  		if sum == 0 || duration < min {
   197  			min = duration
   198  		}
   199  		if duration > max {
   200  			max = duration
   201  		}
   202  		sum += int(duration.Nanoseconds())
   203  	}
   204  	t.Logf("Min: %s, Max: %s, Average: %s", min, max, time.Duration(sum/len(result.Passes))*time.Nanosecond)
   205  	finishedAt := time.Now()
   206  	t.Logf("Setup: %s, shutdown: %s", result.StartedAt.Sub(startedAt), finishedAt.Sub(result.FinishedAt))
   207  }
   208  
   209  func testDiscoveryPersistenceSimulation(t *testing.T, nodes, conns int, adapter adapters.NodeAdapter) map[int][]byte {
   210  	persistenceEnabled = true
   211  	discoveryEnabled = true
   212  
   213  	result, err := discoveryPersistenceSimulation(nodes, conns, adapter)
   214  
   215  	if err != nil {
   216  		t.Fatalf("Setting up simulation failed: %v", err)
   217  	}
   218  	if result.Error != nil {
   219  		t.Fatalf("Simulation failed: %s", result.Error)
   220  	}
   221  	t.Logf("Simulation with %d nodes passed in %s", nodes, result.FinishedAt.Sub(result.StartedAt))
   222  //
   223  //
   224  	discoveryEnabled = true
   225  	persistenceEnabled = false
   226  	return nil
   227  }
   228  
   229  func benchmarkDiscovery(b *testing.B, nodes, conns int) {
   230  	for i := 0; i < b.N; i++ {
   231  		result, err := discoverySimulation(nodes, conns, adapters.NewSimAdapter(services))
   232  		if err != nil {
   233  			b.Fatalf("setting up simulation failed: %v", err)
   234  		}
   235  		if result.Error != nil {
   236  			b.Logf("simulation failed: %s", result.Error)
   237  		}
   238  	}
   239  }
   240  
   241  func discoverySimulation(nodes, conns int, adapter adapters.NodeAdapter) (*simulations.StepResult, error) {
   242  //
   243  	net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{
   244  		ID:             "0",
   245  		DefaultService: serviceName,
   246  	})
   247  	defer net.Shutdown()
   248  	trigger := make(chan discover.NodeID)
   249  	ids := make([]discover.NodeID, nodes)
   250  	for i := 0; i < nodes; i++ {
   251  		conf := adapters.RandomNodeConfig()
   252  		node, err := net.NewNodeWithConfig(conf)
   253  		if err != nil {
   254  			return nil, fmt.Errorf("error starting node: %s", err)
   255  		}
   256  		if err := net.Start(node.ID()); err != nil {
   257  			return nil, fmt.Errorf("error starting node %s: %s", node.ID().TerminalString(), err)
   258  		}
   259  		if err := triggerChecks(trigger, net, node.ID()); err != nil {
   260  			return nil, fmt.Errorf("error triggering checks for node %s: %s", node.ID().TerminalString(), err)
   261  		}
   262  		ids[i] = node.ID()
   263  	}
   264  
   265  //
   266  //
   267  	var addrs [][]byte
   268  	action := func(ctx context.Context) error {
   269  		return nil
   270  	}
   271  	wg := sync.WaitGroup{}
   272  	for i := range ids {
   273  //
   274  		addrs = append(addrs, network.ToOverlayAddr(ids[i].Bytes()))
   275  		for j := 0; j < conns; j++ {
   276  			var k int
   277  			if j == 0 {
   278  				k = (i + 1) % len(ids)
   279  			} else {
   280  				k = rand.Intn(len(ids))
   281  			}
   282  			wg.Add(1)
   283  			go func(i, k int) {
   284  				defer wg.Done()
   285  				net.Connect(ids[i], ids[k])
   286  			}(i, k)
   287  		}
   288  	}
   289  	wg.Wait()
   290  	log.Debug(fmt.Sprintf("nodes: %v", len(addrs)))
   291  //
   292  	ppmap := network.NewPeerPotMap(testMinProxBinSize, addrs)
   293  	check := func(ctx context.Context, id discover.NodeID) (bool, error) {
   294  		select {
   295  		case <-ctx.Done():
   296  			return false, ctx.Err()
   297  		default:
   298  		}
   299  
   300  		node := net.GetNode(id)
   301  		if node == nil {
   302  			return false, fmt.Errorf("unknown node: %s", id)
   303  		}
   304  		client, err := node.Client()
   305  		if err != nil {
   306  			return false, fmt.Errorf("error getting node client: %s", err)
   307  		}
   308  		healthy := &network.Health{}
   309  		addr := common.Bytes2Hex(network.ToOverlayAddr(id.Bytes()))
   310  		if err := client.Call(&healthy, "hive_healthy", ppmap[addr]); err != nil {
   311  			return false, fmt.Errorf("error getting node health: %s", err)
   312  		}
   313  		log.Debug(fmt.Sprintf("node %4s healthy: got nearest neighbours: %v, know nearest neighbours: %v, saturated: %v\n%v", id, healthy.GotNN, healthy.KnowNN, healthy.Full, healthy.Hive))
   314  		return healthy.KnowNN && healthy.GotNN && healthy.Full, nil
   315  	}
   316  
   317  //
   318  //
   319  	timeout := 300 * time.Second
   320  	ctx, cancel := context.WithTimeout(context.Background(), timeout)
   321  	defer cancel()
   322  	result := simulations.NewSimulation(net).Run(ctx, &simulations.Step{
   323  		Action:  action,
   324  		Trigger: trigger,
   325  		Expect: &simulations.Expectation{
   326  			Nodes: ids,
   327  			Check: check,
   328  		},
   329  	})
   330  	if result.Error != nil {
   331  		return result, nil
   332  	}
   333  
   334  	if *snapshotFile != "" {
   335  		snap, err := net.Snapshot()
   336  		if err != nil {
   337  			return nil, errors.New("no shapshot dude")
   338  		}
   339  		jsonsnapshot, err := json.Marshal(snap)
   340  		if err != nil {
   341  			return nil, fmt.Errorf("corrupt json snapshot: %v", err)
   342  		}
   343  		log.Info("writing snapshot", "file", *snapshotFile)
   344  		err = ioutil.WriteFile(*snapshotFile, jsonsnapshot, 0755)
   345  		if err != nil {
   346  			return nil, err
   347  		}
   348  	}
   349  	return result, nil
   350  }
   351  
   352  func discoveryPersistenceSimulation(nodes, conns int, adapter adapters.NodeAdapter) (*simulations.StepResult, error) {
   353  	cleanDbStores()
   354  	defer cleanDbStores()
   355  
   356  //
   357  	net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{
   358  		ID:             "0",
   359  		DefaultService: serviceName,
   360  	})
   361  	defer net.Shutdown()
   362  	trigger := make(chan discover.NodeID)
   363  	ids := make([]discover.NodeID, nodes)
   364  	var addrs [][]byte
   365  
   366  	for i := 0; i < nodes; i++ {
   367  		conf := adapters.RandomNodeConfig()
   368  		node, err := net.NewNodeWithConfig(conf)
   369  		if err != nil {
   370  			panic(err)
   371  		}
   372  		if err != nil {
   373  			return nil, fmt.Errorf("error starting node: %s", err)
   374  		}
   375  		if err := net.Start(node.ID()); err != nil {
   376  			return nil, fmt.Errorf("error starting node %s: %s", node.ID().TerminalString(), err)
   377  		}
   378  		if err := triggerChecks(trigger, net, node.ID()); err != nil {
   379  			return nil, fmt.Errorf("error triggering checks for node %s: %s", node.ID().TerminalString(), err)
   380  		}
   381  		ids[i] = node.ID()
   382  		a := network.ToOverlayAddr(ids[i].Bytes())
   383  
   384  		addrs = append(addrs, a)
   385  	}
   386  
   387  //
   388  //
   389  	ppmap := network.NewPeerPotMap(testMinProxBinSize, addrs)
   390  
   391  	var restartTime time.Time
   392  
   393  	action := func(ctx context.Context) error {
   394  		ticker := time.NewTicker(500 * time.Millisecond)
   395  
   396  		for range ticker.C {
   397  			isHealthy := true
   398  			for _, id := range ids {
   399  //
   400  				node := net.GetNode(id)
   401  				if node == nil {
   402  					return fmt.Errorf("unknown node: %s", id)
   403  				}
   404  				client, err := node.Client()
   405  				if err != nil {
   406  					return fmt.Errorf("error getting node client: %s", err)
   407  				}
   408  				healthy := &network.Health{}
   409  				addr := common.Bytes2Hex(network.ToOverlayAddr(id.Bytes()))
   410  				if err := client.Call(&healthy, "hive_healthy", ppmap[addr]); err != nil {
   411  					return fmt.Errorf("error getting node health: %s", err)
   412  				}
   413  
   414  				log.Info(fmt.Sprintf("NODE: %s, IS HEALTHY: %t", id.String(), healthy.GotNN && healthy.KnowNN && healthy.Full))
   415  				if !healthy.GotNN || !healthy.Full {
   416  					isHealthy = false
   417  					break
   418  				}
   419  			}
   420  			if isHealthy {
   421  				break
   422  			}
   423  		}
   424  		ticker.Stop()
   425  
   426  		log.Info("reached healthy kademlia. starting to shutdown nodes.")
   427  		shutdownStarted := time.Now()
   428  //
   429  		for _, id := range ids {
   430  			node := net.GetNode(id)
   431  
   432  			if err := net.Stop(node.ID()); err != nil {
   433  				return fmt.Errorf("error stopping node %s: %s", node.ID().TerminalString(), err)
   434  			}
   435  		}
   436  		log.Info(fmt.Sprintf("shutting down nodes took: %s", time.Since(shutdownStarted)))
   437  		persistenceEnabled = true
   438  		discoveryEnabled = false
   439  		restartTime = time.Now()
   440  		for _, id := range ids {
   441  			node := net.GetNode(id)
   442  			if err := net.Start(node.ID()); err != nil {
   443  				return fmt.Errorf("error starting node %s: %s", node.ID().TerminalString(), err)
   444  			}
   445  			if err := triggerChecks(trigger, net, node.ID()); err != nil {
   446  				return fmt.Errorf("error triggering checks for node %s: %s", node.ID().TerminalString(), err)
   447  			}
   448  		}
   449  
   450  		log.Info(fmt.Sprintf("restarting nodes took: %s", time.Since(restartTime)))
   451  
   452  		return nil
   453  	}
   454  //
   455  	wg := sync.WaitGroup{}
   456  //
   457  	for i := range ids {
   458  		for j := 1; j <= conns; j++ {
   459  			k := (i + j) % len(ids)
   460  			if k == i {
   461  				k = (k + 1) % len(ids)
   462  			}
   463  			wg.Add(1)
   464  			go func(i, k int) {
   465  				defer wg.Done()
   466  				net.Connect(ids[i], ids[k])
   467  			}(i, k)
   468  		}
   469  	}
   470  	wg.Wait()
   471  	log.Debug(fmt.Sprintf("nodes: %v", len(addrs)))
   472  //
   473  	check := func(ctx context.Context, id discover.NodeID) (bool, error) {
   474  		select {
   475  		case <-ctx.Done():
   476  			return false, ctx.Err()
   477  		default:
   478  		}
   479  
   480  		node := net.GetNode(id)
   481  		if node == nil {
   482  			return false, fmt.Errorf("unknown node: %s", id)
   483  		}
   484  		client, err := node.Client()
   485  		if err != nil {
   486  			return false, fmt.Errorf("error getting node client: %s", err)
   487  		}
   488  		healthy := &network.Health{}
   489  		addr := common.Bytes2Hex(network.ToOverlayAddr(id.Bytes()))
   490  		if err := client.Call(&healthy, "hive_healthy", ppmap[addr]); err != nil {
   491  			return false, fmt.Errorf("error getting node health: %s", err)
   492  		}
   493  		log.Info(fmt.Sprintf("node %4s healthy: got nearest neighbours: %v, know nearest neighbours: %v, saturated: %v", id, healthy.GotNN, healthy.KnowNN, healthy.Full))
   494  
   495  		return healthy.KnowNN && healthy.GotNN && healthy.Full, nil
   496  	}
   497  
   498  //
   499  //
   500  	timeout := 300 * time.Second
   501  	ctx, cancel := context.WithTimeout(context.Background(), timeout)
   502  	defer cancel()
   503  	result := simulations.NewSimulation(net).Run(ctx, &simulations.Step{
   504  		Action:  action,
   505  		Trigger: trigger,
   506  		Expect: &simulations.Expectation{
   507  			Nodes: ids,
   508  			Check: check,
   509  		},
   510  	})
   511  	if result.Error != nil {
   512  		return result, nil
   513  	}
   514  
   515  	return result, nil
   516  }
   517  
   518  //
   519  //
   520  //
   521  func triggerChecks(trigger chan discover.NodeID, net *simulations.Network, id discover.NodeID) error {
   522  	node := net.GetNode(id)
   523  	if node == nil {
   524  		return fmt.Errorf("unknown node: %s", id)
   525  	}
   526  	client, err := node.Client()
   527  	if err != nil {
   528  		return err
   529  	}
   530  	events := make(chan *p2p.PeerEvent)
   531  	sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents")
   532  	if err != nil {
   533  		return fmt.Errorf("error getting peer events for node %v: %s", id, err)
   534  	}
   535  	go func() {
   536  		defer sub.Unsubscribe()
   537  
   538  		tick := time.NewTicker(time.Second)
   539  		defer tick.Stop()
   540  
   541  		for {
   542  			select {
   543  			case <-events:
   544  				trigger <- id
   545  			case <-tick.C:
   546  				trigger <- id
   547  			case err := <-sub.Err():
   548  				if err != nil {
   549  					log.Error(fmt.Sprintf("error getting peer events for node %v", id), "err", err)
   550  				}
   551  				return
   552  			}
   553  		}
   554  	}()
   555  	return nil
   556  }
   557  
   558  func newService(ctx *adapters.ServiceContext) (node.Service, error) {
   559  	host := adapters.ExternalIP()
   560  
   561  	addr := network.NewAddrFromNodeIDAndPort(ctx.Config.ID, host, ctx.Config.Port)
   562  
   563  	kp := network.NewKadParams()
   564  	kp.MinProxBinSize = testMinProxBinSize
   565  
   566  	if ctx.Config.Reachable != nil {
   567  		kp.Reachable = func(o network.OverlayAddr) bool {
   568  			return ctx.Config.Reachable(o.(*network.BzzAddr).ID())
   569  		}
   570  	}
   571  	kad := network.NewKademlia(addr.Over(), kp)
   572  	hp := network.NewHiveParams()
   573  	hp.KeepAliveInterval = time.Duration(200) * time.Millisecond
   574  	hp.Discovery = discoveryEnabled
   575  
   576  	log.Info(fmt.Sprintf("discovery for nodeID %s is %t", ctx.Config.ID.String(), hp.Discovery))
   577  
   578  	config := &network.BzzConfig{
   579  		OverlayAddr:  addr.Over(),
   580  		UnderlayAddr: addr.Under(),
   581  		HiveParams:   hp,
   582  	}
   583  
   584  	if persistenceEnabled {
   585  		log.Info(fmt.Sprintf("persistence enabled for nodeID %s", ctx.Config.ID.String()))
   586  		store, err := getDbStore(ctx.Config.ID.String())
   587  		if err != nil {
   588  			return nil, err
   589  		}
   590  		return network.NewBzz(config, kad, store, nil, nil), nil
   591  	}
   592  
   593  	return network.NewBzz(config, kad, nil, nil, nil), nil
   594  }