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