github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/cmd/devp2p/internal/ethtest/chain_test.go (about)

     1  // Copyright 2020 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU 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  // go-ethereum 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 General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package ethtest
    18  
    19  import (
    20  	"path/filepath"
    21  	"strconv"
    22  	"testing"
    23  
    24  	"github.com/ethereum/go-ethereum/core/types"
    25  	"github.com/ethereum/go-ethereum/eth/protocols/eth"
    26  	"github.com/ethereum/go-ethereum/p2p"
    27  	"github.com/stretchr/testify/assert"
    28  )
    29  
    30  // TestEthProtocolNegotiation tests whether the test suite
    31  // can negotiate the highest eth protocol in a status message exchange
    32  func TestEthProtocolNegotiation(t *testing.T) {
    33  	t.Parallel()
    34  	var tests = []struct {
    35  		conn     *Conn
    36  		caps     []p2p.Cap
    37  		expected uint32
    38  	}{
    39  		{
    40  			conn: &Conn{
    41  				ourHighestProtoVersion: 65,
    42  			},
    43  			caps: []p2p.Cap{
    44  				{Name: "eth", Version: 63},
    45  				{Name: "eth", Version: 64},
    46  				{Name: "eth", Version: 65},
    47  			},
    48  			expected: uint32(65),
    49  		},
    50  		{
    51  			conn: &Conn{
    52  				ourHighestProtoVersion: 65,
    53  			},
    54  			caps: []p2p.Cap{
    55  				{Name: "eth", Version: 63},
    56  				{Name: "eth", Version: 64},
    57  				{Name: "eth", Version: 65},
    58  			},
    59  			expected: uint32(65),
    60  		},
    61  		{
    62  			conn: &Conn{
    63  				ourHighestProtoVersion: 65,
    64  			},
    65  			caps: []p2p.Cap{
    66  				{Name: "eth", Version: 63},
    67  				{Name: "eth", Version: 64},
    68  				{Name: "eth", Version: 65},
    69  			},
    70  			expected: uint32(65),
    71  		},
    72  		{
    73  			conn: &Conn{
    74  				ourHighestProtoVersion: 64,
    75  			},
    76  			caps: []p2p.Cap{
    77  				{Name: "eth", Version: 63},
    78  				{Name: "eth", Version: 64},
    79  				{Name: "eth", Version: 65},
    80  			},
    81  			expected: 64,
    82  		},
    83  		{
    84  			conn: &Conn{
    85  				ourHighestProtoVersion: 65,
    86  			},
    87  			caps: []p2p.Cap{
    88  				{Name: "eth", Version: 0},
    89  				{Name: "eth", Version: 89},
    90  				{Name: "eth", Version: 65},
    91  			},
    92  			expected: uint32(65),
    93  		},
    94  		{
    95  			conn: &Conn{
    96  				ourHighestProtoVersion: 64,
    97  			},
    98  			caps: []p2p.Cap{
    99  				{Name: "eth", Version: 63},
   100  				{Name: "eth", Version: 64},
   101  				{Name: "wrongProto", Version: 65},
   102  			},
   103  			expected: uint32(64),
   104  		},
   105  		{
   106  			conn: &Conn{
   107  				ourHighestProtoVersion: 65,
   108  			},
   109  			caps: []p2p.Cap{
   110  				{Name: "eth", Version: 63},
   111  				{Name: "eth", Version: 64},
   112  				{Name: "wrongProto", Version: 65},
   113  			},
   114  			expected: uint32(64),
   115  		},
   116  	}
   117  
   118  	for i, tt := range tests {
   119  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   120  			tt.conn.negotiateEthProtocol(tt.caps)
   121  			assert.Equal(t, tt.expected, uint32(tt.conn.negotiatedProtoVersion))
   122  		})
   123  	}
   124  }
   125  
   126  // TestChainGetHeaders tests whether the test suite can correctly
   127  // respond to a GetBlockHeaders request from a node.
   128  func TestChainGetHeaders(t *testing.T) {
   129  	t.Parallel()
   130  
   131  	dir, err := filepath.Abs("./testdata")
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  	chain, err := NewChain(dir)
   136  	if err != nil {
   137  		t.Fatal(err)
   138  	}
   139  
   140  	var tests = []struct {
   141  		req      eth.GetBlockHeadersPacket
   142  		expected []*types.Header
   143  	}{
   144  		{
   145  			req: eth.GetBlockHeadersPacket{
   146  				GetBlockHeadersRequest: &eth.GetBlockHeadersRequest{
   147  					Origin:  eth.HashOrNumber{Number: uint64(2)},
   148  					Amount:  uint64(5),
   149  					Skip:    1,
   150  					Reverse: false,
   151  				},
   152  			},
   153  			expected: []*types.Header{
   154  				chain.blocks[2].Header(),
   155  				chain.blocks[4].Header(),
   156  				chain.blocks[6].Header(),
   157  				chain.blocks[8].Header(),
   158  				chain.blocks[10].Header(),
   159  			},
   160  		},
   161  		{
   162  			req: eth.GetBlockHeadersPacket{
   163  				GetBlockHeadersRequest: &eth.GetBlockHeadersRequest{
   164  					Origin:  eth.HashOrNumber{Number: uint64(chain.Len() - 1)},
   165  					Amount:  uint64(3),
   166  					Skip:    0,
   167  					Reverse: true,
   168  				},
   169  			},
   170  			expected: []*types.Header{
   171  				chain.blocks[chain.Len()-1].Header(),
   172  				chain.blocks[chain.Len()-2].Header(),
   173  				chain.blocks[chain.Len()-3].Header(),
   174  			},
   175  		},
   176  		{
   177  			req: eth.GetBlockHeadersPacket{
   178  				GetBlockHeadersRequest: &eth.GetBlockHeadersRequest{
   179  					Origin:  eth.HashOrNumber{Hash: chain.Head().Hash()},
   180  					Amount:  uint64(1),
   181  					Skip:    0,
   182  					Reverse: false,
   183  				},
   184  			},
   185  			expected: []*types.Header{
   186  				chain.Head().Header(),
   187  			},
   188  		},
   189  	}
   190  
   191  	for i, tt := range tests {
   192  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   193  			headers, err := chain.GetHeaders(&tt.req)
   194  			if err != nil {
   195  				t.Fatal(err)
   196  			}
   197  			assert.Equal(t, headers, tt.expected)
   198  		})
   199  	}
   200  }