From 6e5ccc87cfa9ccf75eddadaeefc654c3de1e8d2d Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 6 Oct 2021 13:43:38 +0200 Subject: [PATCH 1/4] cli: add retry for deals stuck in Publish with no funds --- .circleci/config.yml | 5 ++ api/api_storage.go | 1 + api/proxy_gen.go | 13 +++ build/openrpc/full.json.gz | Bin 25455 -> 25453 bytes build/openrpc/miner.json.gz | Bin 10424 -> 10467 bytes build/openrpc/worker.json.gz | Bin 2710 -> 2713 bytes cmd/lotus-miner/market.go | 29 ++++++ documentation/en/api-v0-methods-miner.md | 17 ++++ documentation/en/cli-lotus-miner.md | 15 ++++ go.mod | 2 +- go.sum | 4 +- itests/deals_retry_deal_no_funds_test.go | 107 +++++++++++++++++++++++ node/impl/storminer.go | 4 + 13 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 itests/deals_retry_deal_no_funds_test.go diff --git a/.circleci/config.yml b/.circleci/config.yml index 222f14d50..30f2d5c01 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -825,6 +825,11 @@ workflows: suite: itest-deals_publish target: "./itests/deals_publish_test.go" + - test: + name: test-itest-deals_retry_deal_no_funds + suite: itest-deals_retry_deal_no_funds + target: "./itests/deals_retry_deal_no_funds_test.go" + - test: name: test-itest-deals suite: itest-deals diff --git a/api/api_storage.go b/api/api_storage.go index 6ebee9908..8cca2aa5b 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -166,6 +166,7 @@ type StorageMiner interface { MarketCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error //perm:write MarketPendingDeals(ctx context.Context) (PendingDealInfo, error) //perm:write MarketPublishPendingDeals(ctx context.Context) error //perm:admin + MarketRetryPublishDeal(ctx context.Context, propcid cid.Cid) error //perm:admin // DagstoreListShards returns information about all shards known to the // DAG store. Only available on nodes running the markets subsystem. diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 7a504cf77..b36f19a7e 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -683,6 +683,8 @@ type StorageMinerStruct struct { MarketRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + MarketRetryPublishDeal func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + MarketSetAsk func(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error `perm:"admin"` MarketSetRetrievalAsk func(p0 context.Context, p1 *retrievalmarket.Ask) error `perm:"admin"` @@ -4020,6 +4022,17 @@ func (s *StorageMinerStub) MarketRestartDataTransfer(p0 context.Context, p1 data return ErrNotSupported } +func (s *StorageMinerStruct) MarketRetryPublishDeal(p0 context.Context, p1 cid.Cid) error { + if s.Internal.MarketRetryPublishDeal == nil { + return ErrNotSupported + } + return s.Internal.MarketRetryPublishDeal(p0, p1) +} + +func (s *StorageMinerStub) MarketRetryPublishDeal(p0 context.Context, p1 cid.Cid) error { + return ErrNotSupported +} + func (s *StorageMinerStruct) MarketSetAsk(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error { if s.Internal.MarketSetAsk == nil { return ErrNotSupported diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 8837c745b4e46ae201270a2de36dbb74a3113df1..1c5765efe0dbcb07a8690e6da243d9459b5ef039 100644 GIT binary patch delta 17539 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 delta 17516 zcmV)xK$E}i#sTlf0kHN00V$LB0*nE+lY|3#0lSm_1NDEg)4&EnAQ4Szt4!3jD?9>O7K{WY%}?y<$g(~E=2BtjF&k!bZ&uE!=ri}?C8#5kOV$|NJ# z(*>T`R)0$)QJla)T3SRCYT6DVLvIn1pRA=lr#OF%A7u(s<85IHN;TKg^8Pl!9L?B| zq`ti&%OGDrfKdeJayZ5^xDV4`VofcG&KOrm!ZSA5jrhVITHHv+0&U8ge5O&5mjx>c`WyX}at5DQ%z_?*skmr>+d!Tm%^?PjgWNiuZtEOgIYd278hsnEavX^?KI zho-b7`sgfqAkC{jz{>h+D5s*@#ud3DA1O!s;AAWcL$rVX^R42Cx_;DCWHs*f|-uDXwFklpflrcOCkUTIhHxD=kQ+R`} zh>yq8`o^=dj3YWz!+o6F0SkMF>THy0NN@7`R1laJs4T%5f* zI(d6?1P)I>9sMR+JpKeee!3L(a?M_T5-pguk4}F-esipvxjZ?$cyoD0erG7%3OU)# zhCm4zIVx?q2OfYk#RD~2H1pchYa3I=VZbu*s>}fw$P2HF509{~ z|8A>knjLf#@^2$LYmW}!LG~7*BN%q7dWvV*68yh|>?}ev9Csk{gY*u3jm6kY1 z@9(Z^B5gmCKVT4d&_w=7T)_HKs?{=mfuvvji`ZkXeC;FLEik5eG z$xTSz(Ny}@2I^%HP8*-oUx}%6b0M~SPz(O`%jN~2h`_E3Ue~uiO4sFWR=+OV>*~+Q zU2MWg`i~IwCB{jA7yWNC`^8Yv$#H5AxFXW4%l^}2UZy}%K1k5tR)*Nhhqc4O(aCZ7ta&t(x+g1t zHu&CB&vwY$A@7HGg<@;-m6eQUC*)EBuVsaG+EAU;Hi6e~X#NyD`SP{B;7+?~xLA?4 z+x{*^^?0nsdPZI0a6+9;Nb|oJN7B@<@NRFyyD+_0(x4}iH!Sh(aEDEKM0R(sUru&n z5+VPem*YFKJNfIy&W^uBcX#;TWINnJ#^K%FG`jJoH)!zv>q;cGaZg8y~{}K1$EO-~4myb+aZ4Gy(zIvs(-n0Rft` zat(0<0lSmr5IOz!`eH{ zVnx+f`VGxjscKx%IPw~mjEB3i_ZsiBiUpiTHC$$IXN}Zt@3e%y$s=pDaiiydTJE^t zbM!CT@&;Y?W{@Z=RA&e2ffeM&UcnKH?^kS@pL4{{AokyCsl0GQ%Npm%L-@v4{cu)* zd#nvPMdxu^0c^==)Xr4guI>>Gm(uJ6r|P8GrMg+w=C=Qyl*2%<*7h{qPle2dDQSXr zFB?M<$oM@CQH|_yU7?jaXEN=7^thpe|Co6OWljSlZd;qEZH3+&5a3dw+scEq&3I5G zFoA;5h|gAxhT?&ls3rBne#4>^zJi_0w!V?Rnsh=go8Fpw=Qd_*aM9)ZjV{-~gs*}_X37=4JVMn zKNU5goujCW%hwZ{c5(TBTwK2UjBZ~w-gcCH^MGA3Noz9@Pr^AWa9wih|UW4DkNy_53AmbL{??c zx^@t|@}@@J`Ya>8hLU!F@wPJYpPZhW&xCX=rp)*N@5;}LK;RP35aVzbiV|C!ThfOD z3u^Sw3-tF#+96eQ(u|cMDo3eRjof%GYji;Y9WjTVH7jFN_64j=f%&ihxMkPt#+$GAn~ix}&jnA4cn^tND_Z&?nOiIR?Q6?b4anA#Sw$A)9L++`0H+{Q?_DBSm&ny6 za{VEUaH}zqt9I(>nsY3vUdQrMpOH_Ik0OigsvuK;5H#Sbfrxf%tw{j1%HpyU$dAqAGvN z+{dUkPCFB`GclK)NZNm*pJAD9%z*WnL$N$MEVSJiB`J}A`IpgLt1%~p#p5ydWTw5C z_+8zaEn2p8iLpja4PEsMsG7&L*kZGo+$#N%aTo;1H(jGCNfUj9is1rJxv5St*e> zKnv$!vKf}oZIXBfAJHIy97U<}q%T27T;C)V;zWZ56&8U7A@WyhC~{$gAa#luxWP zwNBe}+TKIe_V#LGi71x!8S|+h!P}0~AgTVdBtg>uN~C}>I9myj(sQf-U?3&|l}lO6 zfh4JsGXSnNwN4~Bk?>GO!mFBa4Kk#OzSJ+6R(qjPe`uiAIZVF2M6)n}9A!RV^6>{Y zX=MC`K6>%@svx}H-q)9BR&Ek(y*`Rjlg?lyc4KdAy)UD#`a2&8%19=*yFC=05lkj$^n&Yt zWPts4fBph_D!vUcN3+GT=c_|Wbvi#kr!lcQ)US%hq#vj}^xxC@vJ1+Te6$uL%|2W z<2X^(JhaSJSr$LtSW>P5i=8Ek9?m)Hy1N!He}P`Z$mM}yo!6uB-UdazN6=Smv?AxL zEoupnCx|%f4qo069^nkFe8!{zMvPry{``#aWXiQm<$L`@gB(>t20iUL>Zfd23&3;a zAsnjR+E4SQWbUWM!_$j{$s|G(fv)$zX|A_D)V#CuyA&Xzj-olSt^Srq*OH?Laucc4 ze^O%F4k1ISx3*}P6`|?{^1|!dxW8J#L)HjP%{LEt9`$m4XxB|%f7e8fm5luzl05o^jA^$62BU#i=guR%aWsXP zNGoUE5a#E)|~tLD~li^wQv_s^Jia`&F|uhE7!&M)@N^L^i~>-HV4DON5pSwbZtJme~^ii zGm{RDu2CdDmtkU3WmIyGo!y-muV3!G+Sz+0Br&?l6uP+}Kx>X6G9c=?`strY~cq5VOUR~fB15mqV>Xql43mQcMyR|Qnu!|y z1-`4ENGqwTv*BnK@Wma*yTf>Q7~l3V-Vg?c>Y=1fcMzTOt&07=(5B zLGH)oM@s%5CG(y1cG9~hK2ukg`-o%nRg3)^Fz+zG;~EcyYdFlm##nQ^CWv(&_54nF z6f@o>NKth=Kf+3scD7=3e~~#TTf0$4o2>y!-DQo_dW^=Ahk8t?;AD)GF;2$ZXBp${ zO3tp-BX3;Y8XJ%q>cRre>kg{a3|EAP`_V7 z{SO#mKbx3>3(3l5XchOU*l0DyI_$MhyH3dR)*cr^fZ8p#H&J9ve%8W!tZqewkPBXU zmZNFoS^Zj3-=Gc;8DIa?Z%cgj2PVXK>*5Kg0_O}7vGse9<%O2);|nh%&I_IXD5+i^ ztBr6k5?d$ZWkA9pTmYdepGtY9)k84BH;6pWV8o8QI_|nQ-1S9WZ0B^xpQA8<9_oR+ z7Fx1Bf?txo7JB_r?6o{t8}?cxwn2p|an@VRryx=d%n;%37~bhc4?{0=B_-X+om0jjgHDux7qdbLoHVKTY!rpS+j&W5i-Gs~%QqD|ePr4%!|ZV+ci zyIrMOevDR%T#-Igw%w?Az(*Y7fGN{gUYT=Bm*bF&IHa+#OY@k2XLB-lqWl;VQ@A=a zyAU8q9b50q^X1{-cj*jqtbHN$BeZR0^X`klt)yoxMS`*GSzIm_jl^fRdq! zhBGYA=@k+1T(zLXUy06C`K%ZiX~K{{)G@*I?zkeD_}GKeB9#Q*rx75Ot3=~?LZlzT zG(v1j1K$X{AJAJAAs>w9fD&{?U_eD9m``)v>lt~hHm!B0_P*bLj&@=B9hP)h(qT!5 zCA(tD?S`=Y7q>86CN#fMf5jO}t1iU$5Zd1uKyQ#UKPm04#wJabF=I2MsVJ%->I&04 z)rLAfDcPQVX{D+A0cN%g? z2$Z-)%+9R(kHz?ZUGaR+fjV=;uR`<9NWLLZXBCd`)i0!77|q3S-T`(8*d1WM&w$-Q zUI&|ppA)>>77d5fK71Dz|X03r?R<#Zj zYFF5-U=xbVN;O<|&I+}<>zpH1kX8-eE~h9$GKdtR9Ly01kj#NcXEQ{25|=8?9lOyJ zBKmngehnW#_sT|`UCfE6E9`$8=*z1@OdX;rCcgMva2JH4td#i0F6mi33NV{~U=udj z-`d_87G4~G2GqM&uf7ilGSqa|hI)C1qDvey#7`mPTbrAr@W#%t>g`)hV1W5t75Uy$ z3>A8BQL~QFZ)G0bNOh@v6?4naa|K38VI3X4SEUU5Xp7)LYYAI!M6Ht3kIr3arO<`;-? zEc+sVaS#j#{~e>)tosLzy(x;$5%Li-T5XTo)QH;ZnEBzft=-M~V9r;^y7{TixUl2^ zgo6`byc}Z_?_@f>@e$hg-%0(i`o_zL?!3=J;#EzY&I-y}#CunROhbx6>yC$dC*_I!a|qLK~d+d9HNhy*oEo&rF?P%wV3%8W3X zsMV82pF=*tX=@wcgaa(k4rVHn1O)ovY6u`WqCWD#liMlwra%X($O7eg;_dSgde_K* zPkRw__f*HY_#jG6A)9XG%_jXs4DA}4YE4$Zbs2} zwP5a~5U9HSpS!AdS8?o`QtVD$-Kp!E+WFR%jqKIjJX9O2+tov(ZVLy0cca!~Uea(A zv5Td^;`ZTV;vmnOzJB4Qm9j$#kEllFnZk37Bjl-8+vf1hwb&YbXZ=35T%6lmFPpBD zX|?UZFG~-rO`p|oV@!M&in<#z#-Oj8&=$qfoFf^8rr?CZb16F)aEpwp2K15Zpfv-@ z4csmk%|m4wI&=X+lsTTINQpjw5{}e7V{JGsy2qK zT5B)40�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 H1Na00TbW&U diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 6727576ef066258e858b05e796483b6e81cc6fd5..5bdcf035c3be915b1e1292c2d10c38c3472013f4 100644 GIT binary patch literal 10467 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 literal 2710 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 Q1pom5|LSQQmRWiL07ySJ#sB~S diff --git a/cmd/lotus-miner/market.go b/cmd/lotus-miner/market.go index c32f44b6a..2e4db79ce 100644 --- a/cmd/lotus-miner/market.go +++ b/cmd/lotus-miner/market.go @@ -352,6 +352,7 @@ var storageDealsCmd = &cli.Command{ resetBlocklistCmd, setSealDurationCmd, dealsPendingPublish, + dealsRetryPublish, }, } @@ -910,6 +911,34 @@ var dealsPendingPublish = &cli.Command{ }, } +var dealsRetryPublish = &cli.Command{ + Name: "retry-publish", + Usage: "retry publishing a deal", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "proposal-cid", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetMarketsAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := lcli.ReqContext(cctx) + + cid, err := cid.Decode(cctx.String("proposal-cid")) + if err != nil { + return err + } + if err := api.MarketRetryPublishDeal(ctx, cid); err != nil { + return xerrors.Errorf("retrying publishing deal: %w", err) + } + fmt.Println("retried to publish deal") + return nil + }, +} + func listDealsWithJSON(cctx *cli.Context) error { node, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index dd7a1f88e..4d14bcb0e 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -61,6 +61,7 @@ * [MarketPendingDeals](#MarketPendingDeals) * [MarketPublishPendingDeals](#MarketPublishPendingDeals) * [MarketRestartDataTransfer](#MarketRestartDataTransfer) + * [MarketRetryPublishDeal](#MarketRetryPublishDeal) * [MarketSetAsk](#MarketSetAsk) * [MarketSetRetrievalAsk](#MarketSetRetrievalAsk) * [Mining](#Mining) @@ -949,6 +950,22 @@ Inputs: Response: `{}` +### MarketRetryPublishDeal + + +Perms: admin + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `{}` + ### MarketSetAsk diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index 5a0888621..7823e886f 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -629,6 +629,7 @@ COMMANDS: reset-blocklist Remove all entries from the miner's piece CID blocklist set-seal-duration Set the expected time, in minutes, that you expect sealing sectors to take. Deals that start before this duration will be rejected. pending-publish list deals waiting in publish queue + retry-publish retry publishing a deal help, h Shows a list of commands or help for one command OPTIONS: @@ -825,6 +826,20 @@ OPTIONS: ``` +### lotus-miner storage-deals retry-publish +``` +NAME: + lotus-miner storage-deals retry-publish - retry publishing a deal + +USAGE: + lotus-miner storage-deals retry-publish [command options] [arguments...] + +OPTIONS: + --proposal-cid value + --help, -h show help (default: false) + +``` + ## lotus-miner retrieval-deals ``` NAME: diff --git a/go.mod b/go.mod index add0c7f96..bebae0528 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/filecoin-project/go-data-transfer v1.11.1 github.com/filecoin-project/go-fil-commcid v0.1.0 github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 - github.com/filecoin-project/go-fil-markets v1.13.1 + github.com/filecoin-project/go-fil-markets v1.13.2-0.20211007101645-eebce51848eb github.com/filecoin-project/go-jsonrpc v0.1.5 github.com/filecoin-project/go-padreader v0.0.1 github.com/filecoin-project/go-paramfetch v0.0.2 diff --git a/go.sum b/go.sum index 843436bac..fc22b4a2d 100644 --- a/go.sum +++ b/go.sum @@ -338,8 +338,8 @@ github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+ github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 h1:imrrpZWEHRnNqqv0tN7LXep5bFEVOVmQWHJvl2mgsGo= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0/go.mod h1:73S8WSEWh9vr0fDJVnKADhfIv/d6dCbAGaAGWbdJEI8= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.13.1 h1:KjarxgKp/RN4iYXT2pMcMq6veIa1guGJMoVtnwru4BQ= -github.com/filecoin-project/go-fil-markets v1.13.1/go.mod h1:58OjtsWtDt3xlN1QLmgDQxtfCDtDS4RIyHepIUbqXhM= +github.com/filecoin-project/go-fil-markets v1.13.2-0.20211007101645-eebce51848eb h1:8e9XhhvYCUS91GeP4HXj6rH2ySShLuWRDkwff1CFha0= +github.com/filecoin-project/go-fil-markets v1.13.2-0.20211007101645-eebce51848eb/go.mod h1:58OjtsWtDt3xlN1QLmgDQxtfCDtDS4RIyHepIUbqXhM= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= diff --git a/itests/deals_retry_deal_no_funds_test.go b/itests/deals_retry_deal_no_funds_test.go new file mode 100644 index 000000000..e851d3df7 --- /dev/null +++ b/itests/deals_retry_deal_no_funds_test.go @@ -0,0 +1,107 @@ +package itests + +import ( + "context" + "testing" + "time" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/policy" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/wallet" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/markets/storageadapter" + "github.com/filecoin-project/lotus/node" + "github.com/filecoin-project/lotus/node/config" + "github.com/filecoin-project/lotus/node/modules" + "github.com/filecoin-project/lotus/storage" + "github.com/stretchr/testify/require" +) + +var ( + publishPeriod = 1 * time.Second + maxDealsPerMsg = uint64(2) // Set max deals per publish deals message to 2 + + blockTime = 10 * time.Millisecond +) + +func TestDealsRetryLackOfFunds(t *testing.T) { + ctx := context.Background() + oldDelay := policy.GetPreCommitChallengeDelay() + policy.SetPreCommitChallengeDelay(5) + + t.Cleanup(func() { + policy.SetPreCommitChallengeDelay(oldDelay) + }) + + policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg8MiBV1) + kit.QuietMiningLogs() + + // Allow 8MB sectors + eightMBSectorsOpt := kit.SectorSize(8 << 20) + + publishStorageDealKey, err := wallet.GenerateKey(types.KTSecp256k1) + require.NoError(t, err) + + opts := node.Options( + node.Override(new(*storageadapter.DealPublisher), + storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{ + Period: publishPeriod, + MaxDealsPerMsg: maxDealsPerMsg, + }), + ), + node.Override(new(*storage.AddressSelector), modules.AddressSelector(&config.MinerAddressConfig{ + DealPublishControl: []string{ + publishStorageDealKey.Address.String(), + }, + DisableOwnerFallback: true, + DisableWorkerFallback: true, + })), + ) + + minerFullNode, clientFullNode, miner, ens := kit.EnsembleTwoOne(t, kit.Account(publishStorageDealKey, types.NewInt(1020000000000)), kit.ConstructorOpts(opts), kit.MockProofs(), eightMBSectorsOpt) + + //TODO: this fails slightly differently - handle this case as well + //minerFullNode, clientFullNode, miner, ens := kit.EnsembleTwoOne(t, kit.Account(publishStorageDealKey, types.NewInt(1)), kit.ConstructorOpts(opts), kit.MockProofs(), eightMBSectorsOpt) + + kit.QuietMiningLogs() + + ens. + Start(). + InterconnectAll(). + BeginMining(blockTime) + + _, err = minerFullNode.WalletImport(ctx, &publishStorageDealKey.KeyInfo) + require.NoError(t, err) + + miner.SetControlAddresses(publishStorageDealKey.Address) + + dh := kit.NewDealHarness(t, clientFullNode, miner, miner) + + res, _ := clientFullNode.CreateImportFile(ctx, 0, 4<<20) // 4MiB file. + list, err := clientFullNode.ClientListImports(ctx) + require.NoError(t, err) + require.Len(t, list, 1) + require.Equal(t, res.Root, *list[0].Root) + + dp := dh.DefaultStartDealParams() + dp.Data.Root = res.Root + dp.FastRetrieval = true + dp.EpochPrice = abi.NewTokenAmount(62500000) // minimum asking price. + deal := dh.StartDeal(ctx, dp) + + propcid := *deal + + go func() { + time.Sleep(20 * time.Second) + + kit.SendFunds(ctx, t, minerFullNode, publishStorageDealKey.Address, types.FromFil(1)) + + err := miner.MarketRetryPublishDeal(ctx, propcid) + if err != nil { + panic(err) + } + }() + + dh.WaitDealSealed(ctx, deal, false, false, nil) +} diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 4e970343e..39baa97bf 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -557,6 +557,10 @@ func (sm *StorageMinerAPI) MarketPendingDeals(ctx context.Context) (api.PendingD return sm.DealPublisher.PendingDeals(), nil } +func (sm *StorageMinerAPI) MarketRetryPublishDeal(ctx context.Context, propcid cid.Cid) error { + return sm.StorageProvider.RetryDealPublishing(propcid) +} + func (sm *StorageMinerAPI) MarketPublishPendingDeals(ctx context.Context) error { sm.DealPublisher.ForcePublishPendingDeals() return nil From 1acb6b43280e5ecd2f933d6898752a61d9757101 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Fri, 8 Oct 2021 11:54:37 +0200 Subject: [PATCH 2/4] update CLI command to take arg; reduce time for itest --- cmd/lotus-miner/market.go | 18 ++++++++++-------- documentation/en/cli-lotus-miner.md | 5 ++--- itests/deals_retry_deal_no_funds_test.go | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/cmd/lotus-miner/market.go b/cmd/lotus-miner/market.go index 2e4db79ce..d3da6f9b3 100644 --- a/cmd/lotus-miner/market.go +++ b/cmd/lotus-miner/market.go @@ -912,14 +912,13 @@ var dealsPendingPublish = &cli.Command{ } var dealsRetryPublish = &cli.Command{ - Name: "retry-publish", - Usage: "retry publishing a deal", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "proposal-cid", - }, - }, + Name: "retry-publish", + Usage: "retry publishing a deal", + ArgsUsage: "", Action: func(cctx *cli.Context) error { + if !cctx.Args().Present() { + return cli.ShowCommandHelp(cctx, cctx.Command.Name) + } api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err @@ -927,7 +926,10 @@ var dealsRetryPublish = &cli.Command{ defer closer() ctx := lcli.ReqContext(cctx) - cid, err := cid.Decode(cctx.String("proposal-cid")) + propcid := cctx.Args().First() + fmt.Printf("retrying deal with proposal-cid: %s\n", propcid) + + cid, err := cid.Decode(propcid) if err != nil { return err } diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index 7823e886f..b77daf800 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -832,11 +832,10 @@ NAME: lotus-miner storage-deals retry-publish - retry publishing a deal USAGE: - lotus-miner storage-deals retry-publish [command options] [arguments...] + lotus-miner storage-deals retry-publish [command options] OPTIONS: - --proposal-cid value - --help, -h show help (default: false) + --help, -h show help (default: false) ``` diff --git a/itests/deals_retry_deal_no_funds_test.go b/itests/deals_retry_deal_no_funds_test.go index e851d3df7..839359c2f 100644 --- a/itests/deals_retry_deal_no_funds_test.go +++ b/itests/deals_retry_deal_no_funds_test.go @@ -22,7 +22,7 @@ var ( publishPeriod = 1 * time.Second maxDealsPerMsg = uint64(2) // Set max deals per publish deals message to 2 - blockTime = 10 * time.Millisecond + blockTime = 3 * time.Millisecond ) func TestDealsRetryLackOfFunds(t *testing.T) { @@ -93,7 +93,7 @@ func TestDealsRetryLackOfFunds(t *testing.T) { propcid := *deal go func() { - time.Sleep(20 * time.Second) + time.Sleep(3 * time.Second) kit.SendFunds(ctx, t, minerFullNode, publishStorageDealKey.Address, types.FromFil(1)) From 6a3bb184b7eedf8acee8c090c3bb50b7ac9cd229 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Fri, 8 Oct 2021 12:44:20 +0200 Subject: [PATCH 3/4] more tests for deals when provider has no funds in control addr --- itests/deals_retry_deal_no_funds_test.go | 151 ++++++++++++++++++++++- 1 file changed, 147 insertions(+), 4 deletions(-) diff --git a/itests/deals_retry_deal_no_funds_test.go b/itests/deals_retry_deal_no_funds_test.go index 839359c2f..3bb95d148 100644 --- a/itests/deals_retry_deal_no_funds_test.go +++ b/itests/deals_retry_deal_no_funds_test.go @@ -59,10 +59,8 @@ func TestDealsRetryLackOfFunds(t *testing.T) { })), ) - minerFullNode, clientFullNode, miner, ens := kit.EnsembleTwoOne(t, kit.Account(publishStorageDealKey, types.NewInt(1020000000000)), kit.ConstructorOpts(opts), kit.MockProofs(), eightMBSectorsOpt) - - //TODO: this fails slightly differently - handle this case as well - //minerFullNode, clientFullNode, miner, ens := kit.EnsembleTwoOne(t, kit.Account(publishStorageDealKey, types.NewInt(1)), kit.ConstructorOpts(opts), kit.MockProofs(), eightMBSectorsOpt) + publishStorageAccountFunds := types.NewInt(1020000000000) + minerFullNode, clientFullNode, miner, ens := kit.EnsembleTwoOne(t, kit.Account(publishStorageDealKey, publishStorageAccountFunds), kit.ConstructorOpts(opts), kit.MockProofs(), eightMBSectorsOpt) kit.QuietMiningLogs() @@ -105,3 +103,148 @@ func TestDealsRetryLackOfFunds(t *testing.T) { dh.WaitDealSealed(ctx, deal, false, false, nil) } + +func TestDealsRetryLackOfFunds_blockInPublishDeal(t *testing.T) { + ctx := context.Background() + oldDelay := policy.GetPreCommitChallengeDelay() + policy.SetPreCommitChallengeDelay(5) + + t.Cleanup(func() { + policy.SetPreCommitChallengeDelay(oldDelay) + }) + + policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg8MiBV1) + kit.QuietMiningLogs() + + // Allow 8MB sectors + eightMBSectorsOpt := kit.SectorSize(8 << 20) + + publishStorageDealKey, err := wallet.GenerateKey(types.KTSecp256k1) + require.NoError(t, err) + + opts := node.Options( + node.Override(new(*storageadapter.DealPublisher), + storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{ + Period: publishPeriod, + MaxDealsPerMsg: maxDealsPerMsg, + }), + ), + node.Override(new(*storage.AddressSelector), modules.AddressSelector(&config.MinerAddressConfig{ + DealPublishControl: []string{ + publishStorageDealKey.Address.String(), + }, + DisableOwnerFallback: true, + DisableWorkerFallback: true, + })), + ) + + publishStorageAccountFunds := types.NewInt(1020000000000) + minerFullNode, clientFullNode, miner, ens := kit.EnsembleTwoOne(t, kit.Account(publishStorageDealKey, publishStorageAccountFunds), kit.ConstructorOpts(opts), kit.MockProofs(), eightMBSectorsOpt) + + kit.QuietMiningLogs() + + ens. + Start(). + InterconnectAll(). + BeginMining(blockTime) + + _, err = minerFullNode.WalletImport(ctx, &publishStorageDealKey.KeyInfo) + require.NoError(t, err) + + miner.SetControlAddresses(publishStorageDealKey.Address) + + dh := kit.NewDealHarness(t, clientFullNode, miner, miner) + + res, _ := clientFullNode.CreateImportFile(ctx, 0, 4<<20) // 4MiB file. + list, err := clientFullNode.ClientListImports(ctx) + require.NoError(t, err) + require.Len(t, list, 1) + require.Equal(t, res.Root, *list[0].Root) + + dp := dh.DefaultStartDealParams() + dp.Data.Root = res.Root + dp.FastRetrieval = true + dp.EpochPrice = abi.NewTokenAmount(62500000) // minimum asking price. + deal := dh.StartDeal(ctx, dp) + + dealSealed := make(chan struct{}) + go func() { + dh.WaitDealSealed(ctx, deal, false, false, nil) + dealSealed <- struct{}{} + }() + + select { + case <-dealSealed: + t.Fatal("deal shouldn't have sealed") + case <-time.After(time.Second * 15): + } +} + +func TestDealsRetryLackOfFunds_belowLimit(t *testing.T) { + ctx := context.Background() + oldDelay := policy.GetPreCommitChallengeDelay() + policy.SetPreCommitChallengeDelay(5) + + t.Cleanup(func() { + policy.SetPreCommitChallengeDelay(oldDelay) + }) + + policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg8MiBV1) + kit.QuietMiningLogs() + + // Allow 8MB sectors + eightMBSectorsOpt := kit.SectorSize(8 << 20) + + publishStorageDealKey, err := wallet.GenerateKey(types.KTSecp256k1) + require.NoError(t, err) + + opts := node.Options( + node.Override(new(*storageadapter.DealPublisher), + storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{ + Period: publishPeriod, + MaxDealsPerMsg: maxDealsPerMsg, + }), + ), + node.Override(new(*storage.AddressSelector), modules.AddressSelector(&config.MinerAddressConfig{ + DealPublishControl: []string{ + publishStorageDealKey.Address.String(), + }, + DisableOwnerFallback: true, + DisableWorkerFallback: true, + })), + ) + + publishStorageAccountFunds := types.NewInt(1) + minerFullNode, clientFullNode, miner, ens := kit.EnsembleTwoOne(t, kit.Account(publishStorageDealKey, publishStorageAccountFunds), kit.ConstructorOpts(opts), kit.MockProofs(), eightMBSectorsOpt) + + kit.QuietMiningLogs() + + ens. + Start(). + InterconnectAll(). + BeginMining(blockTime) + + _, err = minerFullNode.WalletImport(ctx, &publishStorageDealKey.KeyInfo) + require.NoError(t, err) + + miner.SetControlAddresses(publishStorageDealKey.Address) + + dh := kit.NewDealHarness(t, clientFullNode, miner, miner) + + res, _ := clientFullNode.CreateImportFile(ctx, 0, 4<<20) // 4MiB file. + list, err := clientFullNode.ClientListImports(ctx) + require.NoError(t, err) + require.Len(t, list, 1) + require.Equal(t, res.Root, *list[0].Root) + + dp := dh.DefaultStartDealParams() + dp.Data.Root = res.Root + dp.FastRetrieval = true + dp.EpochPrice = abi.NewTokenAmount(62500000) // minimum asking price. + deal := dh.StartDeal(ctx, dp) + + err = dh.ExpectDealFailure(ctx, deal, "actor balance less than needed") + if err != nil { + t.Fatal(err) + } +} From a19dbb8c913ef99a90f7ff0a995fd049707ebe9d Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Fri, 8 Oct 2021 12:52:56 +0200 Subject: [PATCH 4/4] remove log --- itests/deals_retry_deal_no_funds_test.go | 2 +- itests/kit/deals.go | 35 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/itests/deals_retry_deal_no_funds_test.go b/itests/deals_retry_deal_no_funds_test.go index 3bb95d148..202d86b9f 100644 --- a/itests/deals_retry_deal_no_funds_test.go +++ b/itests/deals_retry_deal_no_funds_test.go @@ -169,7 +169,7 @@ func TestDealsRetryLackOfFunds_blockInPublishDeal(t *testing.T) { dealSealed := make(chan struct{}) go func() { - dh.WaitDealSealed(ctx, deal, false, false, nil) + dh.WaitDealSealedQuiet(ctx, deal, false, false, nil) dealSealed <- struct{}{} }() diff --git a/itests/kit/deals.go b/itests/kit/deals.go index 1b1daa5e4..4a9af69e6 100644 --- a/itests/kit/deals.go +++ b/itests/kit/deals.go @@ -177,6 +177,41 @@ loop: } } +// WaitDealSealedQuiet waits until the deal is sealed, without logging anything. +func (dh *DealHarness) WaitDealSealedQuiet(ctx context.Context, deal *cid.Cid, noseal, noSealStart bool, cb func()) { +loop: + for { + di, err := dh.client.ClientGetDealInfo(ctx, *deal) + require.NoError(dh.t, err) + + switch di.State { + case storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing: + if noseal { + return + } + if !noSealStart { + dh.StartSealingWaiting(ctx) + } + case storagemarket.StorageDealProposalRejected: + dh.t.Fatal("deal rejected") + case storagemarket.StorageDealFailing: + dh.t.Fatal("deal failed") + case storagemarket.StorageDealError: + dh.t.Fatal("deal errored", di.Message) + case storagemarket.StorageDealActive: + break loop + } + + _, err = dh.market.MarketListIncompleteDeals(ctx) + require.NoError(dh.t, err) + + time.Sleep(time.Second / 2) + if cb != nil { + cb() + } + } +} + func (dh *DealHarness) ExpectDealFailure(ctx context.Context, deal *cid.Cid, errs string) error { for { di, err := dh.client.ClientGetDealInfo(ctx, *deal)