github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/les/freeclient_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:38</date> 10 //</624450093935759360> 11 12 13 //package light实现可按需检索的状态和链对象 14 //对于以太坊Light客户端。 15 package les 16 17 import ( 18 "fmt" 19 "math/rand" 20 "testing" 21 "time" 22 23 "github.com/ethereum/go-ethereum/common/mclock" 24 "github.com/ethereum/go-ethereum/ethdb" 25 ) 26 27 func TestFreeClientPoolL10C100(t *testing.T) { 28 testFreeClientPool(t, 10, 100) 29 } 30 31 func TestFreeClientPoolL40C200(t *testing.T) { 32 testFreeClientPool(t, 40, 200) 33 } 34 35 func TestFreeClientPoolL100C300(t *testing.T) { 36 testFreeClientPool(t, 100, 300) 37 } 38 39 const testFreeClientPoolTicks = 500000 40 41 func testFreeClientPool(t *testing.T, connLimit, clientCount int) { 42 var ( 43 clock mclock.Simulated 44 db = ethdb.NewMemDatabase() 45 pool = newFreeClientPool(db, connLimit, 10000, &clock) 46 connected = make([]bool, clientCount) 47 connTicks = make([]int, clientCount) 48 disconnCh = make(chan int, clientCount) 49 ) 50 peerId := func(i int) string { 51 return fmt.Sprintf("test peer #%d", i) 52 } 53 disconnFn := func(i int) func() { 54 return func() { 55 disconnCh <- i 56 } 57 } 58 59 //池应接受达到其连接限制的新对等方 60 for i := 0; i < connLimit; i++ { 61 if pool.connect(peerId(i), disconnFn(i)) { 62 connected[i] = true 63 } else { 64 t.Fatalf("Test peer #%d rejected", i) 65 } 66 } 67 //因为所有被接受的同龄人都是新的,不应该被淘汰,所以下一个同龄人应该被拒绝。 68 if pool.connect(peerId(connLimit), disconnFn(connLimit)) { 69 connected[connLimit] = true 70 t.Fatalf("Peer accepted over connected limit") 71 } 72 73 //随机连接和断开对等端,希望在端部具有相似的总连接时间 74 for tickCounter := 0; tickCounter < testFreeClientPoolTicks; tickCounter++ { 75 clock.Run(1 * time.Second) 76 77 i := rand.Intn(clientCount) 78 if connected[i] { 79 pool.disconnect(peerId(i)) 80 connected[i] = false 81 connTicks[i] += tickCounter 82 } else { 83 if pool.connect(peerId(i), disconnFn(i)) { 84 connected[i] = true 85 connTicks[i] -= tickCounter 86 } 87 } 88 pollDisconnects: 89 for { 90 select { 91 case i := <-disconnCh: 92 pool.disconnect(peerId(i)) 93 if connected[i] { 94 connTicks[i] += tickCounter 95 connected[i] = false 96 } 97 default: 98 break pollDisconnects 99 } 100 } 101 } 102 103 expTicks := testFreeClientPoolTicks * connLimit / clientCount 104 expMin := expTicks - expTicks/10 105 expMax := expTicks + expTicks/10 106 107 //检查对等节点的总连接时间是否在预期范围内 108 for i, c := range connected { 109 if c { 110 connTicks[i] += testFreeClientPoolTicks 111 } 112 if connTicks[i] < expMin || connTicks[i] > expMax { 113 t.Errorf("Total connected time of test node #%d (%d) outside expected range (%d to %d)", i, connTicks[i], expMin, expMax) 114 } 115 } 116 117 //现在应接受以前未知的对等机 118 if !pool.connect("newPeer", func() {}) { 119 t.Fatalf("Previously unknown peer rejected") 120 } 121 122 //关闭并重新启动池 123 pool.stop() 124 pool = newFreeClientPool(db, connLimit, 10000, &clock) 125 126 //尝试连接所有已知对等端(应填写connlimit) 127 for i := 0; i < clientCount; i++ { 128 pool.connect(peerId(i), func() {}) 129 } 130 //期望池记住已知节点,并将其中一个节点踢出以接受新节点 131 if !pool.connect("newPeer2", func() {}) { 132 t.Errorf("Previously unknown peer rejected after restarting pool") 133 } 134 pool.stop() 135 } 136