src.protocol

Implementation of the P2P protocol.

The protocol is text-based and works over TCP. Once a TCP connection is established, there is no difference between server and client. Both sides start by sending a fixed HELLO_MSG to make sure they speak the same protocol. After that, they can send any number of messages.

Messages start with a length (ending with a new-line), followed by the JSON-encoded contents of the message of that length. On the top level, the sent JSON values are always dicts, with a ‘msg_type’ key indicating the kind of message and a ‘msg_param’ key containing a type-specific payload.

To make sure that the peer acting as a TCP server in a connection knows how to reach the TCP client, there is a ‘myport’ message containing the TCP port where a peer listens for incoming connections.

For other message types, you can look at the received_* methods of Protocol.

Functions

Classes

PeerConnection(peer_addr, proto[, sock]) Handles the low-level socket connection to one other peer.
Protocol(bootstrap_peers, primary_block[, ...]) Manages connections to our peers.
class src.protocol.Protocol(bootstrap_peers, primary_block, listen_port=0, listen_addr='')

Manages connections to our peers. Allows sending messages to them and has event handlers for handling messages from other peers.

Variables:
  • block_receive_handlers (List[Callable]) – Event handlers that get called when a new block is received.
  • trans_receive_handlers (List[Callable]) – Event handlers that get called when a new transaction is received.
  • block_request_handlers (List[Callable]) – Event handlers that get called when a block request is received.
  • peers (List[PeerConnection]) – The peers we are connected to.
broadcast_primary_block(block)

Notifies all peers and local listeners of a new primary block.

broadcast_transaction(trans)

Notifies all peers and local listeners of a new transaction.

received(msg_type, msg_param, peer, prio=1)

Called by a PeerConnection when a new message was received.

Parameters:
  • msg_type (str) – The message type identifier.
  • msg_param – The JSON-compatible object that was received.
  • peer (Optional[PeerConnection]) – The peer who sent us the message.
  • prio (int) – The priority of the message. (Should be lower for locally generated events than for remote events, to make sure self-mined blocks get handled first.)
received_block(block, sender)

Someone sent us a block.

received_disconnected(_, peer)

Removes a disconnected peer from our list of connected peers.

(Not actually a message received from the peer, but a message sent by the reader or writer thread to the main thread.)

received_getblock(block_hash, peer)

We received a request for a new block from a certain peer.

received_id(uuid, sender)

A unique connection id was received. We use this to detect and close connections to ourselves.

TODO: detect duplicate connections to other peers (needs TLS or something similar)

received_peer(peer_addr, sender)

Information about a peer has been received.

received_transaction(transaction, sender)

Someone sent us a transaction.

send_block_request(block_hash)

Sends a request for a block to all our peers.

class src.protocol.PeerConnection(peer_addr, proto, sock=None)

Handles the low-level socket connection to one other peer.

Variables:
  • peer_addr – The self-reported address one can use to connect to this peer.
  • param – The self-reported address one can use to connect to this peer.
  • _sock_addr – The address our socket is or will be connected to.
  • socket – The socket object we use to communicate with our peer.
  • proto – The Protocol instance this peer connection belongs to.
  • is_connected – A boolean indicating the current connection status.
  • outgoing_msgs – A queue of messages we want to send to this peer.
Parameters:

sock (Optional[socket]) – A socket object we should use to communicate with our peer.

close()

Closes the connection to this peer.

close_on_error()

A decorator that closes both threads if one dies.

run()

Creates a connection, handles the handshake, then hands off to the reader and writer threads.

Does not return until the writer thread does.

send_msg(msg_type, msg_param)

Sends a message to this peer.

Msg_type:The type of message.
Msg_param:the JSON-compatible parameter of this message
send_peers()

Sends all known peers to this peer.

src.protocol.MAX_PEERS = 10

The maximum number of peers that we connect to.

src.protocol.HELLO_MSG = b'bl0ckch41ne7295b4f1d7e80d722b3503a27eb7f\n'

The hello message two peers use to make sure they are speaking the same protocol. Contains the genesis block hash, so that communication of incompatible forks of the program is less likely to succeed.