当扇区出现错误,由于一些不可抗力无法恢复(如硬盘损坏、备份丢失等),那么区块浏览器就总会显示有几个错误扇区,影响了存储提供者形象,便要及时终止错误扇区。或是连续14天windowpost证明错误会自动终止扇区。
终止扇区的操作如下:
一、终止错误的扇区
0. 编译lotus-shed
# cd lotus/
# env RUSTFLAGS="-C target-cpu=native -g" FFI_BUILD_FROM_SOURCE=1 make lotus-shed
# cp lotus-shed /usr/local/bin/
1.评估待终止扇区的损失费用
./lotus-shed sectors termination-estimate [sectorNum1 sectorNum2 ...]
2.确保owner钱包余额大于这个值
3.执行终止扇区操作
./lotus-shed sectors terminate --really-do-it [sectorNum1 sectorNum2 ...]
4删除非错误扇区, 如PreCommitFailed和SealPreCommit1Failed状态的扇区,因为还没有质押,可通过以下命令直接删除:
./lotus-miner sectors remove --really-do-it [sectorNum1 sectorNum2 ...]
5.从MIner取回fil到钱包地址
./lotus-miner actor withdraw fil数量(未指定数量则默认返回miner全部余额到lotus钱包账户)
或
./lotus wallet market withdraw --wallet address-of-wallet
二、终止扇区逻辑分析
业务逻辑分析:
var sectorsCmd = &cli.Command{
Name: "sectors",
Usage: "Tools for interacting with sectors",
Flags: []cli.Flag{},
Subcommands: []*cli.Command{
terminateSectorCmd, /* 将扇区号用cbor编码为[]byte类型,向主网发送一条消息:this miner要永久性的删除参数 指定的扇区,则主网上面收到消息的所有在线链节点,就会从本地仓库的数据库中删除这些扇区的记录。*/
terminateSectorPenaltyEstimationCmd, /* 探测扇区删除的惩罚费用。主网所有在线链节点收到消息后,返回罚币的额度,不具体删除其仓库 中,leveldb数据库里面的值 */
visAllocatedSectorsCmd,
},
}
主要参数数据结构
type TerminateSectorsParams struct {
Terminations []TerminationDeclaration
}
type TerminationDeclaration struct {
Deadline uint64
Partition uint64
Sectors bitfield.BitField
}
需要给出每个待终止扇区对应的deadline,Partition,Sectors。
参数检查
-
一次调用可以终止的最大分区数为3000,最大扇区数为25000
-
标记一组扇区为终止
-
将扇区从错误或恢复状态中移除
-
记录终止Epoch,用于未来的终止费用计算
更新链上状态
havePendingEarlyTerminations //判断之前是否有提前终止的扇区
!deadlineIsMutable //不允许终止当前deadline或下一次deadline中的扇区
TerminateSectors {
对于每个待终止的扇区
util.BitFieldContainsAll(liveSectors, sectorNos) //首先确保他们是活跃扇区
expirations.RemoveSectors //从过期队列中移除对应扇区
bitfield.MergeBitFields(removed.OnTimeSectors, removed.EarlySectors) //记录提前终止的扇区
//更新分区的元数据,从错误和恢复中移除指定扇区,加入到终止扇区中,并更新当前算力,最后检查分区中的各个变量是否符合要求,如算力必须要大于0
}
//取得移除扇区中未证明的扇区,从Partition中的Faults、Recoveries和Unprove中删除终止的扇区,加入Terminated中,并调整相应的算力
bitfield.IntersectBitField(removedSectors,p.Unproven)
st.SaveDeadlines(store, deadlines) //最后保存并更新deadline
processEarlyTerminations(rt) { //处理这些提前终止的扇区
//移除每个提前终止的sector,修改deadline中对应的partition,最后保存deadline,检查处理完了所有st.EarlyTerminations代表的提前终止的扇区,返回result保存了每个提前终止的扇区,统计终止的惩罚和初始质押
st.PopEarlyTerminations -> dl.popEarlyTerminations partition.PopEarlyTerminations
burnFunds(rt, penalty) //燃烧惩罚
notifyPledgeChanged(rt, pledgeDelta) //调整质押
requestTerminateDeals //终止交易
}
// 如果还有需要终止的扇区就再调用一次终止扇区合约
requestUpdatePower //更新算力
三、惩罚fil计算
终止扇区至少扣除该扇区3.5天的预计收益,如果矿工的实际收益已经超过该值,则再扣除20天预期区块奖励(提交一个扇区需要的存储质押的预期区块奖励的预测阶段)的基础上,扣除140天的预期奖励。
TerminationLifetimeCap = 140 //扇区终止时惩罚的生命周期天数为140天
CappedSectorAge = min(sectorAge,lifetimecap) //扇区年龄和140取较小值
expectedReward = dayReward * CappedSectorAge //预期的奖励
RelevantReplaceAge = min(replaceSectorAge,lifetime-cappedSectorAge) //如果生命周期低于上限,并且扇区替换了capacity,老扇区生命周期的预期奖励提高到上限
expectedReward = expectedReward + replaceDayReward*relevantReplaceAge
max(twentyDayRewardAtActivation + expectedReward/2, qaSectorPower*expectedRewardForProvingPeriod) // 参数2:终止扇区惩罚的下限,是对扇区预期奖励的预测
将deadline中所有扇区的惩罚加起来
st.ApplyPenalty(penalty) //支付惩罚FeeDebt = FeeDebt + penalty
st.AddInitialPledge(totalInitialPledge.Neg()) //移除初始质押 InitialPledge = InitialPledge - totalInitialPledge
优先从奖励锁仓扣除,扣光后从可用余额扣除 //必要时可以提前把余额取走,减少损失
BurnFunds //烧掉惩罚
lotus 从miner提币到钱包
./lotus-miner actor withdraw count(如果未指定数量,则余额全部提走)
查看钱包余额
./lotus wallet list
Address Balance Nonce Default
t17avblosugzoesvt76xsgbj2rett2av22mhmnayq 55000 FIL 0
t3u4fkk5wyjsq4ukr6km2xypx5gypsaciuxqsgo5wegfaejrbjz7on7ulrbpxbkrmqllxu62zyvxausoflawlq 49944999.999749895749262395 FIL 30 X
设置当前钱包地址
./lotus wallet set-default t17avblosugzoesvt76xsgbj2rett2av22mhmnayq
向其它地址转10000个fil:
./lotus send t3xalzv2yxh47jj7ydhvahrv3rklzddvioe33c6n427dt7sk2es2ryl6jckteg4dn6ajoyvvosejkxw6j7x53q 10000