Bismuth源码剖析(三)—-客户端的工作流程

前两篇介绍了node节点的工作流程和node节点作为服务端的工作流程,这一篇介绍下node节点作为客户端的工作流程

在node节点启动后,会启动一个服务端的线程和一个客户端的线程,客户端的代码如下:

t_manager = threading.Thread(target=manager(c, conn))

然后去看下对应的函数manager(c, conn)

首先是peer_dict = peers_get(),获取peers.txt中的对端IP,然后比较关键的代码就是

t = threading.Thread(target=worker, args=(HOST, PORT))

启动一个线程worker去处理这个链接

所以我们去看下worker函数

this_client = (HOST + ":" + str(PORT))
s = socks.socksocket()
if tor_conf == 1:
    s.setproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
# s.setblocking(0)
s.connect((HOST, PORT))   建立远端链接
app_log.warning("Outbound: Connected to {}".format(this_client))

# communication starter

发送版本信息
connections.send(s, "version", 10)
connections.send(s, version, 10)

对端会根据信息返回对应的结果,这一部分在服务端的流程中有讲解
data = connections.receive(s, 10)

if (data == "ok"):
    app_log.info("Outbound: Node protocol version of {} matches our client".format(this_client))
else:
    raise ValueError("Outbound: Node protocol version of {} mismatch".format(this_client))

如果对端允许链接,则发送hello
connections.send(s, "hello", 10)

接下来就是等待对端给出响应

介绍到对端的响应后,根据不同的内容走不同的分支

peers:
继续接收对端的内容,主要是对端的peers信息,然后进行测试,如果可以链接则更改本地的peers.txt

sync:
发送blockheight给对端,然后接收对端给出的received_block_height
if int(received_block_height) < db_block_height: data = connections.receive(s, 10) 接收对端的hash数据 if db_block_hash == data: connections.send(s, "nonewblk", 10) 给对端发送nonewblk else: connections.send(s, "blocksfnd", 10) confirmation = connections.receive(s, 10) if confirmation == "blockscf": connections.send(s, blocks_send, 10) elif confirmation == "blocksrj": pass elif int(received_block_height) >= db_block_height:
connections.send(s, db_block_hash, 10) 给对端发送本地最新的hash数据

blocknf:
block_hash_delete = connections.receive(s, 10) 接收对端发送的hash数据,然后在数据库中删除这些数据
connections.send(s, “sendsync”, 10) 发送sendsync给对端

blocksfnd:
if int(received_block_height) >= block_req: 判断接收的block与本地block_req的关系
connections.send(s, “blockscf”, 10) 发送blockscf给对端
segments = connections.receive(s, 10) 接收对端的消息
digest_block(segments, s, peer_ip, conn, c, mempool, m, hdd, h, hdd2, h2, h3) 消化对端的消息
else:
connections.send(s, “blocksrj”, 10) 发送blocksrj给对端
connections.send(s, “sendsync”, 10) 发送sendsync给对端

nonewblk:
connections.send(s, “mempool”, 10) 发送mempool给对端
connections.send(s, mempool_txs, 10) 发送本地的mempool_txs给对端
segments = connections.receive(s, 10) 接收对端发送的信息
mempool_merge(segments, peer_ip, c, mempool, m) 消息对端的mempool_txs信息
connections.send(s, “sendsync”, 10) 发送sendsync给对端