github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/eth/protocol_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 //版权所有2014 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package eth 26 27 import ( 28 "fmt" 29 "sync" 30 "testing" 31 "time" 32 33 "github.com/ethereum/go-ethereum/common" 34 "github.com/ethereum/go-ethereum/core/types" 35 "github.com/ethereum/go-ethereum/crypto" 36 "github.com/ethereum/go-ethereum/eth/downloader" 37 "github.com/ethereum/go-ethereum/p2p" 38 "github.com/ethereum/go-ethereum/rlp" 39 ) 40 41 func init() { 42 //log.root().sethandler(log.lvlfilterhandler(log.lvltrace,log.streamhandler(os.stderr,log.terminalformat(false))) 43 } 44 45 var testAccount, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 46 47 //检测并正确报告握手失败的测试。 48 func TestStatusMsgErrors62(t *testing.T) { testStatusMsgErrors(t, 62) } 49 func TestStatusMsgErrors63(t *testing.T) { testStatusMsgErrors(t, 63) } 50 51 func testStatusMsgErrors(t *testing.T, protocol int) { 52 pm, _ := newTestProtocolManagerMust(t, downloader.FullSync, 0, nil, nil) 53 var ( 54 genesis = pm.blockchain.Genesis() 55 head = pm.blockchain.CurrentHeader() 56 td = pm.blockchain.GetTd(head.Hash(), head.Number.Uint64()) 57 ) 58 defer pm.Stop() 59 60 tests := []struct { 61 code uint64 62 data interface{} 63 wantError error 64 }{ 65 { 66 code: TxMsg, data: []interface{}{}, 67 wantError: errResp(ErrNoStatusMsg, "first msg has code 2 (!= 0)"), 68 }, 69 { 70 code: StatusMsg, data: statusData{10, DefaultConfig.NetworkId, td, head.Hash(), genesis.Hash()}, 71 wantError: errResp(ErrProtocolVersionMismatch, "10 (!= %d)", protocol), 72 }, 73 { 74 code: StatusMsg, data: statusData{uint32(protocol), 999, td, head.Hash(), genesis.Hash()}, 75 wantError: errResp(ErrNetworkIdMismatch, "999 (!= 1)"), 76 }, 77 { 78 code: StatusMsg, data: statusData{uint32(protocol), DefaultConfig.NetworkId, td, head.Hash(), common.Hash{3}}, 79 wantError: errResp(ErrGenesisBlockMismatch, "0300000000000000 (!= %x)", genesis.Hash().Bytes()[:8]), 80 }, 81 } 82 83 for i, test := range tests { 84 p, errc := newTestPeer("peer", protocol, pm, false) 85 //在重置之前,发送呼叫可能挂起,因为 86 //协议可能无法读取有效负载。 87 go p2p.Send(p.app, test.code, test.data) 88 89 select { 90 case err := <-errc: 91 if err == nil { 92 t.Errorf("test %d: protocol returned nil error, want %q", i, test.wantError) 93 } else if err.Error() != test.wantError.Error() { 94 t.Errorf("test %d: wrong error: got %q, want %q", i, err, test.wantError) 95 } 96 case <-time.After(2 * time.Second): 97 t.Errorf("protocol did not shut down within 2 seconds") 98 } 99 p.close() 100 } 101 } 102 103 //此测试检查接收到的事务是否添加到本地池。 104 func TestRecvTransactions62(t *testing.T) { testRecvTransactions(t, 62) } 105 func TestRecvTransactions63(t *testing.T) { testRecvTransactions(t, 63) } 106 107 func testRecvTransactions(t *testing.T, protocol int) { 108 txAdded := make(chan []*types.Transaction) 109 pm, _ := newTestProtocolManagerMust(t, downloader.FullSync, 0, nil, txAdded) 110 pm.acceptTxs = 1 //标记为同步以接受交易记录 111 p, _ := newTestPeer("peer", protocol, pm, true) 112 defer pm.Stop() 113 defer p.close() 114 115 tx := newTestTransaction(testAccount, 0, 0) 116 if err := p2p.Send(p.app, TxMsg, []interface{}{tx}); err != nil { 117 t.Fatalf("send error: %v", err) 118 } 119 select { 120 case added := <-txAdded: 121 if len(added) != 1 { 122 t.Errorf("wrong number of added transactions: got %d, want 1", len(added)) 123 } else if added[0].Hash() != tx.Hash() { 124 t.Errorf("added wrong tx hash: got %v, want %v", added[0].Hash(), tx.Hash()) 125 } 126 case <-time.After(2 * time.Second): 127 t.Errorf("no NewTxsEvent received within 2 seconds") 128 } 129 } 130 131 //此测试检查是否发送挂起的事务。 132 func TestSendTransactions62(t *testing.T) { testSendTransactions(t, 62) } 133 func TestSendTransactions63(t *testing.T) { testSendTransactions(t, 63) } 134 135 func testSendTransactions(t *testing.T, protocol int) { 136 pm, _ := newTestProtocolManagerMust(t, downloader.FullSync, 0, nil, nil) 137 defer pm.Stop() 138 139 //把大交易填满池。 140 const txsize = txsyncPackSize / 10 141 alltxs := make([]*types.Transaction, 100) 142 for nonce := range alltxs { 143 alltxs[nonce] = newTestTransaction(testAccount, uint64(nonce), txsize) 144 } 145 pm.txpool.AddRemotes(alltxs) 146 147 //连接多个对等点。他们都应该收到待处理的事务。 148 var wg sync.WaitGroup 149 checktxs := func(p *testPeer) { 150 defer wg.Done() 151 defer p.close() 152 seen := make(map[common.Hash]bool) 153 for _, tx := range alltxs { 154 seen[tx.Hash()] = false 155 } 156 for n := 0; n < len(alltxs) && !t.Failed(); { 157 var txs []*types.Transaction 158 msg, err := p.app.ReadMsg() 159 if err != nil { 160 t.Errorf("%v: read error: %v", p.Peer, err) 161 } else if msg.Code != TxMsg { 162 t.Errorf("%v: got code %d, want TxMsg", p.Peer, msg.Code) 163 } 164 if err := msg.Decode(&txs); err != nil { 165 t.Errorf("%v: %v", p.Peer, err) 166 } 167 for _, tx := range txs { 168 hash := tx.Hash() 169 seentx, want := seen[hash] 170 if seentx { 171 t.Errorf("%v: got tx more than once: %x", p.Peer, hash) 172 } 173 if !want { 174 t.Errorf("%v: got unexpected tx: %x", p.Peer, hash) 175 } 176 seen[hash] = true 177 n++ 178 } 179 } 180 } 181 for i := 0; i < 3; i++ { 182 p, _ := newTestPeer(fmt.Sprintf("peer #%d", i), protocol, pm, true) 183 wg.Add(1) 184 go checktxs(p) 185 } 186 wg.Wait() 187 } 188 189 //测试自定义联合字段编码器和解码器是否正常工作。 190 func TestGetBlockHeadersDataEncodeDecode(t *testing.T) { 191 //为测试创建“随机”哈希 192 var hash common.Hash 193 for i := range hash { 194 hash[i] = byte(i) 195 } 196 //组装一些表驱动测试 197 tests := []struct { 198 packet *getBlockHeadersData 199 fail bool 200 }{ 201 //以哈希或数字的形式提供源站应该都有效 202 {fail: false, packet: &getBlockHeadersData{Origin: hashOrNumber{Number: 314}}}, 203 {fail: false, packet: &getBlockHeadersData{Origin: hashOrNumber{Hash: hash}}}, 204 205 //提供任意查询字段也应该有效 206 {fail: false, packet: &getBlockHeadersData{Origin: hashOrNumber{Number: 314}, Amount: 314, Skip: 1, Reverse: true}}, 207 {fail: false, packet: &getBlockHeadersData{Origin: hashOrNumber{Hash: hash}, Amount: 314, Skip: 1, Reverse: true}}, 208 209 //提供源哈希和源编号必须失败 210 {fail: true, packet: &getBlockHeadersData{Origin: hashOrNumber{Hash: hash, Number: 314}}}, 211 } 212 //迭代每个测试,然后尝试编码然后解码 213 for i, tt := range tests { 214 bytes, err := rlp.EncodeToBytes(tt.packet) 215 if err != nil && !tt.fail { 216 t.Fatalf("test %d: failed to encode packet: %v", i, err) 217 } else if err == nil && tt.fail { 218 t.Fatalf("test %d: encode should have failed", i) 219 } 220 if !tt.fail { 221 packet := new(getBlockHeadersData) 222 if err := rlp.DecodeBytes(bytes, packet); err != nil { 223 t.Fatalf("test %d: failed to decode packet: %v", i, err) 224 } 225 if packet.Origin.Hash != tt.packet.Origin.Hash || packet.Origin.Number != tt.packet.Origin.Number || packet.Amount != tt.packet.Amount || 226 packet.Skip != tt.packet.Skip || packet.Reverse != tt.packet.Reverse { 227 t.Fatalf("test %d: encode decode mismatch: have %+v, want %+v", i, packet, tt.packet) 228 } 229 } 230 } 231 }