This note expands an item from Cron safety - survey of the problem and solutions. It describes why and how to to remove from cron the expensive sector and deal activation work associated with onboarding via the single-sector ProveCommit method. This:
- is a pre-requisite for any kind of push-style events associated with sector activation for user-programmed actors/contracts;
- resolves an imbalance in the sector activation gas subsidy available to different onboarding methods; and
- removes some unnecessary work from cron, as one step towards bounding its cost.
Developed in collaboration with @zenground0.
Background
Single PoRep proofs are validated asynchronously via a cron call to the power actor. The asynchrony is to enable the use of multiple CPU cores by verifying multiple proofs submitted that epoch in parallel. Blockchain execution is usually single-threaded, so multiple processor cores are seen as an otherwise wasted resource. After a proof is verified the sector is activated back with the miner actor, all in the power actor’s cron handler.
By contrast, when submitting an aggregated PoRep, all of the proof validation and sector activation is executed synchronously and billed to the caller.
Problems
We explicitly charge gas (discounted) for the single proof validation when it is submitted, so it’s both bounded and paid for. However, the state updates associated with sector activation are not metered, because they execute in cron. The execution cost of this activation varies significantly with the deal content of the sector, but the storage provider doesn’t pay gas for this. On the other hand, aggregated proof validation also activates the sector synchronously, for which the SP pays the gas cost.
Thus single-sector onboarding is subsidised relative to aggregation, but aggregation would otherwise efficiently support much higher onboarding rates.
Deal activation is cron only (kind-of) ok at the moment because the built-in market is the only market, and it offers no facility to synchronously invoke (notify) user actors/contracts during deal activation. To better support deal-related user actors we would like support activation notifications to untrusted code, which we cannot do from cron.
Proposal
Ultimately the SP must pay the gas costs associated with sector activation, including deal activation. The present cron subsidy must be removed.
Synchronous sector activation
Add a new ProveCommitAndActivate
method which validates the PoRep and synchronously activates a single sector. This method will not enjoy the verification gas discount for asynchronous validation, but is essentially the same workflow as today. (Assumption: this is cheaper than using ProveCommitAggregate
with a single proof).
The existing ProveCommitSector
method must be deprecated in a subsequent upgrade.
This will have the effect of removing the subsidy to single ProveCommitSector
calls relative to aggregate proofs. The result is increased cost of the single-verification method. This will resolve the imbalance and make ProveCommitAggregate
again preferred when onboarding multiple sectors. However, it won’t reduce any SP costs.
Optimise deal activation costs
Resolving the imbalance results in an aggregate increase in onboarding gas costs, as the SP must pay for the deal activation work currently hidden in cron.
We should also optimise the on-chain work that’s now uniformly paid for by the SP. Details of how are omitted here (we need to profile and understand the costs first).
Asynchronous sector activation (optional)
Add a new ProveCommitAsync
method which schedules a proof for asynchronous validation via the power actor cron, but does not activate the sector. This method can offer proof verification at a discount, accounting for the parallel verification potential.
Internally, instead of calling the current ConfirmSectorProofsValid
method (which activates the sector), the power actor calls a new miner actor method which stores the validated sector number in miner state but does not activate the sector. This introduces a new state in sector onboarding: validated but not yet active. Such a sector has no power and is not scheduled for WindowPoSt.
Add a new ActivateSectors
method which activates sectors that have validated proofs. This includes activating the deals which, today, are referenced in the sectors’ on-chain info. The SP calls this and pays the gas cost.
This will restore the global efficiency gain of asynchronous, batched proof validation, but requires an SP to submit a total of three messages to complete sector onboarding (or four, with deals).
This would introduce protocol and operational complexity which may not be worth the gain. It’s also a stepping stone to more functionality.
Sealing as a service support (optional)
Add ProveCommitAggregateOnly
method which verifies an aggregated PoRep but does not activate the sectors. The sectors may be subsequently activated via ActivateSectors
. The existing ProveCommitAggregate
method continues to do both at once.
This method efficiently supports sealing as a service. The sealer may submit proof verification on chain, then take their time to transport the physical sector to the miner, who then activates it when they are ready to submit regular WindowPost.
The motivation for this is from discussion #570.
Deadline assignment support (optional)
Add parameters to ActivateSectors
to support the SP nominating a WindowPoSt deadline to which the sectors are to be assigned. SPs have requested this, and it may significantly reduce off-chain staffing costs associated with production monitoring and failure resolution. See https://github.com/filecoin-project/FIPs/discussions/505.
TODO: determine if SP control over WindowPoSt scheduling is safe; initial design assumed not.
Future-proofing
Future changes for improved storage programmability (sector events/notifications) will need additional parameters to sector activation methods (ActivateSector, ProveCommitSync, and the existing methods) to include a list of PieceCIDs and associated actor addresses and piece identifiers to be notified about piece inclusion in an activated sector. We could probably add these to the parameter object for this method now, but require them to be empty.