用 bitcoin-cli 或者 HTTP 调用节点时,报错返回的是一个负数。很多脚本只把这段错误原样打印出来给人看,于是同样的 -4 今天被重试一百次、明天被直接忽略。比特币核心的错误码是一份写死在源码里的机器可读接口:v31.0 的 rpc/protocol.h 把所有码值分成四个来源不同的组,每组的正确处置方式完全不同。把这张表读明白,节点自动化脚本的失败处理才有依据。
第一组是 JSON-RPC 协议自身的标准码,值为 -32700 到 -32600 这一族:解析失败、请求结构不合法、方法不存在、参数不匹配、内部错误。它们的共同点是请求根本没有进入比特币的业务逻辑。头文件中对其中两个还写了 HTTP 映射说明:RPC_INVALID_REQUEST 内部映射为 HTTP 400,RPC_METHOD_NOT_FOUND 映射为 404。这类错误重试毫无意义,因为下一次请求还是同一个坏请求,唯一正确的动作是修调用方——改方法名拼写、补参数、修 JSON 转义。
第二组是通用业务错误,码值不大但含义很杂:-1 是命令处理里抛了未分类异常,-3 是参数类型不对,-5 是地址或密钥无效,-8 是参数缺失或重复,-7 是内存耗尽,-20 是数据库错误,-22 是结构解析失败,-25 是提交交易或区块时的通用校验失败,-26 是被网络规则拒绝,-27 在 v31.0 的注释里写作“交易已在 UTXO 集合中”,-28 是节点仍在预热,-32 是方法已弃用。这一组要拆开看:-8 与 -3 属于调用方 bug;-25 与 -26 说明交易本身不合规或与其他交易冲突,重试只会反复失败,必须重新构造;-22 说明传进去的十六进制根本不是合法结构;-28 是唯一一个“等一等就好”的码,因为它表示节点还在启动过程中。-32 值得单独记住,它是一个信号:某个 RPC 已经走进弃用通道,官方给了过渡窗口,长期依赖它的脚本要在某个版本后突然失灵的后果。
第三组是节点状态类错误,反映的不是你的请求有问题,而是这台节点当前的运行条件不允许。-9 表示未连接任何对端,-10 表示仍在初始区块下载中,-23 与 -24 是手动连接的增删冲突,-29 是要断开的目标本来就没连,-30 是 IP 或子网写法不合法,-31 是 P2P 功能整体关闭,-33 表示这个节点没有内存池实例(典型场景是只收块模式),-34 表示出站或区块专线连接名额已满。这一组的正确动作几乎都是“等条件满足再来”或“换一个端点问”,而不是原地重试。比如对 -34 反复重试只会把队列堆满;正确做法是复用现有连接或者降低并发。
第四组是钱包类,码段密集中在 -4 到 -19 与 -35:-4 是钱包侧的未指明问题,-6 余额不足,-11 标签名不合法,-12 密钥池耗尽需要先补充密钥窗口,-13 需要先用口令解锁,-14 口令错误,-15 加密状态与命令不匹配,-16 加密失败,-17 已经解锁,-18 找不到指定钱包,-19 是没指定钱包而在多钱包加载时无法判断该操作作用于哪一个,-35 是同一个钱包文件已被加载。其中 -12 和 -19 是最容易被误当成“节点坏了”的两个:-12 的正确处置是按钱包的密钥范围刷新或导入更大区间,-19 则是多钱包节点的必然后果,解法是在调用里显式指定钱包,而不是重试。
有了分组,重试策略就能写成一个不依赖错误文本的判断。稳定的是码值,会漂的是 message 字符串——版本升级时官方会调整提示语,甚至同一码在不同路径下附带不同细节,所以任何“匹配报错文字来决定行为”的脚本都在制造未来的故障。按码值分支的写法完全不同:JSON-RPC 标准码转成配置修复工单;状态码进等待队列并带退避;业务码直接失败并把交易回捞给上层重做。
三个实操提醒。第一,-28 与 -10 长得像但不是一回事:前者是进程还在启动,后者是已经连网但还没追上链,等待的超时设置应当不同。第二,-26 的 message 里常带一个短代号(例如替换规则、脚本限制一类的标识),那才是定位根因的关键,日志里要保留而不是只留数字。第三,钱包类错误在节点侧和钱包侧的因果链可能隔了几层,看到 -4 时先看同时间点的 debug 日志,比反复试命令有效得多。整张表的本质是把“谁该负责”编码进了符号:调用方、节点状态、交易本身、钱包配置,四类各占一段,看清归属,重试与告警才不会打错地方。
风险提示:本文为节点接口机制说明,不构成任何投资建议;文中码值与语义以比特币核心 v31.0 源码为准,升级后可能变化,请按对应版本源码核对。

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