github.com/c4dt/go-ethereum@v1.9.2/les/peer_test.go (about)

     1  // Copyright 2019 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 les
    18  
    19  import (
    20  	"math/big"
    21  	"testing"
    22  
    23  	"github.com/ethereum/go-ethereum/common"
    24  	"github.com/ethereum/go-ethereum/common/mclock"
    25  	"github.com/ethereum/go-ethereum/les/flowcontrol"
    26  	"github.com/ethereum/go-ethereum/p2p"
    27  	"github.com/ethereum/go-ethereum/rlp"
    28  )
    29  
    30  const (
    31  	test_networkid   = 10
    32  	protocol_version = lpv2
    33  )
    34  
    35  var (
    36  	hash    = common.HexToHash("some string")
    37  	genesis = common.HexToHash("genesis hash")
    38  	headNum = uint64(1234)
    39  	td      = big.NewInt(123)
    40  )
    41  
    42  //ulc connects to trusted peer and send announceType=announceTypeSigned
    43  func TestPeerHandshakeSetAnnounceTypeToAnnounceTypeSignedForTrustedPeer(t *testing.T) {
    44  	id := newNodeID(t).ID()
    45  
    46  	//peer to connect(on ulc side)
    47  	p := peer{
    48  		Peer:    p2p.NewPeer(id, "test peer", []p2p.Cap{}),
    49  		version: protocol_version,
    50  		trusted: true,
    51  		rw: &rwStub{
    52  			WriteHook: func(recvList keyValueList) {
    53  				//checking that ulc sends to peer allowedRequests=onlyAnnounceRequests and announceType = announceTypeSigned
    54  				recv, _ := recvList.decode()
    55  				var reqType uint64
    56  
    57  				err := recv.get("announceType", &reqType)
    58  				if err != nil {
    59  					t.Fatal(err)
    60  				}
    61  
    62  				if reqType != announceTypeSigned {
    63  					t.Fatal("Expected announceTypeSigned")
    64  				}
    65  			},
    66  			ReadHook: func(l keyValueList) keyValueList {
    67  				l = l.add("serveHeaders", nil)
    68  				l = l.add("serveChainSince", uint64(0))
    69  				l = l.add("serveStateSince", uint64(0))
    70  				l = l.add("txRelay", nil)
    71  				l = l.add("flowControl/BL", uint64(0))
    72  				l = l.add("flowControl/MRR", uint64(0))
    73  				l = l.add("flowControl/MRC", testCostList(0))
    74  
    75  				return l
    76  			},
    77  		},
    78  		network: test_networkid,
    79  	}
    80  
    81  	err := p.Handshake(td, hash, headNum, genesis, nil)
    82  	if err != nil {
    83  		t.Fatalf("Handshake error: %s", err)
    84  	}
    85  
    86  	if p.announceType != announceTypeSigned {
    87  		t.Fatal("Incorrect announceType")
    88  	}
    89  }
    90  
    91  func TestPeerHandshakeAnnounceTypeSignedForTrustedPeersPeerNotInTrusted(t *testing.T) {
    92  	id := newNodeID(t).ID()
    93  	p := peer{
    94  		Peer:    p2p.NewPeer(id, "test peer", []p2p.Cap{}),
    95  		version: protocol_version,
    96  		rw: &rwStub{
    97  			WriteHook: func(recvList keyValueList) {
    98  				//checking that ulc sends to peer allowedRequests=noRequests and announceType != announceTypeSigned
    99  				recv, _ := recvList.decode()
   100  				var reqType uint64
   101  
   102  				err := recv.get("announceType", &reqType)
   103  				if err != nil {
   104  					t.Fatal(err)
   105  				}
   106  
   107  				if reqType == announceTypeSigned {
   108  					t.Fatal("Expected not announceTypeSigned")
   109  				}
   110  			},
   111  			ReadHook: func(l keyValueList) keyValueList {
   112  				l = l.add("serveHeaders", nil)
   113  				l = l.add("serveChainSince", uint64(0))
   114  				l = l.add("serveStateSince", uint64(0))
   115  				l = l.add("txRelay", nil)
   116  				l = l.add("flowControl/BL", uint64(0))
   117  				l = l.add("flowControl/MRR", uint64(0))
   118  				l = l.add("flowControl/MRC", testCostList(0))
   119  
   120  				return l
   121  			},
   122  		},
   123  		network: test_networkid,
   124  	}
   125  
   126  	err := p.Handshake(td, hash, headNum, genesis, nil)
   127  	if err != nil {
   128  		t.Fatal(err)
   129  	}
   130  	if p.announceType == announceTypeSigned {
   131  		t.Fatal("Incorrect announceType")
   132  	}
   133  }
   134  
   135  func TestPeerHandshakeDefaultAllRequests(t *testing.T) {
   136  	id := newNodeID(t).ID()
   137  
   138  	s := generateLesServer()
   139  
   140  	p := peer{
   141  		Peer:    p2p.NewPeer(id, "test peer", []p2p.Cap{}),
   142  		version: protocol_version,
   143  		rw: &rwStub{
   144  			ReadHook: func(l keyValueList) keyValueList {
   145  				l = l.add("announceType", uint64(announceTypeSigned))
   146  				l = l.add("allowedRequests", uint64(0))
   147  
   148  				return l
   149  			},
   150  		},
   151  		network: test_networkid,
   152  	}
   153  
   154  	err := p.Handshake(td, hash, headNum, genesis, s)
   155  	if err != nil {
   156  		t.Fatal(err)
   157  	}
   158  
   159  	if p.onlyAnnounce {
   160  		t.Fatal("Incorrect announceType")
   161  	}
   162  }
   163  
   164  func TestPeerHandshakeServerSendOnlyAnnounceRequestsHeaders(t *testing.T) {
   165  	id := newNodeID(t).ID()
   166  
   167  	s := generateLesServer()
   168  	s.onlyAnnounce = true
   169  
   170  	p := peer{
   171  		Peer:    p2p.NewPeer(id, "test peer", []p2p.Cap{}),
   172  		version: protocol_version,
   173  		rw: &rwStub{
   174  			ReadHook: func(l keyValueList) keyValueList {
   175  				l = l.add("announceType", uint64(announceTypeSigned))
   176  
   177  				return l
   178  			},
   179  			WriteHook: func(l keyValueList) {
   180  				for _, v := range l {
   181  					if v.Key == "serveHeaders" ||
   182  						v.Key == "serveChainSince" ||
   183  						v.Key == "serveStateSince" ||
   184  						v.Key == "txRelay" {
   185  						t.Fatalf("%v exists", v.Key)
   186  					}
   187  				}
   188  			},
   189  		},
   190  		network: test_networkid,
   191  	}
   192  
   193  	err := p.Handshake(td, hash, headNum, genesis, s)
   194  	if err != nil {
   195  		t.Fatal(err)
   196  	}
   197  }
   198  func TestPeerHandshakeClientReceiveOnlyAnnounceRequestsHeaders(t *testing.T) {
   199  	id := newNodeID(t).ID()
   200  
   201  	p := peer{
   202  		Peer:    p2p.NewPeer(id, "test peer", []p2p.Cap{}),
   203  		version: protocol_version,
   204  		rw: &rwStub{
   205  			ReadHook: func(l keyValueList) keyValueList {
   206  				l = l.add("flowControl/BL", uint64(0))
   207  				l = l.add("flowControl/MRR", uint64(0))
   208  				l = l.add("flowControl/MRC", RequestCostList{})
   209  
   210  				l = l.add("announceType", uint64(announceTypeSigned))
   211  
   212  				return l
   213  			},
   214  		},
   215  		network: test_networkid,
   216  		trusted: true,
   217  	}
   218  
   219  	err := p.Handshake(td, hash, headNum, genesis, nil)
   220  	if err != nil {
   221  		t.Fatal(err)
   222  	}
   223  
   224  	if !p.onlyAnnounce {
   225  		t.Fatal("onlyAnnounce must be true")
   226  	}
   227  }
   228  
   229  func TestPeerHandshakeClientReturnErrorOnUselessPeer(t *testing.T) {
   230  	id := newNodeID(t).ID()
   231  
   232  	p := peer{
   233  		Peer:    p2p.NewPeer(id, "test peer", []p2p.Cap{}),
   234  		version: protocol_version,
   235  		rw: &rwStub{
   236  			ReadHook: func(l keyValueList) keyValueList {
   237  				l = l.add("flowControl/BL", uint64(0))
   238  				l = l.add("flowControl/MRR", uint64(0))
   239  				l = l.add("flowControl/MRC", RequestCostList{})
   240  
   241  				l = l.add("announceType", uint64(announceTypeSigned))
   242  
   243  				return l
   244  			},
   245  		},
   246  		network: test_networkid,
   247  	}
   248  
   249  	err := p.Handshake(td, hash, headNum, genesis, nil)
   250  	if err == nil {
   251  		t.FailNow()
   252  	}
   253  }
   254  
   255  func generateLesServer() *LesServer {
   256  	s := &LesServer{
   257  		defParams: flowcontrol.ServerParams{
   258  			BufLimit:    uint64(300000000),
   259  			MinRecharge: uint64(50000),
   260  		},
   261  		fcManager: flowcontrol.NewClientManager(nil, &mclock.System{}),
   262  	}
   263  	return s
   264  }
   265  
   266  type rwStub struct {
   267  	ReadHook  func(l keyValueList) keyValueList
   268  	WriteHook func(l keyValueList)
   269  }
   270  
   271  func (s *rwStub) ReadMsg() (p2p.Msg, error) {
   272  	payload := keyValueList{}
   273  	payload = payload.add("protocolVersion", uint64(protocol_version))
   274  	payload = payload.add("networkId", uint64(test_networkid))
   275  	payload = payload.add("headTd", td)
   276  	payload = payload.add("headHash", hash)
   277  	payload = payload.add("headNum", headNum)
   278  	payload = payload.add("genesisHash", genesis)
   279  
   280  	if s.ReadHook != nil {
   281  		payload = s.ReadHook(payload)
   282  	}
   283  
   284  	size, p, err := rlp.EncodeToReader(payload)
   285  	if err != nil {
   286  		return p2p.Msg{}, err
   287  	}
   288  
   289  	return p2p.Msg{
   290  		Size:    uint32(size),
   291  		Payload: p,
   292  	}, nil
   293  }
   294  
   295  func (s *rwStub) WriteMsg(m p2p.Msg) error {
   296  	recvList := keyValueList{}
   297  	if err := m.Decode(&recvList); err != nil {
   298  		return err
   299  	}
   300  
   301  	if s.WriteHook != nil {
   302  		s.WriteHook(recvList)
   303  	}
   304  
   305  	return nil
   306  }