github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/cmd/devp2p/internal/ethtest/suite.go (about)

     1  // Copyright 2020 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 ethtest
    18  
    19  import (
    20  	"time"
    21  
    22  	"github.com/ethereum/go-ethereum/common"
    23  	"github.com/ethereum/go-ethereum/eth/protocols/eth"
    24  	"github.com/ethereum/go-ethereum/internal/utesting"
    25  	"github.com/ethereum/go-ethereum/p2p/enode"
    26  )
    27  
    28  // Suite represents a structure used to test a node's conformance
    29  // to the eth protocol.
    30  type Suite struct {
    31  	Dest *enode.Node
    32  
    33  	chain     *Chain
    34  	fullChain *Chain
    35  }
    36  
    37  // NewSuite creates and returns a new eth-test suite that can
    38  // be used to test the given node against the given blockchain
    39  // data.
    40  func NewSuite(dest *enode.Node, chainfile string, genesisfile string) (*Suite, error) {
    41  	chain, err := loadChain(chainfile, genesisfile)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	return &Suite{
    46  		Dest:      dest,
    47  		chain:     chain.Shorten(1000),
    48  		fullChain: chain,
    49  	}, nil
    50  }
    51  
    52  func (s *Suite) AllEthTests() []utesting.Test {
    53  	return []utesting.Test{
    54  		// status
    55  		{Name: "TestStatus65", Fn: s.TestStatus65},
    56  		{Name: "TestStatus66", Fn: s.TestStatus66},
    57  		// get block headers
    58  		{Name: "TestGetBlockHeaders65", Fn: s.TestGetBlockHeaders65},
    59  		{Name: "TestGetBlockHeaders66", Fn: s.TestGetBlockHeaders66},
    60  		{Name: "TestSimultaneousRequests66", Fn: s.TestSimultaneousRequests66},
    61  		{Name: "TestSameRequestID66", Fn: s.TestSameRequestID66},
    62  		{Name: "TestZeroRequestID66", Fn: s.TestZeroRequestID66},
    63  		// get block bodies
    64  		{Name: "TestGetBlockBodies65", Fn: s.TestGetBlockBodies65},
    65  		{Name: "TestGetBlockBodies66", Fn: s.TestGetBlockBodies66},
    66  		// broadcast
    67  		{Name: "TestBroadcast65", Fn: s.TestBroadcast65},
    68  		{Name: "TestBroadcast66", Fn: s.TestBroadcast66},
    69  		{Name: "TestLargeAnnounce65", Fn: s.TestLargeAnnounce65},
    70  		{Name: "TestLargeAnnounce66", Fn: s.TestLargeAnnounce66},
    71  		{Name: "TestOldAnnounce65", Fn: s.TestOldAnnounce65},
    72  		{Name: "TestOldAnnounce66", Fn: s.TestOldAnnounce66},
    73  		{Name: "TestBlockHashAnnounce65", Fn: s.TestBlockHashAnnounce65},
    74  		{Name: "TestBlockHashAnnounce66", Fn: s.TestBlockHashAnnounce66},
    75  		// malicious handshakes + status
    76  		{Name: "TestMaliciousHandshake65", Fn: s.TestMaliciousHandshake65},
    77  		{Name: "TestMaliciousStatus65", Fn: s.TestMaliciousStatus65},
    78  		{Name: "TestMaliciousHandshake66", Fn: s.TestMaliciousHandshake66},
    79  		{Name: "TestMaliciousStatus66", Fn: s.TestMaliciousStatus66},
    80  		// test transactions
    81  		{Name: "TestTransaction65", Fn: s.TestTransaction65},
    82  		{Name: "TestTransaction66", Fn: s.TestTransaction66},
    83  		{Name: "TestMaliciousTx65", Fn: s.TestMaliciousTx65},
    84  		{Name: "TestMaliciousTx66", Fn: s.TestMaliciousTx66},
    85  		{Name: "TestLargeTxRequest66", Fn: s.TestLargeTxRequest66},
    86  		{Name: "TestNewPooledTxs66", Fn: s.TestNewPooledTxs66},
    87  	}
    88  }
    89  
    90  func (s *Suite) EthTests() []utesting.Test {
    91  	return []utesting.Test{
    92  		{Name: "TestStatus65", Fn: s.TestStatus65},
    93  		{Name: "TestGetBlockHeaders65", Fn: s.TestGetBlockHeaders65},
    94  		{Name: "TestGetBlockBodies65", Fn: s.TestGetBlockBodies65},
    95  		{Name: "TestBroadcast65", Fn: s.TestBroadcast65},
    96  		{Name: "TestLargeAnnounce65", Fn: s.TestLargeAnnounce65},
    97  		{Name: "TestOldAnnounce65", Fn: s.TestOldAnnounce65},
    98  		{Name: "TestBlockHashAnnounce65", Fn: s.TestBlockHashAnnounce65},
    99  		{Name: "TestMaliciousHandshake65", Fn: s.TestMaliciousHandshake65},
   100  		{Name: "TestMaliciousStatus65", Fn: s.TestMaliciousStatus65},
   101  		{Name: "TestTransaction65", Fn: s.TestTransaction65},
   102  		{Name: "TestMaliciousTx65", Fn: s.TestMaliciousTx65},
   103  	}
   104  }
   105  
   106  func (s *Suite) Eth66Tests() []utesting.Test {
   107  	return []utesting.Test{
   108  		// only proceed with eth66 test suite if node supports eth 66 protocol
   109  		{Name: "TestStatus66", Fn: s.TestStatus66},
   110  		{Name: "TestGetBlockHeaders66", Fn: s.TestGetBlockHeaders66},
   111  		{Name: "TestSimultaneousRequests66", Fn: s.TestSimultaneousRequests66},
   112  		{Name: "TestSameRequestID66", Fn: s.TestSameRequestID66},
   113  		{Name: "TestZeroRequestID66", Fn: s.TestZeroRequestID66},
   114  		{Name: "TestGetBlockBodies66", Fn: s.TestGetBlockBodies66},
   115  		{Name: "TestBroadcast66", Fn: s.TestBroadcast66},
   116  		{Name: "TestLargeAnnounce66", Fn: s.TestLargeAnnounce66},
   117  		{Name: "TestOldAnnounce66", Fn: s.TestOldAnnounce66},
   118  		{Name: "TestBlockHashAnnounce66", Fn: s.TestBlockHashAnnounce66},
   119  		{Name: "TestMaliciousHandshake66", Fn: s.TestMaliciousHandshake66},
   120  		{Name: "TestMaliciousStatus66", Fn: s.TestMaliciousStatus66},
   121  		{Name: "TestTransaction66", Fn: s.TestTransaction66},
   122  		{Name: "TestMaliciousTx66", Fn: s.TestMaliciousTx66},
   123  		{Name: "TestLargeTxRequest66", Fn: s.TestLargeTxRequest66},
   124  		{Name: "TestNewPooledTxs66", Fn: s.TestNewPooledTxs66},
   125  	}
   126  }
   127  
   128  func (s *Suite) SnapTests() []utesting.Test {
   129  	return []utesting.Test{
   130  		{Name: "TestSnapStatus", Fn: s.TestSnapStatus},
   131  		{Name: "TestSnapAccountRange", Fn: s.TestSnapGetAccountRange},
   132  		{Name: "TestSnapGetByteCodes", Fn: s.TestSnapGetByteCodes},
   133  		{Name: "TestSnapGetTrieNodes", Fn: s.TestSnapTrieNodes},
   134  		{Name: "TestSnapGetStorageRanges", Fn: s.TestSnapGetStorageRanges},
   135  	}
   136  }
   137  
   138  var (
   139  	eth66 = true  // indicates whether suite should negotiate eth66 connection
   140  	eth65 = false // indicates whether suite should negotiate eth65 connection or below.
   141  )
   142  
   143  // TestStatus65 attempts to connect to the given node and exchange
   144  // a status message with it.
   145  func (s *Suite) TestStatus65(t *utesting.T) {
   146  	conn, err := s.dial()
   147  	if err != nil {
   148  		t.Fatalf("dial failed: %v", err)
   149  	}
   150  	defer conn.Close()
   151  	if err := conn.peer(s.chain, nil); err != nil {
   152  		t.Fatalf("peering failed: %v", err)
   153  	}
   154  }
   155  
   156  // TestStatus66 attempts to connect to the given node and exchange
   157  // a status message with it on the eth66 protocol.
   158  func (s *Suite) TestStatus66(t *utesting.T) {
   159  	conn, err := s.dial66()
   160  	if err != nil {
   161  		t.Fatalf("dial failed: %v", err)
   162  	}
   163  	defer conn.Close()
   164  	if err := conn.peer(s.chain, nil); err != nil {
   165  		t.Fatalf("peering failed: %v", err)
   166  	}
   167  }
   168  
   169  // TestGetBlockHeaders65 tests whether the given node can respond to
   170  // a `GetBlockHeaders` request accurately.
   171  func (s *Suite) TestGetBlockHeaders65(t *utesting.T) {
   172  	conn, err := s.dial()
   173  	if err != nil {
   174  		t.Fatalf("dial failed: %v", err)
   175  	}
   176  	defer conn.Close()
   177  	if err := conn.peer(s.chain, nil); err != nil {
   178  		t.Fatalf("handshake(s) failed: %v", err)
   179  	}
   180  	// write request
   181  	req := &GetBlockHeaders{
   182  		Origin: eth.HashOrNumber{
   183  			Hash: s.chain.blocks[1].Hash(),
   184  		},
   185  		Amount:  2,
   186  		Skip:    1,
   187  		Reverse: false,
   188  	}
   189  	headers, err := conn.headersRequest(req, s.chain, eth65, 0)
   190  	if err != nil {
   191  		t.Fatalf("GetBlockHeaders request failed: %v", err)
   192  	}
   193  	// check for correct headers
   194  	expected, err := s.chain.GetHeaders(*req)
   195  	if err != nil {
   196  		t.Fatalf("failed to get headers for given request: %v", err)
   197  	}
   198  	if !headersMatch(expected, headers) {
   199  		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers)
   200  	}
   201  }
   202  
   203  // TestGetBlockHeaders66 tests whether the given node can respond to
   204  // an eth66 `GetBlockHeaders` request and that the response is accurate.
   205  func (s *Suite) TestGetBlockHeaders66(t *utesting.T) {
   206  	conn, err := s.dial66()
   207  	if err != nil {
   208  		t.Fatalf("dial failed: %v", err)
   209  	}
   210  	defer conn.Close()
   211  	if err = conn.peer(s.chain, nil); err != nil {
   212  		t.Fatalf("peering failed: %v", err)
   213  	}
   214  	// write request
   215  	req := &GetBlockHeaders{
   216  		Origin: eth.HashOrNumber{
   217  			Hash: s.chain.blocks[1].Hash(),
   218  		},
   219  		Amount:  2,
   220  		Skip:    1,
   221  		Reverse: false,
   222  	}
   223  	headers, err := conn.headersRequest(req, s.chain, eth66, 33)
   224  	if err != nil {
   225  		t.Fatalf("could not get block headers: %v", err)
   226  	}
   227  	// check for correct headers
   228  	expected, err := s.chain.GetHeaders(*req)
   229  	if err != nil {
   230  		t.Fatalf("failed to get headers for given request: %v", err)
   231  	}
   232  	if !headersMatch(expected, headers) {
   233  		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers)
   234  	}
   235  }
   236  
   237  // TestSimultaneousRequests66 sends two simultaneous `GetBlockHeader` requests from
   238  // the same connection with different request IDs and checks to make sure the node
   239  // responds with the correct headers per request.
   240  func (s *Suite) TestSimultaneousRequests66(t *utesting.T) {
   241  	// create a connection
   242  	conn, err := s.dial66()
   243  	if err != nil {
   244  		t.Fatalf("dial failed: %v", err)
   245  	}
   246  	defer conn.Close()
   247  	if err := conn.peer(s.chain, nil); err != nil {
   248  		t.Fatalf("peering failed: %v", err)
   249  	}
   250  	// create two requests
   251  	req1 := &eth.GetBlockHeadersPacket66{
   252  		RequestId: uint64(111),
   253  		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
   254  			Origin: eth.HashOrNumber{
   255  				Hash: s.chain.blocks[1].Hash(),
   256  			},
   257  			Amount:  2,
   258  			Skip:    1,
   259  			Reverse: false,
   260  		},
   261  	}
   262  	req2 := &eth.GetBlockHeadersPacket66{
   263  		RequestId: uint64(222),
   264  		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
   265  			Origin: eth.HashOrNumber{
   266  				Hash: s.chain.blocks[1].Hash(),
   267  			},
   268  			Amount:  4,
   269  			Skip:    1,
   270  			Reverse: false,
   271  		},
   272  	}
   273  	// write the first request
   274  	if err := conn.Write66(req1, GetBlockHeaders{}.Code()); err != nil {
   275  		t.Fatalf("failed to write to connection: %v", err)
   276  	}
   277  	// write the second request
   278  	if err := conn.Write66(req2, GetBlockHeaders{}.Code()); err != nil {
   279  		t.Fatalf("failed to write to connection: %v", err)
   280  	}
   281  	// wait for responses
   282  	msg := conn.waitForResponse(s.chain, timeout, req1.RequestId)
   283  	headers1, ok := msg.(BlockHeaders)
   284  	if !ok {
   285  		t.Fatalf("unexpected %s", pretty.Sdump(msg))
   286  	}
   287  	msg = conn.waitForResponse(s.chain, timeout, req2.RequestId)
   288  	headers2, ok := msg.(BlockHeaders)
   289  	if !ok {
   290  		t.Fatalf("unexpected %s", pretty.Sdump(msg))
   291  	}
   292  	// check received headers for accuracy
   293  	expected1, err := s.chain.GetHeaders(GetBlockHeaders(*req1.GetBlockHeadersPacket))
   294  	if err != nil {
   295  		t.Fatalf("failed to get expected headers for request 1: %v", err)
   296  	}
   297  	expected2, err := s.chain.GetHeaders(GetBlockHeaders(*req2.GetBlockHeadersPacket))
   298  	if err != nil {
   299  		t.Fatalf("failed to get expected headers for request 2: %v", err)
   300  	}
   301  	if !headersMatch(expected1, headers1) {
   302  		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected1, headers1)
   303  	}
   304  	if !headersMatch(expected2, headers2) {
   305  		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected2, headers2)
   306  	}
   307  }
   308  
   309  // TestSameRequestID66 sends two requests with the same request ID to a
   310  // single node.
   311  func (s *Suite) TestSameRequestID66(t *utesting.T) {
   312  	conn, err := s.dial66()
   313  	if err != nil {
   314  		t.Fatalf("dial failed: %v", err)
   315  	}
   316  	defer conn.Close()
   317  	if err := conn.peer(s.chain, nil); err != nil {
   318  		t.Fatalf("peering failed: %v", err)
   319  	}
   320  	// create requests
   321  	reqID := uint64(1234)
   322  	request1 := &eth.GetBlockHeadersPacket66{
   323  		RequestId: reqID,
   324  		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
   325  			Origin: eth.HashOrNumber{
   326  				Number: 1,
   327  			},
   328  			Amount: 2,
   329  		},
   330  	}
   331  	request2 := &eth.GetBlockHeadersPacket66{
   332  		RequestId: reqID,
   333  		GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
   334  			Origin: eth.HashOrNumber{
   335  				Number: 33,
   336  			},
   337  			Amount: 2,
   338  		},
   339  	}
   340  	// write the requests
   341  	if err = conn.Write66(request1, GetBlockHeaders{}.Code()); err != nil {
   342  		t.Fatalf("failed to write to connection: %v", err)
   343  	}
   344  	if err = conn.Write66(request2, GetBlockHeaders{}.Code()); err != nil {
   345  		t.Fatalf("failed to write to connection: %v", err)
   346  	}
   347  	// wait for responses
   348  	msg := conn.waitForResponse(s.chain, timeout, reqID)
   349  	headers1, ok := msg.(BlockHeaders)
   350  	if !ok {
   351  		t.Fatalf("unexpected %s", pretty.Sdump(msg))
   352  	}
   353  	msg = conn.waitForResponse(s.chain, timeout, reqID)
   354  	headers2, ok := msg.(BlockHeaders)
   355  	if !ok {
   356  		t.Fatalf("unexpected %s", pretty.Sdump(msg))
   357  	}
   358  	// check if headers match
   359  	expected1, err := s.chain.GetHeaders(GetBlockHeaders(*request1.GetBlockHeadersPacket))
   360  	if err != nil {
   361  		t.Fatalf("failed to get expected block headers: %v", err)
   362  	}
   363  	expected2, err := s.chain.GetHeaders(GetBlockHeaders(*request2.GetBlockHeadersPacket))
   364  	if err != nil {
   365  		t.Fatalf("failed to get expected block headers: %v", err)
   366  	}
   367  	if !headersMatch(expected1, headers1) {
   368  		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected1, headers1)
   369  	}
   370  	if !headersMatch(expected2, headers2) {
   371  		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected2, headers2)
   372  	}
   373  }
   374  
   375  // TestZeroRequestID_66 checks that a message with a request ID of zero is still handled
   376  // by the node.
   377  func (s *Suite) TestZeroRequestID66(t *utesting.T) {
   378  	conn, err := s.dial66()
   379  	if err != nil {
   380  		t.Fatalf("dial failed: %v", err)
   381  	}
   382  	defer conn.Close()
   383  	if err := conn.peer(s.chain, nil); err != nil {
   384  		t.Fatalf("peering failed: %v", err)
   385  	}
   386  	req := &GetBlockHeaders{
   387  		Origin: eth.HashOrNumber{
   388  			Number: 0,
   389  		},
   390  		Amount: 2,
   391  	}
   392  	headers, err := conn.headersRequest(req, s.chain, eth66, 0)
   393  	if err != nil {
   394  		t.Fatalf("failed to get block headers: %v", err)
   395  	}
   396  	expected, err := s.chain.GetHeaders(*req)
   397  	if err != nil {
   398  		t.Fatalf("failed to get expected block headers: %v", err)
   399  	}
   400  	if !headersMatch(expected, headers) {
   401  		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers)
   402  	}
   403  }
   404  
   405  // TestGetBlockBodies65 tests whether the given node can respond to
   406  // a `GetBlockBodies` request and that the response is accurate.
   407  func (s *Suite) TestGetBlockBodies65(t *utesting.T) {
   408  	conn, err := s.dial()
   409  	if err != nil {
   410  		t.Fatalf("dial failed: %v", err)
   411  	}
   412  	defer conn.Close()
   413  	if err := conn.peer(s.chain, nil); err != nil {
   414  		t.Fatalf("peering failed: %v", err)
   415  	}
   416  	// create block bodies request
   417  	req := &GetBlockBodies{
   418  		s.chain.blocks[54].Hash(),
   419  		s.chain.blocks[75].Hash(),
   420  	}
   421  	if err := conn.Write(req); err != nil {
   422  		t.Fatalf("could not write to connection: %v", err)
   423  	}
   424  	// wait for response
   425  	switch msg := conn.readAndServe(s.chain, timeout).(type) {
   426  	case *BlockBodies:
   427  		t.Logf("received %d block bodies", len(*msg))
   428  		if len(*msg) != len(*req) {
   429  			t.Fatalf("wrong bodies in response: expected %d bodies, "+
   430  				"got %d", len(*req), len(*msg))
   431  		}
   432  	default:
   433  		t.Fatalf("unexpected: %s", pretty.Sdump(msg))
   434  	}
   435  }
   436  
   437  // TestGetBlockBodies66 tests whether the given node can respond to
   438  // a `GetBlockBodies` request and that the response is accurate over
   439  // the eth66 protocol.
   440  func (s *Suite) TestGetBlockBodies66(t *utesting.T) {
   441  	conn, err := s.dial66()
   442  	if err != nil {
   443  		t.Fatalf("dial failed: %v", err)
   444  	}
   445  	defer conn.Close()
   446  	if err := conn.peer(s.chain, nil); err != nil {
   447  		t.Fatalf("peering failed: %v", err)
   448  	}
   449  	// create block bodies request
   450  	req := &eth.GetBlockBodiesPacket66{
   451  		RequestId: uint64(55),
   452  		GetBlockBodiesPacket: eth.GetBlockBodiesPacket{
   453  			s.chain.blocks[54].Hash(),
   454  			s.chain.blocks[75].Hash(),
   455  		},
   456  	}
   457  	if err := conn.Write66(req, GetBlockBodies{}.Code()); err != nil {
   458  		t.Fatalf("could not write to connection: %v", err)
   459  	}
   460  	// wait for block bodies response
   461  	msg := conn.waitForResponse(s.chain, timeout, req.RequestId)
   462  	blockBodies, ok := msg.(BlockBodies)
   463  	if !ok {
   464  		t.Fatalf("unexpected: %s", pretty.Sdump(msg))
   465  	}
   466  	t.Logf("received %d block bodies", len(blockBodies))
   467  	if len(blockBodies) != len(req.GetBlockBodiesPacket) {
   468  		t.Fatalf("wrong bodies in response: expected %d bodies, "+
   469  			"got %d", len(req.GetBlockBodiesPacket), len(blockBodies))
   470  	}
   471  }
   472  
   473  // TestBroadcast65 tests whether a block announcement is correctly
   474  // propagated to the given node's peer(s).
   475  func (s *Suite) TestBroadcast65(t *utesting.T) {
   476  	if err := s.sendNextBlock(eth65); err != nil {
   477  		t.Fatalf("block broadcast failed: %v", err)
   478  	}
   479  }
   480  
   481  // TestBroadcast66 tests whether a block announcement is correctly
   482  // propagated to the given node's peer(s) on the eth66 protocol.
   483  func (s *Suite) TestBroadcast66(t *utesting.T) {
   484  	if err := s.sendNextBlock(eth66); err != nil {
   485  		t.Fatalf("block broadcast failed: %v", err)
   486  	}
   487  }
   488  
   489  // TestLargeAnnounce65 tests the announcement mechanism with a large block.
   490  func (s *Suite) TestLargeAnnounce65(t *utesting.T) {
   491  	nextBlock := len(s.chain.blocks)
   492  	blocks := []*NewBlock{
   493  		{
   494  			Block: largeBlock(),
   495  			TD:    s.fullChain.TotalDifficultyAt(nextBlock),
   496  		},
   497  		{
   498  			Block: s.fullChain.blocks[nextBlock],
   499  			TD:    largeNumber(2),
   500  		},
   501  		{
   502  			Block: largeBlock(),
   503  			TD:    largeNumber(2),
   504  		},
   505  	}
   506  
   507  	for i, blockAnnouncement := range blocks {
   508  		t.Logf("Testing malicious announcement: %v\n", i)
   509  		conn, err := s.dial()
   510  		if err != nil {
   511  			t.Fatalf("dial failed: %v", err)
   512  		}
   513  		if err = conn.peer(s.chain, nil); err != nil {
   514  			t.Fatalf("peering failed: %v", err)
   515  		}
   516  		if err = conn.Write(blockAnnouncement); err != nil {
   517  			t.Fatalf("could not write to connection: %v", err)
   518  		}
   519  		// Invalid announcement, check that peer disconnected
   520  		switch msg := conn.readAndServe(s.chain, time.Second*8).(type) {
   521  		case *Disconnect:
   522  		case *Error:
   523  			break
   524  		default:
   525  			t.Fatalf("unexpected: %s wanted disconnect", pretty.Sdump(msg))
   526  		}
   527  		conn.Close()
   528  	}
   529  	// Test the last block as a valid block
   530  	if err := s.sendNextBlock(eth65); err != nil {
   531  		t.Fatalf("failed to broadcast next block: %v", err)
   532  	}
   533  }
   534  
   535  // TestLargeAnnounce66 tests the announcement mechanism with a large
   536  // block over the eth66 protocol.
   537  func (s *Suite) TestLargeAnnounce66(t *utesting.T) {
   538  	nextBlock := len(s.chain.blocks)
   539  	blocks := []*NewBlock{
   540  		{
   541  			Block: largeBlock(),
   542  			TD:    s.fullChain.TotalDifficultyAt(nextBlock),
   543  		},
   544  		{
   545  			Block: s.fullChain.blocks[nextBlock],
   546  			TD:    largeNumber(2),
   547  		},
   548  		{
   549  			Block: largeBlock(),
   550  			TD:    largeNumber(2),
   551  		},
   552  	}
   553  
   554  	for i, blockAnnouncement := range blocks[0:3] {
   555  		t.Logf("Testing malicious announcement: %v\n", i)
   556  		conn, err := s.dial66()
   557  		if err != nil {
   558  			t.Fatalf("dial failed: %v", err)
   559  		}
   560  		if err := conn.peer(s.chain, nil); err != nil {
   561  			t.Fatalf("peering failed: %v", err)
   562  		}
   563  		if err := conn.Write(blockAnnouncement); err != nil {
   564  			t.Fatalf("could not write to connection: %v", err)
   565  		}
   566  		// Invalid announcement, check that peer disconnected
   567  		switch msg := conn.readAndServe(s.chain, time.Second*8).(type) {
   568  		case *Disconnect:
   569  		case *Error:
   570  			break
   571  		default:
   572  			t.Fatalf("unexpected: %s wanted disconnect", pretty.Sdump(msg))
   573  		}
   574  		conn.Close()
   575  	}
   576  	// Test the last block as a valid block
   577  	if err := s.sendNextBlock(eth66); err != nil {
   578  		t.Fatalf("failed to broadcast next block: %v", err)
   579  	}
   580  }
   581  
   582  // TestOldAnnounce65 tests the announcement mechanism with an old block.
   583  func (s *Suite) TestOldAnnounce65(t *utesting.T) {
   584  	if err := s.oldAnnounce(eth65); err != nil {
   585  		t.Fatal(err)
   586  	}
   587  }
   588  
   589  // TestOldAnnounce66 tests the announcement mechanism with an old block,
   590  // over the eth66 protocol.
   591  func (s *Suite) TestOldAnnounce66(t *utesting.T) {
   592  	if err := s.oldAnnounce(eth66); err != nil {
   593  		t.Fatal(err)
   594  	}
   595  }
   596  
   597  // TestBlockHashAnnounce65 sends a new block hash announcement and expects
   598  // the node to perform a `GetBlockHeaders` request.
   599  func (s *Suite) TestBlockHashAnnounce65(t *utesting.T) {
   600  	if err := s.hashAnnounce(eth65); err != nil {
   601  		t.Fatalf("block hash announcement failed: %v", err)
   602  	}
   603  }
   604  
   605  // TestBlockHashAnnounce66 sends a new block hash announcement and expects
   606  // the node to perform a `GetBlockHeaders` request.
   607  func (s *Suite) TestBlockHashAnnounce66(t *utesting.T) {
   608  	if err := s.hashAnnounce(eth66); err != nil {
   609  		t.Fatalf("block hash announcement failed: %v", err)
   610  	}
   611  }
   612  
   613  // TestMaliciousHandshake65 tries to send malicious data during the handshake.
   614  func (s *Suite) TestMaliciousHandshake65(t *utesting.T) {
   615  	if err := s.maliciousHandshakes(t, eth65); err != nil {
   616  		t.Fatal(err)
   617  	}
   618  }
   619  
   620  // TestMaliciousHandshake66 tries to send malicious data during the handshake.
   621  func (s *Suite) TestMaliciousHandshake66(t *utesting.T) {
   622  	if err := s.maliciousHandshakes(t, eth66); err != nil {
   623  		t.Fatal(err)
   624  	}
   625  }
   626  
   627  // TestMaliciousStatus65 sends a status package with a large total difficulty.
   628  func (s *Suite) TestMaliciousStatus65(t *utesting.T) {
   629  	conn, err := s.dial()
   630  	if err != nil {
   631  		t.Fatalf("dial failed: %v", err)
   632  	}
   633  	defer conn.Close()
   634  
   635  	if err := s.maliciousStatus(conn); err != nil {
   636  		t.Fatal(err)
   637  	}
   638  }
   639  
   640  // TestMaliciousStatus66 sends a status package with a large total
   641  // difficulty over the eth66 protocol.
   642  func (s *Suite) TestMaliciousStatus66(t *utesting.T) {
   643  	conn, err := s.dial66()
   644  	if err != nil {
   645  		t.Fatalf("dial failed: %v", err)
   646  	}
   647  	defer conn.Close()
   648  
   649  	if err := s.maliciousStatus(conn); err != nil {
   650  		t.Fatal(err)
   651  	}
   652  }
   653  
   654  // TestTransaction65 sends a valid transaction to the node and
   655  // checks if the transaction gets propagated.
   656  func (s *Suite) TestTransaction65(t *utesting.T) {
   657  	if err := s.sendSuccessfulTxs(t, eth65); err != nil {
   658  		t.Fatal(err)
   659  	}
   660  }
   661  
   662  // TestTransaction66 sends a valid transaction to the node and
   663  // checks if the transaction gets propagated.
   664  func (s *Suite) TestTransaction66(t *utesting.T) {
   665  	if err := s.sendSuccessfulTxs(t, eth66); err != nil {
   666  		t.Fatal(err)
   667  	}
   668  }
   669  
   670  // TestMaliciousTx65 sends several invalid transactions and tests whether
   671  // the node will propagate them.
   672  func (s *Suite) TestMaliciousTx65(t *utesting.T) {
   673  	if err := s.sendMaliciousTxs(t, eth65); err != nil {
   674  		t.Fatal(err)
   675  	}
   676  }
   677  
   678  // TestMaliciousTx66 sends several invalid transactions and tests whether
   679  // the node will propagate them.
   680  func (s *Suite) TestMaliciousTx66(t *utesting.T) {
   681  	if err := s.sendMaliciousTxs(t, eth66); err != nil {
   682  		t.Fatal(err)
   683  	}
   684  }
   685  
   686  // TestLargeTxRequest66 tests whether a node can fulfill a large GetPooledTransactions
   687  // request.
   688  func (s *Suite) TestLargeTxRequest66(t *utesting.T) {
   689  	// send the next block to ensure the node is no longer syncing and
   690  	// is able to accept txs
   691  	if err := s.sendNextBlock(eth66); err != nil {
   692  		t.Fatalf("failed to send next block: %v", err)
   693  	}
   694  	// send 2000 transactions to the node
   695  	hashMap, txs, err := generateTxs(s, 2000)
   696  	if err != nil {
   697  		t.Fatalf("failed to generate transactions: %v", err)
   698  	}
   699  	if err = sendMultipleSuccessfulTxs(t, s, txs); err != nil {
   700  		t.Fatalf("failed to send multiple txs: %v", err)
   701  	}
   702  	// set up connection to receive to ensure node is peered with the receiving connection
   703  	// before tx request is sent
   704  	conn, err := s.dial66()
   705  	if err != nil {
   706  		t.Fatalf("dial failed: %v", err)
   707  	}
   708  	defer conn.Close()
   709  	if err = conn.peer(s.chain, nil); err != nil {
   710  		t.Fatalf("peering failed: %v", err)
   711  	}
   712  	// create and send pooled tx request
   713  	hashes := make([]common.Hash, 0)
   714  	for _, hash := range hashMap {
   715  		hashes = append(hashes, hash)
   716  	}
   717  	getTxReq := &eth.GetPooledTransactionsPacket66{
   718  		RequestId:                   1234,
   719  		GetPooledTransactionsPacket: hashes,
   720  	}
   721  	if err = conn.Write66(getTxReq, GetPooledTransactions{}.Code()); err != nil {
   722  		t.Fatalf("could not write to conn: %v", err)
   723  	}
   724  	// check that all received transactions match those that were sent to node
   725  	switch msg := conn.waitForResponse(s.chain, timeout, getTxReq.RequestId).(type) {
   726  	case PooledTransactions:
   727  		for _, gotTx := range msg {
   728  			if _, exists := hashMap[gotTx.Hash()]; !exists {
   729  				t.Fatalf("unexpected tx received: %v", gotTx.Hash())
   730  			}
   731  		}
   732  	default:
   733  		t.Fatalf("unexpected %s", pretty.Sdump(msg))
   734  	}
   735  }
   736  
   737  // TestNewPooledTxs_66 tests whether a node will do a GetPooledTransactions
   738  // request upon receiving a NewPooledTransactionHashes announcement.
   739  func (s *Suite) TestNewPooledTxs66(t *utesting.T) {
   740  	// send the next block to ensure the node is no longer syncing and
   741  	// is able to accept txs
   742  	if err := s.sendNextBlock(eth66); err != nil {
   743  		t.Fatalf("failed to send next block: %v", err)
   744  	}
   745  
   746  	// generate 50 txs
   747  	hashMap, _, err := generateTxs(s, 50)
   748  	if err != nil {
   749  		t.Fatalf("failed to generate transactions: %v", err)
   750  	}
   751  
   752  	// create new pooled tx hashes announcement
   753  	hashes := make([]common.Hash, 0)
   754  	for _, hash := range hashMap {
   755  		hashes = append(hashes, hash)
   756  	}
   757  	announce := NewPooledTransactionHashes(hashes)
   758  
   759  	// send announcement
   760  	conn, err := s.dial66()
   761  	if err != nil {
   762  		t.Fatalf("dial failed: %v", err)
   763  	}
   764  	defer conn.Close()
   765  	if err = conn.peer(s.chain, nil); err != nil {
   766  		t.Fatalf("peering failed: %v", err)
   767  	}
   768  	if err = conn.Write(announce); err != nil {
   769  		t.Fatalf("failed to write to connection: %v", err)
   770  	}
   771  
   772  	// wait for GetPooledTxs request
   773  	for {
   774  		_, msg := conn.readAndServe66(s.chain, timeout)
   775  		switch msg := msg.(type) {
   776  		case GetPooledTransactions:
   777  			if len(msg) != len(hashes) {
   778  				t.Fatalf("unexpected number of txs requested: wanted %d, got %d", len(hashes), len(msg))
   779  			}
   780  			return
   781  		// ignore propagated txs from previous tests
   782  		case *NewPooledTransactionHashes:
   783  			continue
   784  		// ignore block announcements from previous tests
   785  		case *NewBlockHashes:
   786  			continue
   787  		case *NewBlock:
   788  			continue
   789  		default:
   790  			t.Fatalf("unexpected %s", pretty.Sdump(msg))
   791  		}
   792  	}
   793  }