Tinychain源码阅读笔记4-p2p通信

in #cn6 years ago

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数据前添加该段数据字节长度。