handler_test.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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. package diff
  17. import (
  18. "math/big"
  19. "math/rand"
  20. "testing"
  21. "github.com/ethereum/go-ethereum/common"
  22. "github.com/ethereum/go-ethereum/consensus/ethash"
  23. "github.com/ethereum/go-ethereum/core"
  24. "github.com/ethereum/go-ethereum/core/rawdb"
  25. "github.com/ethereum/go-ethereum/core/types"
  26. "github.com/ethereum/go-ethereum/core/vm"
  27. "github.com/ethereum/go-ethereum/crypto"
  28. "github.com/ethereum/go-ethereum/ethdb"
  29. "github.com/ethereum/go-ethereum/p2p"
  30. "github.com/ethereum/go-ethereum/p2p/enode"
  31. "github.com/ethereum/go-ethereum/params"
  32. "github.com/ethereum/go-ethereum/rlp"
  33. )
  34. var (
  35. // testKey is a private key to use for funding a tester account.
  36. testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  37. // testAddr is the Ethereum address of the tester account.
  38. testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
  39. )
  40. // testBackend is a mock implementation of the live Ethereum message handler. Its
  41. // purpose is to allow testing the request/reply workflows and wire serialization
  42. // in the `eth` protocol without actually doing any data processing.
  43. type testBackend struct {
  44. db ethdb.Database
  45. chain *core.BlockChain
  46. txpool *core.TxPool
  47. }
  48. // newTestBackend creates an empty chain and wraps it into a mock backend.
  49. func newTestBackend(blocks int) *testBackend {
  50. return newTestBackendWithGenerator(blocks)
  51. }
  52. // newTestBackend creates a chain with a number of explicitly defined blocks and
  53. // wraps it into a mock backend.
  54. func newTestBackendWithGenerator(blocks int) *testBackend {
  55. signer := types.HomesteadSigner{}
  56. // Create a database pre-initialize with a genesis block
  57. db := rawdb.NewMemoryDatabase()
  58. (&core.Genesis{
  59. Config: params.TestChainConfig,
  60. Alloc: core.GenesisAlloc{testAddr: {Balance: big.NewInt(100000000000000000)}},
  61. }).MustCommit(db)
  62. chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
  63. generator := func(i int, block *core.BlockGen) {
  64. // The chain maker doesn't have access to a chain, so the difficulty will be
  65. // lets unset (nil). Set it here to the correct value.
  66. block.SetCoinbase(testAddr)
  67. // We want to simulate an empty middle block, having the same state as the
  68. // first one. The last is needs a state change again to force a reorg.
  69. tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), common.Address{0x01}, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testKey)
  70. if err != nil {
  71. panic(err)
  72. }
  73. block.AddTxWithChain(chain, tx)
  74. }
  75. bs, _ := core.GenerateChain(params.TestChainConfig, chain.Genesis(), ethash.NewFaker(), db, blocks, generator)
  76. if _, err := chain.InsertChain(bs); err != nil {
  77. panic(err)
  78. }
  79. txconfig := core.DefaultTxPoolConfig
  80. txconfig.Journal = "" // Don't litter the disk with test journals
  81. return &testBackend{
  82. db: db,
  83. chain: chain,
  84. txpool: core.NewTxPool(txconfig, params.TestChainConfig, chain),
  85. }
  86. }
  87. // close tears down the transaction pool and chain behind the mock backend.
  88. func (b *testBackend) close() {
  89. b.txpool.Stop()
  90. b.chain.Stop()
  91. }
  92. func (b *testBackend) Chain() *core.BlockChain { return b.chain }
  93. func (b *testBackend) RunPeer(peer *Peer, handler Handler) error {
  94. // Normally the backend would do peer mainentance and handshakes. All that
  95. // is omitted and we will just give control back to the handler.
  96. return handler(peer)
  97. }
  98. func (b *testBackend) PeerInfo(enode.ID) interface{} { panic("not implemented") }
  99. func (b *testBackend) Handle(*Peer, Packet) error {
  100. panic("data processing tests should be done in the handler package")
  101. }
  102. func TestGetDiffLayers(t *testing.T) { testGetDiffLayers(t, Diff1) }
  103. func testGetDiffLayers(t *testing.T, protocol uint) {
  104. t.Parallel()
  105. blockNum := 2048
  106. backend := newTestBackend(blockNum)
  107. defer backend.close()
  108. peer, _ := newTestPeer("peer", protocol, backend)
  109. defer peer.close()
  110. foundDiffBlockHashes := make([]common.Hash, 0)
  111. foundDiffPackets := make([]FullDiffLayersPacket, 0)
  112. foundDiffRlps := make([]rlp.RawValue, 0)
  113. missDiffBlockHashes := make([]common.Hash, 0)
  114. missDiffPackets := make([]FullDiffLayersPacket, 0)
  115. for i := 0; i < 100; i++ {
  116. number := uint64(rand.Int63n(1024))
  117. if number == 0 {
  118. continue
  119. }
  120. foundHash := backend.chain.GetCanonicalHash(number + 1024)
  121. missHash := backend.chain.GetCanonicalHash(number)
  122. foundRlp := backend.chain.GetDiffLayerRLP(foundHash)
  123. if len(foundHash) == 0 {
  124. t.Fatalf("Faild to fond rlp encoded diff layer %v", foundHash)
  125. }
  126. foundDiffPackets = append(foundDiffPackets, FullDiffLayersPacket{
  127. RequestId: uint64(i),
  128. DiffLayersPacket: []rlp.RawValue{foundRlp},
  129. })
  130. foundDiffRlps = append(foundDiffRlps, foundRlp)
  131. missDiffPackets = append(missDiffPackets, FullDiffLayersPacket{
  132. RequestId: uint64(i),
  133. DiffLayersPacket: []rlp.RawValue{},
  134. })
  135. missDiffBlockHashes = append(missDiffBlockHashes, missHash)
  136. foundDiffBlockHashes = append(foundDiffBlockHashes, foundHash)
  137. }
  138. for idx, blockHash := range foundDiffBlockHashes {
  139. p2p.Send(peer.app, GetDiffLayerMsg, GetDiffLayersPacket{RequestId: uint64(idx), BlockHashes: []common.Hash{blockHash}})
  140. if err := p2p.ExpectMsg(peer.app, FullDiffLayerMsg, foundDiffPackets[idx]); err != nil {
  141. t.Errorf("test %d: diff layer mismatch: %v", idx, err)
  142. }
  143. }
  144. for idx, blockHash := range missDiffBlockHashes {
  145. p2p.Send(peer.app, GetDiffLayerMsg, GetDiffLayersPacket{RequestId: uint64(idx), BlockHashes: []common.Hash{blockHash}})
  146. if err := p2p.ExpectMsg(peer.app, FullDiffLayerMsg, missDiffPackets[idx]); err != nil {
  147. t.Errorf("test %d: diff layer mismatch: %v", idx, err)
  148. }
  149. }
  150. p2p.Send(peer.app, GetDiffLayerMsg, GetDiffLayersPacket{RequestId: 111, BlockHashes: foundDiffBlockHashes})
  151. if err := p2p.ExpectMsg(peer.app, FullDiffLayerMsg, FullDiffLayersPacket{
  152. 111,
  153. foundDiffRlps,
  154. }); err != nil {
  155. t.Errorf("test: diff layer mismatch: %v", err)
  156. }
  157. p2p.Send(peer.app, GetDiffLayerMsg, GetDiffLayersPacket{RequestId: 111, BlockHashes: missDiffBlockHashes})
  158. if err := p2p.ExpectMsg(peer.app, FullDiffLayerMsg, FullDiffLayersPacket{
  159. 111,
  160. nil,
  161. }); err != nil {
  162. t.Errorf("test: diff layer mismatch: %v", err)
  163. }
  164. }