From 1622db3454bfc6d25c70de092816ad45ad8d7d58 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 6 Oct 2021 15:27:09 +0200 Subject: [PATCH] block in Publish state when message sending fails due to lack of funds --- .../impl/providerstates/provider_states.go | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/storagemarket/impl/providerstates/provider_states.go b/storagemarket/impl/providerstates/provider_states.go index f8c851305..233b15dad 100644 --- a/storagemarket/impl/providerstates/provider_states.go +++ b/storagemarket/impl/providerstates/provider_states.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "io" + "strings" + "time" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" @@ -29,6 +31,11 @@ import ( var log = logging.Logger("providerstates") +var ( + RetryInterval = 2 * time.Minute + MaxAttempts = 10 +) + // TODO: These are copied from spec-actors master, use spec-actors exports when we update const DealMaxLabelSize = 256 @@ -274,20 +281,33 @@ func WaitForFunding(ctx fsm.Context, environment ProviderDealEnvironment, deal s // PublishDeal sends a message to publish a deal on chain func PublishDeal(ctx fsm.Context, environment ProviderDealEnvironment, deal storagemarket.MinerDeal) error { - smDeal := storagemarket.MinerDeal{ - Client: deal.Client, - ClientDealProposal: deal.ClientDealProposal, - ProposalCid: deal.ProposalCid, - State: deal.State, - Ref: deal.Ref, - } + attempt := 0 + retry := RetryInterval - mcid, err := environment.Node().PublishDeals(ctx.Context(), smDeal) - if err != nil { - return ctx.Trigger(storagemarket.ProviderEventNodeErrored, xerrors.Errorf("publishing deal: %w", err)) - } + for { + attempt++ + retry *= 2 + + smDeal := storagemarket.MinerDeal{ + Client: deal.Client, + ClientDealProposal: deal.ClientDealProposal, + ProposalCid: deal.ProposalCid, + State: deal.State, + Ref: deal.Ref, + } - return ctx.Trigger(storagemarket.ProviderEventDealPublishInitiated, mcid) + mcid, err := environment.Node().PublishDeals(ctx.Context(), smDeal) + if err != nil { + if strings.Contains(err.Error(), "not enough funds") && attempt <= MaxAttempts { + log.Warnf("publishing deal failed due to lack of funds: %s; retrying again after backoff interval: %s", err, retry) + time.Sleep(retry) + continue + } + return ctx.Trigger(storagemarket.ProviderEventNodeErrored, xerrors.Errorf("publishing deal: %w", err)) + } + + return ctx.Trigger(storagemarket.ProviderEventDealPublishInitiated, mcid) + } } // WaitForPublish waits for the publish message on chain and saves the deal id