Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

Discovery protocol updates #1706

Merged
merged 35 commits into from
May 7, 2015
Merged

Discovery protocol updates #1706

merged 35 commits into from
May 7, 2015

Conversation

subtly
Copy link
Member

@subtly subtly commented Apr 21, 2015

unsigned ts;
NodeIPEndpoint source;
NodeIPEndpoint destination;
uint32_t ts;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not always initialized.

@chriseth
Copy link
Contributor

Are there tests for ipv6?

@subtly
Copy link
Member Author

subtly commented Apr 24, 2015

@chriseth simple IPv6 goes in after this is working, where simple means that only IPv4 or IPv6 is supposed (not both at once). It's supported by encapsulation but because the listener doesn't support IPv6 such nodes are simply not added to the table. IPv6 was removed previously because some changes are needed:

  • additional address verification and NAT is different
  • most IPv6 systems can connect to IPv4 systems, but reverse isn't true
  • must consider considering IPv6 as another network (node table, networkid)

@fjl
Copy link
Contributor

fjl commented Apr 27, 2015

This is not interoperable with go-ethereum (this branch) because IP addresses are encoded as RLP lists.
I think lists are not a good choice for IP addresses. But we need to decide.

I0427 02:33:57.213023   87752 udp.go:404] Bad packet from 127.0.0.1:30303: rlp: expected input string or byte for net.IP, decoding into (discover.ping).From.IP

The ping packets sent by Go look like this:

dc 04  cb 845b40e7ba    827660 827660  c9 847f000001 82765f 80   84553d833f
[  v   [  91.64.231.186 30304  30304 ] [  127.0.0.1  30303  0  ] expiration ]

The ones sent by C++ look like this:

de 04  cb c480808080    82765f 82765f  cb c47f808001    827660 827660  84553e0dc8 
[  v   [  [ 0 0 0 0 ]   30303  30303 ] [  [ 127 0 0 1 ] 30304  30304 ] expiration ] 

@@ -177,6 +185,9 @@ struct NodeIPEndpoint
operator bool() const { return !address.is_unspecified() && udpPort > 0 && tcpPort > 0; }

bool isAllowed() const { return NodeIPEndpoint::test_allowLocal ? !address.is_unspecified() : isPublicAddress(address); }

void streamRLP(RLPStream& _s, RLPAppend _inline = StreamList) const { if (_inline == StreamList) _s.appendList(3); if (address.is_v4()) _s << address.to_v4().to_bytes(); else if (address.is_v6()) _s << address.to_v6().to_bytes(); else _s << ""; _s << udpPort << tcpPort; }
void interpretRLP(RLP const& _r) { if (_r[0].size() == 0) address = bi::address(); else if (_r[0].size() == 4) address = bi::address_v4(_r[0].toArray<byte, 4>()); else address = bi::address_v6(_r[0].toArray<byte, 16>()); udpPort = _r[1].toInt<uint16_t>(); tcpPort = _r[2].toInt<uint16_t>(); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stylistic issues aside (296 characters in a line, including a three-way braceless conditional, oh my), there seems to be some confusion about the type of input here.

size() only works for RLP strings and returns 0 otherwise, yet toArray() is used, which only works for lists. If IP addresses are supposed to be represented as lists maybe this should switch on itemCount() instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fjl Byte string makes sense. Is that supported by Go?

ret.push_back(n);
return move(ret);
}

void NodeTable::ping(bi::udp::endpoint _to) const
void NodeTable::ping(NodeIPEndpoint _to) const
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const& ?

@gavofyork
Copy link
Contributor

code looks reasonable - as long as this is 100% compatible with Go, it looksgood.

@fjl
Copy link
Contributor

fjl commented Apr 30, 2015

The RLP encoding of pong is missing the destination endpoint:

@@ -330,8 +330,8 @@ struct Pong: RLPXDatagram<Pong>
    h256 echo;              ///< MCD of PingNode
    uint32_t ts = 0;
-   void streamRLP(RLPStream& _s) const { _s.appendList(2); _s << echo << ts; }
-   void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); echo = (h256)r[0]; ts = r[1].toInt<uint32_t>(); }
+   void streamRLP(RLPStream& _s) const { _s.appendList(3); destination.streamRLP(_s); _s << echo << ts; }
+   void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); destination.interpretRLP(r[0]); echo = (h256)r[1]; ts = r[2].toInt<uint32_t>(); }
 };

 /**

@fjl
Copy link
Contributor

fjl commented Apr 30, 2015

With the pong encoding fixed, we are interoperable once again.

@fjl
Copy link
Contributor

fjl commented Apr 30, 2015

Is the sha3 distance going to be part of this PR?

@subtly
Copy link
Member Author

subtly commented Apr 30, 2015

@fjl Nice catch. How'd you create a comment like that?

@fjl
Copy link
Contributor

fjl commented Apr 30, 2015

I pasted the diff and put diff ... around it.

@fjl
Copy link
Contributor

fjl commented Apr 30, 2015

I tested again, the ping/pong seems to work (geth is accepting a pong sent by cpp). It looks like
eth doesn't accept the pongs from geth, though, because it doesn't reply to findnode.

eth crashed after ~15seconds. The nodes exchanged blocks before the crash. Trace here: https://gist.github.com/fjl/f08e36c5d4026f37085c

@fjl
Copy link
Contributor

fjl commented May 5, 2015

I have tested this again. The crash is no longer happening and cpp responds to findnode if it has nodes in the table.

gavofyork pushed a commit that referenced this pull request May 7, 2015
Discovery protocol updates
@gavofyork gavofyork merged commit c85b3f6 into ethereum:develop May 7, 2015
@subtly subtly deleted the discovery branch May 7, 2015 16:07
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants