github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/network/kademlia_test.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:43</date>
    10  //</624450113879674880>
    11  
    12  
    13  package network
    14  
    15  import (
    16  	"fmt"
    17  	"os"
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/ethereum/go-ethereum/common"
    22  	"github.com/ethereum/go-ethereum/log"
    23  	"github.com/ethereum/go-ethereum/p2p"
    24  	"github.com/ethereum/go-ethereum/p2p/enode"
    25  	"github.com/ethereum/go-ethereum/p2p/protocols"
    26  	"github.com/ethereum/go-ethereum/swarm/pot"
    27  )
    28  
    29  func init() {
    30  	h := log.LvlFilterHandler(log.LvlWarn, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))
    31  	log.Root().SetHandler(h)
    32  }
    33  
    34  func testKadPeerAddr(s string) *BzzAddr {
    35  	a := pot.NewAddressFromString(s)
    36  	return &BzzAddr{OAddr: a, UAddr: a}
    37  }
    38  
    39  func newTestKademliaParams() *KadParams {
    40  	params := NewKadParams()
    41  	params.MinBinSize = 2
    42  	params.NeighbourhoodSize = 2
    43  	return params
    44  }
    45  
    46  type testKademlia struct {
    47  	*Kademlia
    48  	t *testing.T
    49  }
    50  
    51  func newTestKademlia(t *testing.T, b string) *testKademlia {
    52  	base := pot.NewAddressFromString(b)
    53  	return &testKademlia{
    54  		Kademlia: NewKademlia(base, newTestKademliaParams()),
    55  		t:        t,
    56  	}
    57  }
    58  
    59  func (tk *testKademlia) newTestKadPeer(s string, lightNode bool) *Peer {
    60  	return NewPeer(&BzzPeer{BzzAddr: testKadPeerAddr(s), LightNode: lightNode}, tk.Kademlia)
    61  }
    62  
    63  func (tk *testKademlia) On(ons ...string) {
    64  	for _, s := range ons {
    65  		tk.Kademlia.On(tk.newTestKadPeer(s, false))
    66  	}
    67  }
    68  
    69  func (tk *testKademlia) Off(offs ...string) {
    70  	for _, s := range offs {
    71  		tk.Kademlia.Off(tk.newTestKadPeer(s, false))
    72  	}
    73  }
    74  
    75  func (tk *testKademlia) Register(regs ...string) {
    76  	var as []*BzzAddr
    77  	for _, s := range regs {
    78  		as = append(as, testKadPeerAddr(s))
    79  	}
    80  	err := tk.Kademlia.Register(as...)
    81  	if err != nil {
    82  		panic(err.Error())
    83  	}
    84  }
    85  
    86  //检验邻域深度计算的有效性
    87  //
    88  //特别是,它测试如果有一个或多个连续的
    89  //然后清空最远“最近邻居”上方的垃圾箱。
    90  //深度应该设置在那些空箱子的最远处。
    91  //
    92  //TODO:使测试适应邻里关系的变化
    93  func TestNeighbourhoodDepth(t *testing.T) {
    94  	baseAddressBytes := RandomAddr().OAddr
    95  	kad := NewKademlia(baseAddressBytes, NewKadParams())
    96  
    97  	baseAddress := pot.NewAddressFromBytes(baseAddressBytes)
    98  
    99  //生成对等点
   100  	var peers []*Peer
   101  	for i := 0; i < 7; i++ {
   102  		addr := pot.RandomAddressAt(baseAddress, i)
   103  		peers = append(peers, newTestDiscoveryPeer(addr, kad))
   104  	}
   105  	var sevenPeers []*Peer
   106  	for i := 0; i < 2; i++ {
   107  		addr := pot.RandomAddressAt(baseAddress, 7)
   108  		sevenPeers = append(sevenPeers, newTestDiscoveryPeer(addr, kad))
   109  	}
   110  
   111  	testNum := 0
   112  //第一次尝试空花环
   113  	depth := kad.NeighbourhoodDepth()
   114  	if depth != 0 {
   115  		t.Fatalf("%d expected depth 0, was %d", testNum, depth)
   116  	}
   117  	testNum++
   118  
   119  //在7上添加一个对等点
   120  	kad.On(sevenPeers[0])
   121  	depth = kad.NeighbourhoodDepth()
   122  	if depth != 0 {
   123  		t.Fatalf("%d expected depth 0, was %d", testNum, depth)
   124  	}
   125  	testNum++
   126  
   127  //7点再加一秒
   128  	kad.On(sevenPeers[1])
   129  	depth = kad.NeighbourhoodDepth()
   130  	if depth != 0 {
   131  		t.Fatalf("%d expected depth 0, was %d", testNum, depth)
   132  	}
   133  	testNum++
   134  
   135  //从0增加到6
   136  	for i, p := range peers {
   137  		kad.On(p)
   138  		depth = kad.NeighbourhoodDepth()
   139  		if depth != i+1 {
   140  			t.Fatalf("%d.%d expected depth %d, was %d", i+1, testNum, i, depth)
   141  		}
   142  	}
   143  	testNum++
   144  
   145  	kad.Off(sevenPeers[1])
   146  	depth = kad.NeighbourhoodDepth()
   147  	if depth != 6 {
   148  		t.Fatalf("%d expected depth 6, was %d", testNum, depth)
   149  	}
   150  	testNum++
   151  
   152  	kad.Off(peers[4])
   153  	depth = kad.NeighbourhoodDepth()
   154  	if depth != 4 {
   155  		t.Fatalf("%d expected depth 4, was %d", testNum, depth)
   156  	}
   157  	testNum++
   158  
   159  	kad.Off(peers[3])
   160  	depth = kad.NeighbourhoodDepth()
   161  	if depth != 3 {
   162  		t.Fatalf("%d expected depth 3, was %d", testNum, depth)
   163  	}
   164  	testNum++
   165  }
   166  
   167  //testHealthStrict测试最简单的健康定义
   168  //这意味着我们是否与我们所认识的所有邻居都有联系
   169  func TestHealthStrict(t *testing.T) {
   170  
   171  //基址都是零
   172  //没有对等体
   173  //不健康(和孤独)
   174  	tk := newTestKademlia(t, "11111111")
   175  	tk.checkHealth(false, false)
   176  
   177  //知道一个对等点但没有连接
   178  //不健康的
   179  	tk.Register("11100000")
   180  	tk.checkHealth(false, false)
   181  
   182  //认识一个同伴并建立联系
   183  //健康的
   184  	tk.On("11100000")
   185  	tk.checkHealth(true, false)
   186  
   187  //认识两个同龄人,只有一个相连
   188  //不健康的
   189  	tk.Register("11111100")
   190  	tk.checkHealth(false, false)
   191  
   192  //认识两个同龄人并与两个同龄人都有联系
   193  //健康的
   194  	tk.On("11111100")
   195  	tk.checkHealth(true, false)
   196  
   197  //认识三个同龄人,连到两个最深的
   198  //健康的
   199  	tk.Register("00000000")
   200  	tk.checkHealth(true, false)
   201  
   202  //认识三个同龄人,连接到所有三个
   203  //健康的
   204  	tk.On("00000000")
   205  	tk.checkHealth(true, false)
   206  
   207  //添加比当前深度更深的第四个对等点
   208  //不健康的
   209  	tk.Register("11110000")
   210  	tk.checkHealth(false, false)
   211  
   212  //连接到三个最深的对等点
   213  //健康的
   214  	tk.On("11110000")
   215  	tk.checkHealth(true, false)
   216  
   217  //在同一个bin中添加其他对等机作为最深对等机
   218  //不健康的
   219  	tk.Register("11111101")
   220  	tk.checkHealth(false, false)
   221  
   222  //五个对等点中连接最深的四个
   223  //健康的
   224  	tk.On("11111101")
   225  	tk.checkHealth(true, false)
   226  }
   227  
   228  func (tk *testKademlia) checkHealth(expectHealthy bool, expectSaturation bool) {
   229  	tk.t.Helper()
   230  	kid := common.Bytes2Hex(tk.BaseAddr())
   231  	addrs := [][]byte{tk.BaseAddr()}
   232  	tk.EachAddr(nil, 255, func(addr *BzzAddr, po int) bool {
   233  		addrs = append(addrs, addr.Address())
   234  		return true
   235  	})
   236  
   237  	pp := NewPeerPotMap(tk.NeighbourhoodSize, addrs)
   238  	healthParams := tk.Healthy(pp[kid])
   239  
   240  //健康的定义,所有条件,但必须真实:
   241  //-我们至少认识一个同伴
   242  //我们认识所有的邻居
   243  //-我们与所有已知的邻居都有联系
   244  	health := healthParams.KnowNN && healthParams.ConnectNN && healthParams.CountKnowNN > 0
   245  	if expectHealthy != health {
   246  		tk.t.Fatalf("expected kademlia health %v, is %v\n%v", expectHealthy, health, tk.String())
   247  	}
   248  }
   249  
   250  func (tk *testKademlia) checkSuggestPeer(expAddr string, expDepth int, expChanged bool) {
   251  	tk.t.Helper()
   252  	addr, depth, changed := tk.SuggestPeer()
   253  	log.Trace("suggestPeer return", "addr", addr, "depth", depth, "changed", changed)
   254  	if binStr(addr) != expAddr {
   255  		tk.t.Fatalf("incorrect peer address suggested. expected %v, got %v", expAddr, binStr(addr))
   256  	}
   257  	if depth != expDepth {
   258  		tk.t.Fatalf("incorrect saturation depth suggested. expected %v, got %v", expDepth, depth)
   259  	}
   260  	if changed != expChanged {
   261  		tk.t.Fatalf("expected depth change = %v, got %v", expChanged, changed)
   262  	}
   263  }
   264  
   265  func binStr(a *BzzAddr) string {
   266  	if a == nil {
   267  		return "<nil>"
   268  	}
   269  	return pot.ToBin(a.Address())[:8]
   270  }
   271  
   272  func TestSuggestPeerFindPeers(t *testing.T) {
   273  	tk := newTestKademlia(t, "00000000")
   274  	tk.On("00100000")
   275  	tk.checkSuggestPeer("<nil>", 0, false)
   276  
   277  	tk.On("00010000")
   278  	tk.checkSuggestPeer("<nil>", 0, false)
   279  
   280  	tk.On("10000000", "10000001")
   281  	tk.checkSuggestPeer("<nil>", 0, false)
   282  
   283  	tk.On("01000000")
   284  	tk.Off("10000001")
   285  	tk.checkSuggestPeer("10000001", 0, true)
   286  
   287  	tk.On("00100001")
   288  	tk.Off("01000000")
   289  	tk.checkSuggestPeer("01000000", 0, false)
   290  
   291  //第二次断开连接的对等机不可调用
   292  //间隔合理
   293  	tk.checkSuggestPeer("<nil>", 0, false)
   294  
   295  //一次又一次地打开和关闭,对等呼叫再次
   296  	tk.On("01000000")
   297  	tk.Off("01000000")
   298  	tk.checkSuggestPeer("01000000", 0, false)
   299  
   300  	tk.On("01000000", "10000001")
   301  	tk.checkSuggestPeer("<nil>", 0, false)
   302  
   303  	tk.Register("00010001")
   304  	tk.checkSuggestPeer("00010001", 0, false)
   305  
   306  	tk.On("00010001")
   307  	tk.Off("01000000")
   308  	tk.checkSuggestPeer("01000000", 0, false)
   309  
   310  	tk.On("01000000")
   311  	tk.checkSuggestPeer("<nil>", 0, false)
   312  
   313  	tk.Register("01000001")
   314  	tk.checkSuggestPeer("01000001", 0, false)
   315  
   316  	tk.On("01000001")
   317  	tk.checkSuggestPeer("<nil>", 0, false)
   318  
   319  	tk.Register("10000010", "01000010", "00100010")
   320  	tk.checkSuggestPeer("<nil>", 0, false)
   321  
   322  	tk.Register("00010010")
   323  	tk.checkSuggestPeer("00010010", 0, false)
   324  
   325  	tk.Off("00100001")
   326  	tk.checkSuggestPeer("00100010", 2, true)
   327  
   328  	tk.Off("01000001")
   329  	tk.checkSuggestPeer("01000010", 1, true)
   330  
   331  	tk.checkSuggestPeer("01000001", 0, false)
   332  	tk.checkSuggestPeer("00100001", 0, false)
   333  	tk.checkSuggestPeer("<nil>", 0, false)
   334  
   335  	tk.On("01000001", "00100001")
   336  	tk.Register("10000100", "01000100", "00100100")
   337  	tk.Register("00000100", "00000101", "00000110")
   338  	tk.Register("00000010", "00000011", "00000001")
   339  
   340  	tk.checkSuggestPeer("00000110", 0, false)
   341  	tk.checkSuggestPeer("00000101", 0, false)
   342  	tk.checkSuggestPeer("00000100", 0, false)
   343  	tk.checkSuggestPeer("00000011", 0, false)
   344  	tk.checkSuggestPeer("00000010", 0, false)
   345  	tk.checkSuggestPeer("00000001", 0, false)
   346  	tk.checkSuggestPeer("<nil>", 0, false)
   347  
   348  }
   349  
   350  //如果一个节点从Kademlia中删除,它应该留在通讯簿中。
   351  func TestOffEffectingAddressBookNormalNode(t *testing.T) {
   352  	tk := newTestKademlia(t, "00000000")
   353  //添加到Kademlia的对等
   354  	tk.On("01000000")
   355  //对等机应该在通讯簿中
   356  	if tk.addrs.Size() != 1 {
   357  		t.Fatal("known peer addresses should contain 1 entry")
   358  	}
   359  //对等端应位于活动连接之间
   360  	if tk.conns.Size() != 1 {
   361  		t.Fatal("live peers should contain 1 entry")
   362  	}
   363  //从Kademlia中删除对等
   364  	tk.Off("01000000")
   365  //对等机应该在通讯簿中
   366  	if tk.addrs.Size() != 1 {
   367  		t.Fatal("known peer addresses should contain 1 entry")
   368  	}
   369  //对等端不应位于活动连接之间
   370  	if tk.conns.Size() != 0 {
   371  		t.Fatal("live peers should contain 0 entry")
   372  	}
   373  }
   374  
   375  //轻节点不应在通讯簿中
   376  func TestOffEffectingAddressBookLightNode(t *testing.T) {
   377  	tk := newTestKademlia(t, "00000000")
   378  //添加到Kademlia的光节点对等体
   379  	tk.Kademlia.On(tk.newTestKadPeer("01000000", true))
   380  //对等机不应在通讯簿中
   381  	if tk.addrs.Size() != 0 {
   382  		t.Fatal("known peer addresses should contain 0 entry")
   383  	}
   384  //对等端应位于活动连接之间
   385  	if tk.conns.Size() != 1 {
   386  		t.Fatal("live peers should contain 1 entry")
   387  	}
   388  //从Kademlia中删除对等
   389  	tk.Kademlia.Off(tk.newTestKadPeer("01000000", true))
   390  //对等机不应在通讯簿中
   391  	if tk.addrs.Size() != 0 {
   392  		t.Fatal("known peer addresses should contain 0 entry")
   393  	}
   394  //对等端不应位于活动连接之间
   395  	if tk.conns.Size() != 0 {
   396  		t.Fatal("live peers should contain 0 entry")
   397  	}
   398  }
   399  
   400  func TestSuggestPeerRetries(t *testing.T) {
   401  	tk := newTestKademlia(t, "00000000")
   402  tk.RetryInterval = int64(300 * time.Millisecond) //周期
   403  	tk.MaxRetries = 50
   404  	tk.RetryExponent = 2
   405  	sleep := func(n int) {
   406  		ts := tk.RetryInterval
   407  		for i := 1; i < n; i++ {
   408  			ts *= int64(tk.RetryExponent)
   409  		}
   410  		time.Sleep(time.Duration(ts))
   411  	}
   412  
   413  	tk.Register("01000000")
   414  	tk.On("00000001", "00000010")
   415  	tk.checkSuggestPeer("01000000", 0, false)
   416  
   417  	tk.checkSuggestPeer("<nil>", 0, false)
   418  
   419  	sleep(1)
   420  	tk.checkSuggestPeer("01000000", 0, false)
   421  
   422  	tk.checkSuggestPeer("<nil>", 0, false)
   423  
   424  	sleep(1)
   425  	tk.checkSuggestPeer("01000000", 0, false)
   426  
   427  	tk.checkSuggestPeer("<nil>", 0, false)
   428  
   429  	sleep(2)
   430  	tk.checkSuggestPeer("01000000", 0, false)
   431  
   432  	tk.checkSuggestPeer("<nil>", 0, false)
   433  
   434  	sleep(2)
   435  	tk.checkSuggestPeer("<nil>", 0, false)
   436  }
   437  
   438  func TestKademliaHiveString(t *testing.T) {
   439  	tk := newTestKademlia(t, "00000000")
   440  	tk.On("01000000", "00100000")
   441  	tk.Register("10000000", "10000001")
   442  	tk.MaxProxDisplay = 8
   443  	h := tk.String()
   444  	expH := "\n=========================================================================\nMon Feb 27 12:10:28 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 000000\npopulation: 2 (4), NeighbourhoodSize: 2, MinBinSize: 2, MaxBinSize: 4\n============ DEPTH: 0 ==========================================\n000  0                              |  2 8100 (0) 8000 (0)\n001  1 4000                         |  1 4000 (0)\n002  1 2000                         |  1 2000 (0)\n003  0                              |  0\n004  0                              |  0\n005  0                              |  0\n006  0                              |  0\n007  0                              |  0\n========================================================================="
   445  	if expH[104:] != h[104:] {
   446  		t.Fatalf("incorrect hive output. expected %v, got %v", expH, h)
   447  	}
   448  }
   449  
   450  func newTestDiscoveryPeer(addr pot.Address, kad *Kademlia) *Peer {
   451  	rw := &p2p.MsgPipeRW{}
   452  	p := p2p.NewPeer(enode.ID{}, "foo", []p2p.Cap{})
   453  	pp := protocols.NewPeer(p, rw, &protocols.Spec{})
   454  	bp := &BzzPeer{
   455  		Peer: pp,
   456  		BzzAddr: &BzzAddr{
   457  			OAddr: addr.Bytes(),
   458  			UAddr: []byte(fmt.Sprintf("%x", addr[:])),
   459  		},
   460  	}
   461  	return NewPeer(bp, kad)
   462  }
   463