github.com/hyperion-hyn/go-ethereum@v2.4.0+incompatible/p2p/enode/urlv4_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  	"crypto/ecdsa"
    22  	"math/big"
    23  	"reflect"
    24  	"strings"
    25  	"testing"
    26  	"testing/quick"
    27  )
    28  
    29  var parseNodeTests = []struct {
    30  	rawurl     string
    31  	wantError  string
    32  	wantResult *Node
    33  }{
    34  	{
    35  		rawurl:    "http://foobar",
    36  		wantError: `invalid URL scheme, want "enode"`,
    37  	},
    38  	{
    39  		rawurl:    "enode://01010101@123.124.125.126:3",
    40  		wantError: `invalid node ID (wrong length, want 128 hex chars)`,
    41  	},
    42  	// Complete nodes with IP address.
    43  	{
    44  		rawurl:    "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:foo",
    45  		wantError: `invalid port`,
    46  	},
    47  	{
    48  		rawurl:    "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:3?discport=foo",
    49  		wantError: `invalid discport in query`,
    50  	},
    51  	{
    52  		rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150",
    53  		wantResult: NewV4Hostname(
    54  			hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
    55  			"127.0.0.1",
    56  			52150,
    57  			52150,
    58  			0,
    59  		),
    60  	},
    61  	{
    62  		rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[::]:52150",
    63  		wantResult: NewV4Hostname(
    64  			hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
    65  			"::",
    66  			52150,
    67  			52150,
    68  			0,
    69  		),
    70  	},
    71  	{
    72  		rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[2001:db8:3c4d:15::abcd:ef12]:52150",
    73  		wantResult: NewV4Hostname(
    74  			hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
    75  			"2001:db8:3c4d:15::abcd:ef12",
    76  			52150,
    77  			52150,
    78  			0,
    79  		),
    80  	},
    81  	{
    82  		rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150?discport=22334",
    83  		wantResult: NewV4Hostname(
    84  			hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
    85  			"127.0.0.1",
    86  			52150,
    87  			22334,
    88  			0,
    89  		),
    90  	},
    91  	// Incomplete nodes with no address.
    92  	{
    93  		rawurl: "1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439",
    94  		wantResult: NewV4(
    95  			hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
    96  			nil, 0, 0, 0,
    97  		),
    98  	},
    99  	{
   100  		rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439",
   101  		wantResult: NewV4(
   102  			hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   103  			nil, 0, 0, 0,
   104  		),
   105  	},
   106  	// Invalid URLs
   107  	{
   108  		rawurl:    "01010101",
   109  		wantError: `invalid node ID (wrong length, want 128 hex chars)`,
   110  	},
   111  	{
   112  		rawurl:    "enode://01010101",
   113  		wantError: `invalid node ID (wrong length, want 128 hex chars)`,
   114  	},
   115  	{
   116  		// This test checks that errors from url.Parse are handled.
   117  		rawurl:    "://foo",
   118  		wantError: `parse ://foo: missing protocol scheme`,
   119  	},
   120  }
   121  
   122  func hexPubkey(h string) *ecdsa.PublicKey {
   123  	k, err := parsePubkey(h)
   124  	if err != nil {
   125  		panic(err)
   126  	}
   127  	return k
   128  }
   129  
   130  func TestParseNode(t *testing.T) {
   131  	extraTests := []struct {
   132  		rawurl     string
   133  		wantError  string
   134  		wantResult *Node
   135  	}{
   136  		{
   137  			rawurl:    "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@hostname:3",
   138  			wantResult: NewV4Hostname(hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), "hostname", 3, 3, 0, ),
   139  		},
   140  	}
   141  
   142  	testNodes := append(parseNodeTests, extraTests...)
   143  
   144  	for _, test := range testNodes {
   145  		n, err := ParseV4(test.rawurl)
   146  		if test.wantError != "" {
   147  			if err == nil {
   148  				t.Errorf("test %q:\n  got nil error, expected %#q", test.rawurl, test.wantError)
   149  				continue
   150  			} else if !strings.Contains(err.Error(), test.wantError) {
   151  				t.Errorf("test %q:\n  got error %#q, expected %#q", test.rawurl, err.Error(), test.wantError)
   152  				continue
   153  			}
   154  		} else {
   155  			if err != nil {
   156  				t.Errorf("test %q:\n  unexpected error: %v", test.rawurl, err)
   157  				continue
   158  			}
   159  			if !reflect.DeepEqual(n, test.wantResult) {
   160  				t.Errorf("test %q:\n  result mismatch:\ngot:  %#v\nwant: %#v", test.rawurl, n, test.wantResult)
   161  			}
   162  		}
   163  	}
   164  }
   165  
   166  func TestNodeString(t *testing.T) {
   167  	for i, test := range parseNodeTests {
   168  		if test.wantError == "" && strings.HasPrefix(test.rawurl, "enode://") {
   169  			str := test.wantResult.String()
   170  			if str != test.rawurl {
   171  				t.Errorf("test %d: Node.String() mismatch:\ngot:  %s\nwant: %s", i, str, test.rawurl)
   172  			}
   173  		}
   174  	}
   175  }
   176  
   177  func TestHexID(t *testing.T) {
   178  	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}
   179  	id1 := HexID("0x00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
   180  	id2 := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
   181  
   182  	if id1 != ref {
   183  		t.Errorf("wrong id1\ngot  %v\nwant %v", id1[:], ref[:])
   184  	}
   185  	if id2 != ref {
   186  		t.Errorf("wrong id2\ngot  %v\nwant %v", id2[:], ref[:])
   187  	}
   188  }
   189  
   190  func TestID_textEncoding(t *testing.T) {
   191  	ref := ID{
   192  		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
   193  		0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
   194  		0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
   195  		0x31, 0x32,
   196  	}
   197  	hex := "0102030405060708091011121314151617181920212223242526272829303132"
   198  
   199  	text, err := ref.MarshalText()
   200  	if err != nil {
   201  		t.Fatal(err)
   202  	}
   203  	if !bytes.Equal(text, []byte(hex)) {
   204  		t.Fatalf("text encoding did not match\nexpected: %s\ngot:      %s", hex, text)
   205  	}
   206  
   207  	id := new(ID)
   208  	if err := id.UnmarshalText(text); err != nil {
   209  		t.Fatal(err)
   210  	}
   211  	if *id != ref {
   212  		t.Fatalf("text decoding did not match\nexpected: %s\ngot:      %s", ref, id)
   213  	}
   214  }
   215  
   216  func TestNodeID_distcmp(t *testing.T) {
   217  	distcmpBig := func(target, a, b ID) int {
   218  		tbig := new(big.Int).SetBytes(target[:])
   219  		abig := new(big.Int).SetBytes(a[:])
   220  		bbig := new(big.Int).SetBytes(b[:])
   221  		return new(big.Int).Xor(tbig, abig).Cmp(new(big.Int).Xor(tbig, bbig))
   222  	}
   223  	if err := quick.CheckEqual(DistCmp, distcmpBig, nil); err != nil {
   224  		t.Error(err)
   225  	}
   226  }
   227  
   228  // The random tests is likely to miss the case where a and b are equal,
   229  // this test checks it explicitly.
   230  func TestNodeID_distcmpEqual(t *testing.T) {
   231  	base := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
   232  	x := ID{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
   233  	if DistCmp(base, x, x) != 0 {
   234  		t.Errorf("DistCmp(base, x, x) != 0")
   235  	}
   236  }
   237  
   238  func TestNodeID_logdist(t *testing.T) {
   239  	logdistBig := func(a, b ID) int {
   240  		abig, bbig := new(big.Int).SetBytes(a[:]), new(big.Int).SetBytes(b[:])
   241  		return new(big.Int).Xor(abig, bbig).BitLen()
   242  	}
   243  	if err := quick.CheckEqual(LogDist, logdistBig, nil); err != nil {
   244  		t.Error(err)
   245  	}
   246  }
   247  
   248  // The random tests is likely to miss the case where a and b are equal,
   249  // this test checks it explicitly.
   250  func TestNodeID_logdistEqual(t *testing.T) {
   251  	x := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
   252  	if LogDist(x, x) != 0 {
   253  		t.Errorf("LogDist(x, x) != 0")
   254  	}
   255  }