| 
									
										
										
										
											2020-10-07 17:22:44 +02:00
										 |  |  | // Copyright 2020 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | package ethtest | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2020-11-04 17:36:56 +01:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2021-02-16 15:23:03 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/eth/protocols/eth" | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/internal/utesting" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/p2p/enode" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // Suite represents a structure used to test a node's conformance | 
					
						
							|  |  |  | // to the eth protocol. | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | type Suite struct { | 
					
						
							|  |  |  | 	Dest *enode.Node | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	chain     *Chain | 
					
						
							|  |  |  | 	fullChain *Chain | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewSuite creates and returns a new eth-test suite that can | 
					
						
							|  |  |  | // be used to test the given node against the given blockchain | 
					
						
							|  |  |  | // data. | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | func NewSuite(dest *enode.Node, chainfile string, genesisfile string) (*Suite, error) { | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	chain, err := loadChain(chainfile, genesisfile) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return &Suite{ | 
					
						
							|  |  |  | 		Dest:      dest, | 
					
						
							|  |  |  | 		chain:     chain.Shorten(1000), | 
					
						
							|  |  |  | 		fullChain: chain, | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 	}, nil | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 14:15:39 +00:00
										 |  |  | func (s *Suite) AllEthTests() []utesting.Test { | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	return []utesting.Test{ | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 		// status | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		{Name: "TestStatus", Fn: s.TestStatus}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestStatus66", Fn: s.TestStatus66}, | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 		// get block headers | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		{Name: "TestGetBlockHeaders", Fn: s.TestGetBlockHeaders}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestGetBlockHeaders66", Fn: s.TestGetBlockHeaders66}, | 
					
						
							|  |  |  | 		{Name: "TestSimultaneousRequests66", Fn: s.TestSimultaneousRequests66}, | 
					
						
							|  |  |  | 		{Name: "TestSameRequestID66", Fn: s.TestSameRequestID66}, | 
					
						
							|  |  |  | 		{Name: "TestZeroRequestID66", Fn: s.TestZeroRequestID66}, | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 		// get block bodies | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		{Name: "TestGetBlockBodies", Fn: s.TestGetBlockBodies}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestGetBlockBodies66", Fn: s.TestGetBlockBodies66}, | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 		// broadcast | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		{Name: "TestBroadcast", Fn: s.TestBroadcast}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestBroadcast66", Fn: s.TestBroadcast66}, | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		{Name: "TestLargeAnnounce", Fn: s.TestLargeAnnounce}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestLargeAnnounce66", Fn: s.TestLargeAnnounce66}, | 
					
						
							| 
									
										
										
										
											2021-03-20 18:50:44 +00:00
										 |  |  | 		{Name: "TestOldAnnounce", Fn: s.TestOldAnnounce}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestOldAnnounce66", Fn: s.TestOldAnnounce66}, | 
					
						
							| 
									
										
										
										
											2021-05-27 11:57:49 +02:00
										 |  |  | 		{Name: "TestBlockHashAnnounce", Fn: s.TestBlockHashAnnounce}, | 
					
						
							|  |  |  | 		{Name: "TestBlockHashAnnounce66", Fn: s.TestBlockHashAnnounce66}, | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 		// malicious handshakes + status | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		{Name: "TestMaliciousHandshake", Fn: s.TestMaliciousHandshake}, | 
					
						
							|  |  |  | 		{Name: "TestMaliciousStatus", Fn: s.TestMaliciousStatus}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestMaliciousHandshake66", Fn: s.TestMaliciousHandshake66}, | 
					
						
							|  |  |  | 		{Name: "TestMaliciousStatus66", Fn: s.TestMaliciousStatus66}, | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 		// test transactions | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		{Name: "TestTransaction", Fn: s.TestTransaction}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestTransaction66", Fn: s.TestTransaction66}, | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		{Name: "TestMaliciousTx", Fn: s.TestMaliciousTx}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestMaliciousTx66", Fn: s.TestMaliciousTx66}, | 
					
						
							|  |  |  | 		{Name: "TestLargeTxRequest66", Fn: s.TestLargeTxRequest66}, | 
					
						
							|  |  |  | 		{Name: "TestNewPooledTxs66", Fn: s.TestNewPooledTxs66}, | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 14:15:39 +00:00
										 |  |  | func (s *Suite) EthTests() []utesting.Test { | 
					
						
							|  |  |  | 	return []utesting.Test{ | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		{Name: "TestStatus", Fn: s.TestStatus}, | 
					
						
							|  |  |  | 		{Name: "TestGetBlockHeaders", Fn: s.TestGetBlockHeaders}, | 
					
						
							|  |  |  | 		{Name: "TestGetBlockBodies", Fn: s.TestGetBlockBodies}, | 
					
						
							|  |  |  | 		{Name: "TestBroadcast", Fn: s.TestBroadcast}, | 
					
						
							| 
									
										
										
										
											2021-03-19 14:15:39 +00:00
										 |  |  | 		{Name: "TestLargeAnnounce", Fn: s.TestLargeAnnounce}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestOldAnnounce", Fn: s.TestOldAnnounce}, | 
					
						
							| 
									
										
										
										
											2021-05-27 11:57:49 +02:00
										 |  |  | 		{Name: "TestBlockHashAnnounce", Fn: s.TestBlockHashAnnounce}, | 
					
						
							| 
									
										
										
										
											2021-03-19 14:15:39 +00:00
										 |  |  | 		{Name: "TestMaliciousHandshake", Fn: s.TestMaliciousHandshake}, | 
					
						
							|  |  |  | 		{Name: "TestMaliciousStatus", Fn: s.TestMaliciousStatus}, | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		{Name: "TestTransaction", Fn: s.TestTransaction}, | 
					
						
							|  |  |  | 		{Name: "TestMaliciousTx", Fn: s.TestMaliciousTx}, | 
					
						
							| 
									
										
										
										
											2021-03-19 14:15:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Suite) Eth66Tests() []utesting.Test { | 
					
						
							|  |  |  | 	return []utesting.Test{ | 
					
						
							|  |  |  | 		// only proceed with eth66 test suite if node supports eth 66 protocol | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestStatus66", Fn: s.TestStatus66}, | 
					
						
							|  |  |  | 		{Name: "TestGetBlockHeaders66", Fn: s.TestGetBlockHeaders66}, | 
					
						
							|  |  |  | 		{Name: "TestSimultaneousRequests66", Fn: s.TestSimultaneousRequests66}, | 
					
						
							|  |  |  | 		{Name: "TestSameRequestID66", Fn: s.TestSameRequestID66}, | 
					
						
							|  |  |  | 		{Name: "TestZeroRequestID66", Fn: s.TestZeroRequestID66}, | 
					
						
							|  |  |  | 		{Name: "TestGetBlockBodies66", Fn: s.TestGetBlockBodies66}, | 
					
						
							|  |  |  | 		{Name: "TestBroadcast66", Fn: s.TestBroadcast66}, | 
					
						
							|  |  |  | 		{Name: "TestLargeAnnounce66", Fn: s.TestLargeAnnounce66}, | 
					
						
							|  |  |  | 		{Name: "TestOldAnnounce66", Fn: s.TestOldAnnounce66}, | 
					
						
							| 
									
										
										
										
											2021-05-27 11:57:49 +02:00
										 |  |  | 		{Name: "TestBlockHashAnnounce66", Fn: s.TestBlockHashAnnounce66}, | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		{Name: "TestMaliciousHandshake66", Fn: s.TestMaliciousHandshake66}, | 
					
						
							|  |  |  | 		{Name: "TestMaliciousStatus66", Fn: s.TestMaliciousStatus66}, | 
					
						
							|  |  |  | 		{Name: "TestTransaction66", Fn: s.TestTransaction66}, | 
					
						
							|  |  |  | 		{Name: "TestMaliciousTx66", Fn: s.TestMaliciousTx66}, | 
					
						
							|  |  |  | 		{Name: "TestLargeTxRequest66", Fn: s.TestLargeTxRequest66}, | 
					
						
							|  |  |  | 		{Name: "TestNewPooledTxs66", Fn: s.TestNewPooledTxs66}, | 
					
						
							| 
									
										
										
										
											2021-03-19 14:15:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | var ( | 
					
						
							|  |  |  | 	eth66 = true  // indicates whether suite should negotiate eth66 connection | 
					
						
							|  |  |  | 	eth65 = false // indicates whether suite should negotiate eth65 connection or below. | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | // TestStatus attempts to connect to the given node and exchange | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // a status message with it. | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | func (s *Suite) TestStatus(t *utesting.T) { | 
					
						
							|  |  |  | 	conn, err := s.dial() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 	defer conn.Close() | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err := conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("peering failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestStatus66 attempts to connect to the given node and exchange | 
					
						
							|  |  |  | // a status message with it on the eth66 protocol. | 
					
						
							|  |  |  | func (s *Suite) TestStatus66(t *utesting.T) { | 
					
						
							|  |  |  | 	conn, err := s.dial66() | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 	defer conn.Close() | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err := conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("peering failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | // TestGetBlockHeaders tests whether the given node can respond to | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // a `GetBlockHeaders` request accurately. | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | func (s *Suite) TestGetBlockHeaders(t *utesting.T) { | 
					
						
							|  |  |  | 	conn, err := s.dial() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 	defer conn.Close() | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err := conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("handshake(s) failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// write request | 
					
						
							|  |  |  | 	req := &GetBlockHeaders{ | 
					
						
							|  |  |  | 		Origin: eth.HashOrNumber{ | 
					
						
							|  |  |  | 			Hash: s.chain.blocks[1].Hash(), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		Amount:  2, | 
					
						
							|  |  |  | 		Skip:    1, | 
					
						
							|  |  |  | 		Reverse: false, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	headers, err := conn.headersRequest(req, s.chain, eth65, 0) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("GetBlockHeaders request failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// check for correct headers | 
					
						
							|  |  |  | 	expected, err := s.chain.GetHeaders(*req) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to get headers for given request: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !headersMatch(expected, headers) { | 
					
						
							|  |  |  | 		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestGetBlockHeaders66 tests whether the given node can respond to | 
					
						
							|  |  |  | // an eth66 `GetBlockHeaders` request and that the response is accurate. | 
					
						
							|  |  |  | func (s *Suite) TestGetBlockHeaders66(t *utesting.T) { | 
					
						
							|  |  |  | 	conn, err := s.dial66() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conn.Close() | 
					
						
							|  |  |  | 	if err = conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// write request | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	req := &GetBlockHeaders{ | 
					
						
							| 
									
										
										
										
											2021-02-16 15:23:03 +01:00
										 |  |  | 		Origin: eth.HashOrNumber{ | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 			Hash: s.chain.blocks[1].Hash(), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		Amount:  2, | 
					
						
							|  |  |  | 		Skip:    1, | 
					
						
							|  |  |  | 		Reverse: false, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	headers, err := conn.headersRequest(req, s.chain, eth66, 33) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not get block headers: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// check for correct headers | 
					
						
							|  |  |  | 	expected, err := s.chain.GetHeaders(*req) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to get headers for given request: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !headersMatch(expected, headers) { | 
					
						
							|  |  |  | 		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestSimultaneousRequests66 sends two simultaneous `GetBlockHeader` requests from | 
					
						
							|  |  |  | // the same connection with different request IDs and checks to make sure the node | 
					
						
							|  |  |  | // responds with the correct headers per request. | 
					
						
							|  |  |  | func (s *Suite) TestSimultaneousRequests66(t *utesting.T) { | 
					
						
							|  |  |  | 	// create a connection | 
					
						
							|  |  |  | 	conn, err := s.dial66() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conn.Close() | 
					
						
							|  |  |  | 	if err := conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// create two requests | 
					
						
							|  |  |  | 	req1 := ð.GetBlockHeadersPacket66{ | 
					
						
							|  |  |  | 		RequestId: uint64(111), | 
					
						
							|  |  |  | 		GetBlockHeadersPacket: ð.GetBlockHeadersPacket{ | 
					
						
							|  |  |  | 			Origin: eth.HashOrNumber{ | 
					
						
							|  |  |  | 				Hash: s.chain.blocks[1].Hash(), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			Amount:  2, | 
					
						
							|  |  |  | 			Skip:    1, | 
					
						
							|  |  |  | 			Reverse: false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	req2 := ð.GetBlockHeadersPacket66{ | 
					
						
							|  |  |  | 		RequestId: uint64(222), | 
					
						
							|  |  |  | 		GetBlockHeadersPacket: ð.GetBlockHeadersPacket{ | 
					
						
							|  |  |  | 			Origin: eth.HashOrNumber{ | 
					
						
							|  |  |  | 				Hash: s.chain.blocks[1].Hash(), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			Amount:  4, | 
					
						
							|  |  |  | 			Skip:    1, | 
					
						
							|  |  |  | 			Reverse: false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// write the first request | 
					
						
							|  |  |  | 	if err := conn.Write66(req1, GetBlockHeaders{}.Code()); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to write to connection: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// write the second request | 
					
						
							|  |  |  | 	if err := conn.Write66(req2, GetBlockHeaders{}.Code()); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to write to connection: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// wait for responses | 
					
						
							|  |  |  | 	msg := conn.waitForResponse(s.chain, timeout, req1.RequestId) | 
					
						
							|  |  |  | 	headers1, ok := msg.(BlockHeaders) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected %s", pretty.Sdump(msg)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	msg = conn.waitForResponse(s.chain, timeout, req2.RequestId) | 
					
						
							|  |  |  | 	headers2, ok := msg.(BlockHeaders) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected %s", pretty.Sdump(msg)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// check received headers for accuracy | 
					
						
							|  |  |  | 	expected1, err := s.chain.GetHeaders(GetBlockHeaders(*req1.GetBlockHeadersPacket)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to get expected headers for request 1: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expected2, err := s.chain.GetHeaders(GetBlockHeaders(*req2.GetBlockHeadersPacket)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to get expected headers for request 2: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !headersMatch(expected1, headers1) { | 
					
						
							|  |  |  | 		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected1, headers1) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if !headersMatch(expected2, headers2) { | 
					
						
							|  |  |  | 		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected2, headers2) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestSameRequestID66 sends two requests with the same request ID to a | 
					
						
							|  |  |  | // single node. | 
					
						
							|  |  |  | func (s *Suite) TestSameRequestID66(t *utesting.T) { | 
					
						
							|  |  |  | 	conn, err := s.dial66() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conn.Close() | 
					
						
							|  |  |  | 	if err := conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// create requests | 
					
						
							|  |  |  | 	reqID := uint64(1234) | 
					
						
							|  |  |  | 	request1 := ð.GetBlockHeadersPacket66{ | 
					
						
							|  |  |  | 		RequestId: reqID, | 
					
						
							|  |  |  | 		GetBlockHeadersPacket: ð.GetBlockHeadersPacket{ | 
					
						
							|  |  |  | 			Origin: eth.HashOrNumber{ | 
					
						
							|  |  |  | 				Number: 1, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			Amount: 2, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	request2 := ð.GetBlockHeadersPacket66{ | 
					
						
							|  |  |  | 		RequestId: reqID, | 
					
						
							|  |  |  | 		GetBlockHeadersPacket: ð.GetBlockHeadersPacket{ | 
					
						
							|  |  |  | 			Origin: eth.HashOrNumber{ | 
					
						
							|  |  |  | 				Number: 33, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			Amount: 2, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// write the requests | 
					
						
							|  |  |  | 	if err = conn.Write66(request1, GetBlockHeaders{}.Code()); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to write to connection: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err = conn.Write66(request2, GetBlockHeaders{}.Code()); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to write to connection: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// wait for responses | 
					
						
							|  |  |  | 	msg := conn.waitForResponse(s.chain, timeout, reqID) | 
					
						
							|  |  |  | 	headers1, ok := msg.(BlockHeaders) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected %s", pretty.Sdump(msg)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	msg = conn.waitForResponse(s.chain, timeout, reqID) | 
					
						
							|  |  |  | 	headers2, ok := msg.(BlockHeaders) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected %s", pretty.Sdump(msg)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// check if headers match | 
					
						
							|  |  |  | 	expected1, err := s.chain.GetHeaders(GetBlockHeaders(*request1.GetBlockHeadersPacket)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to get expected block headers: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expected2, err := s.chain.GetHeaders(GetBlockHeaders(*request2.GetBlockHeadersPacket)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to get expected block headers: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !headersMatch(expected1, headers1) { | 
					
						
							|  |  |  | 		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected1, headers1) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !headersMatch(expected2, headers2) { | 
					
						
							|  |  |  | 		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected2, headers2) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestZeroRequestID_66 checks that a message with a request ID of zero is still handled | 
					
						
							|  |  |  | // by the node. | 
					
						
							|  |  |  | func (s *Suite) TestZeroRequestID66(t *utesting.T) { | 
					
						
							|  |  |  | 	conn, err := s.dial66() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conn.Close() | 
					
						
							|  |  |  | 	if err := conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	req := &GetBlockHeaders{ | 
					
						
							|  |  |  | 		Origin: eth.HashOrNumber{ | 
					
						
							|  |  |  | 			Number: 0, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		Amount: 2, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	headers, err := conn.headersRequest(req, s.chain, eth66, 0) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to get block headers: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expected, err := s.chain.GetHeaders(*req) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to get expected block headers: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !headersMatch(expected, headers) { | 
					
						
							|  |  |  | 		t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestGetBlockBodies tests whether the given node can respond to | 
					
						
							|  |  |  | // a `GetBlockBodies` request and that the response is accurate. | 
					
						
							|  |  |  | func (s *Suite) TestGetBlockBodies(t *utesting.T) { | 
					
						
							|  |  |  | 	conn, err := s.dial() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 	defer conn.Close() | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err := conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	// create block bodies request | 
					
						
							| 
									
										
										
										
											2021-02-16 15:23:03 +01:00
										 |  |  | 	req := &GetBlockBodies{ | 
					
						
							|  |  |  | 		s.chain.blocks[54].Hash(), | 
					
						
							|  |  |  | 		s.chain.blocks[75].Hash(), | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	if err := conn.Write(req); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not write to connection: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	// wait for response | 
					
						
							|  |  |  | 	switch msg := conn.readAndServe(s.chain, timeout).(type) { | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	case *BlockBodies: | 
					
						
							| 
									
										
										
										
											2020-11-04 17:36:56 +01:00
										 |  |  | 		t.Logf("received %d block bodies", len(*msg)) | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		if len(*msg) != len(*req) { | 
					
						
							|  |  |  | 			t.Fatalf("wrong bodies in response: expected %d bodies, "+ | 
					
						
							|  |  |  | 				"got %d", len(*req), len(*msg)) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2020-11-04 17:36:56 +01:00
										 |  |  | 		t.Fatalf("unexpected: %s", pretty.Sdump(msg)) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestGetBlockBodies66 tests whether the given node can respond to | 
					
						
							|  |  |  | // a `GetBlockBodies` request and that the response is accurate over | 
					
						
							|  |  |  | // the eth66 protocol. | 
					
						
							|  |  |  | func (s *Suite) TestGetBlockBodies66(t *utesting.T) { | 
					
						
							|  |  |  | 	conn, err := s.dial66() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conn.Close() | 
					
						
							|  |  |  | 	if err := conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// create block bodies request | 
					
						
							|  |  |  | 	req := ð.GetBlockBodiesPacket66{ | 
					
						
							|  |  |  | 		RequestId: uint64(55), | 
					
						
							|  |  |  | 		GetBlockBodiesPacket: eth.GetBlockBodiesPacket{ | 
					
						
							|  |  |  | 			s.chain.blocks[54].Hash(), | 
					
						
							|  |  |  | 			s.chain.blocks[75].Hash(), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := conn.Write66(req, GetBlockBodies{}.Code()); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not write to connection: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// wait for block bodies response | 
					
						
							|  |  |  | 	msg := conn.waitForResponse(s.chain, timeout, req.RequestId) | 
					
						
							|  |  |  | 	blockBodies, ok := msg.(BlockBodies) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected: %s", pretty.Sdump(msg)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	t.Logf("received %d block bodies", len(blockBodies)) | 
					
						
							|  |  |  | 	if len(blockBodies) != len(req.GetBlockBodiesPacket) { | 
					
						
							|  |  |  | 		t.Fatalf("wrong bodies in response: expected %d bodies, "+ | 
					
						
							|  |  |  | 			"got %d", len(req.GetBlockBodiesPacket), len(blockBodies)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | // TestBroadcast tests whether a block announcement is correctly | 
					
						
							|  |  |  | // propagated to the given node's peer(s). | 
					
						
							|  |  |  | func (s *Suite) TestBroadcast(t *utesting.T) { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err := s.sendNextBlock(eth65); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("block broadcast failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-30 22:47:36 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestBroadcast66 tests whether a block announcement is correctly | 
					
						
							|  |  |  | // propagated to the given node's peer(s) on the eth66 protocol. | 
					
						
							|  |  |  | func (s *Suite) TestBroadcast66(t *utesting.T) { | 
					
						
							|  |  |  | 	if err := s.sendNextBlock(eth66); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("block broadcast failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestLargeAnnounce tests the announcement mechanism with a large block. | 
					
						
							|  |  |  | func (s *Suite) TestLargeAnnounce(t *utesting.T) { | 
					
						
							|  |  |  | 	nextBlock := len(s.chain.blocks) | 
					
						
							|  |  |  | 	blocks := []*NewBlock{ | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			Block: largeBlock(), | 
					
						
							|  |  |  | 			TD:    s.fullChain.TotalDifficultyAt(nextBlock), | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			Block: s.fullChain.blocks[nextBlock], | 
					
						
							|  |  |  | 			TD:    largeNumber(2), | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			Block: largeBlock(), | 
					
						
							|  |  |  | 			TD:    largeNumber(2), | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for i, blockAnnouncement := range blocks { | 
					
						
							|  |  |  | 		t.Logf("Testing malicious announcement: %v\n", i) | 
					
						
							|  |  |  | 		conn, err := s.dial() | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("dial failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		if err = conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("peering failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		if err = conn.Write(blockAnnouncement); err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("could not write to connection: %v", err) | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		// Invalid announcement, check that peer disconnected | 
					
						
							|  |  |  | 		switch msg := conn.readAndServe(s.chain, time.Second*8).(type) { | 
					
						
							|  |  |  | 		case *Disconnect: | 
					
						
							|  |  |  | 		case *Error: | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			t.Fatalf("unexpected: %s wanted disconnect", pretty.Sdump(msg)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		conn.Close() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Test the last block as a valid block | 
					
						
							|  |  |  | 	if err := s.sendNextBlock(eth65); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to broadcast next block: %v", err) | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestLargeAnnounce66 tests the announcement mechanism with a large | 
					
						
							|  |  |  | // block over the eth66 protocol. | 
					
						
							|  |  |  | func (s *Suite) TestLargeAnnounce66(t *utesting.T) { | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 	nextBlock := len(s.chain.blocks) | 
					
						
							|  |  |  | 	blocks := []*NewBlock{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Block: largeBlock(), | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			TD:    s.fullChain.TotalDifficultyAt(nextBlock), | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Block: s.fullChain.blocks[nextBlock], | 
					
						
							|  |  |  | 			TD:    largeNumber(2), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Block: largeBlock(), | 
					
						
							|  |  |  | 			TD:    largeNumber(2), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 	for i, blockAnnouncement := range blocks[0:3] { | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 		t.Logf("Testing malicious announcement: %v\n", i) | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		conn, err := s.dial66() | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("dial failed: %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if err := conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("peering failed: %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if err := conn.Write(blockAnnouncement); err != nil { | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 			t.Fatalf("could not write to connection: %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Invalid announcement, check that peer disconnected | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		switch msg := conn.readAndServe(s.chain, time.Second*8).(type) { | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 		case *Disconnect: | 
					
						
							|  |  |  | 		case *Error: | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			t.Fatalf("unexpected: %s wanted disconnect", pretty.Sdump(msg)) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		conn.Close() | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Test the last block as a valid block | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err := s.sendNextBlock(eth66); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to broadcast next block: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestOldAnnounce tests the announcement mechanism with an old block. | 
					
						
							| 
									
										
										
										
											2021-03-20 18:50:44 +00:00
										 |  |  | func (s *Suite) TestOldAnnounce(t *utesting.T) { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err := s.oldAnnounce(eth65); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestOldAnnounce66 tests the announcement mechanism with an old block, | 
					
						
							|  |  |  | // over the eth66 protocol. | 
					
						
							|  |  |  | func (s *Suite) TestOldAnnounce66(t *utesting.T) { | 
					
						
							|  |  |  | 	if err := s.oldAnnounce(eth66); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-27 11:57:49 +02:00
										 |  |  | // TestBlockHashAnnounce sends a new block hash announcement and expects | 
					
						
							|  |  |  | // the node to perform a `GetBlockHeaders` request. | 
					
						
							|  |  |  | func (s *Suite) TestBlockHashAnnounce(t *utesting.T) { | 
					
						
							|  |  |  | 	if err := s.hashAnnounce(eth65); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("block hash announcement failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestBlockHashAnnounce66 sends a new block hash announcement and expects | 
					
						
							|  |  |  | // the node to perform a `GetBlockHeaders` request. | 
					
						
							|  |  |  | func (s *Suite) TestBlockHashAnnounce66(t *utesting.T) { | 
					
						
							|  |  |  | 	if err := s.hashAnnounce(eth66); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("block hash announcement failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestMaliciousHandshake tries to send malicious data during the handshake. | 
					
						
							|  |  |  | func (s *Suite) TestMaliciousHandshake(t *utesting.T) { | 
					
						
							|  |  |  | 	if err := s.maliciousHandshakes(t, eth65); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestMaliciousHandshake66 tries to send malicious data during the handshake. | 
					
						
							|  |  |  | func (s *Suite) TestMaliciousHandshake66(t *utesting.T) { | 
					
						
							|  |  |  | 	if err := s.maliciousHandshakes(t, eth66); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-03-20 18:50:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestMaliciousStatus sends a status package with a large total difficulty. | 
					
						
							|  |  |  | func (s *Suite) TestMaliciousStatus(t *utesting.T) { | 
					
						
							|  |  |  | 	conn, err := s.dial() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							| 
									
										
										
										
											2021-03-20 18:50:44 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	defer conn.Close() | 
					
						
							| 
									
										
										
										
											2021-03-20 18:50:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err := s.maliciousStatus(conn); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2021-03-20 18:50:44 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-03-20 18:50:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestMaliciousStatus66 sends a status package with a large total | 
					
						
							|  |  |  | // difficulty over the eth66 protocol. | 
					
						
							|  |  |  | func (s *Suite) TestMaliciousStatus66(t *utesting.T) { | 
					
						
							|  |  |  | 	conn, err := s.dial66() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conn.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := s.maliciousStatus(conn); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2021-03-20 18:50:44 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestTransaction sends a valid transaction to the node and | 
					
						
							|  |  |  | // checks if the transaction gets propagated. | 
					
						
							|  |  |  | func (s *Suite) TestTransaction(t *utesting.T) { | 
					
						
							|  |  |  | 	if err := s.sendSuccessfulTxs(t, eth65); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestTransaction66 sends a valid transaction to the node and | 
					
						
							|  |  |  | // checks if the transaction gets propagated. | 
					
						
							|  |  |  | func (s *Suite) TestTransaction66(t *utesting.T) { | 
					
						
							|  |  |  | 	if err := s.sendSuccessfulTxs(t, eth66); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-24 16:09:17 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestMaliciousTx sends several invalid transactions and tests whether | 
					
						
							|  |  |  | // the node will propagate them. | 
					
						
							|  |  |  | func (s *Suite) TestMaliciousTx(t *utesting.T) { | 
					
						
							|  |  |  | 	if err := s.sendMaliciousTxs(t, eth65); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestMaliciousTx66 sends several invalid transactions and tests whether | 
					
						
							|  |  |  | // the node will propagate them. | 
					
						
							|  |  |  | func (s *Suite) TestMaliciousTx66(t *utesting.T) { | 
					
						
							|  |  |  | 	if err := s.sendMaliciousTxs(t, eth66); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestLargeTxRequest66 tests whether a node can fulfill a large GetPooledTransactions | 
					
						
							|  |  |  | // request. | 
					
						
							|  |  |  | func (s *Suite) TestLargeTxRequest66(t *utesting.T) { | 
					
						
							|  |  |  | 	// send the next block to ensure the node is no longer syncing and | 
					
						
							|  |  |  | 	// is able to accept txs | 
					
						
							|  |  |  | 	if err := s.sendNextBlock(eth66); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to send next block: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// send 2000 transactions to the node | 
					
						
							|  |  |  | 	hashMap, txs, err := generateTxs(s, 2000) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		t.Fatalf("failed to generate transactions: %v", err) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	if err = sendMultipleSuccessfulTxs(t, s, txs); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to send multiple txs: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// set up connection to receive to ensure node is peered with the receiving connection | 
					
						
							|  |  |  | 	// before tx request is sent | 
					
						
							|  |  |  | 	conn, err := s.dial66() | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	defer conn.Close() | 
					
						
							|  |  |  | 	if err = conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// create and send pooled tx request | 
					
						
							|  |  |  | 	hashes := make([]common.Hash, 0) | 
					
						
							|  |  |  | 	for _, hash := range hashMap { | 
					
						
							|  |  |  | 		hashes = append(hashes, hash) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	getTxReq := ð.GetPooledTransactionsPacket66{ | 
					
						
							|  |  |  | 		RequestId:                   1234, | 
					
						
							|  |  |  | 		GetPooledTransactionsPacket: hashes, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err = conn.Write66(getTxReq, GetPooledTransactions{}.Code()); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not write to conn: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// check that all received transactions match those that were sent to node | 
					
						
							|  |  |  | 	switch msg := conn.waitForResponse(s.chain, timeout, getTxReq.RequestId).(type) { | 
					
						
							|  |  |  | 	case PooledTransactions: | 
					
						
							|  |  |  | 		for _, gotTx := range msg { | 
					
						
							|  |  |  | 			if _, exists := hashMap[gotTx.Hash()]; !exists { | 
					
						
							|  |  |  | 				t.Fatalf("unexpected tx received: %v", gotTx.Hash()) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		t.Fatalf("unexpected %s", pretty.Sdump(msg)) | 
					
						
							| 
									
										
										
										
											2021-02-25 18:36:01 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-09-23 15:18:17 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | // TestNewPooledTxs_66 tests whether a node will do a GetPooledTransactions | 
					
						
							|  |  |  | // request upon receiving a NewPooledTransactionHashes announcement. | 
					
						
							|  |  |  | func (s *Suite) TestNewPooledTxs66(t *utesting.T) { | 
					
						
							|  |  |  | 	// send the next block to ensure the node is no longer syncing and | 
					
						
							|  |  |  | 	// is able to accept txs | 
					
						
							|  |  |  | 	if err := s.sendNextBlock(eth66); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to send next block: %v", err) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-27 20:53:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	// generate 50 txs | 
					
						
							|  |  |  | 	hashMap, _, err := generateTxs(s, 50) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to generate transactions: %v", err) | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-27 20:53:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	// create new pooled tx hashes announcement | 
					
						
							|  |  |  | 	hashes := make([]common.Hash, 0) | 
					
						
							|  |  |  | 	for _, hash := range hashMap { | 
					
						
							|  |  |  | 		hashes = append(hashes, hash) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	announce := NewPooledTransactionHashes(hashes) | 
					
						
							| 
									
										
										
										
											2021-05-27 20:53:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	// send announcement | 
					
						
							|  |  |  | 	conn, err := s.dial66() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("dial failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer conn.Close() | 
					
						
							|  |  |  | 	if err = conn.peer(s.chain, nil); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("peering failed: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err = conn.Write(announce); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to write to connection: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-27 20:53:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 	// wait for GetPooledTxs request | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		_, msg := conn.readAndServe66(s.chain, timeout) | 
					
						
							|  |  |  | 		switch msg := msg.(type) { | 
					
						
							|  |  |  | 		case GetPooledTransactions: | 
					
						
							|  |  |  | 			if len(msg) != len(hashes) { | 
					
						
							|  |  |  | 				t.Fatalf("unexpected number of txs requested: wanted %d, got %d", len(hashes), len(msg)) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											2021-05-27 20:53:33 +02:00
										 |  |  | 		// ignore propagated txs from previous tests | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 		case *NewPooledTransactionHashes: | 
					
						
							| 
									
										
										
										
											2021-05-27 20:53:33 +02:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		// ignore block announcements from previous tests | 
					
						
							|  |  |  | 		case *NewBlockHashes: | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		case *NewBlock: | 
					
						
							| 
									
										
										
										
											2021-05-25 23:09:11 +02:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			t.Fatalf("unexpected %s", pretty.Sdump(msg)) | 
					
						
							| 
									
										
										
										
											2021-04-23 11:15:42 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-11-30 15:23:48 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } |