From 739066ec56393e63b93531787746fb8ba5f1df15 Mon Sep 17 00:00:00 2001
From: Felix Lange <fjl@twurst.com>
Date: Thu, 5 Feb 2015 03:07:18 +0100
Subject: [PATCH] p2p/discover: add some helper functions

---
 p2p/discover/table.go      | 37 +++++++++++++++++++++++++++++--------
 p2p/discover/table_test.go |  6 +++---
 p2p/discover/udp.go        |  4 ++--
 p2p/discover/udp_test.go   | 14 +++++++-------
 4 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/p2p/discover/table.go b/p2p/discover/table.go
index 26526330b..ea9680404 100644
--- a/p2p/discover/table.go
+++ b/p2p/discover/table.go
@@ -87,6 +87,16 @@ func newTable(t transport, ourID NodeID, ourAddr *net.UDPAddr) *Table {
 	return tab
 }
 
+// Self returns the local node ID.
+func (tab *Table) Self() NodeID {
+	return tab.self.ID
+}
+
+// Close terminates the network listener.
+func (tab *Table) Close() {
+	tab.net.close()
+}
+
 // Bootstrap sets the bootstrap nodes. These nodes are used to connect
 // to the network if the table is empty. Bootstrap will also attempt to
 // fill the table by performing random lookup operations on the
@@ -319,27 +329,38 @@ func (n NodeID) GoString() string {
 
 // HexID converts a hex string to a NodeID.
 // The string may be prefixed with 0x.
-func HexID(in string) NodeID {
+func HexID(in string) (NodeID, error) {
 	if strings.HasPrefix(in, "0x") {
 		in = in[2:]
 	}
 	var id NodeID
 	b, err := hex.DecodeString(in)
 	if err != nil {
-		panic(err)
+		return id, err
 	} else if len(b) != len(id) {
-		panic("wrong length")
+		return id, fmt.Errorf("wrong length, need %d hex bytes", len(id))
 	}
 	copy(id[:], b)
+	return id, nil
+}
+
+// MustHexID converts a hex string to a NodeID.
+// It panics if the string is not a valid NodeID.
+func MustHexID(in string) NodeID {
+	id, err := HexID(in)
+	if err != nil {
+		panic(err)
+	}
 	return id
 }
 
-func newNodeID(priv *ecdsa.PrivateKey) (id NodeID) {
-	pubkey := elliptic.Marshal(priv.Curve, priv.X, priv.Y)
-	if len(pubkey)-1 != len(id) {
-		panic(fmt.Errorf("invalid key: need %d bit pubkey, got %d bits", (len(id)+1)*8, len(pubkey)))
+func PubkeyID(pub *ecdsa.PublicKey) NodeID {
+	var id NodeID
+	pbytes := elliptic.Marshal(pub.Curve, pub.X, pub.Y)
+	if len(pbytes)-1 != len(id) {
+		panic(fmt.Errorf("invalid key: need %d bit pubkey, got %d bits", (len(id)+1)*8, len(pbytes)))
 	}
-	copy(id[:], pubkey[1:])
+	copy(id[:], pbytes[1:])
 	return id
 }
 
diff --git a/p2p/discover/table_test.go b/p2p/discover/table_test.go
index 88563fe65..90f89b147 100644
--- a/p2p/discover/table_test.go
+++ b/p2p/discover/table_test.go
@@ -22,8 +22,8 @@ var (
 
 func TestHexID(t *testing.T) {
 	ref := NodeID{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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}
-	id1 := HexID("0x000000000000000000000000000000000000000000000000000000000000000000000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
-	id2 := HexID("000000000000000000000000000000000000000000000000000000000000000000000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
+	id1 := MustHexID("0x000000000000000000000000000000000000000000000000000000000000000000000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
+	id2 := MustHexID("000000000000000000000000000000000000000000000000000000000000000000000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
 
 	if id1 != ref {
 		t.Errorf("wrong id1\ngot  %v\nwant %v", id1[:], ref[:])
@@ -41,7 +41,7 @@ func TestNodeID_recover(t *testing.T) {
 		t.Fatalf("signing error: %v", err)
 	}
 
-	pub := newNodeID(prv)
+	pub := PubkeyID(&prv.PublicKey)
 	recpub, err := recoverNodeID(hash, sig)
 	if err != nil {
 		t.Fatalf("recovery error: %v", err)
diff --git a/p2p/discover/udp.go b/p2p/discover/udp.go
index ec1f62dac..449139c1d 100644
--- a/p2p/discover/udp.go
+++ b/p2p/discover/udp.go
@@ -120,8 +120,8 @@ func ListenUDP(priv *ecdsa.PrivateKey, laddr string) (*Table, error) {
 	if err != nil {
 		return nil, err
 	}
-	net.Table = newTable(net, newNodeID(priv), realaddr)
-	log.DebugDetailf("Listening on %v, my ID %x\n", realaddr, net.self.ID[:])
+	net.Table = newTable(net, PubkeyID(&priv.PublicKey), realaddr)
+	log.Debugf("Listening on %v, my ID %x\n", realaddr, net.self.ID[:])
 	return net.Table, nil
 }
 
diff --git a/p2p/discover/udp_test.go b/p2p/discover/udp_test.go
index f2ab2b661..8ed6ec9c0 100644
--- a/p2p/discover/udp_test.go
+++ b/p2p/discover/udp_test.go
@@ -19,8 +19,8 @@ func TestUDP_ping(t *testing.T) {
 
 	n1, _ := ListenUDP(newkey(), "127.0.0.1:0")
 	n2, _ := ListenUDP(newkey(), "127.0.0.1:0")
-	defer n1.net.close()
-	defer n2.net.close()
+	defer n1.Close()
+	defer n2.Close()
 
 	if err := n1.net.ping(n2.self); err != nil {
 		t.Fatalf("ping error: %v", err)
@@ -49,8 +49,8 @@ func TestUDP_findnode(t *testing.T) {
 
 	n1, _ := ListenUDP(newkey(), "127.0.0.1:0")
 	n2, _ := ListenUDP(newkey(), "127.0.0.1:0")
-	defer n1.net.close()
-	defer n2.net.close()
+	defer n1.Close()
+	defer n2.Close()
 
 	entry := &Node{ID: NodeID{1}, Addr: &net.UDPAddr{IP: net.IP{1, 2, 3, 4}, Port: 15}}
 	n2.add([]*Node{entry})
@@ -77,7 +77,7 @@ func TestUDP_replytimeout(t *testing.T) {
 	defer fd.Close()
 
 	n1, _ := ListenUDP(newkey(), "127.0.0.1:0")
-	defer n1.net.close()
+	defer n1.Close()
 	n2 := n1.bumpOrAdd(randomID(n1.self.ID, 10), fd.LocalAddr().(*net.UDPAddr))
 
 	if err := n1.net.ping(n2); err != errTimeout {
@@ -97,8 +97,8 @@ func TestUDP_findnodeMultiReply(t *testing.T) {
 	n1, _ := ListenUDP(newkey(), "127.0.0.1:0")
 	n2, _ := ListenUDP(newkey(), "127.0.0.1:0")
 	udp2 := n2.net.(*udp)
-	defer n1.net.close()
-	defer n2.net.close()
+	defer n1.Close()
+	defer n2.Close()
 
 	nodes := make([]*Node, bucketSize)
 	for i := range nodes {
-- 
GitLab