diff --git a/markets/retrievaladapter/provider.go b/markets/retrievaladapter/provider.go index 95b7e1b3c..a9e893211 100644 --- a/markets/retrievaladapter/provider.go +++ b/markets/retrievaladapter/provider.go @@ -5,6 +5,7 @@ import ( "io" "github.com/filecoin-project/lotus/api/v1api" + "github.com/hashicorp/go-multierror" "golang.org/x/xerrors" "github.com/ipfs/go-cid" @@ -135,10 +136,14 @@ func (rpn *retrievalProviderNode) GetRetrievalPricingInput(ctx context.Context, } tsk := head.Key() + var mErr error + for _, dealID := range storageDeals { ds, err := rpn.full.StateMarketStorageDeal(ctx, dealID, tsk) if err != nil { - return resp, xerrors.Errorf("failed to look up deal %d on chain: err=%w", dealID, err) + log.Warnf("failed to look up deal %d on chain: err=%w", dealID, err) + mErr = multierror.Append(mErr, err) + continue } if ds.Proposal.VerifiedDeal { resp.VerifiedDeal = true @@ -158,7 +163,11 @@ func (rpn *retrievalProviderNode) GetRetrievalPricingInput(ctx context.Context, // Note: The piece size can never actually be zero. We only use it to here // to assert that we didn't find a matching piece. if resp.PieceSize == 0 { - return resp, xerrors.New("failed to find matching piece") + if mErr == nil { + return resp, xerrors.New("failed to find matching piece") + } + + return resp, xerrors.Errorf("failed to fetch storage deal state: %w", mErr) } return resp, nil diff --git a/markets/retrievaladapter/provider_test.go b/markets/retrievaladapter/provider_test.go index 5cdf5d060..eca3b1152 100644 --- a/markets/retrievaladapter/provider_test.go +++ b/markets/retrievaladapter/provider_test.go @@ -66,6 +66,31 @@ func TestGetPricingInput(t *testing.T) { expectedErrorStr: "failed to find matching piece", }, + "error when fails to fetch deal state": { + fFnc: func(n *mocks.MockFullNode) { + out1 := &api.MarketDeal{ + Proposal: market.DealProposal{ + PieceCID: pcid, + PieceSize: paddedSize, + }, + } + out2 := &api.MarketDeal{ + Proposal: market.DealProposal{ + PieceCID: testnet.GenerateCids(1)[0], + VerifiedDeal: true, + }, + } + + n.EXPECT().ChainHead(gomock.Any()).Return(tsk, nil).Times(1) + gomock.InOrder( + n.EXPECT().StateMarketStorageDeal(gomock.Any(), deals[0], key).Return(out1, xerrors.New("error 1")), + n.EXPECT().StateMarketStorageDeal(gomock.Any(), deals[1], key).Return(out2, xerrors.New("error 2")), + ) + + }, + expectedErrorStr: "failed to fetch storage deal state", + }, + "verified is true even if one deal is verified and we get the correct piecesize": { fFnc: func(n *mocks.MockFullNode) { out1 := &api.MarketDeal{ @@ -92,6 +117,32 @@ func TestGetPricingInput(t *testing.T) { expectedVerified: true, }, + "success even if one deal state fetch errors out but the other deal is verified and has the required piececid": { + fFnc: func(n *mocks.MockFullNode) { + out1 := &api.MarketDeal{ + Proposal: market.DealProposal{ + PieceCID: testnet.GenerateCids(1)[0], + }, + } + out2 := &api.MarketDeal{ + Proposal: market.DealProposal{ + PieceCID: pcid, + PieceSize: paddedSize, + VerifiedDeal: true, + }, + } + + n.EXPECT().ChainHead(gomock.Any()).Return(tsk, nil).Times(1) + gomock.InOrder( + n.EXPECT().StateMarketStorageDeal(gomock.Any(), deals[0], key).Return(out1, xerrors.New("some error")), + n.EXPECT().StateMarketStorageDeal(gomock.Any(), deals[1], key).Return(out2, nil), + ) + + }, + expectedPieceSize: unpaddedSize, + expectedVerified: true, + }, + "verified is false if both deals are unverified and we get the correct piece size": { fFnc: func(n *mocks.MockFullNode) { out1 := &api.MarketDeal{