Skip to content

Instantly share code, notes, and snippets.

@yangby-cryptape
Last active March 27, 2024 04:26
Show Gist options
  • Save yangby-cryptape/0d59a7c48b2e414fced9261a3290ba16 to your computer and use it in GitHub Desktop.
Save yangby-cryptape/0d59a7c48b2e414fced9261a3290ba16 to your computer and use it in GitHub Desktop.
[2024-02-21] BTC SPV on CKB

BTC Simplified Payment Verification (SPV) on CKB

Requirements

BTC SPV on CKB 需要的需求有:

  1. 更新必须进行合法性验证。
  2. 所有权和使用权分离。
  3. 尽量避免读写竞争问题。
  4. 可以用来验证 BTC TX 。
  5. 支持一定高度的 Revert (or Reorg)。

Refs:

SPV Client contracts 需要 4 个 Operations:

  • Initialiaze
  • Append
  • Revert (or Reorg)
  • Destory (only owner)

SPV Client 还需要提供 library,包含 1 个 function:

  • Prove if a TXID in SPV Client.

Detailed Design

SPV Cell

⚠️ 我看目前设计选了 MMR ,我先这么写了,看后续有无别的想法,因为我还没看完别的 SPV clients 实现。

一个 SPV Cell 的 Data 包含:

- index (用来做 Multi SPV Cells )
- min height
- max height
- hash of the max height header
- MMR root digest
- total diff from 0 to max height

A SPV Client Contains Multi SPV Cells

使用 Multi SPV Cells 的设计,是为了解决上面需求中的 "3. 避免读写竞争" 和 "5. 支持 Revert" 。

将一个 BTC SPV Client 设计成 $N+1$ 个 Cells ,其中:

  • $N$ 个 SPV Cells

    • 所有 SPV Cells 的 min height 都是相同的,这里记做 $H_{min}$

    • 所有 SPV Cells 的 max height 都是不同的,分别是:

      • $H_{min} + a_{0}$
      • $H_{min} + a_{0} + a_{1}$
      • $\cdots$
      • $H_{min} + a_{0} + a_{1} + \cdots + a_{n-2}$
      • $H_{min} + a_{0} + a_{1} + \cdots + a_{n-2} + a_{n-1}$

      其中 $a_{i} \gt 0$ ,代表每次更新 SPV 对应的 BTC height interval 。
      如果每个 BTC block 都立刻更新,就是 $a_{i} = 1$

      如果同步服务出现了异常中断,再恢复时可以设置 $a_{i} \gt 1$ 来提速同步。
      或者 reorg 的时候,不可能再去一个一个补,肯定也是一次多个 heights 快速同步,即 $a_{i} \gt 1$

  • $1$ 个 Index Cell

    由于有 Multi SPV Cells ,循环更新,所以需要:

    • 每个 SPV Cells 里记录自己的 Index Number ,
    • 有一个 Index Cell 来保存当前最新的一个 SPV Cell 的 Index Number 。

Update 操作

