github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/p2p/transport_test.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package p2p
    18  
    19  import (
    20  	"errors"
    21  	"reflect"
    22  	"sync"
    23  	"testing"
    24  
    25  	"github.com/davecgh/go-spew/spew"
    26  
    27  	"github.com/scroll-tech/go-ethereum/crypto"
    28  	"github.com/scroll-tech/go-ethereum/p2p/simulations/pipes"
    29  )
    30  
    31  func TestProtocolHandshake(t *testing.T) {
    32  	var (
    33  		prv0, _ = crypto.GenerateKey()
    34  		pub0    = crypto.FromECDSAPub(&prv0.PublicKey)[1:]
    35  		hs0     = &protoHandshake{Version: 3, ID: pub0, Caps: []Cap{{"a", 0}, {"b", 2}}}
    36  
    37  		prv1, _ = crypto.GenerateKey()
    38  		pub1    = crypto.FromECDSAPub(&prv1.PublicKey)[1:]
    39  		hs1     = &protoHandshake{Version: 3, ID: pub1, Caps: []Cap{{"c", 1}, {"d", 3}}}
    40  
    41  		wg sync.WaitGroup
    42  	)
    43  
    44  	fd0, fd1, err := pipes.TCPPipe()
    45  	if err != nil {
    46  		t.Fatal(err)
    47  	}
    48  
    49  	wg.Add(2)
    50  	go func() {
    51  		defer wg.Done()
    52  		defer fd0.Close()
    53  		frame := newRLPX(fd0, &prv1.PublicKey)
    54  		rpubkey, err := frame.doEncHandshake(prv0)
    55  		if err != nil {
    56  			t.Errorf("dial side enc handshake failed: %v", err)
    57  			return
    58  		}
    59  		if !reflect.DeepEqual(rpubkey, &prv1.PublicKey) {
    60  			t.Errorf("dial side remote pubkey mismatch: got %v, want %v", rpubkey, &prv1.PublicKey)
    61  			return
    62  		}
    63  
    64  		phs, err := frame.doProtoHandshake(hs0)
    65  		if err != nil {
    66  			t.Errorf("dial side proto handshake error: %v", err)
    67  			return
    68  		}
    69  		phs.Rest = nil
    70  		if !reflect.DeepEqual(phs, hs1) {
    71  			t.Errorf("dial side proto handshake mismatch:\ngot: %s\nwant: %s\n", spew.Sdump(phs), spew.Sdump(hs1))
    72  			return
    73  		}
    74  		frame.close(DiscQuitting)
    75  	}()
    76  	go func() {
    77  		defer wg.Done()
    78  		defer fd1.Close()
    79  		rlpx := newRLPX(fd1, nil)
    80  		rpubkey, err := rlpx.doEncHandshake(prv1)
    81  		if err != nil {
    82  			t.Errorf("listen side enc handshake failed: %v", err)
    83  			return
    84  		}
    85  		if !reflect.DeepEqual(rpubkey, &prv0.PublicKey) {
    86  			t.Errorf("listen side remote pubkey mismatch: got %v, want %v", rpubkey, &prv0.PublicKey)
    87  			return
    88  		}
    89  
    90  		phs, err := rlpx.doProtoHandshake(hs1)
    91  		if err != nil {
    92  			t.Errorf("listen side proto handshake error: %v", err)
    93  			return
    94  		}
    95  		phs.Rest = nil
    96  		if !reflect.DeepEqual(phs, hs0) {
    97  			t.Errorf("listen side proto handshake mismatch:\ngot: %s\nwant: %s\n", spew.Sdump(phs), spew.Sdump(hs0))
    98  			return
    99  		}
   100  
   101  		if err := ExpectMsg(rlpx, discMsg, []DiscReason{DiscQuitting}); err != nil {
   102  			t.Errorf("error receiving disconnect: %v", err)
   103  		}
   104  	}()
   105  	wg.Wait()
   106  }
   107  
   108  func TestProtocolHandshakeErrors(t *testing.T) {
   109  	tests := []struct {
   110  		code uint64
   111  		msg  interface{}
   112  		err  error
   113  	}{
   114  		{
   115  			code: discMsg,
   116  			msg:  []DiscReason{DiscQuitting},
   117  			err:  DiscQuitting,
   118  		},
   119  		{
   120  			code: 0x989898,
   121  			msg:  []byte{1},
   122  			err:  errors.New("expected handshake, got 989898"),
   123  		},
   124  		{
   125  			code: handshakeMsg,
   126  			msg:  make([]byte, baseProtocolMaxMsgSize+2),
   127  			err:  errors.New("message too big"),
   128  		},
   129  		{
   130  			code: handshakeMsg,
   131  			msg:  []byte{1, 2, 3},
   132  			err:  newPeerError(errInvalidMsg, "(code 0) (size 4) rlp: expected input list for p2p.protoHandshake"),
   133  		},
   134  		{
   135  			code: handshakeMsg,
   136  			msg:  &protoHandshake{Version: 3},
   137  			err:  DiscInvalidIdentity,
   138  		},
   139  	}
   140  
   141  	for i, test := range tests {
   142  		p1, p2 := MsgPipe()
   143  		go Send(p1, test.code, test.msg)
   144  		_, err := readProtocolHandshake(p2)
   145  		if !reflect.DeepEqual(err, test.err) {
   146  			t.Errorf("test %d: error mismatch: got %q, want %q", i, err, test.err)
   147  		}
   148  	}
   149  }