ping源码分析
进入主方法
初始化配置
如果是master,初始化数据
删除 reachable
删除 open
删除 opendata
删除 ping:cidr:*
- 根据配置的 workers 数量初始化线程池
启动相应数量的 cron 线程
- cron函数的内容
publish_key = snapshot:{} (magic_number)
都在一个true循环里面:
如果是master:
读取crawler打印的json中,最新的一个文件,同时把文件的节点读成一个数组
遍历节点数组,如果节点不在 open 集合中,就把节点加到 reachable 集合中
稍微休息了一下
publish了 publish_key和当前时间点
调用 set_bestblockhash() 方法,找到一个比较好的节点(50%以上节点都认可)
如果 lastblockhash 是空,return
如果 bestblockhash 和 lastblockhash 一样,return
从 nodes 查询节点总数 (= reachable_nodes)
查询 inv:2:****{} (lastblockhash) 的总数 (= nodes)
如果 nodes >= reachable_nodes / 2
设值 bestblockhash = lastblockhash
查询 reachable 里有多少个节点,启动相应数量的 task 线程
- task函数的内容
从 reachable 中获取一个元素,并且不移除元素 (= node)
如果是ipv6地址,ping:cidr:****{} 累加1,如果累加之后的值大于1(配置的值),减1,目前始终是1,return
添加 node 到 open 列表里,如果已经存在就退出
和节点建立连接,握手连接,获取 handshake_msgs 消息,如果 handshake_msgs 是空,从 open 中移除node
调用 Keepalive,与指定节点保持连接
设值 opendata
node + (version, user_agent, last_ping, services)
"(u'96.244.222.237', 8333, 70015, '/Satoshi:0.19.1/', 1589609394, 1033)"
在一个true循环里
ping方法
发送 消息给节点
key = ping:{}-{}:****{} (address, port, nonce)
redis设值 key,值为现在的时间 ,也就是发送ping消息的时间
redis设置 key 过期时间 3个小时
成员属性 keepalive_time = elapsed,这个值影响发ping请求的频率
send_bestblockhash方法
查询 bestblockhash,如果和 类里面的 last_bestblockhash (默认None)一样,return
发送 命令,参数 bestblockhash(没有返回值)
类的 last_bestblockhash = bestblockhash
send_addr方法
从 opendata 里随机取 10 条
如果取出来的 services 不是 1,跳过
将取出来的 10 个节点信息发送 命令到当前连接(3小时不发,比特币节点就会忘记你)
如果出来循环了,就移除一开始设值的 opendata
问题:
ping脚本的worker数是多少
一个线程池 2000 个worker,一共7个线程池一共 14000 个task,最多同时ping一万四个节点。
cron里publish了 snapshot,在哪儿订阅的?
resolve脚本
cron里设值 bestblockhash 依赖于 inv:2:****{} 的总数, *inv:2:***{}**是哪儿设值的?
pcap脚本
ping:cidr:* 有什么用?