假设 Index Cell 里记录 Latest SPV Cell 的 index 为 $t$ 时,更新 SPV Client 更新:

  • CellDep 包含:
    • index 为 $t$ 的 SPV Cell
  • Inputs 包含:
    • index 为 $t+1$ (如果 $t+1 = N$ 则取 index 为 $0$) 的 SPV Cell
    • Index Cell
  • Outputs 包含:
    • index 为 $t+1$ (如果 $t+1 = N$ 则取 index 为 $0$) 的 SPV Cell 更新 Cell Data
    • Index Cell 将 index 修改为 $t+1$(如果 $t+1 = N$ 则为 $0$
  • Witnesses 包含:
    • 从 index 为 $t$ 的 SPV Cell 的 max height 开始的新的 headers 。

验证逻辑:

  • 检查 Index Cell 里 index 为 $t$
  • 检查 Witnesses 包含的 tip headers 是连续的,且验证 POW
  • 检查 Witnesses 包含的 tip headers 可以和 index 为 $t$ 的 SPV Cell 连上
  • 检查 将要更新的 SPV Cell 的 index 为 $t+1$

总结下,每次更新的时候需要检查 Input,CellDep 和 Output 的 index :

  • $i_{\mathrm{Output}} = i_{\mathrm{Input}}$
  • $i_{\mathrm{Output}} \equiv i_{\mathrm{CellDep}} + 1 \pmod{N}$
  • $i \in {0, 1, \dots, N-1}$

Users 使用

用户如果要验证一笔高度在 $h$ 的 TX ,那么选择任何包含这个高度的 SPV Cell 都可以。

但建议选择 Index Cell 里记录的 Latest SPV Cell ,因为这个 Cell 的下一次更新时刻,距离当前时间最长。

这样可以 "3. 避免读写竞争" 。


Reorg 操作

$C_{i}$ 来表示 max height 为 $H_{min} + a_{0} + a_{1} + \cdots + a_{i-1} + a_{i}$ 的 SPV Cell 。

假设目前要从 $C_{r}$ 处进行 reorg (即 $C_{r}$ 是合法的,之后的全要 revert ),那么:

  • CellDep 包含:
    • $C_{r}$ 的 SPV Cell
  • Inputs 包含:
    • $C_{r+1}$ 的 SPV Cell
    • $C_{r+2}$ 的 SPV Cell
    • $\cdots$
    • $C_{N-1}$ 的 SPV Cell
    • 指向 $C_{N-1}$ 的 Index Cell
  • Outputs 包含:
    • $C_{r+1}$ 的 SPV Cell 更新 Cell Data 为最新 tip 对应的数据
    • $C_{r+2}$$C_{N-1}$ 的 SPV Cells 清空数据,等待后面 turns 再写入新数据
    • Index Cell 修改为 指向 $C_{r+1}$
  • Witnesses 包含:
    • $C_{r}$ 开始的,到要 reorg 到的最新 tip 之间的所有的 headers 。

验证逻辑:

  • 检查 Index Cell 指向的是 $C_{N-1}$
  • 检查 Witnesses 包含的 tip headers 是连续的,且验证 POW
  • 检查 Witnesses 包含的 tip headers 可以和 $C_{r}$ 连上
  • 检查 Witnesses 包含的 tip headers 比当前 $C_{N-1}$ 拥有 better total diff 。

Revert 操作

如果 Reorg 操作受到 CKB Block Size Limit 或 Cycles Limit 影响无法做到,那么只能先强行进行 Revert 操作,然后重新同步。

考虑到单纯的 revert 意味没有验证 better total diff ,所以这个操作应该是需要 Owenrship 的。

我理解这个操作不可以有,因为违背了需求 "2. 所有权和使用权分离。" 。

所以对于 reorg 不了的,无论是

  • 计算或数据 超出 CKB 的 limit ,无法验证;
  • 还是预先 Multi SPV Cells 个数设置太少了, reorg 不到。

我的建议是用户应该另部署一套 SPV Client 。


Usecase: How to verify a TX or TXID in BTC chain?

用户如果需要在一个 script 里校验 TX 或 TXID 在 BTC chain 上(仅限于 SPV Cell 的 min height 和 max height 之间的 TX),则:

  • CellDeps 包含:
    • 包含 有该 TX 的 Block 的 SPV Cell
  • Witnesses 包含:
    • TX data (如果不需要验证 data ,可以直接用 TXID )
    • TX 的 Merkle Proof
    • TX 所在 Header
    • TX 所在 Header 的 MMR Proof

验证逻辑:

  • [Optional] 用 TX data 计算出 TXID 。
  • 用 TX 的 Merkle Proof,TXID 和 Header 里的 merkle root 进行校验:TX 在 Header 里。
  • 用 TX 所在 Header 的 MMR Proof, TX 的 Header 和 SPV Cell 里的 MMR root digest 进行校验:header 在 SPV Cell 里。

References:

SPV Testnet Deployment Information

Contracts

SPV Instances

@yangby-cryptape
Copy link
Author

在这个项目之前,我还没写过最终 生产 部署的 合约项目,在 ckb-core 写合约多,但大部分都是写 tests 。

这个设计模式我确实觉得不是很认同。
但讨论后,貌似现在普遍都是这么做的,那我也不好说什么了。

按照当前 10s 才 1 个 Block , Block limit 是 597×1000 ,一年极限才 4 GiB 原始数据(不算存下来实际磁盘会放大的部分,比如 索引 之类)。


但我还是觉得这个方案是在制造不必要的冗余数据。

@xcshuan
Copy link

xcshuan commented Mar 11, 2024

反正要限制,只限制Witness定价肯定是不够的。

一年极限才 4 GiB 原始数据

@yangby-cryptape 这是一天的极限数据吧。。

做一个简单的运算,一个block最大597*1000 Bytes= 583 KB,按照 1000 feeRate来计算,假设出块时间 12s,则一天出块个数为 86400/12 = 7200,一年出块个数为 2628000,总大小为 2628000 * 583 KB = 1461 GB,那么攻击者需要的成本是多少呢?
攻击成本 = 2628000 * 583 * 1000 * 10^-8 = 15321.16 CKB,可以说,即便CKB涨到 10 美金,这个成本也算不上多高,所以目前的 feeRate 设置是极不合理的,之前就是没人用,如果有人想要恶意攻击的,完全可以在协议允许的情况下攻击。
如果将最低 feeRate 提高 100 倍,一笔普通转账交易的手续费从 0.00001 变成 0.001,对普通用户应该体感相差不大。

@matt-nervos
Copy link

matt-nervos commented Mar 12, 2024

regarding spam through witness data- Signature verification is the heaviest part of syncing a UTXO chain. In the case of recent zcash and monero spam attacks, though the transaction fee is priced in bytes, the verification burden is calculated in cycles. Downloading data is much faster than verifying signatures.

though CKB fees are calculated based on bytes, there is a limit to the number of cycles per block. I hope the market can find some equilibrium that discourages spam (because those spam transactions will reduce the # of cycles available to other transactions). Overall, an important distinction is that CKB does limit the verification burden explicitly, while other UTXO chains do not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment