github.com/Unheilbar/quorum@v1.0.0/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/ethereum/go-ethereum/p2p/enr"
    30  	"github.com/ethereum/go-ethereum/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  // Quorum - test parsing url with hostname (if host is FQDN)
   171  func TestNodeParseUrlWithHostnameForQuorum(t *testing.T) {
   172  	var url = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@localhost:21000?discport=0&raftport=50401"
   173  	n, err := ParseV4(url)
   174  	if err != nil {
   175  		t.Errorf("parsing host failed %v", err)
   176  	}
   177  	assert.Equal(t, 50401, n.RaftPort())
   178  
   179  	url = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@localhost1:21000?discport=0&raftport=50401"
   180  	_, err = ParseV4(url)
   181  	if err != nil {
   182  		errMsg := err.Error()
   183  		hasError := strings.Contains(errMsg, "no such host")
   184  
   185  		assert.Equal(t, true, hasError, err.Error())
   186  	}
   187  }
   188  
   189  // Quorum
   190  // test Incomplete
   191  func TestIncomplete(t *testing.T) {
   192  	var testCases = []struct {
   193  		n            *Node
   194  		isIncomplete bool
   195  	}{
   196  		{
   197  			n: NewV4(
   198  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   199  				net.IP{127, 0, 0, 1},
   200  				52150,
   201  				52150,
   202  			),
   203  			isIncomplete: false,
   204  		},
   205  		{
   206  			n: NewV4(hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   207  				net.ParseIP("::"),
   208  				52150,
   209  				52150,
   210  			),
   211  			isIncomplete: false,
   212  		},
   213  		{
   214  			n: NewV4(
   215  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   216  				net.ParseIP("2001:db8:3c4d:15::abcd:ef12"),
   217  				52150,
   218  				52150,
   219  			),
   220  			isIncomplete: false,
   221  		},
   222  		{
   223  			n: NewV4(
   224  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   225  				nil,
   226  				52150,
   227  				52150,
   228  			),
   229  			isIncomplete: true,
   230  		},
   231  		{
   232  			n: NewV4Hostname(
   233  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   234  				"hostname",
   235  				52150,
   236  				52150,
   237  				50400,
   238  			),
   239  			isIncomplete: false,
   240  		},
   241  		{
   242  			n: NewV4Hostname(
   243  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   244  				"hostname",
   245  				52150,
   246  				52150,
   247  				0,
   248  			),
   249  			isIncomplete: true,
   250  		},
   251  		{
   252  			n: NewV4Hostname(
   253  				hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   254  				"",
   255  				52150,
   256  				52150,
   257  				50400,
   258  			),
   259  			isIncomplete: true,
   260  		},
   261  	}
   262  
   263  	for i, test := range testCases {
   264  		if test.n.Incomplete() != test.isIncomplete {
   265  			t.Errorf("test %d: Node.Incomplete() mismatch:\ngot:  %v\nwant: %v", i, test.n.Incomplete(), test.isIncomplete)
   266  		}
   267  	}
   268  }