Tinychain源码阅读笔记4-p2p通信
for peer in peer_hostnames:
send_to_peer(block, peer)
在connect_block
函数最后,调用了send_to_peer
def send_to_peer(data, peer=None):
"""Send a message to a (by default) random peer."""
global peer_hostnames
peer = peer or random.choice(list(peer_hostnames))
tries_left = 3
while tries_left > 0:
try:
with socket.create_connection((peer, PORT), timeout=1) as s:
s.sendall(encode_socket_data(data))
except Exception:
logger.exception(f'failed to send to peer {peer}')
tries_left -= 1
time.sleep(2)
else:
return
logger.info(f"[p2p] removing dead peer {peer}")
peer_hostnames = {x for x in peer_hostnames if x != peer}
peer_hostnames = {p for p in os.environ.get('TC_PEERS', '').split(',') if p}
peer_hostnames
是全局定义的set
变量,也就是我们需要连接的节点ip地址,可由TC_PEERS
这个系统变量定义,ip地址由逗号分隔。
随机从peer_hostnames
中选取一个节点,进行socket.create_connection
连接,然后将加密的区块数据传递给这个节点,如果连接不上最多尝试三次,并将连接不上的节点移出peer_hostnames
。
def encode_socket_data(data: object) -> bytes:
"""Our protocol is: first 4 bytes signify msg length."""
to_send = serialize(data).encode()
return int_to_8bytes(len(to_send)) + to_send
encode_socket_data
首先将传进来的Block
对象解析成str
,然后转化成bytes
,此外,会在Block数据前添加该段数据字节长度。