Bitcoin Forum
May 07, 2024, 12:50:46 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Is the handshake version-verack?  (Read 111 times)
wunchofbankers (OP)
Newbie
*
Offline Offline

Activity: 4
Merit: 2


View Profile
March 06, 2023, 07:44:02 PM
Merited by ABCbits (2)
 #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
1715086246
Hero Member
*
Offline Offline

Posts: 1715086246

View Profile Personal Message (Offline)

Ignore
1715086246
Reply with quote  #2

1715086246
Report to moderator
1715086246
Hero Member
*
Offline Offline

Posts: 1715086246

View Profile Personal Message (Offline)

Ignore
1715086246
Reply with quote  #2

1715086246
Report to moderator
1715086246
Hero Member
*
Offline Offline

Posts: 1715086246

View Profile Personal Message (Offline)

Ignore
1715086246
Reply with quote  #2

1715086246
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1715086246
Hero Member
*
Offline Offline

Posts: 1715086246

View Profile Personal Message (Offline)

Ignore
1715086246
Reply with quote  #2

1715086246
Report to moderator
1715086246
Hero Member
*
Offline Offline

Posts: 1715086246

View Profile Personal Message (Offline)

Ignore
1715086246
Reply with quote  #2

1715086246
Report to moderator
ymgve2
Full Member
***
Offline Offline

Activity: 161
Merit: 230


View Profile
March 06, 2023, 08:31:08 PM
 #2

Since it's not properly specified: your code should handle both cases.
wunchofbankers (OP)
Newbie
*
Offline Offline

Activity: 4
Merit: 2


View Profile
March 06, 2023, 08: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.
ymgve2
Full Member
***
Offline Offline

Activity: 161
Merit: 230


View Profile
March 06, 2023, 09: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.
wunchofbankers (OP)
Newbie
*
Offline Offline

Activity: 4
Merit: 2


View Profile
March 06, 2023, 11: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?
pooya87
Legendary
*
Offline Offline

Activity: 3444
Merit: 10555



View Profile
March 07, 2023, 03:57:47 AM
Merited by ABCbits (1)
 #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.

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
NotATether
Legendary
*
Offline Offline

Activity: 1596
Merit: 6730


bitcoincleanup.com / bitmixlist.org


View Profile WWW
March 07, 2023, 06:33:02 AM
Merited by ABCbits (3)
 #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.

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
wunchofbankers (OP)
Newbie
*
Offline Offline

Activity: 4
Merit: 2


View Profile
March 07, 2023, 04:01:53 PM
 #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?
digaran
Copper Member
Hero Member
*****
Offline Offline

Activity: 1330
Merit: 899

🖤😏


View Profile
March 07, 2023, 06:17:01 PM
Last edit: March 07, 2023, 06:43:21 PM by digaran
 #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

🖤😏
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!