programmingbitcoin icon indicating copy to clipboard operation
programmingbitcoin copied to clipboard

Handshake code issue

Open Engelberg opened this issue 6 years ago • 5 comments

In the handshake code on page 183 of the book, in the line with the numbered comment 3, the and should be an or.

Also, I note that in answers.py for chapter 10, the handshake code there doesn't reflect the logic described on page 183. The answer code only waits for VerAckMessage, it doesn't wait for the other node to send its VersionMessage.

Engelberg avatar May 17 '19 05:05 Engelberg

Another issue is that the example handshake code (p. 183) is sending VerAckMessage twice, the first time in the wait_for method and the second in the conditional after the wait_for call.

chanhosuh avatar Jun 30 '19 22:06 chanhosuh

I've addressed the above issues in PR #152.

chanhosuh avatar Jun 30 '19 22:06 chanhosuh

Please, could someone point me to an alternative implementation that is asynchronous and, in general, better than the wait_for call ?

As the author says, "A commercial-strength node would definitely not use something like this.", so I would like to know how to do it properly.

Thanks in advance.

xamevou avatar Mar 17 '21 15:03 xamevou

Here's the parse method if anybody needs it:

@classmethod
    def parse(cls, s):
        version = little_endian_to_int(s.read(4))
        services = little_endian_to_int(s.read(8))
        timestamp = little_endian_to_int(s.read(8))
        receiver_services = little_endian_to_int(s.read(8))
        receiver_ip = s.read(16)
        receiver_port = s.read(2)
        sender_services = little_endian_to_int(s.read(8))
        sender_ip = s.read(16)
        sender_port = s.read(2)
        nonce = s.read(8)
        user_agent_length = read_varint(s)
        user_agent = s.read(user_agent_length)
        latest_block = little_endian_to_int(s.read(4))
        relay = True if s.read(1) == b'\x01' else False
        
        return cls(version, services, timestamp,
                 receiver_services,
                 receiver_ip, receiver_port,
                 sender_services,
                 sender_ip, sender_port,
                 nonce, user_agent,
                 latest_block, relay)

sjorsvanheuveln avatar Oct 28 '21 21:10 sjorsvanheuveln

One note I'd add is when parsing the receiver and sender IP's, you might need to read the first 12 bytes and do nothing with them, and then save the sender/receiver IPs in the next 4 bytes. When you serialize the object, we add b'\x00'*10 + b'\xff'*2 to the IP. See code below:

    receiver_services = little_endian_to_int(s.read(8))
    s.read(12)
    receiver_ip = s.read(4)
    receiver_port = int.from_bytes(s.read(2), 'big')
    sender_services = little_endian_to_int(s.read(8))
    s.read(12)
    sender_ip = s.read(4)
    sender_port = int.from_bytes(s.read(2), 'big')

wickblue avatar Oct 17 '23 15:10 wickblue