Fix slashing / power recovery issues
This commit is contained in:
parent
adf71f502c
commit
703bc7e774
@ -5,10 +5,22 @@ package build
|
|||||||
import "os"
|
import "os"
|
||||||
|
|
||||||
// Seconds
|
// Seconds
|
||||||
const BlockDelay = 4
|
const BlockDelay = 6
|
||||||
|
|
||||||
// Blocks
|
// FallbackPoStDelay is the number of epochs the miner needs to wait after
|
||||||
const ProvingPeriodDuration uint64 = 40
|
// ElectionPeriodStart before starting fallback post computation
|
||||||
|
//
|
||||||
|
// Epochs
|
||||||
|
const FallbackPoStDelay = 10
|
||||||
|
|
||||||
|
// SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after
|
||||||
|
// which the miner is slashed
|
||||||
|
//
|
||||||
|
// Epochs
|
||||||
|
const SlashablePowerDelay = 20
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const InteractivePoRepDelay = 2
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
os.Setenv("TRUST_PARAMS", "1")
|
os.Setenv("TRUST_PARAMS", "1")
|
||||||
|
@ -5,5 +5,17 @@ package build
|
|||||||
// Seconds
|
// Seconds
|
||||||
const BlockDelay = 12
|
const BlockDelay = 12
|
||||||
|
|
||||||
// Blocks
|
// FallbackPoStDelay is the number of epochs the miner needs to wait after
|
||||||
const ProvingPeriodDuration uint64 = 300
|
// ElectionPeriodStart before starting fallback post computation
|
||||||
|
//
|
||||||
|
// Epochs
|
||||||
|
const FallbackPoStDelay = 1000
|
||||||
|
|
||||||
|
// SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after
|
||||||
|
// which the miner is slashed
|
||||||
|
//
|
||||||
|
// Epochs
|
||||||
|
const SlashablePowerDelay = 2000
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const InteractivePoRepDelay = 10
|
||||||
|
@ -57,13 +57,6 @@ const WRatioDen = 2
|
|||||||
// /////
|
// /////
|
||||||
// Proofs
|
// Proofs
|
||||||
|
|
||||||
// PoStRandomnessLookback is additional randomness lookback for PoSt computation
|
|
||||||
// To compute randomness epoch in a given proving period:
|
|
||||||
// RandH = PPE - PoStChallangeTime - PoStRandomnessLookback
|
|
||||||
//
|
|
||||||
// Epochs
|
|
||||||
const PoStRandomnessLookback = 1
|
|
||||||
|
|
||||||
// Epochs
|
// Epochs
|
||||||
const SealRandomnessLookback = Finality
|
const SealRandomnessLookback = Finality
|
||||||
|
|
||||||
@ -75,16 +68,6 @@ const SectorChallengeRatioDiv = 25
|
|||||||
|
|
||||||
const MaxFallbackPostChallengeCount = 10
|
const MaxFallbackPostChallengeCount = 10
|
||||||
|
|
||||||
// FallbackPoStDelay is the number of epochs the miner needs to wait after
|
|
||||||
// ElectionPeriodStart before starting fallback post computation
|
|
||||||
//
|
|
||||||
// Epochs
|
|
||||||
const FallbackPoStDelay = 1000
|
|
||||||
|
|
||||||
// SlashablePowerDelay is the number of epochs
|
|
||||||
// Epochs
|
|
||||||
const SlashablePowerDelay = 2000
|
|
||||||
|
|
||||||
// /////
|
// /////
|
||||||
// Mining
|
// Mining
|
||||||
|
|
||||||
@ -95,9 +78,6 @@ const PowerCollateralProportion = 5
|
|||||||
const PerCapitaCollateralProportion = 1
|
const PerCapitaCollateralProportion = 1
|
||||||
const CollateralPrecision = 1000
|
const CollateralPrecision = 1000
|
||||||
|
|
||||||
// Epochs
|
|
||||||
const InteractivePoRepDelay = 10
|
|
||||||
|
|
||||||
// /////
|
// /////
|
||||||
// Devnet settings
|
// Devnet settings
|
||||||
|
|
||||||
|
@ -854,6 +854,10 @@ func (sma StorageMinerActor) SubmitElectionPoSt(act *types.Actor, vmctx types.VM
|
|||||||
return nil, aerr
|
return nil, aerr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.SlashedAt != 0 {
|
||||||
|
return nil, aerrors.New(1, "slashed miners can't perform election PoSt")
|
||||||
|
}
|
||||||
|
|
||||||
if err := onSuccessfulPoSt(self, vmctx); err != nil {
|
if err := onSuccessfulPoSt(self, vmctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -548,9 +548,7 @@ func (sma StorageMarketActor) ProcessStorageDealsPayment(act *types.Actor, vmctx
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: check math (written on a plane, also tired)
|
toPay := types.BigMul(dealInfo.Deal.Proposal.StoragePricePerEpoch, types.NewInt(build.SlashablePowerDelay))
|
||||||
// TODO: division is hard, this more than likely has some off-by-one issue
|
|
||||||
toPay := types.BigMul(dealInfo.Deal.Proposal.StoragePricePerEpoch, types.NewInt(build.ProvingPeriodDuration))
|
|
||||||
|
|
||||||
b, bnd, aerr := GetMarketBalances(vmctx.Context(), vmctx.Ipld(), self.Balances, dealInfo.Deal.Proposal.Client, providerWorker)
|
b, bnd, aerr := GetMarketBalances(vmctx.Context(), vmctx.Ipld(), self.Balances, dealInfo.Deal.Proposal.Client, providerWorker)
|
||||||
if aerr != nil {
|
if aerr != nil {
|
||||||
|
@ -289,8 +289,8 @@ func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMConte
|
|||||||
|
|
||||||
self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta)
|
self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta)
|
||||||
|
|
||||||
previousBucket := params.PreviousProvingPeriodEnd % build.ProvingPeriodDuration
|
previousBucket := params.PreviousProvingPeriodEnd % build.SlashablePowerDelay
|
||||||
nextBucket := params.NextProvingPeriodEnd % build.ProvingPeriodDuration
|
nextBucket := params.NextProvingPeriodEnd % build.SlashablePowerDelay
|
||||||
|
|
||||||
if previousBucket == nextBucket && params.PreviousProvingPeriodEnd != 0 {
|
if previousBucket == nextBucket && params.PreviousProvingPeriodEnd != 0 {
|
||||||
nroot, err := vmctx.Storage().Put(&self)
|
nroot, err := vmctx.Storage().Put(&self)
|
||||||
@ -601,7 +601,7 @@ func (spa StoragePowerActor) CheckProofSubmissions(act *types.Actor, vmctx types
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkProofSubmissionsAtH(vmctx types.VMContext, self *StoragePowerState, height uint64) aerrors.ActorError {
|
func checkProofSubmissionsAtH(vmctx types.VMContext, self *StoragePowerState, height uint64) aerrors.ActorError {
|
||||||
bucketID := height % build.ProvingPeriodDuration
|
bucketID := height % build.SlashablePowerDelay
|
||||||
|
|
||||||
buckets, eerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingBuckets)
|
buckets, eerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingBuckets)
|
||||||
if eerr != nil {
|
if eerr != nil {
|
||||||
|
@ -181,7 +181,7 @@ class MinerState extends React.Component {
|
|||||||
<div>Worker: <Address addr={this.state.worker} client={this.props.client} mountWindow={this.props.mountWindow}/></div>
|
<div>Worker: <Address addr={this.state.worker} client={this.props.client} mountWindow={this.props.mountWindow}/></div>
|
||||||
<div>Sector Size: <b>{this.state.sectorSize/1024}</b> KiB</div>
|
<div>Sector Size: <b>{this.state.sectorSize/1024}</b> KiB</div>
|
||||||
<div>Power: <b>{state.Power}</b> (<b>{state.Power/this.state.networkPower*100}</b>%)</div>
|
<div>Power: <b>{state.Power}</b> (<b>{state.Power/this.state.networkPower*100}</b>%)</div>
|
||||||
<div>Proving Period End: <b>{state.ProvingPeriodEnd}</b></div>
|
<div>Election Period Start: <b>{state.ElectionPeriodStart}</b></div>
|
||||||
<div>Slashed: <b>{state.SlashedAt === 0 ? "NO" : state.SlashedAt}</b></div>
|
<div>Slashed: <b>{state.SlashedAt === 0 ? "NO" : state.SlashedAt}</b></div>
|
||||||
<div>
|
<div>
|
||||||
<div>----</div>
|
<div>----</div>
|
||||||
|
@ -120,7 +120,7 @@ class StorageNode extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Address client={this.props.fullConn} addr={this.state.actor} mountWindow={this.props.mountWindow}/>
|
<Address client={this.props.fullConn} addr={this.state.actor} mountWindow={this.props.mountWindow}/>
|
||||||
<span> <abbr title="Proving period end">PPE:</abbr> <b>{this.state.actorState.State.ProvingPeriodEnd}</b></span>
|
<span> <abbr title="Proving period end">EPS:</abbr> <b>{this.state.actorState.State.ElectionPeriodStart}</b></span>
|
||||||
</div>
|
</div>
|
||||||
<div>{this.state.statusCounts.map((c, i) => <span key={i}>{sealCodes[i]}: {c} | </span>)}</div>
|
<div>{this.state.statusCounts.map((c, i) => <span key={i}>{sealCodes[i]}: {c} | </span>)}</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -237,10 +237,29 @@ func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error)
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Miner) isSlashed(ctx context.Context, addr address.Address, ts *types.TipSet) (bool, error) {
|
||||||
|
power, err := m.api.StateMinerPower(ctx, addr, ts)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return power.MinerPower.Equals(types.NewInt(0)), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningBase) (*types.BlockMsg, error) {
|
func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningBase) (*types.BlockMsg, error) {
|
||||||
log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.ts.Cids()))
|
log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.ts.Cids()))
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
|
slashed, err := m.isSlashed(ctx, addr, base.ts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("checking if miner is slashed: %w", err)
|
||||||
|
}
|
||||||
|
if slashed {
|
||||||
|
log.Warnf("Slashed at epoch %d, not attempting to mine a block", base.ts.Height()+base.nullRounds)
|
||||||
|
base.nullRounds++
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
ticket, err := m.computeTicket(ctx, addr, base)
|
ticket, err := m.computeTicket(ctx, addr, base)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("scratching ticket failed: %w", err)
|
return nil, xerrors.Errorf("scratching ticket failed: %w", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user