Documentation
¶
Overview ¶
Package providerstates contains state machine logic relating to the `StorageProvider`.
provider_fsm.go is where the state transitions are defined, and the default handlers for each new state are defined.
provider_states.go contains state handler functions.
The following diagram illustrates the operation of the provider state machine. This diagram is auto-generated from current code and should remain up to date over time:
Index ¶
- Constants
- Variables
- func CleanupDeal(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func DecideOnProposal(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func FailDeal(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func HandoffDeal(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func PublishDeal(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func RejectDeal(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func ReserveProviderFunds(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func ValidateDealProposal(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func VerifyData(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func VerifyDealActivated(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func VerifyDealPreCommitted(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func WaitForDealCompletion(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func WaitForFunding(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- func WaitForPublish(ctx fsm.Context, environment ProviderDealEnvironment, ...) error
- type ProviderDealEnvironment
- type ProviderStateEntryFunc
Constants ¶
const DealMaxLabelSize = 256
TODO: These are copied from spec-actors master, use spec-actors exports when we update
Variables ¶
var ProviderEvents = fsm.Events{ fsm.Event(storagemarket.ProviderEventOpen).From(storagemarket.StorageDealUnknown).To(storagemarket.StorageDealValidating), fsm.Event(storagemarket.ProviderEventNodeErrored).FromAny().To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("error calling node: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventDealRejected). FromMany(storagemarket.StorageDealValidating, storagemarket.StorageDealVerifyData, storagemarket.StorageDealAcceptWait).To(storagemarket.StorageDealRejecting). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("deal rejected: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventRejectionSent). From(storagemarket.StorageDealRejecting).To(storagemarket.StorageDealFailing), fsm.Event(storagemarket.ProviderEventDealDeciding). From(storagemarket.StorageDealValidating).To(storagemarket.StorageDealAcceptWait), fsm.Event(storagemarket.ProviderEventDataRequested). From(storagemarket.StorageDealAcceptWait).To(storagemarket.StorageDealWaitingForData), fsm.Event(storagemarket.ProviderEventDataTransferFailed). FromMany(storagemarket.StorageDealTransferring, storagemarket.StorageDealProviderTransferAwaitRestart). To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("error transferring data: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventDataTransferInitiated). FromMany(storagemarket.StorageDealWaitingForData, storagemarket.StorageDealProviderTransferAwaitRestart). To(storagemarket.StorageDealTransferring). Action(func(deal *storagemarket.MinerDeal, channelId datatransfer.ChannelID) error { deal.TransferChannelId = &channelId return nil }), fsm.Event(storagemarket.ProviderEventDataTransferRestarted). FromMany(storagemarket.StorageDealWaitingForData, storagemarket.StorageDealProviderTransferAwaitRestart). To(storagemarket.StorageDealTransferring). From(storagemarket.StorageDealTransferring).ToJustRecord(). Action(func(deal *storagemarket.MinerDeal, channelId datatransfer.ChannelID) error { deal.TransferChannelId = &channelId deal.Message = "" return nil }), fsm.Event(storagemarket.ProviderEventDataTransferStalled). FromMany(storagemarket.StorageDealTransferring, storagemarket.StorageDealProviderTransferAwaitRestart). ToJustRecord(). Action(func(deal *storagemarket.MinerDeal) error { deal.Message = "data transfer appears to be stalled, awaiting reconnect from client" return nil }), fsm.Event(storagemarket.ProviderEventDataTransferCancelled). FromMany( storagemarket.StorageDealWaitingForData, storagemarket.StorageDealTransferring, storagemarket.StorageDealProviderTransferAwaitRestart, ). To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal) error { deal.Message = "data transfer cancelled" return nil }), fsm.Event(storagemarket.ProviderEventDataTransferCompleted). FromMany(storagemarket.StorageDealTransferring, storagemarket.StorageDealProviderTransferAwaitRestart). To(storagemarket.StorageDealVerifyData), fsm.Event(storagemarket.ProviderEventDataVerificationFailed). From(storagemarket.StorageDealVerifyData).To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error, path filestore.Path, metadataPath filestore.Path) error { deal.PiecePath = path deal.MetadataPath = metadataPath deal.Message = xerrors.Errorf("deal data verification failed: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventVerifiedData). FromMany(storagemarket.StorageDealVerifyData, storagemarket.StorageDealWaitingForData).To(storagemarket.StorageDealReserveProviderFunds). Action(func(deal *storagemarket.MinerDeal, path filestore.Path, metadataPath filestore.Path) error { deal.PiecePath = path deal.MetadataPath = metadataPath return nil }), fsm.Event(storagemarket.ProviderEventFundingInitiated). From(storagemarket.StorageDealReserveProviderFunds).To(storagemarket.StorageDealProviderFunding). Action(func(deal *storagemarket.MinerDeal, mcid cid.Cid) error { deal.AddFundsCid = &mcid return nil }), fsm.Event(storagemarket.ProviderEventFunded). FromMany(storagemarket.StorageDealProviderFunding, storagemarket.StorageDealReserveProviderFunds).To(storagemarket.StorageDealPublish), fsm.Event(storagemarket.ProviderEventDealPublishInitiated). From(storagemarket.StorageDealPublish).To(storagemarket.StorageDealPublishing). Action(func(deal *storagemarket.MinerDeal, finalCid cid.Cid) error { deal.PublishCid = &finalCid return nil }), fsm.Event(storagemarket.ProviderEventDealPublishError). From(storagemarket.StorageDealPublishing).To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("PublishStorageDeal error: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventSendResponseFailed). FromMany(storagemarket.StorageDealAcceptWait, storagemarket.StorageDealRejecting).To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("sending response to deal: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventDealPublished). From(storagemarket.StorageDealPublishing).To(storagemarket.StorageDealStaged). Action(func(deal *storagemarket.MinerDeal, dealID abi.DealID, finalCid cid.Cid) error { deal.DealID = dealID deal.PublishCid = &finalCid return nil }), fsm.Event(storagemarket.ProviderEventFileStoreErrored). FromMany(storagemarket.StorageDealStaged, storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing, storagemarket.StorageDealActive).To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("accessing file store: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventMultistoreErrored). FromMany(storagemarket.StorageDealStaged).To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("operating on multistore: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventDealHandoffFailed).From(storagemarket.StorageDealStaged).To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("handing off deal to node: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventPieceStoreErrored). From(storagemarket.StorageDealStaged).ToJustRecord(). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("recording piece for retrieval: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventDealHandedOff). From(storagemarket.StorageDealStaged).To(storagemarket.StorageDealAwaitingPreCommit). Action(func(deal *storagemarket.MinerDeal) error { deal.AvailableForRetrieval = true return nil }), fsm.Event(storagemarket.ProviderEventDealPrecommitFailed). From(storagemarket.StorageDealAwaitingPreCommit).To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("error awaiting deal pre-commit: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventDealPrecommitted). From(storagemarket.StorageDealAwaitingPreCommit).To(storagemarket.StorageDealSealing). Action(func(deal *storagemarket.MinerDeal, sectorNumber abi.SectorNumber) error { deal.SectorNumber = sectorNumber return nil }), fsm.Event(storagemarket.ProviderEventDealActivationFailed). From(storagemarket.StorageDealSealing).To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("error activating deal: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventDealActivated). FromMany(storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing). To(storagemarket.StorageDealFinalizing), fsm.Event(storagemarket.ProviderEventFinalized). From(storagemarket.StorageDealFinalizing).To(storagemarket.StorageDealActive). Action(func(deal *storagemarket.MinerDeal) error { deal.StoreID = nil return nil }), fsm.Event(storagemarket.ProviderEventDealSlashed). From(storagemarket.StorageDealActive).To(storagemarket.StorageDealSlashed). Action(func(deal *storagemarket.MinerDeal, slashEpoch abi.ChainEpoch) error { deal.SlashEpoch = slashEpoch return nil }), fsm.Event(storagemarket.ProviderEventDealExpired). From(storagemarket.StorageDealActive).To(storagemarket.StorageDealExpired), fsm.Event(storagemarket.ProviderEventDealCompletionFailed). From(storagemarket.StorageDealActive).To(storagemarket.StorageDealError). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("error waiting for deal completion: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventFailed).From(storagemarket.StorageDealFailing).To(storagemarket.StorageDealError), fsm.Event(storagemarket.ProviderEventRestart). FromMany(storagemarket.StorageDealValidating, storagemarket.StorageDealAcceptWait, storagemarket.StorageDealRejecting). To(storagemarket.StorageDealError). From(storagemarket.StorageDealTransferring). To(storagemarket.StorageDealProviderTransferAwaitRestart). FromAny().ToNoChange(), fsm.Event(storagemarket.ProviderEventTrackFundsFailed). From(storagemarket.StorageDealReserveProviderFunds).To(storagemarket.StorageDealFailing). Action(func(deal *storagemarket.MinerDeal, err error) error { deal.Message = xerrors.Errorf("error tracking deal funds: %w", err).Error() return nil }), fsm.Event(storagemarket.ProviderEventFundsReserved). From(storagemarket.StorageDealReserveProviderFunds).ToJustRecord(). Action(func(deal *storagemarket.MinerDeal, fundsReserved abi.TokenAmount) error { if deal.FundsReserved.Nil() { deal.FundsReserved = fundsReserved } else { deal.FundsReserved = big.Add(deal.FundsReserved, fundsReserved) } return nil }), fsm.Event(storagemarket.ProviderEventFundsReleased). FromMany(storagemarket.StorageDealPublishing, storagemarket.StorageDealFailing).ToJustRecord(). Action(func(deal *storagemarket.MinerDeal, fundsReleased abi.TokenAmount) error { deal.FundsReserved = big.Subtract(deal.FundsReserved, fundsReleased) return nil }), }
ProviderEvents are the events that can happen in a storage provider
var ProviderFinalityStates = []fsm.StateKey{ storagemarket.StorageDealError, storagemarket.StorageDealSlashed, storagemarket.StorageDealExpired, }
ProviderFinalityStates are the states that terminate deal processing for a deal. When a provider restarts, it restarts only deals that are not in a finality state.
var ProviderStateEntryFuncs = fsm.StateEntryFuncs{ storagemarket.StorageDealValidating: ValidateDealProposal, storagemarket.StorageDealAcceptWait: DecideOnProposal, storagemarket.StorageDealVerifyData: VerifyData, storagemarket.StorageDealReserveProviderFunds: ReserveProviderFunds, storagemarket.StorageDealProviderFunding: WaitForFunding, storagemarket.StorageDealPublish: PublishDeal, storagemarket.StorageDealPublishing: WaitForPublish, storagemarket.StorageDealStaged: HandoffDeal, storagemarket.StorageDealAwaitingPreCommit: VerifyDealPreCommitted, storagemarket.StorageDealSealing: VerifyDealActivated, storagemarket.StorageDealRejecting: RejectDeal, storagemarket.StorageDealFinalizing: CleanupDeal, storagemarket.StorageDealActive: WaitForDealCompletion, storagemarket.StorageDealFailing: FailDeal, }
ProviderStateEntryFuncs are the handlers for different states in a storage client
Functions ¶
func CleanupDeal ¶ added in v0.5.3
func CleanupDeal(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
CleanupDeal clears the filestore once we know the mining component has read the data and it is in a sealed sector
func DecideOnProposal ¶ added in v0.2.7
func DecideOnProposal(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
DecideOnProposal allows custom decision logic to run before accepting a deal, such as allowing a manual operator to decide whether or not to accept the deal
func FailDeal ¶
func FailDeal(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
FailDeal cleans up before terminating a deal
func HandoffDeal ¶
func HandoffDeal(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
HandoffDeal hands off a published deal for sealing and commitment in a sector
func PublishDeal ¶
func PublishDeal(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
PublishDeal sends a message to publish a deal on chain
func RejectDeal ¶ added in v0.4.0
func RejectDeal(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
RejectDeal sends a failure response before terminating a deal
func ReserveProviderFunds ¶ added in v1.0.4
func ReserveProviderFunds(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
ReserveProviderFunds adds funds, as needed to the StorageMarketActor, so the miner has adequate collateral for the deal
func ValidateDealProposal ¶
func ValidateDealProposal(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
ValidateDealProposal validates a proposed deal against the provider criteria
func VerifyData ¶
func VerifyData(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
VerifyData verifies that data received for a deal matches the pieceCID in the proposal
func VerifyDealActivated ¶
func VerifyDealActivated(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
VerifyDealActivated verifies that a deal has been committed to a sector and activated
func VerifyDealPreCommitted ¶ added in v1.0.7
func VerifyDealPreCommitted(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
VerifyDealPreCommitted verifies that a deal has been pre-committed
func WaitForDealCompletion ¶ added in v0.4.0
func WaitForDealCompletion(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
WaitForDealCompletion waits for the deal to be slashed or to expire
func WaitForFunding ¶ added in v0.2.0
func WaitForFunding(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
WaitForFunding waits for a message posted to add funds to the StorageMarketActor to appear on chain
func WaitForPublish ¶ added in v0.2.0
func WaitForPublish(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
WaitForPublish waits for the publish message on chain and saves the deal id so it can be sent back to the client
Types ¶
type ProviderDealEnvironment ¶
type ProviderDealEnvironment interface { Address() address.Address Node() storagemarket.StorageProviderNode Ask() storagemarket.StorageAsk DeleteStore(storeID multistore.StoreID) error GeneratePieceCommitment(storeID *multistore.StoreID, payloadCid cid.Cid, selector ipld.Node) (cid.Cid, filestore.Path, error) GeneratePieceReader(storeID *multistore.StoreID, payloadCid cid.Cid, selector ipld.Node) (io.ReadCloser, uint64, error, <-chan error) SendSignedResponse(ctx context.Context, response *network.Response) error Disconnect(proposalCid cid.Cid) error FileStore() filestore.FileStore PieceStore() piecestore.PieceStore RunCustomDecisionLogic(context.Context, storagemarket.MinerDeal) (bool, string, error) network.PeerTagger }
ProviderDealEnvironment are the dependencies needed for processing deals with a ProviderStateEntryFunc
type ProviderStateEntryFunc ¶
type ProviderStateEntryFunc func(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error
ProviderStateEntryFunc is the signature for a StateEntryFunc in the provider FSM