Author

Topic: Is the handshake version-verack? (Read 137 times)

copper member
Activity: 1330
Merit: 899
🖤😏
March 07, 2023, 01:17:01 PM
#9
Say verack comes first. Then the node which initiates the connection sends version, then receiving node responds with varack-version in this order and then the initiating node responds with its own verack. What's the problem?
Do you have any example to show us? Where did you see any interruption between sender and receiver?

Edit, according to my source, both clients need to exchange their versions first, then the header ( verack ).

Read from here, https://en.bitcoin.it/wiki/Protocol_documentation
newbie
Activity: 4
Merit: 2
March 07, 2023, 11:01:53 AM
#8
Connections are two way (bidirectional) not one way and what you refer to as "listener" is just listening for incoming connections so after that it receives a connect request it opens up a new "socket" where it can both send and receive messages over TCP at the same time.

The reason why you see version first then verack second or vice versa is that the clients put both messages into a single "package" and then send it over the opened socket. This only make implementation slightly more complicated (to handle both cases).

Otherwise to make sure other node receives verack first it would have to first initiate a "I/O send" operation for verack then finish it and initiate another for version and both messages are tiny and have to be sent so it makes sense to send them together.
I know now that both message orders are supported but I'm still a bit unclear on this explanation though. By packet do you mean a single TCP packet? I still don't get why, even if the verack and the version are sent together somehow, we don't just specify that one comes first.

Say verack comes first. Then the node which initiates the connection sends version, then receiving node responds with varack-version in this order and then the initiating node responds with its own verack. What's the problem?
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
March 07, 2023, 01:33:02 AM
#7
Ok. Then what is the reason the protocol doesn't specify whether the listener should respond with version or verack first?

Here is what I found inside Bitcoin Core unit tests that seems to imply that nodes can send anything before receiving the "verack" message:

Code:
"""Test message sending before handshake completion.
Before receiving a VERACK, a node should not send anything but VERSION/VERACK
and feature negotiation messages (WTXIDRELAY, SENDADDRV2).
This test connects to a node and sends it a few messages, trying to entice it
into sending us something it shouldn't."""

And this is from another unit test that appears to support the theory that the version message should be received before verack is sent:

Code:
        p2p_conn.peer_connect(**kwargs, net=self.chain, timeout_factor=self.timeout_factor)()
        self.p2ps.append(p2p_conn)
        p2p_conn.wait_until(lambda: p2p_conn.is_connected, check_connected=False)
        if wait_for_verack:
            # Wait for the node to send us the version and verack
            p2p_conn.wait_for_verack()
            # At this point we have sent our version message and received the version and verack, however the full node
            # has not yet received the verack from us (in reply to their version). So, the connection is not yet fully
            # established (fSuccessfullyConnected).
            #
            # This shouldn't lead to any issues when sending messages, since the verack will be in-flight before the
            # message we send. However, it might lead to races where we are expecting to receive a message. E.g. a
            # transaction that will be added to the mempool as soon as we return here.
            #
            # So syncing here is redundant when we only want to send a message, but the cost is low (a few milliseconds)
            # in comparison to the upside of making tests less fragile and unexpected intermittent errors less likely.
            p2p_conn.sync_with_ping()

Pay special attention to this section:

Code:
            # At this point we have sent our version message and received the version and verack, however the full node
            # has not yet received the verack from us (in reply to their version). So, the connection is not yet fully
            # established (fSuccessfullyConnected).

I'm sure you can get a more precise answer by inspecting the P2P code written in C++, but then it's not guaranteed that other full nodes will do the same thing. Just do what ymgve2 said and handle both cases.
legendary
Activity: 3472
Merit: 10611
March 06, 2023, 10:57:47 PM
#6
Connections are two way (bidirectional) not one way and what you refer to as "listener" is just listening for incoming connections so after that it receives a connect request it opens up a new "socket" where it can both send and receive messages over TCP at the same time.

The reason why you see version first then verack second or vice versa is that the clients put both messages into a single "package" and then send it over the opened socket. This only make implementation slightly more complicated (to handle both cases).

Otherwise to make sure other node receives verack first it would have to first initiate a "I/O send" operation for verack then finish it and initiate another for version and both messages are tiny and have to be sent so it makes sense to send them together.
newbie
Activity: 4
Merit: 2
March 06, 2023, 06:19:25 PM
#5
Ok. Then what is the reason the protocol doesn't specify whether the listener should respond with version or verack first?
full member
Activity: 161
Merit: 230
March 06, 2023, 04:14:53 PM
#4
Why doesn't the protocol just specify this? Oh I guess there is a remote chance 2 peers both try and initiate a connection with each other at the same time. Specifying one or the other would cause a handshake failure if the listener sent a version message (coincidentally) whilst the client's own version message was in flight.

If both peers try to connect to each other at the same time, it will result in two different TCP connections, it doesn't automatically become a single connection.
newbie
Activity: 4
Merit: 2
March 06, 2023, 03:48:41 PM
#3
Why doesn't the protocol just specify this? Oh I guess there is a remote chance 2 peers both try and initiate a connection with each other at the same time. Specifying one or the other would cause a handshake failure if the listener sent a version message (coincidentally) whilst the client's own version message was in flight.
full member
Activity: 161
Merit: 230
March 06, 2023, 03:31:08 PM
#2
Since it's not properly specified: your code should handle both cases.
newbie
Activity: 4
Merit: 2
March 06, 2023, 02:44:02 PM
#1
I have read conflicting specs online: when a node initiates a connection to another node, does the protocol level handshake go:
version -->
version <--
verack <--
verack -->

OR

version -->
verack <--
version <--
verack -->

(arrow from left to right represents a message from the connecting node to the listening node, and vice versa)

In other words, does the listening node respond first with verack and then with a version message, or vice versa? Thanks all
Jump to: