协议演进 / BIP/比特币改进提案 / BIP-310
BIP-310
为 Stratum 挖矿协议定义通用的扩展协商机制 mining.configure,并首先规范 version rolling:让矿工与矿池协商可改写的 nVersion 位。本 BIP 目前处于草案状态。
一、档案卡
| 编号 | BIP-310 |
|---|---|
| 标题 | Stratum protocol extensions |
| 作者 | Pavel Moravec <[email protected]>、Jan Čapek <[email protected]> |
| 指定日期 | 2018-03-10 |
| 层级 | Applications(应用) |
| 类型 | Informational(信息类) |
| 状态 | Draft(草案) |
| 阅读版 | https://bips.dev/310 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0310.mediawiki |
二、放在哪一族
挖矿协议族。Stratum 是矿工(矿机)与矿池服务器之间通信的协议;比特币早期的挖矿协议文档还有 BIP-40、BIP-41(Stratum 线路协议与挖矿协议,仅分配编号)与 BIP-22、BIP-23(getblocktemplate,节点与矿池之间取区块模板的接口)。
BIP-310 不重写 Stratum,而是给它加一层“扩展协商”:以后再加新功能,不必再逐个发明新消息。它规范的第一个、也是最重要的扩展 version rolling,与区块头 nVersion 位的用途直接相关,因此常与下面两篇一起读:
BIP-320:把 nVersion 的 16 位预留为通用用途
BIP-323:把预留扩大到 24 位
三、它要解决什么
3.1 矿工想改 nVersion,却没法告诉矿池
最初的动机是 version rolling:矿工改写区块头第一个字段 nVersion 的值。区块头里可供矿工滚动的空间有限,多滚一些位能减少向矿机分发新任务的频率;其中 AsicBoost 等技术也要用到 nVersion 的位。
但在原始 Stratum 协议里,这件事做不成:矿工无法把不同的区块版本值传达给服务器,服务器也无法把“哪些位可以安全滚动”告诉矿工。这是一个与旧协议不兼容的改动,矿工与矿池两侧都必须实现某种协议扩展才能支持。
3.2 乱发未知消息不安全
原文指出一个现实约束:通常矿工若向服务器发送未知消息,服务器会直接关闭连接(并非所有实现都这样,但有些会)。因此试探性地发送未知消息并不安全。
3.3 借一次不兼容改动,做成通用机制
作者的取舍是:既然不得不做一次不兼容改动,就把它做成通用的——引入一条新消息 mining.configure,统一处理特性的初始配置与协商。此后添加新特性不必再增加新消息;矿工既能宣告自己的能力,也能向服务器请求所需特性。原文要求同一协商机制也能服务于尚未知晓的未来特性,且在挖矿软件中应当易于实现。每个扩展有一个唯一字符串名,称扩展代码(extension code)。
四、规则本身
4.1 mining.configure 消息
这是矿工在与服务器建立连接后应当发送的第一条消息(JSON-RPC 请求)。它带两个必填参数:
- extensions:扩展代码列表,矿工应宣告其全部可用特性;
- extension-parameters:各扩展的参数映射。参数名按约定由扩展代码加点号加参数名构成,例如 version-rolling.mask 是 version-rolling 扩展的 mask 参数。
返回值为一张映射:extensions 列表中的每个代码都必须有明确返回值——true 表示该特性被支持、配置被理解并应用;false 表示不支持或未知;字符串则表示出错信息。某些扩展还借返回映射把附加信息(如最终掩码)送回矿工。
原文在规范部分列出的扩展有三个:version-rolling、minimum-difficulty、subscribe-extranonce;正文另行定义了 info 扩展。
4.2 扩展一:version-rolling
矿工发送一个掩码,说明自己能改写哪些位(1 为可改、0 为不可改,称 miner_mask),并给出高效滚动所需的最少位数(version-rolling.min-bit-count,必填)。服务器通常只允许改写其中一部分位(server_mask),其余位须固定——例如区块要保持有效、或某些位正用于信号。服务器的回应掩码是两者的交集:
response = server_mask & miner_mask
参数与返回值要点:
- version-rolling.mask(可选,类型 TMask,即 8 位十六进制字符串):矿工可改的位;缺省值为 “ffffffff”,且预期在整个挖矿会话内稳定。
- version-rolling.min-bit-count(必填,大于等于 0 的整数):矿工高效滚动所需的最少位数。原文提醒该参数对矿池有诊断价值;若请求位数超过矿池上限,矿工总可以降级运行,矿池不应为此断开矿工连接。
- 返回的 version-rolling.mask:服务器应返回尽可能大的掩码。原文还提到,服务器选掩码时应优先覆盖相关 BIP 所规定的 nVersion 位——这正是与 BIP-320 的衔接点。
协商成功后,服务器可随时用通知 mining.set_version_mask 下发新掩码,新掩码立即生效、不等下一个任务;矿工提交结果的 mining.submit 消息则须多带一个参数 version_bits(排在 worker_name、job_id、extranonce2、ntime、nonce 之后的第 6 个参数)。矿工只能置位最后收到掩码中为 1 的位(须满足 version_bits & ~last_mask == 0),服务器按下式算出最终 nVersion:
nVersion = (job_version & ~last_mask) | (version_bits & last_mask)
4.3 其余扩展
- minimum-difficulty:矿工请求一个可接受的最低难度(minimum-difficulty.value,大于等于 0 的整数或浮点数,0 相当于关闭该特性)。它解决的是原始 Stratum 无法传达所连设备难度硬下限的问题;该扩展可通过再次调用 mining.configure 重复配置。
- subscribe-extranonce:无参数扩展。矿工宣告自己能接收 mining.set_extranonce 消息,适用于算力路由场景。
- info:矿工提供文本信息,包括连接所用的确切 URL(info.connection-url)、硬件版本(info.hw-version)、软件版本(info.sw-version)与设备唯一标识(info.hw-id),均为可选。
4.4 与旧机制的不兼容
原文专门说明:Stratum 里原有一个类似的特性 mining.capabilities,本意也是承载各种协议扩展;但 mining.configure 与之不兼容,因为 configure 要求服务器对每个被接受、被协商的扩展逐一回复确认,而 mining.capabilities 的请求没有关联响应,无从确认协商结果。
五、谁必须动
普通持币人:完全无感。这份 BIP 只涉及矿机与矿池之间的通信,不涉及钱包与交易。
矿工与矿机固件开发者:要在连接建立后先发 mining.configure,宣告扩展并给出参数;实现 version rolling 的,还须遵守掩码纪律——只改服务器放行的位,提交时带上 version_bits,并处理运行中掩码被更新的情况。
矿池运营者:要实现 mining.configure 的应答语义:对每个请求的扩展明确回 true、false 或错误信息;计算并下发掩码交集;接受带 version_bits 的 mining.submit 并按下式合成 nVersion;超出位数请求时让矿工降级运行而非断开连接。
全节点与共识层:无需改动。本 BIP 是信息类文档,不改变比特币共识规则;它影响的是区块头 nVersion 在矿工侧如何被滚动,而区块是否有效仍由既有规则判定。
六、现在算不算数,以及一个常见误读
状态为 Draft(草案),类型为 Informational(信息类)。信息类 BIP 的作用是描述与说明,不提出必须采用的强制规范;因此它的“算不算数”不在主网共识,而在矿工与矿池的实际实现是否按同一套扩展名与协商格式对接。原文给出的机制与扩展定义可供实现者直接参照,但草案状态意味着文本仍可能变动,引用时应以仓库原文为准。
常见误读:
“BIP-310 规定了矿工可以随便改 nVersion 的哪些位。”
不对。它只规定“怎么协商”:矿工报自己能改的位,矿池报自己放行的位,实际可改的是两者交集,且矿池可以随时下发新掩码收紧。哪些位在比特币规则层面适合通用滚动,是 BIP-320、BIP-323 讨论的事,不是本 BIP 单方面定的。
七、延伸
- 阅读版:https://bips.dev/310
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0310.mediawiki
- 相关:BIP-320 nVersion 位通用、BIP-323 24 个 nVersion 位通用、BIP-23 getblocktemplate——矿池挖矿
- 仓库总目录:https://github.com/bitcoin/bips
