diff --git a/extern/storage-sealing/precommit_policy.go b/extern/storage-sealing/precommit_policy.go index 0b774b56f..a6add5693 100644 --- a/extern/storage-sealing/precommit_policy.go +++ b/extern/storage-sealing/precommit_policy.go @@ -40,7 +40,10 @@ type BasicPreCommitPolicy struct { duration abi.ChainEpoch } -// NewBasicPreCommitPolicy produces a BasicPreCommitPolicy +// NewBasicPreCommitPolicy produces a BasicPreCommitPolicy. +// +// The provided duration is used as the default sector expiry when the sector +// contains no deals. The proving boundary is used to adjust/align the sector's expiration. func NewBasicPreCommitPolicy(api Chain, duration abi.ChainEpoch, provingBoundary abi.ChainEpoch) BasicPreCommitPolicy { return BasicPreCommitPolicy{ api: api, diff --git a/storage/miner.go b/storage/miner.go index 96184724b..dc8fb019a 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -41,6 +41,14 @@ import ( var log = logging.Logger("storageminer") +// Miner is the central miner entrypoint object inside Lotus. It is +// instantiated in the node builder, along with the WindowPoStScheduler. +// +// This object is the owner of the sealing pipeline. Most of the actual logic +// lives in the storage-sealing module (sealing.Sealing), and the Miner object +// exposes it to the rest of the system by proxying calls. +// +// Miner#Run starts the sealing FSM. type Miner struct { api fullNodeFilteredAPI feeCfg config.MinerFeeConfig @@ -118,7 +126,18 @@ type fullNodeFilteredAPI interface { WalletHas(context.Context, address.Address) (bool, error) } -func NewMiner(api fullNodeFilteredAPI, maddr address.Address, h host.Host, ds datastore.Batching, sealer sectorstorage.SectorManager, sc sealing.SectorIDCounter, verif ffiwrapper.Verifier, gsd dtypes.GetSealingConfigFunc, feeCfg config.MinerFeeConfig, journal journal.Journal, as *AddressSelector) (*Miner, error) { +// NewMiner creates a new Miner object. +func NewMiner(api fullNodeFilteredAPI, + maddr address.Address, + h host.Host, + ds datastore.Batching, + sealer sectorstorage.SectorManager, + sc sealing.SectorIDCounter, + verif ffiwrapper.Verifier, + gsd dtypes.GetSealingConfigFunc, + feeCfg config.MinerFeeConfig, + journal journal.Journal, + as *AddressSelector) (*Miner, error) { m := &Miner{ api: api, feeCfg: feeCfg, @@ -138,6 +157,7 @@ func NewMiner(api fullNodeFilteredAPI, maddr address.Address, h host.Host, ds da return m, nil } +// Run starts the sealing FSM in the background, running preliminary checks first. func (m *Miner) Run(ctx context.Context) error { if err := m.runPreflightChecks(ctx); err != nil { return xerrors.Errorf("miner preflight checks failed: %w", err) @@ -186,6 +206,7 @@ func (m *Miner) Stop(ctx context.Context) error { return m.sealing.Stop(ctx) } +// runPreflightChecks verifies that preconditions to run the miner are satisfied. func (m *Miner) runPreflightChecks(ctx context.Context) error { mi, err := m.api.StateMinerInfo(ctx, m.maddr, types.EmptyTSK) if err != nil { diff --git a/storage/wdpost_changehandler.go b/storage/wdpost_changehandler.go index 081cfecaf..8bcd7164e 100644 --- a/storage/wdpost_changehandler.go +++ b/storage/wdpost_changehandler.go @@ -23,9 +23,9 @@ type CompleteSubmitPoSTCb func(err error) type changeHandlerAPI interface { StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) + startGeneratePoST(ctx context.Context, ts *types.TipSet, deadline *dline.Info, onComplete CompleteGeneratePoSTCb) context.CancelFunc startSubmitPoST(ctx context.Context, ts *types.TipSet, deadline *dline.Info, posts []miner.SubmitWindowedPoStParams, onComplete CompleteSubmitPoSTCb) context.CancelFunc - onAbort(ts *types.TipSet, deadline *dline.Info) failPost(err error, ts *types.TipSet, deadline *dline.Info) } diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 15525e001..25bacc6c1 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -31,6 +31,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +// failPost records a failure in the journal. func (s *WindowPoStScheduler) failPost(err error, ts *types.TipSet, deadline *dline.Info) { s.journal.RecordEvent(s.evtTypes[evtTypeWdPoStScheduler], func() interface{} { c := evtCommon{Error: err} @@ -440,6 +441,12 @@ func (s *WindowPoStScheduler) declareFaults(ctx context.Context, dlIdx uint64, p return faults, sm, nil } +// runPost runs a full cycle of the PoSt process: +// +// 1. performs recovery declarations for the next deadline. +// 2. performs fault declarations for the next deadline. +// 3. computes and submits proofs, batching partitions and making sure they +// don't exceed message capacity. func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *types.TipSet) ([]miner.SubmitWindowedPoStParams, error) { ctx, span := trace.StartSpan(ctx, "storage.runPost") defer span.End() @@ -848,7 +855,9 @@ func (s *WindowPoStScheduler) setSender(ctx context.Context, msg *types.Message, } *msg = *gm - // estimate + // calculate a more frugal estimation; premium is estimated to guarantee + // inclusion within 5 tipsets, and fee cap is estimated for inclusion + // within 4 tipsets. minGasFeeMsg := *msg minGasFeeMsg.GasPremium, err = s.api.GasEstimateGasPremium(ctx, 5, msg.From, msg.GasLimit, types.EmptyTSK) @@ -863,6 +872,8 @@ func (s *WindowPoStScheduler) setSender(ctx context.Context, msg *types.Message, minGasFeeMsg.GasFeeCap = msg.GasFeeCap } + // goodFunds = funds needed for optimal inclusion probability. + // minFunds = funds needed for more speculative inclusion probability. goodFunds := big.Add(msg.RequiredFunds(), msg.Value) minFunds := big.Min(big.Add(minGasFeeMsg.RequiredFunds(), minGasFeeMsg.Value), goodFunds) diff --git a/storage/wdpost_sched.go b/storage/wdpost_sched.go index 0ebd491ec..d69f9c591 100644 --- a/storage/wdpost_sched.go +++ b/storage/wdpost_sched.go @@ -23,6 +23,12 @@ import ( "go.opencensus.io/trace" ) +// WindowPoStScheduler is the coordinator for WindowPoSt submissions, fault +// declaration, and recovery declarations. It watches the chain for reverts and +// applies, and schedules/run those processes as partition deadlines arrive. +// +// WindowPoStScheduler watches the chain though the changeHandler, which in turn +// turn calls the scheduler when the time arrives to do work. type WindowPoStScheduler struct { api fullNodeFilteredAPI feeCfg config.MinerFeeConfig @@ -43,7 +49,15 @@ type WindowPoStScheduler struct { // failLk sync.Mutex } -func NewWindowedPoStScheduler(api fullNodeFilteredAPI, fc config.MinerFeeConfig, as *AddressSelector, sb storage.Prover, verif ffiwrapper.Verifier, ft sectorstorage.FaultTracker, j journal.Journal, actor address.Address) (*WindowPoStScheduler, error) { +// NewWindowedPoStScheduler creates a new WindowPoStScheduler scheduler. +func NewWindowedPoStScheduler(api fullNodeFilteredAPI, + cfg config.MinerFeeConfig, + as *AddressSelector, + sp storage.Prover, + verif ffiwrapper.Verifier, + ft sectorstorage.FaultTracker, + j journal.Journal, + actor address.Address) (*WindowPoStScheduler, error) { mi, err := api.StateMinerInfo(context.TODO(), actor, types.EmptyTSK) if err != nil { return nil, xerrors.Errorf("getting sector size: %w", err) @@ -51,9 +65,9 @@ func NewWindowedPoStScheduler(api fullNodeFilteredAPI, fc config.MinerFeeConfig, return &WindowPoStScheduler{ api: api, - feeCfg: fc, + feeCfg: cfg, addrSel: as, - prover: sb, + prover: sp, verifier: verif, faultTracker: ft, proofType: mi.WindowPoStProofType,