submitblock:把整块直接递进节点的命令,返回值怎么读 图 1
submitblock:把整块直接递进节点的命令,返回值怎么读 · 图 1

挖过矿、搭过节点的人大概都听过 submitblock 这条命令:把一个区块的十六进制整块丢给节点,让它去验证并广播。听起来像是矿机对接的标准入口,但它和大多数挖矿软件实际用的 getblocktemplate 并不是同一套流程,返回值的读法也很容易踩坑。本文按 Bitcoin Core v31.0 源码 src/rpc/mining.cpp 里的实现逐段拆解。

命令的来历:一个为 BIP22 保留的占位参数

submitblock 的帮助文本第一句就是 “Attempts to submit new block to network”,并直接把读者指向 BIP 22 规范页。函数签名上它接受两个参数:第一个 hexdata 是必填的区块十六进制;第二个参数在源码里被明确标注为 dummy,说明文字写的是 “dummy value, for compatibility with BIP22. This value is ignored”。源码注释同样直白:为了符合 BIP22 而保留两个参数,第二个参数忽略。

这段历史值得说清楚。BIP 22 定义的是 getblocktemplate(GBT)这套挖矿 RPC 协议,Bitcoin Core 从 v0.7.0 起实现它,这一点记在源码树 doc/bips.md 的对账簿里。BIP 22 早期草案把提交区块和提交区块头当作同一套接口设计,要求提交时带上客户端自己生成的 jobid 或前一次返回的签名数据,用来把结果对回具体任务。Bitcoin Core 后来的实现把任务关联逻辑放回了 getblocktemplate 的长轮询与 submitdata 里,submitblock 只剩”递一块进来”这一件事,第二个参数因此退化成兼容占位。理解这一点很重要:如果你在自己的矿池代理里指望靠第二个参数做任务配对,那套逻辑在 Core 上是空转的。

submitblock:把整块直接递进节点的命令,返回值怎么读 图 2
submitblock:把整块直接递进节点的命令,返回值怎么读 · 图 2

返回值的四种命运

源码里 submitblock 的返回分支一共四条,读法各不相同。

第一条是空返回。如果区块被节点接受,RPC 不返回任何数据(RPCResult 里写的是 “If the block was accepted” 对应 Type::NONE)。矿池程序里用”没有错误也没有字符串”当成功判据是可行的,但要注意这只能说明这块进了本地处理流程。

第二条是字符串 duplicate。实现里的判断条件是 !new_block && accepted——区块被验证接受,但节点此前已经见过它。这在矿池切换节点、或者同一块被从两条路径提交时会出现,属于正常现象,不代表你算的块有问题。

第三条是 inconclusive,对应条件是 !sc->found。这是这条命令最微妙的一档。实现方式叫状态捕获器:submitblock 先注册一个 submitblock_StateCatcher 验证接口回调,然后调用 ProcessNewblock 强制处理这个区块,处理完再注销回调。回调会记录验证结果是否针对目标哈希触发。如果整个流程跑完,回调压根没被这个区块触发过——比如区块进了队列但这一轮没走到落地判定——结果就返回 inconclusive。它既不是接受也不是拒绝,意思是”这台节点现在给不出结论”。稳妥的后续动作是隔一会儿用 getblock 按高度或哈希查这块到底进没进链,而不是当失败重算。

第四条是 BIP22 风格的验证错误串,由 BIP22ValidationResult 把验证状态机里的拒绝原因包装成字符串返回,常见形如 high-hashbad-cb-amount 这类短代号,对得上区块校验各层的规则名。十六进制本身解不出来时更早一步抛反序列化错误,提示词是 Block decode failed。

它与 getblocktemplate 的分工

标准矿机流程是拿模板、算哈希、把结果填回模板再提交,任务身份由 GBT 一侧的数据决定;submitblock 则是无状态的”这块请验一下”。它更适合的场景其实很少:手工复现一个坏块观察本地节点反应、把从别处离线拿到的完整区块塞进一个断网节点(v31.0 的源码里 ProcessNewBlock 对这条路径调用时显式打开了强制处理与工作证明已检查两个开关,前者意味着它会顶过普通的排序判断)、以及在集成测试里造块。对生产矿池来说,submitblock 不是任务提交通道,用它做提交会丢掉 GBT 的长轮询、版本协商与作业声明这些机制。

风险提示:本文是协议与 RPC 机制说明,涉及矿池对接或脚本改动时请先在测试网演练验证;本文不构成投资建议。