github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/p2p/enode/node_test.go (about)

     1  // Copyright 2018 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 enode
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/hex"
    22  	"fmt"
    23  	"math/big"
    24  	"net"
    25  	"strings"
    26  	"testing"
    27  	"testing/quick"
    28  
    29  	"github.com/kisexp/xdchain/p2p/enr"
    30  	"github.com/kisexp/xdchain/rlp"
    31  	"github.com/stretchr/testify/assert"
    32  )
    33  
    34  var pyRecord, _ = hex.DecodeString("f884b8407098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c01826964827634826970847f00000189736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31388375647082765f")
    35  
    36  // TestPythonInterop checks that we can decode and verify a record produced by the Python
    37  // implementation.
    38  func TestPythonInterop(t *testing.T) {
    39  	var r enr.Record
    40  	if err := rlp.DecodeBytes(pyRecord, &r); err != nil {
    41  		t.Fatalf("can't decode: %v", err)
    42  	}
    43  	n, err := New(ValidSchemes, &r)
    44  	if err != nil {
    45  		t.Fatalf("can't verify record: %v", err)
    46  	}
    47  
    48  	var (
    49  		wantID  = HexID("a448f24c6d18e575453db13171562b71999873db5b286df957af199ec94617f7")
    50  		wantSeq = uint64(1)
    51  		wantIP  = enr.IPv4{127, 0, 0, 1}
    52  		wantUDP = enr.UDP(30303)
    53  	)
    54  	if n.Seq() != wantSeq {
    55  		t.Errorf("wrong seq: got %d, want %d", n.Seq(), wantSeq)
    56  	}
    57  	if n.ID() != wantID {
    58  		t.Errorf("wrong id: got %x, want %x", n.ID(), wantID)
    59  	}
    60  	want := map[enr.Entry]interface{}{new(enr.IPv4): &wantIP, new(enr.UDP): &wantUDP}
    61  	for k, v := range want {
    62  		desc := fmt.Sprintf("loading key %q", k.ENRKey())
    63  		if assert.NoError(t, n.Load(k), desc) {
    64  			assert.Equal(t, k, v, desc)
    65  		}
    66  	}
    67  }
    68  
    69  func TestHexID(t *testing.T) {
    70  	ref := ID{0, 0, 0, 0, 0, 0, 0, 128, 106, 217, 182, 31, 165, 174, 1, 67, 7, 235, 220, 150, 66, 83, 173, 205, 159, 44, 10, 57, 42, 161, 26, 188}
    71  	id1 := HexID("0x00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
    72  	id2 := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
    73  
    74  	if id1 != ref {
    75  		t.Errorf("wrong id1\ngot  %v\nwant %v", id1[:], ref[:])
    76  	}
    77  	if id2 != ref {
    78  		t.Errorf("wrong id2\ngot  %v\nwant %v", id2[:], ref[:])
    79  	}
    80  }
    81  
    82  func TestID_textEncoding(t *testing.T) {
    83  	ref := ID{
    84  		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
    85  		0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
    86  		0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
    87  		0x31, 0x32,
    88  	}
    89  	hex := "0102030405060708091011121314151617181920212223242526272829303132"
    90  
    91  	text, err := ref.MarshalText()
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  	if !bytes.Equal(text, []byte(hex)) {
    96  		t.Fatalf("text encoding did not match\nexpected: %s\ngot:      %s", hex, text)
    97  	}
    98  
    99  	id := new(ID)
   100  	if err := id.UnmarshalText(text); err != nil {
   101  		t.Fatal(err)
   102  	}
   103  	if *id != ref {
   104  		t.Fatalf("text decoding did not match\nexpected: %s\ngot:      %s", ref, id)
   105  	}
   106  }
   107  
   108  func TestID_distcmp(t *testing.T) {
   109  	distcmpBig := func(target, a, b ID) int {
   110  		tbig := new(big.Int).SetBytes(target[:])
   111  		abig := new(big.Int).SetBytes(a[:])
   112  		bbig := new(big.Int).SetBytes(b[:])
   113  		return new(big.Int).Xor(tbig, abig).Cmp(new(big.Int).Xor(tbig, bbig))
   114  	}
   115  	if err := quick.CheckEqual(DistCmp, distcmpBig, nil); err != nil {
   116  		t.Error(err)
   117  	}
   118  }
   119  
   120  // The random tests is likely to miss the case where a and b are equal,
   121  // this test checks it explicitly.
   122  func TestID_distcmpEqual(t *testing.T) {
   123  	base := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
   124  	x := ID{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
   125  	if DistCmp(base, x, x) != 0 {
   126  		t.Errorf("DistCmp(base, x, x) != 0")
   127  	}
   128  }
   129  
   130  func TestID_logdist(t *testing.T) {
   131  	logdistBig := func(a, b ID) int {
   132  		abig, bbig := new(big.Int).SetBytes(a[:]), new(big.Int).SetBytes(b[:])
   133  		return new(big.Int).Xor(abig, bbig).BitLen()
   134  	}
   135  	if err := quick.CheckEqual(LogDist, logdistBig, nil); err != nil {
   136  		t.Error(err)
   137  	}
   138  }
   139  
   140  // The random tests is likely to miss the case where a and b are equal,
   141  // this test checks it explicitly.
   142  func TestID_logdistEqual(t *testing.T) {
   143  	x := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
   144  	if LogDist(x, x) != 0 {
   145  		t.Errorf("LogDist(x, x) != 0")
   146  	}
   147  }
   148  
   149  // Quorum
   150  //
   151  // test raft port in node detail
   152  func TestNodeInfoForRaftPort(t *testing.T) {
   153  	node := NewV4Hostname(
   154  		hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   155  		"192.168.0.1",
   156  		30302,
   157  		30303,
   158  		2021,
   159  	)
   160  	wantIP := enr.IPv4{192, 168, 0, 1}
   161  	wantUdp := 30303
   162  	wantTcp := 30302
   163  	wantRaftPort := 2021
   164  	assert.Equal(t, wantRaftPort, node.RaftPort(), "node raft port mismatch")
   165  	assert.Equal(t, net.IP(wantIP), node.IP(), "node ip mismatch")
   166  	assert.Equal(t, wantUdp, node.UDP(), "node UDP port mismatch")
   167  	assert.Equal(t, wantTcp, node.TCP(), "node TCP port mismatch")
   168  
   169  }
   170  
   171  // Quorum - test parsing url with hostname (if host is FQDN)
   172  func TestNodeParseUrlWithHostnameForQuorum(t *testing.T) {
   173  	var url = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@localhost:21000?discport=0&raftport=50401"
   174  	n, err := ParseV4(url)
   175  	if err != nil {
   176  		t.Errorf("parsing host failed %v", err)
   177  	}
   178  	assert.Equal(t, 50401, n.RaftPort())
   179  
   180  	url = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@localhost1:21000?discport=0&raftport=50401"
   181  	_, err = ParseV4(url)
   182  	if err != nil {
   183  		errMsg := err.Error()
   184  		hasError := strings.Contains(errMsg, "no such host")
   185  
   186  		assert.Equal(t, true, hasError, err.Error())
   187  	}
   188  }
   189  
   190  // Quorum
   191  // test Incomplete
   192  func TestIncomplete(t *testing.T) {
   193  	var testCases = []struct {
   194  		n            *Node
   195  		isIncomplete bool
   196  	}{
   197  		{
   198  			n: NewV4(
   199  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   200  				net.IP{127, 0, 0, 1},
   201  				52150,
   202  				52150,
   203  			),
   204  			isIncomplete: false,
   205  		},
   206  		{
   207  			n: NewV4(hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   208  				net.ParseIP("::"),
   209  				52150,
   210  				52150,
   211  			),
   212  			isIncomplete: false,
   213  		},
   214  		{
   215  			n: NewV4(
   216  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   217  				net.ParseIP("2001:db8:3c4d:15::abcd:ef12"),
   218  				52150,
   219  				52150,
   220  			),
   221  			isIncomplete: false,
   222  		},
   223  		{
   224  			n: NewV4(
   225  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   226  				nil,
   227  				52150,
   228  				52150,
   229  			),
   230  			isIncomplete: true,
   231  		},
   232  		{
   233  			n: NewV4Hostname(
   234  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   235  				"hostname",
   236  				52150,
   237  				52150,
   238  				50400,
   239  			),
   240  			isIncomplete: false,
   241  		},
   242  		{
   243  			n: NewV4Hostname(
   244  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   245  				"hostname",
   246  				52150,
   247  				52150,
   248  				0,
   249  			),
   250  			isIncomplete: true,
   251  		},
   252  		{
   253  			n: NewV4Hostname(
   254  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   255  				"",
   256  				52150,
   257  				52150,
   258  				50400,
   259  			),
   260  			isIncomplete: true,
   261  		},
   262  	}
   263  
   264  	for i, test := range testCases {
   265  		if test.n.Incomplete() != test.isIncomplete {
   266  			t.Errorf("test %d: Node.Incomplete() mismatch:\ngot:  %v\nwant: %v", i, test.n.Incomplete(), test.isIncomplete)
   267  		}
   268  	}
   269  }