since 是input cell 里的一个字段,用来防止交易在绝对或相对时间之前被挖掘。
目前CKB 共识规则是使用引用cell提交块之前的37个块的时间戳的中值,但是获取中值时间戳非常消耗资源,因为要获取或者缓存每一个block 的时间戳中值。唯一变化的是StartTime
,使用提交块时间戳代替提交消耗cell的块之前的37个块的中值作为开始时间。新的共识规则会更加严格,以下两个原因说明了使用提交块时间戳作为开始时间是安全的:
- block header 的时间戳已经被网络验证过,它必须大于之前37个的时间戳中值,并且小于或者等于当前时间加15秒
- 消耗具有
since
的cell的transaction 会在创建cell的transaction之后提交;当miner 看见消费transaction 时,开始时间已经被确定。
更多Transaction valid since请参见RFC17
在新共识规则中,当一个input 包含since
字段,并且 metric_flag
为block 的timestamp(10),relative_flag
为relative(1)时,MedianTimestamp ≥ StartTime + SinceValue
则交易成熟。否则,交易失败。
-
StartTime
: block timestamp,cell被提交的时间 -
SinceValue
:since
字段的value 部分 -
MedianTimestamp
: 如果交易在区块中,则是该区块之前的37个块的时间戳中值;如果交易还在pool中,则是最后37个块的时间戳的中值
验证通过老的共识规则的交易可能会在新的共识规则下失败,但是使符合新的共识规则的交易必须在旧的共识规则下也验证成功。
例如:交易使用新规则验证通过但使用旧规则失败
- 一个事务消耗了块 S 中的一个单元,并且即将被提交到块 T 中,
since
要求是:-
metric_flag
为block timestamp(10) -
relative_flag
为relative(1) -
value
为600,000(10分钟)
-
- 区块S之前37个block的中值为10,000
- block S 的timestamp 为20,000
- 区块T 之前的37个blcok 的中值为615,000
在老的共识中,StartTime + SinceValue = 10,000 + 600,000 = 610,000, 小于 MedianTimestamp 615,000,所以交易验证成功。
但是在新的共识中,StartTime + SinceValue = 20,000 + 600,000 = 620,000 ≥ 615,000,所以交易在新的规则中验证失败。
新的共识规则部署分为两个阶段执行,第一阶段从特定epoch激活consensus rule。mainnet 和testnet 将使用不同的epochs,其他的chains 将使用epoch 0的新规则;当fork 激活之后,如果老的交易都满足新consensus rule,老的consensus rule将会被删除,新规则将会在创世块中使用