Lotus 扇区续期详解
转载声明:
当前 Filecoin 网络⾸批 540 天扇区⼤量到期,扇区续期成为大家的一个强烈需求。有不少网友微信给我留言说能否写一篇有关 lotus 扇区续期的文章,
奈何这段时间一直忙其他事情去了,没空写。昨天偶然在 Medium
网站上看到一篇相关的文章,写得很不错,于是转载过来略作修改之后分享给大家。
原文地址:Filecoin:扇区到期续期/删除流程详情 (opens new window), 感谢作者 BitRainforest (opens new window) 的分享。
# 1. 背景
Lotus 扇区默认的生命周期是 540 天,扇区过期之后网络将消减 Miner 有效算力并退回质押币。在扇区过期之前,你有 2 种选择:
- 等待扇区过期,退回质押币,然后持币退场。
- 续期扇区生命周期,继续质押,保持算力。
本文主要探讨的就是上述 2 种选择的具体执行方案。
# 2. 相关源码解读
这里首先给大家做一些必要的源码解读,因为有些概念可能代码的解释能力能强一些。如果你对代码没有兴趣,可以直接跳读到 解读结论 部分。
源码版本
lotus: v1.15.1 (opens new window),git 提交 ID 为 731da455d46cb88ee5de9a70920a2d29dec9365c
specs-actors: v7.0.0 (opens new window), git 提交 ID 为 a2b807566418e72d3586ee285be620dc85ea41a6。这里顺便提一下, specs-actors 是 Filecoin 的共识实现项目,所有跟共识相关的内容都在该项目中定义的。
在此之前,我们先学习 2 个概念:
V1 扇区和 V1_1 扇区:
简单来说,在 2020-11-25 之前上链的扇区都是 V1 扇区,在这之后都是 V1_1 扇区。
网络版本:
Filecoin 共识每更改一次,网络都要强制升级一次,每强制升级一次,网络版本就会增加一次,当前网络版本为 14,下一次网络强制升级的版本为 15。
# 2.1 扇区生命周期定义
specs-actors actor/builtin/miner/policy.go
中关于扇区最大生命周期的定义:// The maximum number of epochs past the current epoch that sector lifetime may be extended. // A sector may be extended multiple times, however, the total maximum lifetime is also bounded by // the associated seal proof's maximum lifetime. // 每次最多续期 540 天 const MaxSectorExpirationExtension = 540 * builtin.EpochsInDay // PARAM_SPEC
specs-actors actors/builtin/sector.go
中对于扇区的最⼤生命周期定义:// For V1 Stacked DRG sectors, the max is 540 days since Network Version 11 // according to https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0014.md // 540 扇区生命周期扇区 const EpochsIn540Days = stabi.ChainEpoch(540 * EpochsInDay) // 5 年生命周期扇区 const EpochsInFiveYears = stabi.ChainEpoch(5 * EpochsInYear) // 网络 11 对于各种扇区的最大生命周期的定义(之后网络没有再更改过) var SealProofPoliciesV11 = map[stabi.RegisteredSealProof]*SealProofPolicy{ // V1 扇区的最大生命周期为 540 天 stabi.RegisteredSealProof_StackedDrg2KiBV1: { SectorMaxLifetime: EpochsIn540Days, }, stabi.RegisteredSealProof_StackedDrg8MiBV1: { SectorMaxLifetime: EpochsIn540Days, }, stabi.RegisteredSealProof_StackedDrg512MiBV1: { SectorMaxLifetime: EpochsIn540Days, }, stabi.RegisteredSealProof_StackedDrg32GiBV1: { SectorMaxLifetime: EpochsIn540Days, }, stabi.RegisteredSealProof_StackedDrg64GiBV1: { SectorMaxLifetime: EpochsIn540Days, }, // V1_1 扇区的最大生命周期是 5 年 stabi.RegisteredSealProof_StackedDrg2KiBV1_1: { SectorMaxLifetime: EpochsInFiveYears, }, stabi.RegisteredSealProof_StackedDrg8MiBV1_1: { SectorMaxLifetime: EpochsInFiveYears, }, stabi.RegisteredSealProof_StackedDrg512MiBV1_1: { SectorMaxLifetime: EpochsInFiveYears, }, stabi.RegisteredSealProof_StackedDrg32GiBV1_1: { SectorMaxLifetime: EpochsInFiveYears, }, stabi.RegisteredSealProof_StackedDrg64GiBV1_1: { SectorMaxLifetime: EpochsInFiveYears, }, }
specs-actors actors/builtin/sector.go
中对于订单的⽣命周期定义:// Minimum deal duration. var DealMinDuration = abi.ChainEpoch(180 * builtin.EpochsInDay) // PARAM_SPEC // Maximum deal duration var DealMaxDuration = abi.ChainEpoch(540 * builtin.EpochsInDay) // PARAM_SPEC
# 2.2 SealProof 对应表
const (
RegisteredSealProof_StackedDrg2KiBV1 = RegisteredSealProof(0)
RegisteredSealProof_StackedDrg8MiBV1 = RegisteredSealProof(1)
RegisteredSealProof_StackedDrg512MiBV1 = RegisteredSealProof(2)
RegisteredSealProof_StackedDrg32GiBV1 = RegisteredSealProof(3)
RegisteredSealProof_StackedDrg64GiBV1 = RegisteredSealProof(4)
RegisteredSealProof_StackedDrg2KiBV1_1 = RegisteredSealProof(5)
RegisteredSealProof_StackedDrg8MiBV1_1 = RegisteredSealProof(6)
RegisteredSealProof_StackedDrg512MiBV1_1 = RegisteredSealProof(7)
RegisteredSealProof_StackedDrg32GiBV1_1 = RegisteredSealProof(8)
RegisteredSealProof_StackedDrg64GiBV1_1 = RegisteredSealProof(9)
)
这里补充一下,其实区分 V1
和 V1_1
扇区,除了上面我们提到的过看提交时间的方法,通过查看扇区的 SealProof
属性也可以判断出来的:
# usage
lotus state sector <miner-id> <sector-num>
# e.g
lotus state sector t010001 0
从上述命令返回结果中可以得到 SealProof
, 对照上边的 SealProof 对应表就可以得出结果:
SealProof:3
:V1
版本的 32GiB 扇区SealProof:8
:V1_1
版本的 32GiB 扇区SealProof:9
:V1_1
版本的 64GiB 扇区- ...
# 2.3 获取链上扇区的 API 定义
type Partition interface {
// AllSectors returns all sector numbers in this partition, including faulty, unproven, and terminated sectors
// List all sector BitFields of a partition(简单理解就是扇区编号)
AllSectors() (bitfield.BitField, error)
// Subset of sectors detected/declared faulty and not yet recovered (excl. from PoSt).
// Faults ∩ Terminated = ∅
// 列出 partition faulty 的扇区,扇区在没有正常做 wdpost 或者扇区因为某些原因没有正常提交证明,此状态中会增加扇区
FaultySectors() (bitfield.BitField, error)
// Subset of faulty sectors expected to recover on next PoSt
// Recoveries ∩ Terminated = ∅
// 列出 partition Recovering 的扇区,扇区在 faulty 后,下次证明前1⼩时会触发恢复检查逻辑,发送 Recovering 消息。(恢复前必须发送 Recovering 消息,不然是⽆法做证明的)注意还有恢复截⽌时间 FaultCutoff
RecoveringSectors() (bitfield.BitField, error)
// Live sectors are those that are not terminated (but may be faulty).
// 列出 partition Live 的扇区,此类是正常需要提交证明扇区的集合。到期的扇区会在⼀定时间后从这⾥移除。
LiveSectors() (bitfield.BitField, error)
// Active sectors are those that are neither terminated nor faulty nor unproven, i.e. actively contributing power.
// 列出 partition Active 的扇区,此类是证明成功过的扇区的集合。
ActiveSectors() (bitfield.BitField, error)
// Unproven sectors in this partition. This bitfield will be cleared on
// a successful window post (or at the end of the partition's next
// deadline). At that time, any still unproven sectors will be added to
// the faulty sector bitfield.
// 列出 partition Unproven 的扇区,此类是封存后扇区第⼀次上链时会存在这个地⽅,证明成功过后,会从当中移除。
UnprovenSectors() (bitfield.BitField, error)
}
# 2.4 解读结论
从上面的源码解读我们可以获取到以下信息:
- 扇区每次续期的时长不能超过 540 天,在扇区没有超过最大生命周期之前,你可以随时再次续期。
V1
扇区的最大生命周期为 540 天,V1_1
扇区的最大生命周期为 5 年。- 订单的最小生命周期为 180 天,最大生命周期为 540 天。
# 3. 演示环境
本演示环境是采用官⽅原版代码(无改动)搭建的本地 2K 网络:
lotusversion1.15.1+2k+git.731da455d
lotus-minerversion1.15.1+2k+git.731da455d
# 4. 扇区续期
扇区续期需要根据扇区类型选择可以续期的策略。扇区可以续期多次,但是扇区有最⼤的⽣命时长。举例:
你租房东的房⼦,每次签订⼏个⽉到⼏年不等的租期,但房东的房⼦有使⽤年限,会有不能续租的⼀天。续期时扇区可以续⾄ 180–540 天,
假设你有⼀个扇区现在还剩下 30 天且是 V1_1
的扇区,那么你可以为此扇区增加 150–510 天;
假设你的扇区还剩下 90 天且是 V1_1
扇区,那么你可以为此扇区增加 90–450 天。以此类推,注意不是增加180–540!!!
V1
的扇区总的寿命只有 540 天,所以如果你在最开始改动代码设置封存 180 天的扇区,那么你可以续期 360 天。
可能有朋友会有疑问,我改了配置⽂件封存 180 天的扇区,为什么查询却是 210 天左右?
答:确实是的,它会⾃⼰增加 30 天左右,原因是 ProveCommit 消息可以在 PreCommit 消息之后 30 天左右提交,这样在 gas 费偏高的时候你可以暂时不提交,节省 gas 费用。
订单(Deal)的⽣命周期也是180–540天,但是它没有最⼤的寿命⼀说。扇区的⽣命周期会以其中的 Deal 最久的设定扇区的周期。
# 4.1 续期命令介绍
续期主要有以下两种命令:
# 1. 第一种方式,
lotus-miner sectors extend --new-expiration=<epoch> <sectorNums...>
# 例如:续期 480 号扇区至 1595712 区块高度:
lotus-miner sectors extend --new-expiration=1595712 480
# 操作成功会返回一条上链消息:
bafy2bzaceczyf5efox72ohgamjzky34jsckli6c3hrg2wiy5z5zopfwzqeaes
# 2. 第二种方式
lotus-miner sectors renew --really-do-it --from=<epoch> --to=<epoch> --extension=<epoch>
# 例如:续期在 607922 和 607924 高度之间过期的扇区
lotus-miner sectors renew --really-do-it --from=607922 --to=607924 --extension=1555200
如果你想续期 V1
版本扇区可以直接使用 sectors extend
命令(操作更便捷),如果你想续期 V1_1
以及之后版本的扇区,推荐使⽤ sectors renew
命令(参数更多,功能更丰富)。
lotus-miner sectors extend
命令参数详解:
- new-expiration : 准备续期到的⾼度
- v1-sectors : 动判断 V1 版本扇区,并全部续期到最长的期限
- tolerance : 续期容差,默认值:20160(7 天)。如果扇区过期到的⾼度跟续期⾼度的高度差⼩于 7 天,那就不续期
- expiration-ignore : 默认值:120,当扩展 V1 扇区时,跳过过期时间⼩于 120 的扇区
- expiration-cutoff : 当扩展 V1 扇区时,跳过过期时间大于 xxx 的扇区,默认值:0,表示不限制
lotus-miner sectors renew
命令参数详解:
- from : 筛选过期扇区高度开始区间,默认值:120,从当前高度往后推迟 120 个高度开始
- from : 筛选过期扇区高度开始区间,默认值:92160,从当前高度往后推迟 92160 高度结束
- sector-file : 以⽂件列表,每⾏⼀个扇区 ID 作为输⼊,进⾏定制化续期,这个参数加上后会忽略上边两个参数
- extension : 续期时长,默认将扇区续期 540 天
- tolerance : 续期容差,默认值:20160(7 天)。如果扇区过期到的⾼度跟续期⾼度的高度差⼩于 7 天,那就不续期
- max-fee : ⼀条消息最多可以使⽤多少 FIL
# 4.2 续期最佳实践
V1
版本的扇区续期直接使⽤默认的参数就可以达到最优的效果
lotus-miner sectors extend — v1-sectors
此命令是将V1版本的扇区全部续期⾄最长的期限,如有特殊需求可使⽤上边介绍的参数。
对于 V1
版本之后的扇区续期,Actor v7
版本每条消息最多能包含 25000 个扇区,所以⼀次性续期超过 25000 会⾃动拆分消息。
第⼀种续期⽅式:使⽤ from + to 或者 lotus-miner sectors check-expire
筛选出想续期的扇区,
使⽤ --extension
指定要将这部分扇区过期时间增加多久,⽐如想将原本还有30天的扇区,续期成还有 180 天,这个地⽅就写 150 天对应的⾼度个数。
如果要增加的⾼度⼤于它允许的最⼤过期⾼度,那就会续期⾄最⼤。
使⽤ from + to 筛选过期时间满⾜我们设定条件的扇区,对它们进⾏调整到 540 天的周期,它会去⾃动设定这些扇区的分别的到期时间:
lotus-miner sectors renew --from 607922 --to 607924 --extension 1555200 # 输出 Renewing 3 sectors: { "Extensions": [ { "Deadline": 1, "Partition": 0, "Sectors": "4", "NewExpiration": 1561026 }, { "Deadline": 2, "Partition": 0, "Sectors": "2,5", "NewExpiration": 1561026 } ] } 3 sectors renewed
如果只续期 1 个⾼度,需要指定
tolerance
为 0,因为默认忽略续期 7 天以内的扇区lotus-miner sectors renew --from 607922 --to 607924 --extension 1 --tolerance 0
使⽤
--new-expiration
参数指定要将这部分扇区过期时间扩展至哪个⾼度,⽐如想将原本还有 30天的扇区,续期成还有 180 天,那你就要计算出它当前的过期时间 + 150 天的⾼度。此命令会将所有筛选出来的扇区续期⾄同一⾼度,它们会基本在同⼀时间段到期。# 1. 把你想要续期的扇区输入到一个文件 sectors.list, 每一行一个扇区 ID # 2. 使用 --sector-file 参数传入文件列表 lotus-miner sectors renew --sector-file sectors.list --new-expiration 608000
# 5. 删除过期扇区
# 5.1 查看即将过期扇区
lotus-miner sectors check-expire --cutoff=<epoch>
命令参数说明:
- cutoff : 查询当前过期时间⼩于多少天的扇区,默认是 60 天,注意单位是⾼度。
如果你想查询所有的扇区信息,直接设定⼀个很⼤的值:
lotus-miner sectors check-expire --cutoff 5184000
# 输出结果
ID SealProof InitialPledge Activation Expiration MaxExpiration MaxExtendNow
2 5 59.605 nFIL 122 (4 hours 51 minutes ago) 607922 (in 3 weeks 6 days) 5256122 (in 34 weeks 5 days) 1559699 (in 10 weeks 2 days)
4 5 59.605 nFIL 119 (4 hours 52 minutes ago) 607923 (in 3 weeks 6 days) 5256119 (in 34 weeks 5 days) 1559699 (in 10 weeks 2 days)
5 5 59.605 nFIL 121 (4 hours 51 minutes ago) 607924 (in 3 weeks 6 days) 5256121 (in 34 weeks 5 days) 1559699 (in 10 weeks 2 days)
6 5 59.605 nFIL 266 (4 hours 42 minutes ago) 608067 (in 3 weeks 6 days) 5256266 (in 34 weeks 5 days) 1559699 (in 10 weeks 2 days)
7 5 59.605 nFIL 264 (4 hours 42 minutes ago) 608067 (in 3 weeks 6 days) 5256264 (in 34 weeks 5 days) 1559699 (in 10 weeks 2 days)
8 5 59.605 nFIL 263 (4 hours 42 minutes ago) 608067 (in 3 weeks 6 days) 5256263 (in 34 weeks 5 days) 1559699 (in 10 weeks 2 days)
9 5 59.605 nFIL 265 (4 hours 42 minutes ago) 608067 (in 3 weeks 6 days) 5256265 (in 34 weeks 5 days) 1559699 (in 10 weeks 2 days)
10 5 59.605 nFIL 262 (4 hours 42 minutes ago) 608067 (in 3 weeks 6 days) 5256262 (in 34 weeks 5 days) 1559699 (in 10 weeks 2 days)
11 5 59.605 nFIL 270 (4 hours 41 minutes ago) 608067 (in 3 weeks 6 days) 5256270 (in 34 weeks 5 days) 1559699 (in 10 weeks 2 days)
输出结果字段说明:
- ID : 扇区编号
- SealProof : 扇区的一个参数,具有辨别网络版本和扇区大小的属性
- InitialPledge : 初始质押,注意这里不包含交易的部分
- Activation : 扇区激活的高度,这里是 ProveCommit 消息上链无误的高度
- Expiration : 扇区过期的高度,这个地方是默认或者设定后在 PreCommit 消息上链无误后确认下来的
- MaxExpiration : 最大的可以续期到多少高度,上边因为是 localnet 环境,出块时间不是 30s ,只看高度是精准的。
- MaxExtendNow : 目前可以续期到多少高度
以上查出来的信息可以作为决策的依据还有后边续期方式的入参。
# 5.2 期扇区的筛选逻辑
- 查看本地的 SectorsList 然后跟链上 AllocatedSectors 取交集
- 过滤掉 LiveSectors、UnprovenSectors 扇区
- 过滤掉没有提交 ProveCommitSector 消息的扇区
- 过滤掉 Removed 状态的扇区
# 5.3 删除过期扇区
lotus-miner sectors expired --remove-expired
命令参数说明:
- show-removed : 打印已删除的扇区,默认值:false
- remove-expired : 删除已过期扇区,默认值:false,只会打印所有的过期扇区,不会删除
- expired-epoch : 筛选多少⾼度以前过期且符合删除逻辑的扇区,默认值:900
本站博文如非注明转载则均属作者原创文章,引用或转载无需申请版权或者注明出处,如需联系作者请加微信: geekmaster01