github.com/phillinzzz/newBsc@v1.1.6/eth/protocols/diff/handler_test.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package diff 18 19 import ( 20 "math/big" 21 "math/rand" 22 "testing" 23 24 "github.com/phillinzzz/newBsc/common" 25 "github.com/phillinzzz/newBsc/consensus/ethash" 26 "github.com/phillinzzz/newBsc/core" 27 "github.com/phillinzzz/newBsc/core/rawdb" 28 "github.com/phillinzzz/newBsc/core/types" 29 "github.com/phillinzzz/newBsc/core/vm" 30 "github.com/phillinzzz/newBsc/crypto" 31 "github.com/phillinzzz/newBsc/ethdb" 32 "github.com/phillinzzz/newBsc/p2p" 33 "github.com/phillinzzz/newBsc/p2p/enode" 34 "github.com/phillinzzz/newBsc/params" 35 "github.com/phillinzzz/newBsc/rlp" 36 ) 37 38 var ( 39 // testKey is a private key to use for funding a tester account. 40 testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 41 42 // testAddr is the Ethereum address of the tester account. 43 testAddr = crypto.PubkeyToAddress(testKey.PublicKey) 44 ) 45 46 // testBackend is a mock implementation of the live Ethereum message handler. Its 47 // purpose is to allow testing the request/reply workflows and wire serialization 48 // in the `eth` protocol without actually doing any data processing. 49 type testBackend struct { 50 db ethdb.Database 51 chain *core.BlockChain 52 txpool *core.TxPool 53 } 54 55 // newTestBackend creates an empty chain and wraps it into a mock backend. 56 func newTestBackend(blocks int) *testBackend { 57 return newTestBackendWithGenerator(blocks) 58 } 59 60 // newTestBackend creates a chain with a number of explicitly defined blocks and 61 // wraps it into a mock backend. 62 func newTestBackendWithGenerator(blocks int) *testBackend { 63 signer := types.HomesteadSigner{} 64 // Create a database pre-initialize with a genesis block 65 db := rawdb.NewMemoryDatabase() 66 (&core.Genesis{ 67 Config: params.TestChainConfig, 68 Alloc: core.GenesisAlloc{testAddr: {Balance: big.NewInt(100000000000000000)}}, 69 }).MustCommit(db) 70 71 chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil) 72 generator := func(i int, block *core.BlockGen) { 73 // The chain maker doesn't have access to a chain, so the difficulty will be 74 // lets unset (nil). Set it here to the correct value. 75 block.SetCoinbase(testAddr) 76 77 // We want to simulate an empty middle block, having the same state as the 78 // first one. The last is needs a state change again to force a reorg. 79 tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), common.Address{0x01}, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testKey) 80 if err != nil { 81 panic(err) 82 } 83 block.AddTxWithChain(chain, tx) 84 } 85 bs, _ := core.GenerateChain(params.TestChainConfig, chain.Genesis(), ethash.NewFaker(), db, blocks, generator) 86 if _, err := chain.InsertChain(bs); err != nil { 87 panic(err) 88 } 89 txconfig := core.DefaultTxPoolConfig 90 txconfig.Journal = "" // Don't litter the disk with test journals 91 92 return &testBackend{ 93 db: db, 94 chain: chain, 95 txpool: core.NewTxPool(txconfig, params.TestChainConfig, chain), 96 } 97 } 98 99 // close tears down the transaction pool and chain behind the mock backend. 100 func (b *testBackend) close() { 101 b.txpool.Stop() 102 b.chain.Stop() 103 } 104 105 func (b *testBackend) Chain() *core.BlockChain { return b.chain } 106 107 func (b *testBackend) RunPeer(peer *Peer, handler Handler) error { 108 // Normally the backend would do peer mainentance and handshakes. All that 109 // is omitted and we will just give control back to the handler. 110 return handler(peer) 111 } 112 func (b *testBackend) PeerInfo(enode.ID) interface{} { panic("not implemented") } 113 114 func (b *testBackend) Handle(*Peer, Packet) error { 115 panic("data processing tests should be done in the handler package") 116 } 117 118 func TestGetDiffLayers(t *testing.T) { testGetDiffLayers(t, Diff1) } 119 120 func testGetDiffLayers(t *testing.T, protocol uint) { 121 t.Parallel() 122 123 blockNum := 2048 124 backend := newTestBackend(blockNum) 125 defer backend.close() 126 127 peer, _ := newTestPeer("peer", protocol, backend) 128 defer peer.close() 129 130 foundDiffBlockHashes := make([]common.Hash, 0) 131 foundDiffPackets := make([]FullDiffLayersPacket, 0) 132 foundDiffRlps := make([]rlp.RawValue, 0) 133 missDiffBlockHashes := make([]common.Hash, 0) 134 missDiffPackets := make([]FullDiffLayersPacket, 0) 135 136 for i := 0; i < 100; i++ { 137 number := uint64(rand.Int63n(1024)) 138 if number == 0 { 139 continue 140 } 141 foundHash := backend.chain.GetCanonicalHash(number + 1024) 142 missHash := backend.chain.GetCanonicalHash(number) 143 foundRlp := backend.chain.GetDiffLayerRLP(foundHash) 144 145 if len(foundHash) == 0 { 146 t.Fatalf("Faild to fond rlp encoded diff layer %v", foundHash) 147 } 148 foundDiffPackets = append(foundDiffPackets, FullDiffLayersPacket{ 149 RequestId: uint64(i), 150 DiffLayersPacket: []rlp.RawValue{foundRlp}, 151 }) 152 foundDiffRlps = append(foundDiffRlps, foundRlp) 153 154 missDiffPackets = append(missDiffPackets, FullDiffLayersPacket{ 155 RequestId: uint64(i), 156 DiffLayersPacket: []rlp.RawValue{}, 157 }) 158 159 missDiffBlockHashes = append(missDiffBlockHashes, missHash) 160 foundDiffBlockHashes = append(foundDiffBlockHashes, foundHash) 161 } 162 163 for idx, blockHash := range foundDiffBlockHashes { 164 p2p.Send(peer.app, GetDiffLayerMsg, GetDiffLayersPacket{RequestId: uint64(idx), BlockHashes: []common.Hash{blockHash}}) 165 if err := p2p.ExpectMsg(peer.app, FullDiffLayerMsg, foundDiffPackets[idx]); err != nil { 166 t.Errorf("test %d: diff layer mismatch: %v", idx, err) 167 } 168 } 169 170 for idx, blockHash := range missDiffBlockHashes { 171 p2p.Send(peer.app, GetDiffLayerMsg, GetDiffLayersPacket{RequestId: uint64(idx), BlockHashes: []common.Hash{blockHash}}) 172 if err := p2p.ExpectMsg(peer.app, FullDiffLayerMsg, missDiffPackets[idx]); err != nil { 173 t.Errorf("test %d: diff layer mismatch: %v", idx, err) 174 } 175 } 176 177 p2p.Send(peer.app, GetDiffLayerMsg, GetDiffLayersPacket{RequestId: 111, BlockHashes: foundDiffBlockHashes}) 178 if err := p2p.ExpectMsg(peer.app, FullDiffLayerMsg, FullDiffLayersPacket{ 179 111, 180 foundDiffRlps, 181 }); err != nil { 182 t.Errorf("test: diff layer mismatch: %v", err) 183 } 184 185 p2p.Send(peer.app, GetDiffLayerMsg, GetDiffLayersPacket{RequestId: 111, BlockHashes: missDiffBlockHashes}) 186 if err := p2p.ExpectMsg(peer.app, FullDiffLayerMsg, FullDiffLayersPacket{ 187 111, 188 nil, 189 }); err != nil { 190 t.Errorf("test: diff layer mismatch: %v", err) 191 } 192 }