比特币核心对外 announcing 自己的地址时,有一件事很容易被忽略:这个”自己的地址”很多时候不是节点算出来的,而是别的节点”告诉”它的。别人在握手 version 消息里附上”我看到的你是某某地址”,节点把这类证言收集、打分、投票,再按 24 小时一次的节拍决定要不要向对端公告。本文按 v31.0 源码拆解这条从他人证言到自我公告的流水线。
一、version 消息里的 addrMe。每条主动连进来的对端,握手时会在 version 消息里带一个它视角下的本节点地址(术语 addrMe)。net_processing 处理 version 时,若是入站连接且该地址可路由,就调用 SeenLocal(addrMe) 给本机地址表里的对应条目投一票——mapLocalHost 是节点心里的”我可能是谁”候选表,每条带一个分数。对端自己视角的”我的地址”也会单独记在该连接上(addrlocal),供后面交叉核对。
二、本机地址表怎么建。这张表的条目有来源等级,net.h 里的阶梯是:LOCAL_NONE(未知)、LOCAL_IF(本机网卡监听的地址)、LOCAL_BIND(参数显式绑定的地址)、LOCAL_MAPPED(PCP 协议报告的映射地址)、LOCAL_MANUAL(-externalip 显式声明)。等级决定可信度:-externalip 是主人亲口说的,优先级最高;网卡与绑定是环境事实;对端证言只是加分项。收到多个对端报告同一地址,等于多张同地点名票——这正是”家庭宽带公网 IP 会被自动发现并公告”的实现路径。
三、什么时候听对端的。GetLocalAddrForPeer 决定向某个对端公告哪个地址:若本机已有可路由的自认地址,默认用它;但若没有,或者对端的”我所见”通过了准入检查(发现功能开启、双方地址都可路由、该网段可达),节点会以概率改用对端报告的地址——本机分数高于 MANUAL 档时抽查频率低(约八分之一),否则更高(约二分之一)。注释写得很坦白:万一对端比你更清楚你的公网长相,就用它。这也解释了 NAT 后节点的常见体验:只要有一个正确看到你外部地址的邻居,公告就能纠偏。
四、24 小时节拍与两条并行的钟。net_processing 里三个常量常被混谈:AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 小时,是本节点向每个对端重新公告自己地址的平均间隔,按指数随机抖动执行;AVG_ADDRESS_BROADCAST_INTERVAL = 30 秒是向对端细水长流送”邻居地址”的节拍;ROTATE_ADDR_RELAY_DEST_INTERVAL = 24 小时是同一批外部地址轮换中继目标的周期。三者分别管”我说我自己""我转发朋友""我换个方向转发”,排障时先分清动的是哪只钟。自己的公网地址迟迟不出现在别人的地址库里,查 24 小时这只;邻居地址灌不满你的库,查 30 秒那只。
五、运维边界与误解。第一,localaddresses 为空不等于节点坏了:全走代理、只监听 onion、或从未有入站连接时,本就不知道该公告什么,属正常。第二,想让节点隐身,正确开关是 -listen=0(不再被连)或在代理配置下关闭发现,而不是到处问”我广播得太频繁怎么办”——24 小时已经是刻意放慢的节拍,再快会显著加重全网地址库的重复流量。第三,动态 IP 用户的正确工具是 -externalip 或带认证的控制面板定时更新,比赌对端证言稳定更可靠。地址公告的全部设计哲学一句话:把自己交给网络的部分尽量少,借别人的眼睛的部分尽量可验证。
风险提示:本文内容为技术机制科普,不构成任何投资建议、收益承诺或买卖时机判断。涉及协议规则与软件行为的描述以对应软件版本(文中已标注)的官方源码与规范为准。涉及资金操作的,请先在测试网或小额环境验证。

发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。