一个布尔开关的连锁反应:-datacarrier 关掉后带数据交易去哪了
写数据的交易能不能进内存池,比特币核心其实设了两道控制:一道管”装多少”(-datacarriersize 的字节数),另一道管”装不装”(-datacarrier 这个布尔开关)。多数讨论聚焦前者,但后者才是”一键封杀”的那只闸门。
两个参数在源码里是一对
node/mempool_args.cpp 里这段逻辑把两者的关系钉死:如果 -datacarrier 为真(默认为真,常量 DEFAULT_ACCEPT_DATACARRIER 的语义即”中继并开采数据承载交易”),则把 -datacarriersize 的值装进内存池选项 max_datacarrier_bytes;如果为假,则 max_datacarrier_bytes 被置为空值(std::optional 不持值)。随后 policy/policy.cpp 的 IsStandardTx 在做标准性检查时,把这个空值按 value_or(0) 处理——预算为零。于是每一枚空数据输出(NULL_DATA 类型,即 OP_RETURN 开头那类)在”尺寸大于剩余预算”的判断下必然越线,交易以 datacarrier 为由判定不标准。
一句话概括:布尔开关不是”改小限额”,而是”把预算清零”。两个参数在代码里是同一处判断的两半,datacarrier=false 时 -datacarriersize 写什么都不生效。
关掉之后会发生什么
不标准不等于不上链。中继政策管的是这台节点转发不转发、内存池收不收:关掉 -datacarrier 的节点仍会接受矿工打包进区块里的带数据交易,因为那是共识层的事。但你会看到这些实际后果:铭文、刻录、存证类客户端向你广播的交易被拒之门外;getmempoolinfo 返回的 maxdatacarriersize 字段会显示 0(rpc/mempool.cpp 里正是 value_or(0) 的同一口径),运维脚本可以据此识别这台节点的姿态;以及最隐蔽的一条——钱包在这台节点上构造的含数据交易可能无法广播,报错只说 txn not standard 一类字样,不知道闸门的人常常往费率、签名方向排查半天。
谁会用这个开关
历史上有两类动机。一类是极简主义节点运营者:不关心数据承载,宁可把攻击面与带宽花销收窄。另一类是排障与取证:想验证某条”数据交易泛滥”的说法在自己节点上的真实成本,就把闸门拉下来对照。反过来,跑索引器(比如给铭文服务喂数据的自建后端)则通常要把限额抬着、开关开着,甚至按旧规则回退到 83 字节口径做重索引对齐。
检查自己节点当前姿态
三条线索交叉即可确认:启动配置里有没有 datacarrier=0;getmempoolinfo 里 maxdatacarriersize 是 0 还是正数;广播一枚测试数据交易是否被拒。配置以运行时读到的为准,因为同一节点上命令行、配置文件、settings.json 三层来源的优先级规则会改写最终生效值。
与两个”邻居开关”的关系
这族开关常被混作一团,实际各管一段。第一个是 -datacarrier 与 -datacarriersize:前者是总闸、后者是限额,已在源码里绑成一处判断。第二个是 -permitbaremultisig:它管的是裸多重签名输出的标准性,和 OP_RETURN 数据承载同属 IsStandardTx 的循环检查,却互不隶属——关掉载数据不影响裸多签,反之亦然。第三个容易混淆的是矿工侧:节点中继政策管不了矿工组块时收不收这笔交易,全节点把闸门拉下来,只是让这类交易到达矿工的速度变慢、路径变窄,而不是使其失效。
还有一条历史口径值得存档:OP_RETURN 数据上限曾长期停留在 83 字节,v30 一代把默认限额抬到十万字节量级并允许一笔交易携带多枚空数据输出,效果接近不设限——也正因为默认值已经足够宽,-datacarrier 这个总闸的存在感反而上升:想收紧,拧限额;想封杀,拉总闸。两种姿态在 getmempoolinfo 里看得分明:一个是小数字或大数字,一个是 0。
风险提示:参数改动影响节点中继行为与工具兼容性,请先在测试链演练;本文不构成任何运营或投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。