ethereum / go-ethereum

Go implementation of the Ethereum protocol
https://geth.ethereum.org
GNU Lesser General Public License v3.0
47.14k stars 19.95k forks source link

Question: ID or NodeID #20104

Closed trung closed 4 years ago

trung commented 4 years ago

Node identifier is mentioned in 2 places:

  1. As 32-byte ID type which is returned via admin.nodeInfo https://github.com/ethereum/go-ethereum/blob/63b18027dc9e5ad86992b3e7acbd3f033a458192/p2p/enode/node.go#L189-L192

  2. As 64-byte NodeID type which is used in p2p https://github.com/ethereum/go-ethereum/blob/461291882edce0ac4a28f64c4e8725b7f57cbeae/p2p/discv5/node.go#L260-L265

Which one is the real node identifier? I would say NodeID. But not sure why there are two.

dherbst commented 4 years ago

From https://github.com/ethereum/devp2p/wiki/Discovery-Overview#discovery-v4

All nodes are identified by their 64-byte elliptic curve public key. However, the Kademlia table identifies nodes as the 32-byte SHA256 hash of the node id.

And then https://github.com/ethereum/devp2p/wiki/Discovery-Overview#discovery-v5-aka-discv5

'discv5' as a software package will be deprecated in geth.

Further down the page:

Discovery v5 wire protocol will attempt to offer a backwards compatible method of relaying ENRs in FindNode responses. The Kademlia tables should maintain ENR s, not discovery v4 tuples.

and

Discovery v4 accepts the 64-byte public key, the node id, as the target to search for in a FindNode call. It is converted to a SHA256(node id) 32-byte Kademlia id. This means it is practically impossible to implement the Kademlia bucket-refresh scheme by selecting a random id in the bucket range.

If you look at the ENR https://eips.ethereum.org/EIPS/eip-778 which references https://github.com/ethereum/devp2p/issues/43 there is good information on the discussion about the EIP.

trung commented 4 years ago

Thanks for the detail response. I guess the answer is "both are ok". However, NodeId in discv5 package is going to be moved/deprecated, despite the fact that its intention is still correct. It represents the node public key and also known as hex node id portion in the enode URL.

ID is used in Kademlia table https://github.com/ethereum/go-ethereum/blob/0568e817012753a9f71fffa50160990dbc3779a2/p2p/discover/table.go#L164-L176

Few things I noticed:

  1. NodeId in discv5 can be obtained via: https://github.com/ethereum/go-ethereum/blob/461291882edce0ac4a28f64c4e8725b7f57cbeae/p2p/discv5/node.go#L305-L314 However, there's another calculation using similar logic but with explicit curve S256() https://github.com/ethereum/go-ethereum/blob/461291882edce0ac4a28f64c4e8725b7f57cbeae/crypto/crypto.go#L136-L141
  2. ID is indeed keccak256() and not SHA256() https://github.com/ethereum/go-ethereum/blob/0568e817012753a9f71fffa50160990dbc3779a2/p2p/enode/idscheme.go#L80-L90