From 19b6dc8d1e3536729a7e4550275b53b1b0d4c8a1 Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Wed, 26 May 2021 19:50:34 -0700 Subject: [PATCH 01/66] feat(cli): add a list retrievals command Currently, there is no way to inspect retrievals on a client. This adds said command, allow with corresponding APIs --- api/api_full.go | 4 + api/mocks/mock_full.go | 30 ++++ api/proxy_gen.go | 20 +++ api/types.go | 19 ++ build/openrpc/full.json.gz | Bin 23305 -> 23431 bytes build/openrpc/miner.json.gz | Bin 7846 -> 7844 bytes build/openrpc/worker.json.gz | Bin 2579 -> 2580 bytes cli/client.go | 187 ++++++++++++++++++++ documentation/en/api-v1-unstable-methods.md | 60 +++++++ documentation/en/cli-lotus.md | 22 +++ node/impl/client/client.go | 78 ++++++++ 11 files changed, 420 insertions(+) diff --git a/api/api_full.go b/api/api_full.go index e524906e3..3dc503f46 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -344,6 +344,10 @@ type FullNode interface { // ClientRetrieveWithEvents initiates the retrieval of a file, as specified in the order, and provides a channel // of status updates. ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error) //perm:admin + // ClientListRetrievals returns information about retrievals made by the local client + ClientListRetrievals(ctx context.Context) ([]RetrievalInfo, error) //perm:write + // ClientGetRetrievalUpdates returns status of updated retrieval deals + ClientGetRetrievalUpdates(ctx context.Context) (<-chan RetrievalInfo, error) //perm:write // ClientQueryAsk returns a signed StorageAsk from the specified miner. ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) //perm:read // ClientCalcCommP calculates the CommP and data size of the specified CID diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index efe5eb89d..71c621846 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -580,6 +580,21 @@ func (mr *MockFullNodeMockRecorder) ClientGetDealUpdates(arg0 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealUpdates), arg0) } +// ClientGetRetrievalUpdates mocks base method +func (m *MockFullNode) ClientGetRetrievalUpdates(arg0 context.Context) (<-chan api.RetrievalInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGetRetrievalUpdates", arg0) + ret0, _ := ret[0].(<-chan api.RetrievalInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientGetRetrievalUpdates indicates an expected call of ClientGetRetrievalUpdates +func (mr *MockFullNodeMockRecorder) ClientGetRetrievalUpdates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetRetrievalUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetRetrievalUpdates), arg0) +} + // ClientHasLocal mocks base method func (m *MockFullNode) ClientHasLocal(arg0 context.Context, arg1 cid.Cid) (bool, error) { m.ctrl.T.Helper() @@ -655,6 +670,21 @@ func (mr *MockFullNodeMockRecorder) ClientListImports(arg0 interface{}) *gomock. return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListImports", reflect.TypeOf((*MockFullNode)(nil).ClientListImports), arg0) } +// ClientListRetrievals mocks base method +func (m *MockFullNode) ClientListRetrievals(arg0 context.Context) ([]api.RetrievalInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientListRetrievals", arg0) + ret0, _ := ret[0].([]api.RetrievalInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientListRetrievals indicates an expected call of ClientListRetrievals +func (mr *MockFullNodeMockRecorder) ClientListRetrievals(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListRetrievals", reflect.TypeOf((*MockFullNode)(nil).ClientListRetrievals), arg0) +} + // ClientMinerQueryOffer mocks base method func (m *MockFullNode) ClientMinerQueryOffer(arg0 context.Context, arg1 address.Address, arg2 cid.Cid, arg3 *cid.Cid) (api.QueryOffer, error) { m.ctrl.T.Helper() diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 8880fb24c..6b4dfa4a1 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -179,6 +179,8 @@ type FullNodeStruct struct { ClientGetDealUpdates func(p0 context.Context) (<-chan DealInfo, error) `perm:"write"` + ClientGetRetrievalUpdates func(p0 context.Context) (<-chan RetrievalInfo, error) `perm:"write"` + ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"` ClientImport func(p0 context.Context, p1 FileRef) (*ImportRes, error) `perm:"admin"` @@ -189,6 +191,8 @@ type FullNodeStruct struct { ClientListImports func(p0 context.Context) ([]Import, error) `perm:"write"` + ClientListRetrievals func(p0 context.Context) ([]RetrievalInfo, error) `perm:"write"` + ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) `perm:"read"` ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"` @@ -1293,6 +1297,14 @@ func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan DealInfo return nil, xerrors.New("method not supported") } +func (s *FullNodeStruct) ClientGetRetrievalUpdates(p0 context.Context) (<-chan RetrievalInfo, error) { + return s.Internal.ClientGetRetrievalUpdates(p0) +} + +func (s *FullNodeStub) ClientGetRetrievalUpdates(p0 context.Context) (<-chan RetrievalInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { return s.Internal.ClientHasLocal(p0, p1) } @@ -1333,6 +1345,14 @@ func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]Import, error) { return *new([]Import), xerrors.New("method not supported") } +func (s *FullNodeStruct) ClientListRetrievals(p0 context.Context) ([]RetrievalInfo, error) { + return s.Internal.ClientListRetrievals(p0) +} + +func (s *FullNodeStub) ClientListRetrievals(p0 context.Context) ([]RetrievalInfo, error) { + return *new([]RetrievalInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) { return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) } diff --git a/api/types.go b/api/types.go index 83de131a2..9d887b0a1 100644 --- a/api/types.go +++ b/api/types.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/lotus/chain/types" datatransfer "github.com/filecoin-project/go-data-transfer" @@ -176,3 +177,21 @@ type MessagePrototype struct { Message types.Message ValidNonce bool } + +type RetrievalInfo struct { + PayloadCID cid.Cid + ID retrievalmarket.DealID + PieceCID *cid.Cid + PricePerByte abi.TokenAmount + UnsealPrice abi.TokenAmount + + Status retrievalmarket.DealStatus + Message string // more information about deal state, particularly errors + Provider peer.ID + BytesReceived uint64 + BytesPaidFor uint64 + TotalPaid abi.TokenAmount + + TransferChannelID *datatransfer.ChannelID + DataTransfer *DataTransferChannel +} diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 394f1998be7c464c835d2474d93a843971cb659d..3a8c7cf9beeb001e4fb8901bc67d32b7ed6cb759 100644 GIT binary patch delta 22762 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 V?h^_Y0>aaiPDr);S{5?Ge*yn0-$noc diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index db17586d0786d2a8dd5de9d00d4de98fc2ce0e10..ed3c7a2a177f95e35e20e9da1ba6d33a9b1602d9 100644 GIT binary patch delta 6052 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 delta 6055 zcmV;Y7g*?|J*GXdf!0(lHf~gW<_egb=<}_|6*C){$?5L?JrU12bM6 zS?3Zj!{TCQ2m_ZEA`H)PylTk)yy{8}zaN;T^-Y>(%6;@Q$~2`tOAas#Dl@o#1IuYx z3pIan+^QuljuS=SJTh6?K^7LBnPLLH$G60!7U!>#F@-)l9>mr#|WsfSbpc15>SpHoynp1~&`zg~-S<2qx4AYyp|5B0hiTk;8|`CDB_Fg2^0w#caXfe<4@D-+Y|> z_2%sS*N@}B-keR|{xv?k`57Q`k3C8pj&k?V!`!k5K4O4T;8OBbJrEPy_ zfTDO9^GG5_d&1_82HDVq{_s|wEONnYe+3XlKx5@LY zAuZZl2~`K4#`kbP_LZ-Cig;w!Bn6C8FIUBh*2`0ClpBuP5l1Pabjc|qTLG#Js&(;H zHtB|`cEePCMSLJ*j%r4!6wO*0s=+j<@4`+4g^QDzp^xMqdBWPRm!-1l*2Gpy;tgx< zhP7Vn80vp)g|V`z*2Go{(hXDXhN+IT>ji=V0m+kY2Q7aGCNaZJQJ)E7TUtiTqpb3{ zWbSCbkEKC>>j~Q5FNg1kGw4q@1(?#jP)~?yGu`?*c#V3)zX!v=!_KByR-6-RT_VgO zTqg%-lW$n~fLM4_OeMt%^&_y(nq)QhZSePCnYX*iZ;UZQ-OHc3q-$hiWdjW(9}Xk; zG~Ky+7h4T;2-nEO3i1sL9}WxmlPCxve+LRTRW28vLt-NP0y22xLE_IcxJE}ZRm4<+ zX+Z{AP^KLgzPu1g87@LzTm0SE(KZ{J&fj9Lstio=i1RP+DhT@;?TG<%e2>WL`Q?RR zWXcxE6C;JQp6&ph`vYc%)hIEO_D(N zlHX6k(F%?z*`DAziLBK#|1NJKaIJx@EdS+nG4)~c%j@j)=OsnD2R3;pI>u^|KK|?j zCb9H}Zl~XC86V(7`k6c)B0SKhe`VZY2l)&-E-%sTbX&&T2N&~B1wSX~zrRsqH0V9G z3_b=ZzuY%Np8e2k86sV9Wc-`hoj)gU7AE;+f&TYj|1zEm9)J}LwLp!qt2$`_$*-YR zBk@f&Yn00u5ffQBMMTbwPRC-itW$iA!-{n*Ge;!OI0YtHvR0|x)h(m&3gILhQ$C(E zupcXv&k11zAi}JZGz!gsL)96IF{~}U^u0!-`mV1u!DjDQv-c~bX0!LJ+51&J5O`Qn zf2um7afPav#H1XyScQBiB{dcNCl^lytzx<$-OiS@f}*GDwZ}OqIq|*$-1C@P~yy+*Tw z+#lvZZk>0o;a8DoS)c}`ta!IV=R1O8g+rZK+%9$~dr@02X1nTfEh-vm2!ei>`B0s8 zU>}xnh2LN4|PX+h33$F9D9^elPWCLO{V4; zKH3zPyQ$+lWGz%P<1T|6Xp8td0(?p?Ar$dAt`M0sO4^vAxvBt>gbUNK5 z@y|`CGZO!Q{AsL}HAcss=zj&1?kYk1GmW4%0iY%Tv=0FwElVRQ=vp5?14q6YGwL~z z$(>{9h+zk9Fi#F6E%j7&S4W^W!tYd%Zc9_kRB;-asM(~pqSk)2{K8Y!O&jvdUn8H( zOHCVJGpOxs=WBM`x?5i}Y6Hj^a$M#EMu8{aH~V0Jn|-j&KG>b$mg-6uDX){N`(P)k zeXs(Z_;>W%Z}9w*Fab$x5BlON;qwK=L>Nyk;11;N!qBpi6&a5$;J(g!u7zk(7vmtt zTjEr=x_h)^; z1e5t2KKrF$A*!y}H7`w$8|+RH%MI1XiEU?(e7rkpC|G-|g8}E*ilXx(DJlB(Gs5!) zGe-I0_Jazjscu^mR)qf^vGdD|%;gasc3UTZlC!^?GoUM~FzTUpP$`cMGaA{t7Hal* zf5$!EnMjf5n>1czmeE2DxxiA#po4`Mfjw8$6nWnP1{E|V%CGvYH(qY3uwYJS`IV|` zWb0>!6xb7bAPBCyRw=^8RgO?443EeZL-DAZHjc*|YLNU#MshXhs!D13fiWbi2hwAI zNgumR)@btZ4tJqjb@i7-$t&!$b8K;@FSo*-CR6c}yi9`41$hT@!1lgMiRx;x6*tPi zD$0obt2POV$TjlO$j27tqu)_oT{gCnHAhl+my?Ycfo!>eQ``=XgIv)_Qp*;L8|1hE zx|s6?V8~~f%nK!*WC=^Wmzis7v6ni3wq>w`x!dV&%ktprx2QNkZlBa_0ljpo!Y&(6)ojF0l-|@_5}o_$gWLtrUcfi)*R& z^OL+*jeMfs9r7fJ+H$hi$Eqm}lW4DsLN4TnFr#xK|9_P6ukimyK_QYZMC4X~X{>PP zOPd29E+xV4am#QpiTzr4WF}?y>1s~=XoDO)AM`nn7fJ2bv-x4h`eZ0Y!_=mlH;BA9h@58iYU#8^4&g{0xluM>wXymem7}3@R9E`1gLGO-%BY-PDU~z!D4o@% zZF-HiX|&BgY8%1jjiPCP6wP5Onv;#ox)X5*5vs?%SrIC!Zcv?0PNFxB=4mv~9%>%c zxH^pnI&=**+_=J>fak>Zfsh8uhc6>Sx96np_esLe_S?%cNF% z1sQMEc(Gk+@z1c6gH#$l+vr&xJ-acHAUJQfVlG*X%5D+}k_|Qw$peiJ-3uMsz-|M( z0qmZW{t+a90w=m1#fonrlM{1+tP2e1Rj?u=qQVP#C)x|l0fEcqx2L=lq%tV0VPm~8 zu$GSN0~`$NJV2Cn8vVmguS!)bCs2vu6$rqK)^i?vmp%$1U=8IbbQScV< zE{T)cAn-+1z^D+c%15>(2AjS!YwhiJZa|9N&RqI7r#)qK)wSUf1Bi)7Hhiqc-4U5O zSvpQMhmWJ8E9MnE%NCIFSw~;($0O52e0~BJ{zAS&%*4Tzz@Z)j7J{}9rf9~0UV0(Q9<<5@qp}F8OrF(QlX6CKU8GFXTX&V#ySX*K zJ8dqQtH9c-JCWtoT_cCyS7B*MpjK9nNNzIQR|UoQyGIhY0|R5`Q72j?1(yt16#3+T z7+}bAFo8^9G$lvo0%Fnv@&sWMk}qV6fJF&^lD8epc5cE-Z6KQD4gn+6WhayFP zsvAWE&f_c+#6_z}QH)Hj=HVLQTtSKz=N2BAB49$>Mivk%M_Ox`fVYmz9s%{hCy1H2 zj7i3N{V#-3z&t#kBQFXFBk0+WjScsM3C_kaLF6V>keY}_ts)brnkO$&*_E%9aIHe8 z3B2HL4ViPT!YF_%PlysQh0I)l8TNdC_OiumlP?4=8Fe7TT=*U%rwy}&v(`w|k0nv6 z8!Oj%@twW&%bi%BMM!bswdUnb3W{1XB?<%VILN|~A)A|a#PVa(gMcHmUSt3w)K5a7 zkQH2b6A4=T3z1o8KH$s%@N88bihzfY2&)`@{z-L>)K5S7oteS*mQWxI-FUeJuOg|F z9~D>uRg-uXI)8q$YEN}vV2m#=$wWBFRarKqqw;w^-$t%HLsgkM)|lEA5{w;-4Y<%_ z*j(Dsi(&#b`6-F9mE2OhZhe&G#6}YLR1!Bv9sFxFt0aNEezwwZp!-=e)h%aJXd~+y z%`{~#AiI@&ZL>R;`UuKmIw{?!!%n9YOYXkB5Lw-;D}T|uox$++$#JI@U0o-BKMDSG zA>*H8oUoeOKN%&jci+}E>?LljQ(oA9V7H3)RClNa{LKM-SxN9D1>HbjbjJBh@FJLE zaj&SBFh)&n-jDVkF&XL;#kt=D!5rVCFiy_h>dT8CC`Pvjr*dcE-)jC-ol3mY-@3x# z;Npq1h#MX9$94Ea9z!)U{!Q%8pOZHWll-zk|NF0h87)Js zo`mIYuz4r3>kqMAEO`9ZrRIX8X1CK7s3rF&Zz>a=Q1HQ@$GenxaE+KJP;=0088gAO<&V8D}QL_kVI-Q+A|fynS%7mwd!W{0ZUtf*B*D zW3-GvkcVd&S*aJ71Tze6dCzt5?00g59kikkJ^L{ncCpPs@!smde=xm8ca#T=P^MZi zSw*YHzhjQ-OzEkB9qZmCwZ0K5m^Piy9_JvP@@q^}^aDg(pV~+nFn&3!S&5ZSJ4tLQ%AEmRd^1E~pZ_t%1bUBeiAhD2bYx7S zkB$eiZmw!akfmqdMd-8zYcN3J0!$EKv<~$E+qWx+S&R{=wM=ddmD7O@Ii~rdVTXpt zQ?`04hAM|vb7+Q5bV!$>ZU8`EEN@ zEgDIV1gz{5c9X(#)$gh9!wV$m%(AYi3De(1OVW}w)Q4*DNz0R{6s;Ycrs2sbf`0}t zCj9Y+A*(Q?YP}#}0LGwMGMOq)VbcjO$PZhSK}xp=X8w|4yZuhYA~jhxY-cn0hYbdi zFAF`?7NJa!MbmT;q(a2`kkYJb%KtjePkY;!sFh_Y%qnd;m~LqAFr>X zU|DF34|*-*1AGWCFc!bhp*W{AWPeEhlXp-4E_w)4NGr=ZSW(V;8~BnbpFh@H9nVOP zI_4OqD6YHnD?epxrraj&nqXkvqqCq3P0SueaP{mSVjE6*&re&%yGio*HS&>n&--#J zKBoBZM_)WB8U$Ps)`|f}ozy9v=(pA>UVJP%1y^4{i+_B*lFbo76;z4po`11G(%> zo!K@ut7wymNdA#w65@F;ZXR7E)XK_apWuIxI0boCehk^-Mx=4R_uZ_Op?Zp9@@PS4gl-yif}pPuxG{o`Q`!$==mn`S9Zqc+$^Ri{0h#mN~-IVDY( zDp{dFo>6gNnMSHRzJfWpK!2tUJro@HR{`=9gmV0d;5^=B5_kgTQ(9pVnu1U(qnJ`z)L5N0t;c4v9!HEM`wq^}2il+*IV+19Fiu0mk) zs9OWlMpSBsSxt0}H@{Qcxq;ONR(A@k4W?c7d#an00yubwiB%obR)19T*B)c{B`J)> zemaB@+K;iIL9nt`G<1;Y>P}6|23mA(6?z`fvJoMlWrSs)3{SO?Z-}a76n$>7m9d9q zf3xZ|fs|@`aPtyuCUX_gfV_ULJ^vECC>`<+8raEo8~b9ZXJLazq_tThKA33kb4DEH zr9Se5mp@rxRe#ea(SJaUZzBzPflONyY&IS-P|Hry%-$)si>k`%h_se8D@|>&yL8PK z9rd=dpL9pp?;Q9R(Z2GAoPe>b=KZOX{!(Hm5m8s(0;)R@xF`W|lcW{M64Vtj7 z$|4C9*T|(F`x!x-Rmy;l)6rX43x3Hevbr9!tu?i?3x)T^Ezbp+wXdps>;Z#Jdb#yv z=(dcEV+9I=yK0Me*w-cnxMB)$b1!Hu7`r*R8KlRT##UZmC%Bo&$Jcay0@^=(TyuRd zL$lN2kYMgWTz^;P&1F)SZ@kB<-fKW&+YaoDDW$r>&{dZjU$*gO8((&%vw{qP?~yjJ zuL!BSQ|=S>?vQs*3E=`z1|Sm@Ds4Mor=+&M5+wmcwk>V8sk6#}Ry2I0>;cNzvPG@M=nGHL~2%#vEAv{Mirq@%8n?YiL zadO-lcBim&bljaihvE(N@3`YV&(w2Ysr&w|gspguFU zvh2EQBqPcrKVt!EvO>KFi#hP&QWESQw+si9*st|ui`D$>jnS75@Wj@lBW}AaDI_J%P&_o3Qh#;xp~S`sgRF|W5%qQS%{nNHihBAc zY-0xsC$pD13P)9^K85qm5IJ@UG?kDo;wp6MnSn4OXS{gyu?cNs)H@jrPfkud$ESlq zi@%zDg|0E`_J+g3X{S3J4m;xUDl*gS4o(Kc{_$YgGS0^zePeVyXc_OtU!M*5e*6)1 z`+xlt diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index d0a18b43acd268400f6888f7f34900d5f665319e..943246923ca199ecdf1a6682f8a0c342242bf704 100644 GIT binary patch literal 2580 zcmV+v3hVVBiwFP!00000|Li?&bJ{xAe?_C`OLNBo0)(b~>qGW-Gt(C~x!rzfG8%wWJDWZnNJ)C41z2A6D;I+P~JD)C9ZR#$Ps#@ zKhiO=p)nw?dvR_d5Q2*%^mNUxl>ik8hGgS{DG-dfjTot#G);&eP@_J&X7g)ydwYv5 zECbIYVut&8HGrA39!6d>Y+;`W;+Z7~gkHwc?AYg$hD#QGomgi7B(<)ol}U`PKiE_7 zh~8&-B%ber!FX}5n?6wn0{2f^t(Jv92i{13dN;T5P;fr}Yvu#)pUrP9OdKa9i?~C< zeGrOjJY(WYu&^I%T3{{#5D~FrL}m!FunGxSe4ejJ+}wA*Y~iCHU@M%QR0#y%7Z`5l z78dY#Km|CsuS5WPGkgIyQMx6Z+}v92Ry(y@IUHMP&sgBPHx{M}BBn^qAUT#<(Kv5H9ZH zsZze|H=C2NOT*?~a~zrZV_$GhSJTxlLv!TvQPU$*foKw+HhsY#XaAW1YfSk6ee85k z+j>rEXW<`=j9hR^`U(+LhO2Od-i$bRH(Br%f^36b!ZK$`t0o~erKoYURO-ErX)_H6 zguQSE=(VyL;7?HYwB+`OFy;Kjm3lPodVK8$gpT6s%OO$IsJR6y~w#?mVU~xJzlTFD*!gxDHDoE@cxOBT6a}wrt0TONntYx;%alm5Hj| zxY~_7G&inymSe>!BQE_3(O#4^=Lz7l`JYAmC1I0F)_HyOg_*9+^InM1KA7h;mXcj>^F?g!eZUgZFVOJ1& zT!!}+r*U&D{8E#Y{jCw)lwbFe+r$lN&-(To(8;t=;J?Lieow{Ww3TyYI27ClDX&0E z!(650A_1H&AVEN##@DZ#{izhPZ1FIFT1gAS9PS~F8}TuE2uVZIz*}en420f>sG~bW z4^v=KziZ~3@sLzRsB#5lS#r0WXKD@O-xN3}DP;I|Qn<9)lpTmH>G|A#8~g`&$pumy7V*YQHvm=XET# zpRv?)hv6yd*kK`Lx79h@O)cchDe0_Z!#XxRu-NeQBzA_1o2p8^(;L;>AB* z8)85mS;2oyPGvncq{pfK$h|OF``|~W+4lhN+~x}6i=Jyb8MUTTb{-UjBMqW6y=YNF zjmZ?caDXW~rg2VQ9qIiKLWJ1Loo-NCTJaXtTFVqe{|Ps>!X)Ead-RjoKspc7nf7KK z(&?#DN8W+w|KN{*`@xKR{*RG2hS|8&9n(%Q>jeRH+xK1LVs8^)NmaQTyxe}qm!S;g zHoc%a-mBxim+aJbb58bG{#@F87j~JwHMO050>iSvm|xqptkX~ zjekWp{xqj@CSeh)#G5PNY9Z&!99NGz6ExI;=UxfYKA7`NUVC{Ky|zoWT{<+o)XOP) zsdlevI~STZ-DLVm?_li;m4!xuLdz>oEUKxA-CNQe>rffKxLMy>dOdfR-sYCBsA|u? zt^o5Kt`X<%hN`Xvl4mNrmfes?#GOQH3JZQF5`p=yx!~&t`pgwlQ=OPr-?A*9gw78%1Z9&=oS(v#&;DBr7Q$pku}47TF9dD#(aqP#iaA;Bzlgj$HwvpH z8^$1WSrCY;wU`WtF%Q%{%Z^E$yJy7|eZ}9VZQi$8^iHteP9mxA0!#`wa*ClUxT@ zppY)mkJQ`doyn{sNa7k$2MImA1g7*a(`TfkZ9Bq297lkZ;2^rh)<73ZFTj`! z4;(a_A%gyGeh|_^1P!g_B0U@SbL`9)@Xb*Yk056|Z}^Zy0_0RR7??FeR1dH?_z=I3+( literal 2579 zcmV+u3hebCiwFP!00000|Li?&bJ{xAe?_C`OLNEJJv8N8AF{WbnZB^e?e;^H*$Ddp zDz@Y+$w_F2|Gp#J7#rKccA-m%r!#F4I!8y+dDoG6!rTQWToVs)yU}U%v4JU@a6EXz ziYgoM0Dt7lljv$RMDItJ*ueK7B<0M9Xtx`!Qw#3#(!dU=8Mh=Je1F1>I2!a%YJ9_IpzpV2OdDUBODqcl1lRN@7|89Syl;9Dt_z~b33{VH z(g`u4F(kHqd0`+Bf{PRMbi;0x0ObjWWaE-45RBN37^#{xO^6;)qdvJ|%NurgcZUru zJ;xzpfd_a!Krm-LjJ#pkz%CKQ36{VUdKt%yQ7;i z-AQ`3(zrv~HdRz6r5hcJ=zu_HJgWz^Fyq$S;LmBsU#ma3l9mXW`Kb`=Zq*JBdAtk| zw)+NlD2sgxI|n?zG-7ipST4T+{G2S z#eBuuDSU-aVIF(#&tuwwyOj3&(t=co>#zi3Q#QphqNEaj%WizQlo%JI%i;G>nW);0 ztKGO`bK`pFIaZu9V$+`x?nOy+o&YYJ|5>$P5jL%4oi|5cnd#a*AA|@Uf_dKHvTC`S z5=;AKGLfK)t*xI}skkr|Ge5Out1a8HS+=u&wq?6y6JFAuX^`yH#O67G?zzoAh1m9z zr^uq`8Np3-Dk8l9>25n6b+lYAhAY8 zhDa=1L4aV%bQ%sTE?7yGdPD@O6_k)Q;{!S=2*tbYD&$s`f!^ zAN1Ia&fAA2Fxg&c5Y2*Ygr-1u-DWvf==S1er~=h_4@yXf=gz>qkn*&Sp-%gY>5;5TMyBrMfh#CUt7KNI+i-j zSn9dM@RW4yu@JJ?>YneX7V_nkbk?z99UC57Z1^tceBughAQHYZ38Z`>>+m?s?yx^ynMtU%lUf&Qxf~i&rLFrGP-8#%M39Uy@ynfUU*5@j~RoC7x!#q zh#|FP1^+QQmCe+U9;fyr55iy_f*+Y?-y^(pn=6PfdamhY)P_pgdr;tyGz`!5!bR~l zCR6Cr0;cGM#yNR?r1w7v5n?NMwnb@a#amEoMJa~C6K-mSNhXWV_$M)ebRVQO>o2;b z+gIbRoP*>3;E#X1-hw;skFhg>#iZMt(5|=Wdmi*U_r1Wy-X*@0s&YMex&4eULm9|j zdO>x(SI2uV*{SX1ob0dtxwQE%>eP11S6AxR(2e}!sbBI#J9Q58(1hm@e9ttOy*z)c zHbk`{Iyys?Q&yuD`ba?a1j`zDCpnglaHpb)N)Q##meiK&Af)RMEY;CxN$Si&ZR2Yj z|B7sUH>YwYVG*mun`_`|A?Mm0SC2XqG}M9TK?%|!nDb0tdwCYUwoA2LIySr1%PD%P zcCTqS7n-)+Wco8VJtC#ON5v5vOQ5C^d=0aAj6XoRhSE|p$@2^S7n zXuLoK{X6(UNCOcxTge7V$Q*eMp3@=O_+rU`lNf! zh@3T&jI*1|0QHY{)CW!VL6h$b_FFlb$xxO{`hg)-c3cywhv)sUHIBW!Cz&^~b^D%d zUbo%toL9Dbhsr)V*~D*zs(*PDR7nPk;4)e0+00BFG@Emx9%yWHb1sp`6t$6>fdE7V pAQqgpNF+SQ{1cjAWVY9qD(ScTc)7e?{x<*s|Np=VL?Tam006&?0`~v_ diff --git a/cli/client.go b/cli/client.go index 84e077943..a0a36cf40 100644 --- a/cli/client.go +++ b/cli/client.go @@ -92,6 +92,7 @@ var clientCmd = &cli.Command{ WithCategory("retrieval", clientFindCmd), WithCategory("retrieval", clientRetrieveCmd), WithCategory("retrieval", clientCancelRetrievalDealCmd), + WithCategory("retrieval", clientListRetrievalsCmd), WithCategory("util", clientCommPCmd), WithCategory("util", clientCarGenCmd), WithCategory("util", clientBalancesCmd), @@ -1209,6 +1210,192 @@ var clientRetrieveCmd = &cli.Command{ }, } +var clientListRetrievalsCmd = &cli.Command{ + Name: "list-retrievals", + Usage: "List retrieval market deals", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "verbose", + Aliases: []string{"v"}, + Usage: "print verbose deal details", + }, + &cli.BoolFlag{ + Name: "color", + Usage: "use color in display output", + Value: true, + }, + &cli.BoolFlag{ + Name: "show-failed", + Usage: "show failed/failing deals", + }, + &cli.BoolFlag{ + Name: "completed", + Usage: "show completed retrievals", + }, + &cli.BoolFlag{ + Name: "watch", + Usage: "watch deal updates in real-time, rather than a one time list", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPIV1(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + verbose := cctx.Bool("verbose") + color := cctx.Bool("color") + watch := cctx.Bool("watch") + showFailed := cctx.Bool("show-failed") + completed := cctx.Bool("completed") + + localDeals, err := api.ClientListRetrievals(ctx) + if err != nil { + return err + } + + if watch { + updates, err := api.ClientGetRetrievalUpdates(ctx) + if err != nil { + return err + } + + for { + tm.Clear() + tm.MoveCursor(1, 1) + + err = outputRetrievalDeals(ctx, tm.Screen, localDeals, verbose, color, showFailed, completed) + if err != nil { + return err + } + + tm.Flush() + + select { + case <-ctx.Done(): + return nil + case updated := <-updates: + var found bool + for i, existing := range localDeals { + if existing.ID == updated.ID { + localDeals[i] = updated + found = true + break + } + } + if !found { + localDeals = append(localDeals, updated) + } + } + } + } + + return outputRetrievalDeals(ctx, cctx.App.Writer, localDeals, verbose, color, showFailed, completed) + }, +} + +func outputRetrievalDeals(ctx context.Context, out io.Writer, localDeals []lapi.RetrievalInfo, verbose bool, color bool, showFailed bool, completed bool) error { + var deals []api.RetrievalInfo + for _, deal := range localDeals { + if !showFailed && retrievalmarket.IsTerminalError(deal.Status) { + continue + } + if !completed && retrievalmarket.IsTerminalSuccess(deal.Status) { + continue + } + deals = append(deals, deal) + } + + tableColumns := []tablewriter.Column{ + tablewriter.Col("PayloadCID"), + tablewriter.Col("DealId"), + tablewriter.Col("Provider"), + tablewriter.Col("Status"), + tablewriter.Col("PricePerByte"), + tablewriter.Col("Received"), + tablewriter.Col("TotalPaid"), + } + + if verbose { + tableColumns = append(tableColumns, + tablewriter.Col("PieceCID"), + tablewriter.Col("UnsealPrice"), + tablewriter.Col("BytesPaidFor"), + tablewriter.Col("TransferChannelID"), + tablewriter.Col("TransferStatus"), + ) + } + tableColumns = append(tableColumns, tablewriter.NewLineCol("Message")) + + w := tablewriter.New(tableColumns...) + + for _, d := range deals { + w.Write(toRetrievalOutput(d, color, verbose)) + } + + return w.Flush(out) +} + +func toRetrievalOutput(d api.RetrievalInfo, color bool, verbose bool) map[string]interface{} { + + payloadCID := d.PayloadCID.String() + provider := d.Provider.String() + if !verbose { + payloadCID = ellipsis(payloadCID, 8) + provider = ellipsis(provider, 8) + } + + retrievalOutput := map[string]interface{}{ + "PayloadCID": payloadCID, + "DealId": d.ID, + "Provider": provider, + "Status": retrievalStatusString(color, d.Status), + "PricePerByte": types.FIL(d.PricePerByte), + "Received": units.BytesSize(float64(d.BytesReceived)), + "TotalPaid": types.FIL(d.TotalPaid), + "Message": d.Message, + } + + if verbose { + transferChannelID := "" + if d.TransferChannelID != nil { + transferChannelID = d.TransferChannelID.String() + } + transferStatus := "" + if d.DataTransfer != nil { + transferStatus = datatransfer.Statuses[d.DataTransfer.Status] + } + pieceCID := "" + if d.PieceCID != nil { + pieceCID = d.PieceCID.String() + } + + retrievalOutput["PieceCID"] = pieceCID + retrievalOutput["UnsealPrice"] = types.FIL(d.UnsealPrice) + retrievalOutput["BytesPaidFor"] = units.BytesSize(float64(d.BytesPaidFor)) + retrievalOutput["TransferChannelID"] = transferChannelID + retrievalOutput["TransferStatus"] = transferStatus + } + return retrievalOutput +} + +func retrievalStatusString(c bool, status retrievalmarket.DealStatus) string { + s := retrievalmarket.DealStatuses[status] + if !c { + return s + } + + if retrievalmarket.IsTerminalError(status) { + return color.RedString(s) + } + if retrievalmarket.IsTerminalSuccess(status) { + return color.GreenString(s) + } + return s +} + var clientInspectDealCmd = &cli.Command{ Name: "inspect-deal", Usage: "Inspect detailed information about deal's lifecycle and the various stages it goes through", diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index be326b3e8..b62323e4c 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -44,11 +44,13 @@ * [ClientGetDealInfo](#ClientGetDealInfo) * [ClientGetDealStatus](#ClientGetDealStatus) * [ClientGetDealUpdates](#ClientGetDealUpdates) + * [ClientGetRetrievalUpdates](#ClientGetRetrievalUpdates) * [ClientHasLocal](#ClientHasLocal) * [ClientImport](#ClientImport) * [ClientListDataTransfers](#ClientListDataTransfers) * [ClientListDeals](#ClientListDeals) * [ClientListImports](#ClientListImports) + * [ClientListRetrievals](#ClientListRetrievals) * [ClientMinerQueryOffer](#ClientMinerQueryOffer) * [ClientQueryAsk](#ClientQueryAsk) * [ClientRemoveImport](#ClientRemoveImport) @@ -1199,6 +1201,54 @@ Response: } ``` +### ClientGetRetrievalUpdates +ClientGetRetrievalUpdates returns status of updated retrieval deals + + +Perms: write + +Inputs: `null` + +Response: +```json +{ + "PayloadCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ID": 5, + "PieceCID": null, + "PricePerByte": "0", + "UnsealPrice": "0", + "Status": 0, + "Message": "string value", + "Provider": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "BytesReceived": 42, + "BytesPaidFor": 42, + "TotalPaid": "0", + "TransferChannelID": { + "Initiator": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Responder": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "ID": 3 + }, + "DataTransfer": { + "TransferID": 3, + "Status": 1, + "BaseCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "IsInitiator": true, + "IsSender": true, + "Voucher": "string value", + "Message": "string value", + "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Transferred": 42, + "Stages": { + "Stages": null + } + } +} +``` + ### ClientHasLocal ClientHasLocal indicates whether a certain CID is locally stored. @@ -1266,6 +1316,16 @@ Response: `null` ClientListImports lists imported files and their root CIDs +Perms: write + +Inputs: `null` + +Response: `null` + +### ClientListRetrievals +ClientListRetrievals returns information about retrievals made by the local client + + Perms: write Inputs: `null` diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index f9eb3aac1..1e1d949a1 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -377,6 +377,7 @@ COMMANDS: find Find data in the network retrieve Retrieve data from network cancel-retrieval Cancel a retrieval deal by deal ID; this also cancels the associated transfer + list-retrievals List retrieval market deals STORAGE: deal Initialize storage deal with a miner query-ask Find a miners ask @@ -521,6 +522,27 @@ OPTIONS: ``` +### lotus client list-retrievals +``` +NAME: + lotus client list-retrievals - List retrieval market deals + +USAGE: + lotus client list-retrievals [command options] [arguments...] + +CATEGORY: + RETRIEVAL + +OPTIONS: + --verbose, -v print verbose deal details (default: false) + --color use color in display output (default: true) + --show-failed show failed/failing deals (default: false) + --completed show completed retrievals (default: false) + --watch watch deal updates in real-time, rather than a one time list (default: false) + --help, -h show help (default: false) + +``` + ### lotus client deal ``` NAME: diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 370cde5da..c5d5ebc89 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + "sort" "time" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -835,6 +836,83 @@ func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref return } +func (a *API) ClientListRetrievals(ctx context.Context) ([]api.RetrievalInfo, error) { + deals, err := a.Retrieval.ListDeals() + if err != nil { + return nil, err + } + dataTransfersByID, err := a.transfersByID(ctx) + if err != nil { + return nil, err + } + out := make([]api.RetrievalInfo, 0, len(deals)) + for _, v := range deals { + // Find the data transfer associated with this deal + var transferCh *api.DataTransferChannel + if v.ChannelID != nil { + if ch, ok := dataTransfersByID[*v.ChannelID]; ok { + transferCh = &ch + } + } + out = append(out, a.newRetrievalInfoWithTransfer(transferCh, v)) + } + sort.Slice(out, func(a, b int) bool { + return out[a].ID < out[b].ID + }) + return out, nil +} + +func (a *API) ClientGetRetrievalUpdates(ctx context.Context) (<-chan api.RetrievalInfo, error) { + updates := make(chan api.RetrievalInfo) + + unsub := a.Retrieval.SubscribeToEvents(func(_ rm.ClientEvent, deal rm.ClientDealState) { + updates <- a.newRetrievalInfo(ctx, deal) + }) + + go func() { + defer unsub() + <-ctx.Done() + }() + + return updates, nil +} + +func (a *API) newRetrievalInfoWithTransfer(ch *api.DataTransferChannel, deal rm.ClientDealState) api.RetrievalInfo { + return api.RetrievalInfo{ + PayloadCID: deal.PayloadCID, + ID: deal.ID, + PieceCID: deal.PieceCID, + PricePerByte: deal.PricePerByte, + UnsealPrice: deal.UnsealPrice, + Status: deal.Status, + Message: deal.Message, + Provider: deal.Sender, + BytesReceived: deal.TotalReceived, + BytesPaidFor: deal.BytesPaidFor, + TotalPaid: deal.FundsSpent, + TransferChannelID: deal.ChannelID, + DataTransfer: ch, + } +} + +func (a *API) newRetrievalInfo(ctx context.Context, v rm.ClientDealState) api.RetrievalInfo { + // Find the data transfer associated with this deal + var transferCh *api.DataTransferChannel + if v.ChannelID != nil { + state, err := a.DataTransfer.ChannelState(ctx, *v.ChannelID) + + // Note: If there was an error just ignore it, as the data transfer may + // be not found if it's no longer active + if err == nil { + ch := api.NewDataTransferChannel(a.Host.ID(), state) + ch.Stages = state.Stages() + transferCh = &ch + } + } + + return a.newRetrievalInfoWithTransfer(transferCh, v) +} + type multiStoreRetrievalStore struct { storeID multistore.StoreID store *multistore.Store From 9c2467b17c66b6fe79f181272783e60797d43acc Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Thu, 27 May 2021 11:18:24 -0700 Subject: [PATCH 02/66] fix(cli): patch for output given fil-markets IsTerminalError ahving a bug --- cli/client.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cli/client.go b/cli/client.go index a0a36cf40..91069bc53 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1296,10 +1296,14 @@ var clientListRetrievalsCmd = &cli.Command{ }, } +func isTerminalError(status retrievalmarket.DealStatus) bool { + // should patch this in go-fil-markets but to solve the problem immediate and not have buggy output + return retrievalmarket.IsTerminalError(status) || status == retrievalmarket.DealStatusErrored +} func outputRetrievalDeals(ctx context.Context, out io.Writer, localDeals []lapi.RetrievalInfo, verbose bool, color bool, showFailed bool, completed bool) error { var deals []api.RetrievalInfo for _, deal := range localDeals { - if !showFailed && retrievalmarket.IsTerminalError(deal.Status) { + if !showFailed && isTerminalError(deal.Status) { continue } if !completed && retrievalmarket.IsTerminalSuccess(deal.Status) { @@ -1387,7 +1391,7 @@ func retrievalStatusString(c bool, status retrievalmarket.DealStatus) string { return s } - if retrievalmarket.IsTerminalError(status) { + if isTerminalError(status) { return color.RedString(s) } if retrievalmarket.IsTerminalSuccess(status) { From 9e73e43272b05845fef8bc90a9d4313033efe127 Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Thu, 27 May 2021 11:24:08 -0700 Subject: [PATCH 03/66] fix(cli): add one more error state --- cli/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/client.go b/cli/client.go index 91069bc53..b9e7b45ac 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1298,7 +1298,7 @@ var clientListRetrievalsCmd = &cli.Command{ func isTerminalError(status retrievalmarket.DealStatus) bool { // should patch this in go-fil-markets but to solve the problem immediate and not have buggy output - return retrievalmarket.IsTerminalError(status) || status == retrievalmarket.DealStatusErrored + return retrievalmarket.IsTerminalError(status) || status == retrievalmarket.DealStatusErrored || status == retrievalmarket.DealStatusCancelled } func outputRetrievalDeals(ctx context.Context, out io.Writer, localDeals []lapi.RetrievalInfo, verbose bool, color bool, showFailed bool, completed bool) error { var deals []api.RetrievalInfo From 3fbe2b320d72762829608654f0623e48e37b3443 Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Thu, 27 May 2021 15:00:31 -0700 Subject: [PATCH 04/66] feat(v0api): add list-retrievals to v0 --- api/v0api/full.go | 4 ++ api/v0api/proxy_gen.go | 20 ++++++++++ api/v0api/v0mocks/mock_full.go | 30 +++++++++++++++ cli/client.go | 2 +- documentation/en/api-v0-methods.md | 62 +++++++++++++++++++++++++++++- 5 files changed, 116 insertions(+), 2 deletions(-) diff --git a/api/v0api/full.go b/api/v0api/full.go index 5e5d61595..076c37013 100644 --- a/api/v0api/full.go +++ b/api/v0api/full.go @@ -326,6 +326,10 @@ type FullNode interface { // of status updates. ClientRetrieveWithEvents(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) //perm:admin // ClientQueryAsk returns a signed StorageAsk from the specified miner. + // ClientListRetrievals returns information about retrievals made by the local client + ClientListRetrievals(ctx context.Context) ([]api.RetrievalInfo, error) //perm:write + // ClientGetRetrievalUpdates returns status of updated retrieval deals + ClientGetRetrievalUpdates(ctx context.Context) (<-chan api.RetrievalInfo, error) //perm:write ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) //perm:read // ClientCalcCommP calculates the CommP and data size of the specified CID ClientDealPieceCID(ctx context.Context, root cid.Cid) (api.DataCIDSize, error) //perm:read diff --git a/api/v0api/proxy_gen.go b/api/v0api/proxy_gen.go index bd0da070e..fc2fc4186 100644 --- a/api/v0api/proxy_gen.go +++ b/api/v0api/proxy_gen.go @@ -97,6 +97,8 @@ type FullNodeStruct struct { ClientGetDealUpdates func(p0 context.Context) (<-chan api.DealInfo, error) `perm:"write"` + ClientGetRetrievalUpdates func(p0 context.Context) (<-chan api.RetrievalInfo, error) `perm:"write"` + ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"` ClientImport func(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) `perm:"admin"` @@ -107,6 +109,8 @@ type FullNodeStruct struct { ClientListImports func(p0 context.Context) ([]api.Import, error) `perm:"write"` + ClientListRetrievals func(p0 context.Context) ([]api.RetrievalInfo, error) `perm:"write"` + ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) `perm:"read"` ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"` @@ -716,6 +720,14 @@ func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan api.Deal return nil, xerrors.New("method not supported") } +func (s *FullNodeStruct) ClientGetRetrievalUpdates(p0 context.Context) (<-chan api.RetrievalInfo, error) { + return s.Internal.ClientGetRetrievalUpdates(p0) +} + +func (s *FullNodeStub) ClientGetRetrievalUpdates(p0 context.Context) (<-chan api.RetrievalInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { return s.Internal.ClientHasLocal(p0, p1) } @@ -756,6 +768,14 @@ func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]api.Import, erro return *new([]api.Import), xerrors.New("method not supported") } +func (s *FullNodeStruct) ClientListRetrievals(p0 context.Context) ([]api.RetrievalInfo, error) { + return s.Internal.ClientListRetrievals(p0) +} + +func (s *FullNodeStub) ClientListRetrievals(p0 context.Context) ([]api.RetrievalInfo, error) { + return *new([]api.RetrievalInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) { return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) } diff --git a/api/v0api/v0mocks/mock_full.go b/api/v0api/v0mocks/mock_full.go index 7a1fa55db..7bcfaf47c 100644 --- a/api/v0api/v0mocks/mock_full.go +++ b/api/v0api/v0mocks/mock_full.go @@ -580,6 +580,21 @@ func (mr *MockFullNodeMockRecorder) ClientGetDealUpdates(arg0 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealUpdates), arg0) } +// ClientGetRetrievalUpdates mocks base method +func (m *MockFullNode) ClientGetRetrievalUpdates(arg0 context.Context) (<-chan api.RetrievalInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGetRetrievalUpdates", arg0) + ret0, _ := ret[0].(<-chan api.RetrievalInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientGetRetrievalUpdates indicates an expected call of ClientGetRetrievalUpdates +func (mr *MockFullNodeMockRecorder) ClientGetRetrievalUpdates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetRetrievalUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetRetrievalUpdates), arg0) +} + // ClientHasLocal mocks base method func (m *MockFullNode) ClientHasLocal(arg0 context.Context, arg1 cid.Cid) (bool, error) { m.ctrl.T.Helper() @@ -655,6 +670,21 @@ func (mr *MockFullNodeMockRecorder) ClientListImports(arg0 interface{}) *gomock. return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListImports", reflect.TypeOf((*MockFullNode)(nil).ClientListImports), arg0) } +// ClientListRetrievals mocks base method +func (m *MockFullNode) ClientListRetrievals(arg0 context.Context) ([]api.RetrievalInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientListRetrievals", arg0) + ret0, _ := ret[0].([]api.RetrievalInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientListRetrievals indicates an expected call of ClientListRetrievals +func (mr *MockFullNodeMockRecorder) ClientListRetrievals(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListRetrievals", reflect.TypeOf((*MockFullNode)(nil).ClientListRetrievals), arg0) +} + // ClientMinerQueryOffer mocks base method func (m *MockFullNode) ClientMinerQueryOffer(arg0 context.Context, arg1 address.Address, arg2 cid.Cid, arg3 *cid.Cid) (api.QueryOffer, error) { m.ctrl.T.Helper() diff --git a/cli/client.go b/cli/client.go index b9e7b45ac..96e7560e5 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1238,7 +1238,7 @@ var clientListRetrievalsCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - api, closer, err := GetFullNodeAPIV1(cctx) + api, closer, err := GetFullNodeAPI(cctx) if err != nil { return err } diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index a8b760f8a..ca0c7ddcf 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -44,11 +44,13 @@ * [ClientGetDealInfo](#ClientGetDealInfo) * [ClientGetDealStatus](#ClientGetDealStatus) * [ClientGetDealUpdates](#ClientGetDealUpdates) + * [ClientGetRetrievalUpdates](#ClientGetRetrievalUpdates) * [ClientHasLocal](#ClientHasLocal) * [ClientImport](#ClientImport) * [ClientListDataTransfers](#ClientListDataTransfers) * [ClientListDeals](#ClientListDeals) * [ClientListImports](#ClientListImports) + * [ClientListRetrievals](#ClientListRetrievals) * [ClientMinerQueryOffer](#ClientMinerQueryOffer) * [ClientQueryAsk](#ClientQueryAsk) * [ClientRemoveImport](#ClientRemoveImport) @@ -1197,6 +1199,54 @@ Response: } ``` +### ClientGetRetrievalUpdates +ClientGetRetrievalUpdates returns status of updated retrieval deals + + +Perms: write + +Inputs: `null` + +Response: +```json +{ + "PayloadCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ID": 5, + "PieceCID": null, + "PricePerByte": "0", + "UnsealPrice": "0", + "Status": 0, + "Message": "string value", + "Provider": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "BytesReceived": 42, + "BytesPaidFor": 42, + "TotalPaid": "0", + "TransferChannelID": { + "Initiator": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Responder": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "ID": 3 + }, + "DataTransfer": { + "TransferID": 3, + "Status": 1, + "BaseCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "IsInitiator": true, + "IsSender": true, + "Voucher": "string value", + "Message": "string value", + "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Transferred": 42, + "Stages": { + "Stages": null + } + } +} +``` + ### ClientHasLocal ClientHasLocal indicates whether a certain CID is locally stored. @@ -1264,6 +1314,17 @@ Response: `null` ClientListImports lists imported files and their root CIDs +Perms: write + +Inputs: `null` + +Response: `null` + +### ClientListRetrievals +ClientQueryAsk returns a signed StorageAsk from the specified miner. +ClientListRetrievals returns information about retrievals made by the local client + + Perms: write Inputs: `null` @@ -1310,7 +1371,6 @@ Response: ``` ### ClientQueryAsk -ClientQueryAsk returns a signed StorageAsk from the specified miner. Perms: read From 93a2530803526431736df7fd776d1827de0786a8 Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Tue, 1 Jun 2021 16:02:35 -0700 Subject: [PATCH 05/66] fix(cli): make failed retrievals show by default --- cli/client.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/client.go b/cli/client.go index 96e7560e5..1dcd59e72 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1227,6 +1227,7 @@ var clientListRetrievalsCmd = &cli.Command{ &cli.BoolFlag{ Name: "show-failed", Usage: "show failed/failing deals", + Value: true, }, &cli.BoolFlag{ Name: "completed", From 9d3410d374242a6b6dde3576160bdbd44a8ed4b7 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Thu, 3 Jun 2021 00:05:43 -0700 Subject: [PATCH 06/66] include appimage on release --- .circleci/config.yml | 50 ++++++++++++++++++++++++++++++++++++-- AppImageBuilder.yml | 38 +++++++++++++++++------------ scripts/build-bundle.sh | 3 +++ scripts/publish-release.sh | 3 +++ 4 files changed, 77 insertions(+), 17 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d59939096..0f4577523 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -428,6 +428,41 @@ jobs: - "~/.rustup" - "~/.cargo" + build-appimage: + machine: + image: ubuntu-2004:202104-01 + steps: + - checkout + - attach_workspace: + at: "." + - run: + name: install appimage-builder + command: | + # docs: https://appimage-builder.readthedocs.io/en/latest/intro/install.html + sudo apt update + sudo apt install -y python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace + sudo curl -Lo /usr/local/bin/appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage + sudo chmod +x /usr/local/bin/appimagetool + sudo pip3 install appimage-builder + - run: + name: install lotus dependencies + command: sudo apt install ocl-icd-opencl-dev libhwloc-dev + - run: + name: build appimage + command: | + sed -i "s/version: latest/version: ${CIRCLE_TAG:-latest}/" AppImageBuilder.yml + make appimage + - run: + name: prepare workspace + command: | + mkdir appimage + mv Lotus-latest-x86_64.AppImage appimage + - persist_to_workspace: + root: "." + paths: + - appimage + + gofmt: executor: golang steps: @@ -767,8 +802,8 @@ workflows: - master - build-debug - build-all: - requires: - - test-short + # requires: + # - test-short filters: tags: only: @@ -805,10 +840,21 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-appimage: + requires: + - test-short + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - publish: requires: - build-all - build-macos + - build-appimage filters: branches: ignore: diff --git a/AppImageBuilder.yml b/AppImageBuilder.yml index 48db68930..19c74e4a2 100644 --- a/AppImageBuilder.yml +++ b/AppImageBuilder.yml @@ -1,4 +1,3 @@ -# appimage-builder recipe see https://appimage-builder.readthedocs.io for details version: 1 AppDir: path: ./AppDir @@ -6,31 +5,40 @@ AppDir: id: io.filecoin.lotus name: Lotus icon: icon - version: current + version: latest exec: usr/bin/lotus exec_args: $@ apt: arch: amd64 allow_unauthenticated: true sources: - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic main restricted - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic-updates main restricted - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic universe - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic-updates universe - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic multiverse - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic-updates multiverse - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic-backports main restricted + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal main restricted + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal universe + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates universe + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal multiverse + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates multiverse + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse - - sourceline: deb http://security.ubuntu.com/ubuntu bionic-security main restricted - - sourceline: deb http://security.ubuntu.com/ubuntu bionic-security universe - - sourceline: deb http://security.ubuntu.com/ubuntu bionic-security multiverse + - sourceline: deb http://security.ubuntu.com/ubuntu focal-security main restricted + - sourceline: deb http://security.ubuntu.com/ubuntu focal-security universe + - sourceline: deb http://security.ubuntu.com/ubuntu focal-security multiverse + - sourceline: deb https://cli-assets.heroku.com/apt ./ + - sourceline: deb http://ppa.launchpad.net/openjdk-r/ppa/ubuntu focal main + - sourceline: deb http://ppa.launchpad.net/git-core/ppa/ubuntu focal main + - sourceline: deb http://archive.canonical.com/ubuntu focal partner include: - - libgcc1 - - libhwloc5 - ocl-icd-libopencl1 + - libhwloc15 exclude: [] files: - include: [] + include: + - /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 + - /usr/lib/x86_64-linux-gnu/libpthread-2.31.so + - /usr/lib/x86_64-linux-gnu/libm-2.31.so + - /usr/lib/x86_64-linux-gnu/libdl-2.31.so + - /usr/lib/x86_64-linux-gnu/libc-2.31.so + - /usr/lib/x86_64-linux-gnu/libudev.so.1.6.17 exclude: - usr/share/man - usr/share/doc/*/README.* diff --git a/scripts/build-bundle.sh b/scripts/build-bundle.sh index 7d37edff8..fe1c88611 100755 --- a/scripts/build-bundle.sh +++ b/scripts/build-bundle.sh @@ -49,4 +49,7 @@ do ipfs add -q "lotus_${CIRCLE_TAG}_${ARCH}-amd64.tar.gz" > "lotus_${CIRCLE_TAG}_${ARCH}-amd64.tar.gz.cid" done +cp "../appimage/Lotus-${CIRCLE_TAG}-x86_64.AppImage" . +sha512sum "Lotus-${CIRCLE_TAG}-x86_64.AppImage" > "Lotus-${CIRCLE_TAG}-x86_64.AppImage.sha512" +ipfs add -q "Lotus-${CIRCLE_TAG}-x86_64.AppImage" > "Lotus-${CIRCLE_TAG}-x86_64.AppImage.cid" popd diff --git a/scripts/publish-release.sh b/scripts/publish-release.sh index ad2a52dcf..4c152d15c 100755 --- a/scripts/publish-release.sh +++ b/scripts/publish-release.sh @@ -68,6 +68,9 @@ artifacts=( "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz" "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz.cid" "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz.sha512" + "Lotus-${CIRCLE_TAG}-x86_64.AppImage" + "Lotus-${CIRCLE_TAG}-x86_64.AppImage.cid" + "Lotus-${CIRCLE_TAG}-x86_64.AppImage.sha512" ) for RELEASE_FILE in "${artifacts[@]}" From 65651099b6d48de43ad3b8490a981ae3be9c4af1 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Thu, 3 Jun 2021 00:11:36 -0700 Subject: [PATCH 07/66] remove extraneous comment --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0f4577523..b0f8120f3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -802,8 +802,8 @@ workflows: - master - build-debug - build-all: - # requires: - # - test-short + requires: + - test-short filters: tags: only: From 78c128f6a3ba9561f9895906f3596c92a5cab152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 3 Jun 2021 10:42:26 +0200 Subject: [PATCH 08/66] chain: Better logging in sync tests --- chain/sync_test.go | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/chain/sync_test.go b/chain/sync_test.go index 2289d6350..9f89f789b 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -433,12 +433,18 @@ func (tu *syncTestUtil) waitUntilSyncTarget(to int, target *types.TipSet) { tu.t.Fatal(err) } - // TODO: some sort of timeout? - for n := range hc { - for _, c := range n { - if c.Val.Equals(target) { - return + timeout := time.After(5 * time.Second) + + for { + select { + case n := <-hc: + for _, c := range n { + if c.Val.Equals(target) { + return + } } + case <-timeout: + tu.t.Fatal("waitUntilSyncTarget timeout") } } } @@ -575,15 +581,20 @@ func TestSyncFork(t *testing.T) { tu.loadChainToNode(p1) tu.loadChainToNode(p2) - phead := func() { + printHead := func() { h1, err := tu.nds[1].ChainHead(tu.ctx) require.NoError(tu.t, err) h2, err := tu.nds[2].ChainHead(tu.ctx) require.NoError(tu.t, err) - fmt.Println("Node 1: ", h1.Cids(), h1.Parents(), h1.Height()) - fmt.Println("Node 2: ", h2.Cids(), h1.Parents(), h2.Height()) + w1, err := tu.nds[1].(*impl.FullNodeAPI).ChainAPI.Chain.Weight(tu.ctx, h1) + require.NoError(tu.t, err) + w2, err := tu.nds[2].(*impl.FullNodeAPI).ChainAPI.Chain.Weight(tu.ctx, h2) + require.NoError(tu.t, err) + + fmt.Println("Node 1: ", h1.Cids(), h1.Parents(), h1.Height(), w1) + fmt.Println("Node 2: ", h2.Cids(), h2.Parents(), h2.Height(), w2) //time.Sleep(time.Second * 2) fmt.Println() fmt.Println() @@ -591,7 +602,7 @@ func TestSyncFork(t *testing.T) { fmt.Println() } - phead() + printHead() base := tu.g.CurTipset fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height()) @@ -611,6 +622,8 @@ func TestSyncFork(t *testing.T) { fmt.Println("A: ", a.Cids(), a.TipSet().Height()) fmt.Println("B: ", b.Cids(), b.TipSet().Height()) + printHead() + // Now for the fun part!! require.NoError(t, tu.mn.LinkAll()) @@ -618,7 +631,7 @@ func TestSyncFork(t *testing.T) { tu.waitUntilSyncTarget(p1, b.TipSet()) tu.waitUntilSyncTarget(p2, b.TipSet()) - phead() + printHead() } // This test crafts a tipset with 2 blocks, A and B. From fd2d2d3ff490ee9a525545fe9fc395046e94e5e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 3 Jun 2021 17:04:45 +0200 Subject: [PATCH 09/66] Fix TestDeadlineToggling flakiness --- api/test/deadlines.go | 57 ++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/api/test/deadlines.go b/api/test/deadlines.go index 987bfb3ae..836c03632 100644 --- a/api/test/deadlines.go +++ b/api/test/deadlines.go @@ -159,7 +159,7 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { build.Clock.Sleep(blocktime) } - checkMiner := func(ma address.Address, power abi.StoragePower, active bool, tsk types.TipSetKey) { + checkMiner := func(ma address.Address, power abi.StoragePower, active, activeIfCron bool, tsk types.TipSetKey) { p, err := client.StateMinerPower(ctx, ma, tsk) require.NoError(t, err) @@ -174,6 +174,22 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { act, err := mst.DeadlineCronActive() require.NoError(t, err) + + if tsk != types.EmptyTSK { + ts, err := client.ChainGetTipSet(ctx, tsk) + require.NoError(t, err) + di, err := mst.DeadlineInfo(ts.Height()) + require.NoError(t, err) + + // cron happened on the same epoch some other condition would have happened + if di.Open == ts.Height() { + act, err := mst.DeadlineCronActive() + require.NoError(t, err) + require.Equal(t, activeIfCron, act) + return + } + } + require.Equal(t, active, act) } @@ -181,7 +197,7 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { { uts, err := client.ChainGetTipSetByHeight(ctx, upgradeH+2, types.EmptyTSK) require.NoError(t, err) - checkMiner(maddrB, types.NewInt(0), true, uts.Key()) + checkMiner(maddrB, types.NewInt(0), true, true, uts.Key()) } nv, err := client.StateNetworkVersion(ctx, types.EmptyTSK) @@ -197,19 +213,19 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { require.NoError(t, err) // first round of miner checks - checkMiner(maddrA, types.NewInt(uint64(ssz)*GenesisPreseals), true, types.EmptyTSK) - checkMiner(maddrC, types.NewInt(uint64(ssz)*sectorsC), true, types.EmptyTSK) + checkMiner(maddrA, types.NewInt(uint64(ssz)*GenesisPreseals), true, true, types.EmptyTSK) + checkMiner(maddrC, types.NewInt(uint64(ssz)*sectorsC), true, true, types.EmptyTSK) - checkMiner(maddrB, types.NewInt(0), false, types.EmptyTSK) - checkMiner(maddrD, types.NewInt(0), false, types.EmptyTSK) - checkMiner(maddrE, types.NewInt(0), false, types.EmptyTSK) + checkMiner(maddrB, types.NewInt(0), false, false, types.EmptyTSK) + checkMiner(maddrD, types.NewInt(0), false, false, types.EmptyTSK) + checkMiner(maddrE, types.NewInt(0), false, false, types.EmptyTSK) // pledge sectors on minerB/minerD, stop post on minerC pledgeSectors(t, ctx, minerB, sectersB, 0, nil) - checkMiner(maddrB, types.NewInt(0), true, types.EmptyTSK) + checkMiner(maddrB, types.NewInt(0), true, true, types.EmptyTSK) pledgeSectors(t, ctx, minerD, sectorsD, 0, nil) - checkMiner(maddrD, types.NewInt(0), true, types.EmptyTSK) + checkMiner(maddrD, types.NewInt(0), true, true, types.EmptyTSK) minerC.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).Fail() @@ -259,7 +275,7 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { build.Clock.Sleep(blocktime) } - checkMiner(maddrE, types.NewInt(0), true, types.EmptyTSK) + checkMiner(maddrE, types.NewInt(0), true, true, types.EmptyTSK) // go through rest of the PP for { @@ -274,11 +290,11 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { } // second round of miner checks - checkMiner(maddrA, types.NewInt(uint64(ssz)*GenesisPreseals), true, types.EmptyTSK) - checkMiner(maddrC, types.NewInt(0), true, types.EmptyTSK) - checkMiner(maddrB, types.NewInt(uint64(ssz)*sectersB), true, types.EmptyTSK) - checkMiner(maddrD, types.NewInt(uint64(ssz)*sectorsD), true, types.EmptyTSK) - checkMiner(maddrE, types.NewInt(0), false, types.EmptyTSK) + checkMiner(maddrA, types.NewInt(uint64(ssz)*GenesisPreseals), true, true, types.EmptyTSK) + checkMiner(maddrC, types.NewInt(0), true, true, types.EmptyTSK) + checkMiner(maddrB, types.NewInt(uint64(ssz)*sectersB), true, true, types.EmptyTSK) + checkMiner(maddrD, types.NewInt(uint64(ssz)*sectorsD), true, true, types.EmptyTSK) + checkMiner(maddrE, types.NewInt(0), false, false, types.EmptyTSK) // disable post on minerB minerB.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).Fail() @@ -329,7 +345,8 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { require.NoError(t, err) require.Equal(t, exitcode.Ok, r.Receipt.ExitCode) - checkMiner(maddrD, types.NewInt(0), true, r.TipSet) + // assert inactive if the message landed in the tipset we run cron in + checkMiner(maddrD, types.NewInt(0), true, false, r.TipSet) } // go through another PP @@ -345,8 +362,8 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { } // third round of miner checks - checkMiner(maddrA, types.NewInt(uint64(ssz)*GenesisPreseals), true, types.EmptyTSK) - checkMiner(maddrC, types.NewInt(0), true, types.EmptyTSK) - checkMiner(maddrB, types.NewInt(0), true, types.EmptyTSK) - checkMiner(maddrD, types.NewInt(0), false, types.EmptyTSK) + checkMiner(maddrA, types.NewInt(uint64(ssz)*GenesisPreseals), true, true, types.EmptyTSK) + checkMiner(maddrC, types.NewInt(0), true, true, types.EmptyTSK) + checkMiner(maddrB, types.NewInt(0), true, true, types.EmptyTSK) + checkMiner(maddrD, types.NewInt(0), false, false, types.EmptyTSK) } From 565bb4f589bc0c341062a27a875791f0b9b45880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 3 Jun 2021 17:31:05 +0200 Subject: [PATCH 10/66] mock: Log debug info on bad aggregates --- extern/sector-storage/mock/mock.go | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/extern/sector-storage/mock/mock.go b/extern/sector-storage/mock/mock.go index 52496f836..977960c8f 100644 --- a/extern/sector-storage/mock/mock.go +++ b/extern/sector-storage/mock/mock.go @@ -34,7 +34,9 @@ type SectorMgr struct { lk sync.Mutex } -type mockVerifProver struct{} +type mockVerifProver struct { + aggregates map[string]proof5.AggregateSealVerifyProofAndInfos // used for logging bad verifies +} func NewMockSectorMgr(genesisSectors []abi.SectorID) *SectorMgr { sectors := make(map[abi.SectorID]*sectorState) @@ -522,7 +524,19 @@ func (m mockVerifProver) VerifyAggregateSeals(aggregate proof5.AggregateSealVeri } } - return bytes.Equal(aggregate.Proof, out), nil + ok := bytes.Equal(aggregate.Proof, out) + if !ok { + genInfo, found := m.aggregates[string(aggregate.Proof)] + if !found { + log.Errorf("BAD AGGREGATE: saved generate inputs not found; agg.Proof: %x; expected: %x", aggregate.Proof, out) + } else { + log.Errorf("BAD AGGREGATE (1): agg.Proof: %x; expected: %x", aggregate.Proof, out) + log.Errorf("BAD AGGREGATE (2): Verify Infos: %+v", aggregate.Infos) + log.Errorf("BAD AGGREGATE (3): Generate Infos: %+v", genInfo.Infos) + } + } + + return ok, nil } func (m mockVerifProver) AggregateSealProofs(aggregateInfo proof5.AggregateSealVerifyProofAndInfos, proofs [][]byte) ([]byte, error) { @@ -533,6 +547,8 @@ func (m mockVerifProver) AggregateSealProofs(aggregateInfo proof5.AggregateSealV } } + m.aggregates[string(out)] = aggregateInfo + return out, nil } @@ -592,8 +608,11 @@ func (m mockVerifProver) GenerateWinningPoStSectorChallenge(ctx context.Context, return []uint64{0}, nil } -var MockVerifier = mockVerifProver{} -var MockProver = mockVerifProver{} +var MockVerifier = mockVerifProver{ + aggregates: map[string]proof5.AggregateSealVerifyProofAndInfos{}, +} + +var MockProver = MockVerifier var _ storage.Sealer = &SectorMgr{} var _ ffiwrapper.Verifier = MockVerifier From c5797482b2dd128dd213308aaf5d30371f6acc50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 3 Jun 2021 18:10:53 +0200 Subject: [PATCH 11/66] Revert CallWithGas hack --- chain/stmgr/call.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index cfbf60a95..961bebd9c 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -155,6 +155,11 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri return nil, xerrors.Errorf("computing tipset state: %w", err) } + state, err = sm.handleStateForks(ctx, state, ts.Height(), nil, ts) + if err != nil { + return nil, fmt.Errorf("failed to handle fork: %w", err) + } + r := store.NewChainRand(sm.cs, ts.Cids()) if span.IsRecordingEvents() { @@ -167,7 +172,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri vmopt := &vm.VMOpts{ StateBase: state, - Epoch: ts.Height(), + Epoch: ts.Height() + 1, Rand: r, Bstore: sm.cs.StateBlockstore(), Syscalls: sm.cs.VMSys(), From 92fdbd80d937bb73a8ef65062a740e291620d185 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Thu, 3 Jun 2021 10:18:13 -0700 Subject: [PATCH 12/66] tmp: publish dry run --- .circleci/config.yml | 14 +++++++------- scripts/publish-release.sh | 16 ++++++++++------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b0f8120f3..69ef892e0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -855,13 +855,13 @@ workflows: - build-all - build-macos - build-appimage - filters: - branches: - ignore: - - /.*/ - tags: - only: - - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + # filters: + # branches: + # ignore: + # - /.*/ + # tags: + # only: + # - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-and-push-image: dockerfile: Dockerfile.lotus path: . diff --git a/scripts/publish-release.sh b/scripts/publish-release.sh index 4c152d15c..fe1c89caf 100755 --- a/scripts/publish-release.sh +++ b/scripts/publish-release.sh @@ -18,6 +18,8 @@ do command -v "${REQUIRE}" >/dev/null 2>&1 || echo >&2 "'${REQUIRE}' must be installed" done +CIRCLE_TAG=DEFINITELYDOESNOTEXIST + #see if the release already exists by tag RELEASE_RESPONSE=` curl \ @@ -47,7 +49,7 @@ if [ "${RELEASE_ID}" = "null" ]; then # create it if it doesn't exist yet RELEASE_RESPONSE=` - curl \ + echo curl \ --request POST \ --header "Authorization: token ${GITHUB_TOKEN}" \ --header "Content-Type: application/json" \ @@ -58,6 +60,8 @@ else echo "release already exists" fi +RELEASE_RESPONSE=DEFINITELYDOESNOTEXIST + RELEASE_UPLOAD_URL=`echo "${RELEASE_RESPONSE}" | jq -r '.upload_url' | cut -d'{' -f1` echo "Preparing to send artifacts to ${RELEASE_UPLOAD_URL}" @@ -68,15 +72,15 @@ artifacts=( "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz" "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz.cid" "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz.sha512" - "Lotus-${CIRCLE_TAG}-x86_64.AppImage" - "Lotus-${CIRCLE_TAG}-x86_64.AppImage.cid" - "Lotus-${CIRCLE_TAG}-x86_64.AppImage.sha512" + "Lotus-${CIRCLE_TAG}-x86_64.AppImage" + "Lotus-${CIRCLE_TAG}-x86_64.AppImage.cid" + "Lotus-${CIRCLE_TAG}-x86_64.AppImage.sha512" ) for RELEASE_FILE in "${artifacts[@]}" do echo "Uploading ${RELEASE_FILE}..." - curl \ + echo curl \ --request POST \ --header "Authorization: token ${GITHUB_TOKEN}" \ --header "Content-Type: application/octet-stream" \ @@ -96,7 +100,7 @@ miscellaneous=( for MISC in "${miscellaneous[@]}" do echo "Uploading release bundle: ${MISC}" - curl \ + echo curl \ --request POST \ --header "Authorization: token ${GITHUB_TOKEN}" \ --header "Content-Type: application/octet-stream" \ From eafcc14f0bd5ed0f3e86544fe99493e96c66ad75 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Thu, 3 Jun 2021 10:20:49 -0700 Subject: [PATCH 13/66] comment out filters --- .circleci/config.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 69ef892e0..2dd564476 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -804,10 +804,10 @@ workflows: - build-all: requires: - test-short - filters: - tags: - only: - - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + # filters: + # tags: + # only: + # - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-ntwk-calibration: requires: - test-short @@ -833,23 +833,23 @@ workflows: - build-macos: requires: - test-short - filters: - branches: - ignore: - - /.*/ - tags: - only: - - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + # filters: + # branches: + # ignore: + # - /.*/ + # tags: + # only: + # - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-appimage: requires: - test-short - filters: - branches: - ignore: - - /.*/ - tags: - only: - - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + # filters: + # branches: + # ignore: + # - /.*/ + # tags: + # only: + # - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - publish: requires: - build-all From 8b2b488d17defbe80a134add481ba9b9140336f7 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Thu, 3 Jun 2021 10:44:48 -0700 Subject: [PATCH 14/66] remove temporary edits --- .circleci/config.yml | 50 +++++++++++++++++++------------------- scripts/publish-release.sh | 10 +++----- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2dd564476..b0f8120f3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -804,10 +804,10 @@ workflows: - build-all: requires: - test-short - # filters: - # tags: - # only: - # - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + filters: + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-ntwk-calibration: requires: - test-short @@ -833,35 +833,35 @@ workflows: - build-macos: requires: - test-short - # filters: - # branches: - # ignore: - # - /.*/ - # tags: - # only: - # - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-appimage: requires: - test-short - # filters: - # branches: - # ignore: - # - /.*/ - # tags: - # only: - # - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - publish: requires: - build-all - build-macos - build-appimage - # filters: - # branches: - # ignore: - # - /.*/ - # tags: - # only: - # - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-and-push-image: dockerfile: Dockerfile.lotus path: . diff --git a/scripts/publish-release.sh b/scripts/publish-release.sh index fe1c89caf..22572de60 100755 --- a/scripts/publish-release.sh +++ b/scripts/publish-release.sh @@ -18,8 +18,6 @@ do command -v "${REQUIRE}" >/dev/null 2>&1 || echo >&2 "'${REQUIRE}' must be installed" done -CIRCLE_TAG=DEFINITELYDOESNOTEXIST - #see if the release already exists by tag RELEASE_RESPONSE=` curl \ @@ -49,7 +47,7 @@ if [ "${RELEASE_ID}" = "null" ]; then # create it if it doesn't exist yet RELEASE_RESPONSE=` - echo curl \ + curl \ --request POST \ --header "Authorization: token ${GITHUB_TOKEN}" \ --header "Content-Type: application/json" \ @@ -60,8 +58,6 @@ else echo "release already exists" fi -RELEASE_RESPONSE=DEFINITELYDOESNOTEXIST - RELEASE_UPLOAD_URL=`echo "${RELEASE_RESPONSE}" | jq -r '.upload_url' | cut -d'{' -f1` echo "Preparing to send artifacts to ${RELEASE_UPLOAD_URL}" @@ -80,7 +76,7 @@ artifacts=( for RELEASE_FILE in "${artifacts[@]}" do echo "Uploading ${RELEASE_FILE}..." - echo curl \ + curl \ --request POST \ --header "Authorization: token ${GITHUB_TOKEN}" \ --header "Content-Type: application/octet-stream" \ @@ -100,7 +96,7 @@ miscellaneous=( for MISC in "${miscellaneous[@]}" do echo "Uploading release bundle: ${MISC}" - echo curl \ + curl \ --request POST \ --header "Authorization: token ${GITHUB_TOKEN}" \ --header "Content-Type: application/octet-stream" \ From a41a1cbd937dbb3d9dd0927639179733ca86687f Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 3 Jun 2021 15:47:49 -0400 Subject: [PATCH 15/66] Gate runtime's GetRandomnessFromBeacon on HyperdriveHeight, not network version --- chain/vm/runtime.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 7c40fed62..2845c7696 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -229,7 +229,7 @@ func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparat func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness { var err error var res []byte - if rt.vm.GetNtwkVersion(rt.ctx, randEpoch) >= network.Version13 { + if randEpoch > build.UpgradeHyperdriveHeight { res, err = rt.vm.rand.GetBeaconRandomnessLookingForward(rt.ctx, personalization, randEpoch, entropy) } else { res, err = rt.vm.rand.GetBeaconRandomnessLookingBack(rt.ctx, personalization, randEpoch, entropy) From c66d66dfcba4907c0d97dfaffdb179a2cce3d796 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 3 Jun 2021 16:10:15 -0400 Subject: [PATCH 16/66] Fix state manager::Call() --- chain/stmgr/call.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index 961bebd9c..67f95c47c 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -39,25 +39,29 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. } bstate := ts.ParentState() - bheight := ts.Height() + pts, err := sm.cs.LoadTipSet(ts.Parents()) + if err != nil { + return nil, xerrors.Errorf("failed to load parent tipset: %w", err) + } + pheight := pts.Height() // If we have to run an expensive migration, and we're not at genesis, // return an error because the migration will take too long. // // We allow this at height 0 for at-genesis migrations (for testing). - if bheight-1 > 0 && sm.hasExpensiveFork(ctx, bheight-1) { + if pheight > 0 && sm.hasExpensiveFork(ctx, pheight) { return nil, ErrExpensiveFork } // Run the (not expensive) migration. - bstate, err := sm.handleStateForks(ctx, bstate, bheight-1, nil, ts) + bstate, err = sm.handleStateForks(ctx, bstate, pheight, nil, ts) if err != nil { return nil, fmt.Errorf("failed to handle fork: %w", err) } vmopt := &vm.VMOpts{ StateBase: bstate, - Epoch: bheight, + Epoch: pheight + 1, Rand: store.NewChainRand(sm.cs, ts.Cids()), Bstore: sm.cs.StateBlockstore(), Syscalls: sm.cs.VMSys(), From 96e67b80c380a85d154e98f93fa08da0dab6ccc4 Mon Sep 17 00:00:00 2001 From: Travis Person Date: Wed, 2 Jun 2021 18:49:10 +0000 Subject: [PATCH 17/66] Add interop network --- Makefile | 3 + build/bootstrap/interopnet.pi | 2 + build/params_interop.go | 104 ++++++++++++++++++++++++++++++++++ build/params_mainnet.go | 1 + build/version.go | 13 +++-- 5 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 build/bootstrap/interopnet.pi create mode 100644 build/params_interop.go diff --git a/Makefile b/Makefile index 11180f8b0..d20343f55 100644 --- a/Makefile +++ b/Makefile @@ -80,6 +80,9 @@ nerpanet: build-devnets butterflynet: GOFLAGS+=-tags=butterflynet butterflynet: build-devnets +interopnet: GOFLAGS+=-tags=interopnet +interopnet: build-devnets + lotus: $(BUILD_DEPS) rm -f lotus go build $(GOFLAGS) -o lotus ./cmd/lotus diff --git a/build/bootstrap/interopnet.pi b/build/bootstrap/interopnet.pi new file mode 100644 index 000000000..112d96113 --- /dev/null +++ b/build/bootstrap/interopnet.pi @@ -0,0 +1,2 @@ +/dns4/bootstrap-0.interop.fildev.network/tcp/1347/p2p/12D3KooWN86wA54r3v9M8bBYbc1vK9W1ehHDxVGPRaoeUYuXF8R7 +/dns4/bootstrap-1.interop.fildev.network/tcp/1347/p2p/12D3KooWNZ41kev8mtBZgWe43qam1VX9pJyf87jnaisQP2urZZ2M diff --git a/build/params_interop.go b/build/params_interop.go new file mode 100644 index 000000000..73cc1c7d9 --- /dev/null +++ b/build/params_interop.go @@ -0,0 +1,104 @@ +// +build interopnet + +package build + +import ( + "os" + "strconv" + + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + "github.com/filecoin-project/lotus/chain/actors/policy" +) + +const BootstrappersFile = "interopnet.pi" +const GenesisFile = "interopnet.car" + +var UpgradeBreezeHeight = abi.ChainEpoch(-1) + +const BreezeGasTampingDuration = 0 + +var UpgradeSmokeHeight = abi.ChainEpoch(-1) +var UpgradeIgnitionHeight = abi.ChainEpoch(-2) +var UpgradeRefuelHeight = abi.ChainEpoch(-3) +var UpgradeTapeHeight = abi.ChainEpoch(-4) + +var UpgradeAssemblyHeight = abi.ChainEpoch(-5) +var UpgradeLiftoffHeight = abi.ChainEpoch(-6) + +var UpgradeKumquatHeight = abi.ChainEpoch(-7) +var UpgradeCalicoHeight = abi.ChainEpoch(-8) +var UpgradePersianHeight = abi.ChainEpoch(-9) +var UpgradeOrangeHeight = abi.ChainEpoch(-10) +var UpgradeClausHeight = abi.ChainEpoch(-11) + +var UpgradeTrustHeight = abi.ChainEpoch(-12) + +var UpgradeNorwegianHeight = abi.ChainEpoch(-13) + +var UpgradeTurboHeight = abi.ChainEpoch(-14) + +var UpgradeHyperdriveHeight = abi.ChainEpoch(-15) + +var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ + 0: DrandMainnet, +} + +func init() { + policy.SetSupportedProofTypes( + abi.RegisteredSealProof_StackedDrg2KiBV1, + abi.RegisteredSealProof_StackedDrg8MiBV1, + abi.RegisteredSealProof_StackedDrg512MiBV1, + ) + policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048)) + policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) + policy.SetPreCommitChallengeDelay(abi.ChainEpoch(10)) + + getUpgradeHeight := func(ev string, def abi.ChainEpoch) abi.ChainEpoch { + hs, found := os.LookupEnv(ev) + if found { + h, err := strconv.Atoi(hs) + if err != nil { + log.Panicf("failed to parse %s env var", ev) + } + + return abi.ChainEpoch(h) + } + + return def + } + + UpgradeBreezeHeight = getUpgradeHeight("LOTUS_BREEZE_HEIGHT", UpgradeBreezeHeight) + UpgradeSmokeHeight = getUpgradeHeight("LOTUS_SMOKE_HEIGHT", UpgradeSmokeHeight) + UpgradeIgnitionHeight = getUpgradeHeight("LOTUS_IGNITION_HEIGHT", UpgradeIgnitionHeight) + UpgradeRefuelHeight = getUpgradeHeight("LOTUS_REFUEL_HEIGHT", UpgradeRefuelHeight) + UpgradeTapeHeight = getUpgradeHeight("LOTUS_TAPE_HEIGHT", UpgradeTapeHeight) + UpgradeAssemblyHeight = getUpgradeHeight("LOTUS_ACTORSV2_HEIGHT", UpgradeAssemblyHeight) + UpgradeLiftoffHeight = getUpgradeHeight("LOTUS_LIFTOFF_HEIGHT", UpgradeLiftoffHeight) + UpgradeKumquatHeight = getUpgradeHeight("LOTUS_KUMQUAT_HEIGHT", UpgradeKumquatHeight) + UpgradeCalicoHeight = getUpgradeHeight("LOTUS_CALICO_HEIGHT", UpgradeCalicoHeight) + UpgradePersianHeight = getUpgradeHeight("LOTUS_PERSIAN_HEIGHT", UpgradePersianHeight) + UpgradeOrangeHeight = getUpgradeHeight("LOTUS_ORANGE_HEIGHT", UpgradeOrangeHeight) + UpgradeClausHeight = getUpgradeHeight("LOTUS_CLAUS_HEIGHT", UpgradeClausHeight) + UpgradeTrustHeight = getUpgradeHeight("LOTUS_ACTORSV3_HEIGHT", UpgradeTrustHeight) + UpgradeNorwegianHeight = getUpgradeHeight("LOTUS_NORWEGIAN_HEIGHT", UpgradeNorwegianHeight) + UpgradeTurboHeight = getUpgradeHeight("LOTUS_ACTORSV4_HEIGHT", UpgradeTurboHeight) + UpgradeHyperdriveHeight = getUpgradeHeight("LOTUS_HYPERDRIVE_HEIGHT", UpgradeHyperdriveHeight) + + BuildType |= BuildInteropnet + SetAddressNetwork(address.Testnet) + Devnet = true +} + +const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds) + +const PropagationDelaySecs = uint64(6) + +// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start +const BootstrapPeerThreshold = 2 + +var WhitelistedBlock = cid.Undef diff --git a/build/params_mainnet.go b/build/params_mainnet.go index 52c622479..e9bf33f5a 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -4,6 +4,7 @@ // +build !calibnet // +build !nerpanet // +build !butterflynet +// +build !interopnet package build diff --git a/build/version.go b/build/version.go index 12b1058b3..5a4a494fc 100644 --- a/build/version.go +++ b/build/version.go @@ -6,11 +6,12 @@ var CurrentCommit string var BuildType int const ( - BuildDefault = 0 - BuildMainnet = 0x1 - Build2k = 0x2 - BuildDebug = 0x3 - BuildCalibnet = 0x4 + BuildDefault = 0 + BuildMainnet = 0x1 + Build2k = 0x2 + BuildDebug = 0x3 + BuildCalibnet = 0x4 + BuildInteropnet = 0x5 ) func buildType() string { @@ -25,6 +26,8 @@ func buildType() string { return "+debug" case BuildCalibnet: return "+calibnet" + case BuildInteropnet: + return "+interopnet" default: return "+huh?" } From e89e0679b51ce592719572ed7e4c4beff8d5065b Mon Sep 17 00:00:00 2001 From: Travis Person Date: Thu, 3 Jun 2021 23:27:45 +0000 Subject: [PATCH 18/66] Interop genesis --- build/genesis/interopnet.car | Bin 0 -> 1000900 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 build/genesis/interopnet.car diff --git a/build/genesis/interopnet.car b/build/genesis/interopnet.car new file mode 100644 index 0000000000000000000000000000000000000000..80ecd6e7297006f9f2530d286d26367fe5697ccb GIT binary patch literal 1000900 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

C+b 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

WURuBds*7@0&{N6Soe9ZP$7ahk^!H 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

ELJ3BiwI~&B& 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

8;z>;j@xLcchl9?9 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 VC#DINqwq7K_mSuTD*gX~{y+aa9_s)A literal 0 HcmV?d00001 From 0fba816846c4badddd166c71b0bd0f27765095a2 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Thu, 3 Jun 2021 20:45:54 -0700 Subject: [PATCH 19/66] publish on snap --- .circleci/config.yml | 64 +++++++++++++++++++++++++++++++++++++++----- snap/snapcraft.yaml | 36 +++++++++++++++---------- 2 files changed, 79 insertions(+), 21 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d59939096..830014409 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -530,6 +530,34 @@ jobs: name: Publish release command: ./scripts/publish-release.sh + publish-snapcraft: + description: build and push snapcraft + machine: + image: ubuntu-2004:202104-01 + resource_class: 2xlarge + parameters: + channel: + type: string + default: "edge" + description: snapcraft channel + steps: + - checkout + - run: + name: install snapcraft + command: sudo snap install snapcraft --classic + - run: + name: create snapcraft config file + command: | + mkdir -p ~/.config/snapcraft + echo "$SNAPCRAFT_LOGIN_FILE" | base64 -d > ~/.config/snapcraft/snapcraft.cfg + - run: + name: build snap + command: snapcraft --use-lxd + - run: + name: publish snap + command: snapcraft push *.snap --release << parameters.channel >> + + build-and-push-image: description: build and push docker images to public AWS ECR registry executor: aws-cli/default @@ -766,13 +794,13 @@ workflows: only: - master - build-debug - - build-all: - requires: - - test-short - filters: - tags: - only: - - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-all + # requires: + # - test-short + # filters: + # tags: + # only: + # - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-ntwk-calibration: requires: - test-short @@ -861,3 +889,25 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - publish-snapcraft: + name: publish-snapcraft-stable + channel: stable + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + nightly: + triggers: + - schedule: + cron: "0 0 * * *" + filters: + branches: + only: + - master + jobs: + - publish-snapcraft: + name: publish-snapcraft-nightly + channel: edge diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 7cdc1746d..9a699439d 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,28 +1,36 @@ -name: lotus -base: core18 -version: '1.8.0' +name: lotus-filecoin +base: core20 +version: latest summary: filecoin daemon/client description: | Filecoin is a peer-to-peer network that stores files on the internet with built-in economic incentives to ensure files are stored reliably over time grade: devel -confinement: devmode # use 'strict' once you have the right plugs and slots +confinement: strict parts: - libs: - plugin: dump + lotus: + plugin: make source: ./ - organize: - 'lotus' : bin/ - 'lotus-*' : bin/ + build-snaps: + - go + - rustup + build-packages: + - git + - jq + - libhwloc-dev + - ocl-icd-opencl-dev + - pkg-config stage-packages: + - libhwloc15 - ocl-icd-libopencl1 - - libhwloc1 - - libgcc1 + override-build: | + LDFLAGS="" make lotus lotus-miner lotus-worker + cp lotus lotus-miner lotus-worker $SNAPCRAFT_PART_INSTALL apps: lotus: - command: bin/lotus + command: lotus lotus-miner: - command: bin/lotus-miner + command: lotus-miner lotus-worker: - command: bin/lotus-worker + command: lotus-worker From 4dde67750c2f64e401aeb742669d4f6b984b3cc0 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Thu, 3 Jun 2021 20:47:07 -0700 Subject: [PATCH 20/66] uncomment build-all --- .circleci/config.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 830014409..1264e909b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -795,12 +795,12 @@ workflows: - master - build-debug - build-all - # requires: - # - test-short - # filters: - # tags: - # only: - # - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + requires: + - test-short + filters: + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-ntwk-calibration: requires: - test-short From 86ab3926c5e087fd31dabfad1a1ef2ff156617e9 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 4 Jun 2021 15:32:52 +0200 Subject: [PATCH 21/66] Add doc on gas balancing Signed-off-by: Jakub Sztandera --- documentation/misc/gas_balancing.md | 54 +++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 documentation/misc/gas_balancing.md diff --git a/documentation/misc/gas_balancing.md b/documentation/misc/gas_balancing.md new file mode 100644 index 000000000..64d9fcf0e --- /dev/null +++ b/documentation/misc/gas_balancing.md @@ -0,0 +1,54 @@ +## Gas Balancing + +The gas balancing process targets to set gas costs of syscalls to be in line with +10 gas per nanosecond on reference hardware. +The process can be either performed for all syscalls based on existing messages and chain or targeted +at single syscall. + +#### Reference hardware + +The reference hardware is TR3970x with 128GB of RAM. This is what was available at the time and +may be subject to change. + +### Complete gas balancing + +Complete gas balancing is performed using `lotus-bench` the process is based on importing a chain export +and collecting gas traces which are later aggregated. + +Before building `lotus-bench` make sure `EnableGasTracing` in `chain/vm/runtime.go` is set to `true`. + +The process can be started using `./lotus-bench import` with `--car` flag set to the location of +CAR chain export. `--start-epoch` and `--end-epoch` can be used to to limit the range of epochs to run +the benchmark. Note that state tree of `start-epoch` needs to be in the CAR file or has to be previously computed +to work. + +The output will be a `bench.json` file containing information about every syscall invoked +and the time taken by these invocations. This file can grow to be quite big in size so make sure you have +spare space. + +After the bench run is complete the `bench.json` file can be analyzed with `./lotus-bench import analyze bench.json`. + +It will compute means, standard deviations and co-variances (when applicable) of syscall runtimes. +The output is in nanoseconds, so the gas values for syscalls should be 10x that. In cases where co-variance of +execution time to some parameter is evaluated, the strength of the correlation should be taken into account. + +#### Special cases + +OnImplPut compute gas is based on the flush time to disk of objects created, +during block execution (when gas traces are formed) objects are only written to memory. Use `vm/flush_copy_ms` and `vm/flush_copy_count` to estimate OnIpldPut compute cost. + + +### Targeted gas balancing + +In some cases complete gas balancing is infeasible, either new syscall gets introduced or +complete balancing is too time consuming. + +In these cases the recommended way to estimate gas for given syscall is to perform an `in-vivo` benchmark. +In the past `in-vitro` as in standalone benchmarks were found to be highly inaccurate when compared to results +of real execution. + +A in-vivo benchmark can be performed by running an example of such syscall during block execution. +The best place to hook-in such benchmark is message execution loop in +`chain/stmgr/stmgr.go` in `ApplyBlocks()`. Depending of time required to complete the syscall it might be +advisable to run the execution only once every few messages. + From 8733cea902fc80f51fc671714e1cc0650f01ffe1 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 31 Mar 2021 09:44:53 +0530 Subject: [PATCH 22/66] fix success handling in retreival --- cli/client.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/cli/client.go b/cli/client.go index 1dcd59e72..31435bc1c 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1195,14 +1195,21 @@ var clientRetrieveCmd = &cli.Command{ retrievalmarket.ClientEvents[evt.Event], retrievalmarket.DealStatuses[evt.Status], ) - } else { - afmt.Println("Success") - return nil } if evt.Err != "" { return xerrors.Errorf("retrieval failed: %s", evt.Err) } + + if !ok { + if evt.Status == retrievalmarket.DealStatusCompleted { + afmt.Println("Success") + return nil + } + + return xerrors.Errorf("saw final deal state %s instead of expected state DealStatusCompleted", retrievalmarket.DealStatuses[evt.Status]) + } + case <-ctx.Done(): return xerrors.Errorf("retrieval timed out") } From 182da9d4ef72ac0640f43fbb58e1908c9772343c Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 31 Mar 2021 10:52:17 +0530 Subject: [PATCH 23/66] fix error handling --- cli/client.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/client.go b/cli/client.go index 31435bc1c..c5d614421 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1204,10 +1204,10 @@ var clientRetrieveCmd = &cli.Command{ if !ok { if evt.Status == retrievalmarket.DealStatusCompleted { afmt.Println("Success") - return nil + } else { + afmt.Printf("saw final deal state %s instead of expected success state DealStatusCompleted", retrievalmarket.DealStatuses[evt.Status]) } - - return xerrors.Errorf("saw final deal state %s instead of expected state DealStatusCompleted", retrievalmarket.DealStatuses[evt.Status]) + return nil } case <-ctx.Done(): From ed4748e8acd1eb10d99f7f3a5d5073761dea3e18 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 2 Apr 2021 16:05:14 +0530 Subject: [PATCH 24/66] fix bug --- cli/client.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cli/client.go b/cli/client.go index c5d614421..f31b4dcfb 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1185,6 +1185,8 @@ var clientRetrieveCmd = &cli.Command{ return xerrors.Errorf("error setting up retrieval: %w", err) } + var prevStatus retrievalmarket.DealStatus + for { select { case evt, ok := <-updates: @@ -1195,6 +1197,7 @@ var clientRetrieveCmd = &cli.Command{ retrievalmarket.ClientEvents[evt.Event], retrievalmarket.DealStatuses[evt.Status], ) + prevStatus = evt.Status } if evt.Err != "" { @@ -1202,10 +1205,11 @@ var clientRetrieveCmd = &cli.Command{ } if !ok { - if evt.Status == retrievalmarket.DealStatusCompleted { + if prevStatus == retrievalmarket.DealStatusCompleted { afmt.Println("Success") } else { - afmt.Printf("saw final deal state %s instead of expected success state DealStatusCompleted", retrievalmarket.DealStatuses[evt.Status]) + afmt.Printf("saw final deal state %s instead of expected success state DealStatusCompleted", + retrievalmarket.DealStatuses[prevStatus]) } return nil } From 35a466f4c45376cf7cbf560cc2bba0b506b16762 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 2 Apr 2021 16:07:29 +0530 Subject: [PATCH 25/66] add new line --- cli/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/client.go b/cli/client.go index f31b4dcfb..4f2c58dc2 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1208,7 +1208,7 @@ var clientRetrieveCmd = &cli.Command{ if prevStatus == retrievalmarket.DealStatusCompleted { afmt.Println("Success") } else { - afmt.Printf("saw final deal state %s instead of expected success state DealStatusCompleted", + afmt.Printf("saw final deal state %s instead of expected success state DealStatusCompleted\n", retrievalmarket.DealStatuses[prevStatus]) } return nil From 52b90e4c9dd008172175a316608d58cf847f3db2 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Wed, 21 Apr 2021 16:39:41 +0200 Subject: [PATCH 26/66] test: offline deals --- api/test/deals.go | 108 ++++++++++++++++++++++++++++++++++++++++------ node/node_test.go | 6 +++ 2 files changed, 101 insertions(+), 13 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index aa7e23bcc..69870beb6 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -75,19 +75,7 @@ func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, } func CreateClientFile(ctx context.Context, client api.FullNode, rseed, size int) (*api.ImportRes, []byte, error) { - if size == 0 { - size = 1600 - } - data := make([]byte, size) - rand.New(rand.NewSource(int64(rseed))).Read(data) - - dir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-") - if err != nil { - return nil, nil, err - } - - path := filepath.Join(dir, "sourcefile.dat") - err = ioutil.WriteFile(path, data, 0644) + data, path, err := createRandomFile(rseed, size) if err != nil { return nil, nil, err } @@ -99,6 +87,27 @@ func CreateClientFile(ctx context.Context, client api.FullNode, rseed, size int) return res, data, nil } +func createRandomFile(rseed, size int) ([]byte, string, error) { + if size == 0 { + size = 1600 + } + data := make([]byte, size) + rand.New(rand.NewSource(int64(rseed))).Read(data) + + dir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-") + if err != nil { + return nil, "", err + } + + path := filepath.Join(dir, "sourcefile.dat") + err = ioutil.WriteFile(path, data, 0644) + if err != nil { + return nil, "", err + } + + return data, path, nil +} + func TestPublishDealsBatching(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) { publishPeriod := 10 * time.Second maxDealsPerMsg := uint64(2) @@ -382,6 +391,79 @@ func TestZeroPricePerByteRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime MakeDeal(t, s.ctx, 6, s.client, s.miner, false, false, startEpoch) } +func TestOfflineDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch, fastRet bool) { + s := setupOneClientOneMiner(t, b, blocktime) + defer s.blockMiner.Stop() + + // Create a random file + data, path, err := createRandomFile(1, 0) + require.NoError(t, err) + + // Import the file on the client + importRes, err := s.client.ClientImport(s.ctx, api.FileRef{Path: path}) + require.NoError(t, err) + + // Get the piece size and commP + fcid := importRes.Root + pieceInfo, err := s.client.ClientDealPieceCID(s.ctx, fcid) + require.NoError(t, err) + fmt.Println("FILE CID: ", fcid) + + // Create a storage deal with the miner + maddr, err := s.miner.ActorAddress(s.ctx) + require.NoError(t, err) + + addr, err := s.client.WalletDefaultAddress(s.ctx) + require.NoError(t, err) + + // Manual storage deal (offline deal) + dataRef := &storagemarket.DataRef{ + TransferType: storagemarket.TTManual, + Root: fcid, + PieceCid: &pieceInfo.PieceCID, + PieceSize: pieceInfo.PieceSize.Unpadded(), + } + + proposalCid, err := s.client.ClientStartDeal(s.ctx, &api.StartDealParams{ + Data: dataRef, + Wallet: addr, + Miner: maddr, + EpochPrice: types.NewInt(1000000), + DealStartEpoch: startEpoch, + MinBlocksDuration: uint64(build.MinDealDuration), + FastRetrieval: fastRet, + }) + require.NoError(t, err) + + // Wait for the deal to reach StorageDealCheckForAcceptance on the client + cd, err := s.client.ClientGetDealInfo(s.ctx, *proposalCid) + require.NoError(t, err) + require.Eventually(t, func() bool { + cd, _ := s.client.ClientGetDealInfo(s.ctx, *proposalCid) + return cd.State == storagemarket.StorageDealCheckForAcceptance + }, 1*time.Second, 100*time.Millisecond, "actual deal status is %s", storagemarket.DealStates[cd.State]) + + // Create a CAR file from the raw file + carFileDir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-car") + require.NoError(t, err) + carFilePath := filepath.Join(carFileDir, "out.car") + err = s.client.ClientGenCar(s.ctx, api.FileRef{Path: path}, carFilePath) + require.NoError(t, err) + + // Import the CAR file on the miner - this is the equivalent to + // transferring the file across the wire in a normal (non-offline) deal + err = s.miner.DealsImportData(s.ctx, *proposalCid, carFilePath) + require.NoError(t, err) + + // Wait for the deal to be published + waitDealPublished(t, s.ctx, s.miner, proposalCid) + + t.Logf("deal published, retrieving") + + // Retrieve the deal + testRetrieval(t, s.ctx, s.client, fcid, &pieceInfo.PieceCID, false, data) +} + func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, fcid cid.Cid, fastRet bool, startEpoch abi.ChainEpoch) *cid.Cid { maddr, err := miner.ActorAddress(ctx) if err != nil { diff --git a/node/node_test.go b/node/node_test.go index dcbc70469..7adc9352b 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -58,6 +58,12 @@ func TestAPIDealFlow(t *testing.T) { t.Run("TestPublishDealsBatching", func(t *testing.T) { test.TestPublishDealsBatching(t, builder.MockSbBuilder, blockTime, dealStartEpoch) }) + t.Run("TestOfflineDealFlow", func(t *testing.T) { + test.TestOfflineDealFlow(t, builder.MockSbBuilder, blockTime, dealStartEpoch, false) + }) + t.Run("TestOfflineDealFlowFastRetrieval", func(t *testing.T) { + test.TestOfflineDealFlow(t, builder.MockSbBuilder, blockTime, dealStartEpoch, true) + }) } func TestBatchDealInput(t *testing.T) { From 39f3384e7ca7b786b8827e1772ac9995903c3dee Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 4 Jun 2021 16:22:57 -0700 Subject: [PATCH 27/66] confine --- .circleci/config.yml | 4 ++++ snap/snapcraft.yaml | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1264e909b..95b44344c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -899,6 +899,10 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - publish-snapcraft: + name: publish-snapcraft-tmp + channel: edge + nightly: triggers: - schedule: diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 9a699439d..b13e6518a 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -27,10 +27,25 @@ parts: override-build: | LDFLAGS="" make lotus lotus-miner lotus-worker cp lotus lotus-miner lotus-worker $SNAPCRAFT_PART_INSTALL + +layout: + /var/tmp/filecoin-proof-parameters: + bind: $SNAP_DATA/var/tmp/filecoin-proof-parameters apps: lotus: command: lotus + plugs: + - network + - network-bind lotus-miner: command: lotus-miner + plugs: + - network + - network-bind + - opengl lotus-worker: command: lotus-worker + plugs: + - network + - network-bind + - opengl From c12318f41370f0d203cd6c2ac910cdbad2eeddf2 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 4 Jun 2021 16:25:02 -0700 Subject: [PATCH 28/66] missing colon --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 95b44344c..0fba6e26b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -794,7 +794,7 @@ workflows: only: - master - build-debug - - build-all + - build-all: requires: - test-short filters: From 8b06f51fb460772755b733f78f491c5d51b7b81b Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 4 Jun 2021 16:47:06 -0700 Subject: [PATCH 29/66] vartmp --- snap/snapcraft.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index b13e6518a..4071e6254 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -29,8 +29,8 @@ parts: cp lotus lotus-miner lotus-worker $SNAPCRAFT_PART_INSTALL layout: - /var/tmp/filecoin-proof-parameters: - bind: $SNAP_DATA/var/tmp/filecoin-proof-parameters + /var/tmp + symlink: $SNAP_DATA/var/tmp apps: lotus: command: lotus From 10632d01315ed40609d9d77625361e1ce9bac30a Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 4 Jun 2021 16:50:23 -0700 Subject: [PATCH 30/66] missing colon --- snap/snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 4071e6254..8182f6548 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -29,7 +29,7 @@ parts: cp lotus lotus-miner lotus-worker $SNAPCRAFT_PART_INSTALL layout: - /var/tmp + /var/tmp: symlink: $SNAP_DATA/var/tmp apps: lotus: From 3921ea6916cd0bb255ba1adca0e017090a5918f5 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 4 Jun 2021 20:13:37 -0700 Subject: [PATCH 31/66] add icon --- snap/local/icon.svg | 1 + snap/snapcraft.yaml | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 snap/local/icon.svg diff --git a/snap/local/icon.svg b/snap/local/icon.svg new file mode 100644 index 000000000..da992296a --- /dev/null +++ b/snap/local/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 8182f6548..033ae9f13 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -2,6 +2,7 @@ name: lotus-filecoin base: core20 version: latest summary: filecoin daemon/client +icon: snap/local/icon.svg description: | Filecoin is a peer-to-peer network that stores files on the internet with built-in economic incentives to ensure files are stored reliably over time @@ -28,24 +29,36 @@ parts: LDFLAGS="" make lotus lotus-miner lotus-worker cp lotus lotus-miner lotus-worker $SNAPCRAFT_PART_INSTALL -layout: - /var/tmp: - symlink: $SNAP_DATA/var/tmp apps: lotus: command: lotus plugs: - network - network-bind + environment: + FIL_PROOFS_PARAMETER_CACHE: $SNAP_USER_COMMON/filecoin-proof-parameters + LOTUS_PATH: $SNAP_USER_COMMON/lotus + LOTUS_MINER_PATH: $SNAP_USER_COMMON/lotus-miner + LOTUS_WORKER_PATH: $SNAP_USER_COMMON/lotus-worker lotus-miner: command: lotus-miner plugs: - network - network-bind - opengl + environment: + FIL_PROOFS_PARAMETER_CACHE: $SNAP_USER_COMMON/filecoin-proof-parameters + LOTUS_PATH: $SNAP_USER_COMMON/lotus + LOTUS_MINER_PATH: $SNAP_USER_COMMON/lotus-miner + LOTUS_WORKER_PATH: $SNAP_USER_COMMON/lotus-worker lotus-worker: command: lotus-worker plugs: - network - network-bind - opengl + environment: + FIL_PROOFS_PARAMETER_CACHE: $SNAP_USER_COMMON/filecoin-proof-parameters + LOTUS_PATH: $SNAP_USER_COMMON/lotus + LOTUS_MINER_PATH: $SNAP_USER_COMMON/lotus-miner + LOTUS_WORKER_PATH: $SNAP_USER_COMMON/lotus-worker From 52380fe7fccf87a1bd04b71aa0b4ab15a3dc48f1 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 4 Jun 2021 20:28:12 -0700 Subject: [PATCH 32/66] more detailed information --- snap/snapcraft.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 033ae9f13..7ece50699 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -3,9 +3,18 @@ base: core20 version: latest summary: filecoin daemon/client icon: snap/local/icon.svg +license: MIT/apache-2.0 description: | Filecoin is a peer-to-peer network that stores files on the internet with built-in economic incentives to ensure files are stored reliably over time + + For documentation and additional information, please see the following resources + + https://filecoin.io + https://fil.org + https://docs.filecoin.io + https://github.com/filecoin-project/lotus + grade: devel confinement: strict From 25080956a7b67097d6443e2041dca3a0633ca218 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 4 Jun 2021 20:35:55 -0700 Subject: [PATCH 33/66] rm license --- snap/snapcraft.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 7ece50699..457e4e8a0 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -3,7 +3,6 @@ base: core20 version: latest summary: filecoin daemon/client icon: snap/local/icon.svg -license: MIT/apache-2.0 description: | Filecoin is a peer-to-peer network that stores files on the internet with built-in economic incentives to ensure files are stored reliably over time From e61ff4153fae6e699056984abb3d6c4a5701294d Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 4 Jun 2021 20:52:12 -0700 Subject: [PATCH 34/66] spaces between urls --- snap/snapcraft.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 457e4e8a0..7e4f3d701 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -10,8 +10,11 @@ description: | For documentation and additional information, please see the following resources https://filecoin.io + https://fil.org + https://docs.filecoin.io + https://github.com/filecoin-project/lotus grade: devel From 02b35bf978d94aac51b562d33579480056ddf57d Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Sun, 6 Jun 2021 15:52:56 -0700 Subject: [PATCH 35/66] remove tmp publish --- .circleci/config.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0fba6e26b..d88dd8a64 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -899,9 +899,6 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - - publish-snapcraft: - name: publish-snapcraft-tmp - channel: edge nightly: triggers: From e4588aed5c0d258a68891da4dc0273ad2d779dba Mon Sep 17 00:00:00 2001 From: Lion Date: Mon, 7 Jun 2021 12:35:43 +0800 Subject: [PATCH 36/66] Fix the doc errors of the sealing config funcs --- node/modules/dtypes/miner.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index 16af48add..b7a1be2e1 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -74,10 +74,12 @@ type ConsiderUnverifiedStorageDealsConfigFunc func() (bool, error) // disable or enable unverified storage deal acceptance. type SetConsiderUnverifiedStorageDealsConfigFunc func(bool) error -// SetSealingDelay sets how long a sector waits for more deals before sealing begins. +// SetSealingConfigFunc is a function which is used to +// sets the sealing config. type SetSealingConfigFunc func(sealiface.Config) error -// GetSealingDelay returns how long a sector waits for more deals before sealing begins. +// GetSealingConfigFunc is a function which is used to +// get the sealing config. type GetSealingConfigFunc func() (sealiface.Config, error) // SetExpectedSealDurationFunc is a function which is used to set how long sealing is expected to take. From becc2465a5b3b18608e917be3a07c4f2c153133a Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Sun, 6 Jun 2021 23:07:59 -0700 Subject: [PATCH 37/66] homeplug --- snap/snapcraft.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 7e4f3d701..472621c2a 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -46,6 +46,7 @@ apps: plugs: - network - network-bind + - home environment: FIL_PROOFS_PARAMETER_CACHE: $SNAP_USER_COMMON/filecoin-proof-parameters LOTUS_PATH: $SNAP_USER_COMMON/lotus From c7c029ea91d801a8c2f26011fce888412e111e92 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Mon, 7 Jun 2021 11:27:29 +0200 Subject: [PATCH 38/66] testplans: lotus-soup: new images with filecoin-ffi ; use default WPoStChallengeWindow --- testplans/Makefile | 18 +++++++++--------- .../docker-images/Dockerfile.oni-buildbase | 2 +- .../docker-images/Dockerfile.oni-runtime-debug | 2 +- testplans/lotus-soup/init.go | 2 +- testplans/lotus-soup/manifest.toml | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/testplans/Makefile b/testplans/Makefile index 0bf685005..38f46baa8 100644 --- a/testplans/Makefile +++ b/testplans/Makefile @@ -6,18 +6,18 @@ download-proofs: go run github.com/filecoin-project/go-paramfetch/paramfetch 2048 ./docker-images/proof-parameters.json build-images: - docker build -t "iptestground/oni-buildbase:v14-lotus" -f "docker-images/Dockerfile.oni-buildbase" "docker-images" - docker build -t "iptestground/oni-runtime:v9" -f "docker-images/Dockerfile.oni-runtime" "docker-images" - docker build -t "iptestground/oni-runtime:v9-debug" -f "docker-images/Dockerfile.oni-runtime-debug" "docker-images" + docker build -t "iptestground/oni-buildbase:v15-lotus" -f "docker-images/Dockerfile.oni-buildbase" "docker-images" + docker build -t "iptestground/oni-runtime:v10" -f "docker-images/Dockerfile.oni-runtime" "docker-images" + docker build -t "iptestground/oni-runtime:v10-debug" -f "docker-images/Dockerfile.oni-runtime-debug" "docker-images" push-images: - docker push iptestground/oni-buildbase:v14-lotus - docker push iptestground/oni-runtime:v9 - docker push iptestground/oni-runtime:v9-debug + docker push iptestground/oni-buildbase:v15-lotus + docker push iptestground/oni-runtime:v10 + docker push iptestground/oni-runtime:v10-debug pull-images: - docker pull iptestground/oni-buildbase:v14-lotus - docker pull iptestground/oni-runtime:v9 - docker pull iptestground/oni-runtime:v9-debug + docker pull iptestground/oni-buildbase:v15-lotus + docker pull iptestground/oni-runtime:v10 + docker pull iptestground/oni-runtime:v10-debug .PHONY: download-proofs build-images push-images pull-images diff --git a/testplans/docker-images/Dockerfile.oni-buildbase b/testplans/docker-images/Dockerfile.oni-buildbase index 306d40f9a..265066537 100644 --- a/testplans/docker-images/Dockerfile.oni-buildbase +++ b/testplans/docker-images/Dockerfile.oni-buildbase @@ -4,7 +4,7 @@ FROM golang:${GO_VERSION}-buster RUN apt-get update && apt-get install -y ca-certificates llvm clang mesa-opencl-icd ocl-icd-opencl-dev jq gcc git pkg-config bzr libhwloc-dev -ARG FILECOIN_FFI_COMMIT=d82899449741ce190e950a3582ebe33806f018a9 +ARG FILECOIN_FFI_COMMIT=8b97bd8230b77bd32f4f27e4766a6d8a03b4e801 ARG FFI_DIR=/extern/filecoin-ffi RUN mkdir -p ${FFI_DIR} \ diff --git a/testplans/docker-images/Dockerfile.oni-runtime-debug b/testplans/docker-images/Dockerfile.oni-runtime-debug index 126ae8de7..856fcc1fc 100644 --- a/testplans/docker-images/Dockerfile.oni-runtime-debug +++ b/testplans/docker-images/Dockerfile.oni-runtime-debug @@ -12,7 +12,7 @@ RUN go get github.com/filecoin-project/go-paramfetch/paramfetch@master COPY /proof-parameters.json / RUN paramfetch 8388608 /proof-parameters.json -ARG LOTUS_COMMIT=7e25a811c3d80ea3e007a54aa1da089985110c2c +ARG LOTUS_COMMIT=b8deee048eaf850113e8626a73f64b17ba69a9f6 ## for debug purposes RUN apt update && apt install -y mesa-opencl-icd ocl-icd-opencl-dev gcc git bzr jq pkg-config libhwloc-dev curl && git clone https://github.com/filecoin-project/lotus.git && cd lotus/ && git checkout ${LOTUS_COMMIT} && make clean && make all && make install diff --git a/testplans/lotus-soup/init.go b/testplans/lotus-soup/init.go index 7eada2ed6..c20f5f2b8 100644 --- a/testplans/lotus-soup/init.go +++ b/testplans/lotus-soup/init.go @@ -42,7 +42,7 @@ func init() { // deadline when the challenge is available. // // This will auto-scale the proving period. - policy.SetWPoStChallengeWindow(abi.ChainEpoch(5)) + // policy.SetWPoStChallengeWindow(abi.ChainEpoch(5)) // commented-out until we enable PoSt faults tests // Number of epochs between publishing the precommit and when the challenge for interactive PoRep is drawn // used to ensure it is not predictable by miner. diff --git a/testplans/lotus-soup/manifest.toml b/testplans/lotus-soup/manifest.toml index fc58fbd5b..9f5a57444 100644 --- a/testplans/lotus-soup/manifest.toml +++ b/testplans/lotus-soup/manifest.toml @@ -9,8 +9,8 @@ enabled = true [builders."docker:go"] enabled = true -build_base_image = "iptestground/oni-buildbase:v14-lotus" -runtime_image = "iptestground/oni-runtime:v9-debug" +build_base_image = "iptestground/oni-buildbase:v15-lotus" +runtime_image = "iptestground/oni-runtime:v10-debug" [runners."local:exec"] enabled = true From 670835fca0a99be9e22f1283459b3eca7d4d1efa Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Tue, 18 May 2021 13:02:30 +0530 Subject: [PATCH 39/66] bypass task scheduler for reading unsealed pieces --- .../sector-storage/ffiwrapper/sealer_cgo.go | 19 +-- .../ffiwrapper/unseal_ranges.go | 3 +- extern/sector-storage/fr32/readers.go | 7 +- extern/sector-storage/manager.go | 99 +----------- .../partialfile.go | 41 ++--- extern/sector-storage/piece_provider.go | 117 ++++++++++++++ extern/sector-storage/stores/http_handler.go | 148 +++++++++++++++--- extern/sector-storage/stores/remote.go | 143 +++++++++++++++++ extern/sector-storage/storiface/ffi.go | 9 ++ markets/retrievaladapter/provider.go | 39 ++--- node/builder.go | 2 + node/modules/storageminer.go | 5 +- 12 files changed, 459 insertions(+), 173 deletions(-) rename extern/sector-storage/{ffiwrapper => partialfile}/partialfile.go (85%) create mode 100644 extern/sector-storage/piece_provider.go diff --git a/extern/sector-storage/ffiwrapper/sealer_cgo.go b/extern/sector-storage/ffiwrapper/sealer_cgo.go index 36fbacb30..10fcad6fd 100644 --- a/extern/sector-storage/ffiwrapper/sealer_cgo.go +++ b/extern/sector-storage/ffiwrapper/sealer_cgo.go @@ -11,6 +11,7 @@ import ( "os" "runtime" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -66,7 +67,7 @@ func (sb *Sealer) AddPiece(ctx context.Context, sector storage.SectorRef, existi } var done func() - var stagedFile *partialFile + var stagedFile *partialfile.PartialFile defer func() { if done != nil { @@ -87,7 +88,7 @@ func (sb *Sealer) AddPiece(ctx context.Context, sector storage.SectorRef, existi return abi.PieceInfo{}, xerrors.Errorf("acquire unsealed sector: %w", err) } - stagedFile, err = createPartialFile(maxPieceSize, stagedPath.Unsealed) + stagedFile, err = partialfile.CreatePartialFile(maxPieceSize, stagedPath.Unsealed) if err != nil { return abi.PieceInfo{}, xerrors.Errorf("creating unsealed sector file: %w", err) } @@ -97,7 +98,7 @@ func (sb *Sealer) AddPiece(ctx context.Context, sector storage.SectorRef, existi return abi.PieceInfo{}, xerrors.Errorf("acquire unsealed sector: %w", err) } - stagedFile, err = openPartialFile(maxPieceSize, stagedPath.Unsealed) + stagedFile, err = partialfile.OpenPartialFile(maxPieceSize, stagedPath.Unsealed) if err != nil { return abi.PieceInfo{}, xerrors.Errorf("opening unsealed sector file: %w", err) } @@ -257,7 +258,7 @@ func (sb *Sealer) UnsealPiece(ctx context.Context, sector storage.SectorRef, off // try finding existing unsealedPath, done, err := sb.sectors.AcquireSector(ctx, sector, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage) - var pf *partialFile + var pf *partialfile.PartialFile switch { case xerrors.Is(err, storiface.ErrSectorNotFound): @@ -267,7 +268,7 @@ func (sb *Sealer) UnsealPiece(ctx context.Context, sector storage.SectorRef, off } defer done() - pf, err = createPartialFile(maxPieceSize, unsealedPath.Unsealed) + pf, err = partialfile.CreatePartialFile(maxPieceSize, unsealedPath.Unsealed) if err != nil { return xerrors.Errorf("create unsealed file: %w", err) } @@ -275,7 +276,7 @@ func (sb *Sealer) UnsealPiece(ctx context.Context, sector storage.SectorRef, off case err == nil: defer done() - pf, err = openPartialFile(maxPieceSize, unsealedPath.Unsealed) + pf, err = partialfile.OpenPartialFile(maxPieceSize, unsealedPath.Unsealed) if err != nil { return xerrors.Errorf("opening partial file: %w", err) } @@ -427,7 +428,7 @@ func (sb *Sealer) ReadPiece(ctx context.Context, writer io.Writer, sector storag } maxPieceSize := abi.PaddedPieceSize(ssize) - pf, err := openPartialFile(maxPieceSize, path.Unsealed) + pf, err := partialfile.OpenPartialFile(maxPieceSize, path.Unsealed) if err != nil { if xerrors.Is(err, os.ErrNotExist) { return false, nil @@ -589,7 +590,7 @@ func (sb *Sealer) FinalizeSector(ctx context.Context, sector storage.SectorRef, if len(keepUnsealed) > 0 { - sr := pieceRun(0, maxPieceSize) + sr := partialfile.PieceRun(0, maxPieceSize) for _, s := range keepUnsealed { si := &rlepluslazy.RunSliceIterator{} @@ -611,7 +612,7 @@ func (sb *Sealer) FinalizeSector(ctx context.Context, sector storage.SectorRef, } defer done() - pf, err := openPartialFile(maxPieceSize, paths.Unsealed) + pf, err := partialfile.OpenPartialFile(maxPieceSize, paths.Unsealed) if err == nil { var at uint64 for sr.HasNext() { diff --git a/extern/sector-storage/ffiwrapper/unseal_ranges.go b/extern/sector-storage/ffiwrapper/unseal_ranges.go index 4519fc21e..bc39abde2 100644 --- a/extern/sector-storage/ffiwrapper/unseal_ranges.go +++ b/extern/sector-storage/ffiwrapper/unseal_ranges.go @@ -1,6 +1,7 @@ package ffiwrapper import ( + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" "golang.org/x/xerrors" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" @@ -17,7 +18,7 @@ const mergeGaps = 32 << 20 // TODO const expandRuns = 16 << 20 // unseal more than requested for future requests func computeUnsealRanges(unsealed rlepluslazy.RunIterator, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (rlepluslazy.RunIterator, error) { - todo := pieceRun(offset.Padded(), size.Padded()) + todo := partialfile.PieceRun(offset.Padded(), size.Padded()) todo, err := rlepluslazy.Subtract(todo, unsealed) if err != nil { return nil, xerrors.Errorf("compute todo-unsealed: %w", err) diff --git a/extern/sector-storage/fr32/readers.go b/extern/sector-storage/fr32/readers.go index 20f3e9b31..f14d5bf1c 100644 --- a/extern/sector-storage/fr32/readers.go +++ b/extern/sector-storage/fr32/readers.go @@ -51,13 +51,12 @@ func (r *unpadReader) Read(out []byte) (int, error) { r.left -= uint64(todo) - n, err := r.src.Read(r.work[:todo]) + n, err := io.ReadAtLeast(r.src, r.work[:todo], int(todo)) if err != nil && err != io.EOF { return n, err } - - if n != int(todo) { - return 0, xerrors.Errorf("didn't read enough: %w", err) + if n < int(todo) { + return 0, xerrors.Errorf("didn't read enough: %d / %d, left %d, out %d", n, todo, r.left, len(out)) } Unpad(r.work[:todo], out[:todo.Unpadded()]) diff --git a/extern/sector-storage/manager.go b/extern/sector-storage/manager.go index d3fef8533..c4026eb04 100644 --- a/extern/sector-storage/manager.go +++ b/extern/sector-storage/manager.go @@ -47,8 +47,6 @@ type Worker interface { } type SectorManager interface { - ReadPiece(context.Context, io.Writer, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error - ffiwrapper.StorageSealer storage.Prover storiface.WorkerReturn @@ -206,71 +204,7 @@ func (m *Manager) schedFetch(sector storage.SectorRef, ft storiface.SectorFileTy } } -func (m *Manager) readPiece(sink io.Writer, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, rok *bool) func(ctx context.Context, w Worker) error { - return func(ctx context.Context, w Worker) error { - log.Debugf("read piece data from sector %d, offset %d, size %d", sector.ID, offset, size) - r, err := m.waitSimpleCall(ctx)(w.ReadPiece(ctx, sink, sector, offset, size)) - if err != nil { - return err - } - if r != nil { - *rok = r.(bool) - } - log.Debugf("completed read piece data from sector %d, offset %d, size %d: read ok? %t", sector.ID, offset, size, *rok) - return nil - } -} - -func (m *Manager) tryReadUnsealedPiece(ctx context.Context, sink io.Writer, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (foundUnsealed bool, readOk bool, selector WorkerSelector, returnErr error) { - - // acquire a lock purely for reading unsealed sectors - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - log.Debugf("acquire read sector lock for sector %d", sector.ID) - if err := m.index.StorageLock(ctx, sector.ID, storiface.FTUnsealed, storiface.FTNone); err != nil { - returnErr = xerrors.Errorf("acquiring read sector lock: %w", err) - return - } - - log.Debugf("find unsealed sector %d", sector.ID) - // passing 0 spt because we only need it when allowFetch is true - best, err := m.index.StorageFindSector(ctx, sector.ID, storiface.FTUnsealed, 0, false) - if err != nil { - returnErr = xerrors.Errorf("read piece: checking for already existing unsealed sector: %w", err) - return - } - - foundUnsealed = len(best) > 0 - if foundUnsealed { // append to existing - // There is unsealed sector, see if we can read from it - log.Debugf("found unsealed sector %d", sector.ID) - - selector = newExistingSelector(m.index, sector.ID, storiface.FTUnsealed, false) - - log.Debugf("scheduling read of unsealed sector %d", sector.ID) - err = m.sched.Schedule(ctx, sector, sealtasks.TTReadUnsealed, selector, m.schedFetch(sector, storiface.FTUnsealed, storiface.PathSealing, storiface.AcquireMove), - m.readPiece(sink, sector, offset, size, &readOk)) - if err != nil { - returnErr = xerrors.Errorf("reading piece from sealed sector: %w", err) - } - } else { - log.Debugf("did not find unsealed sector %d", sector.ID) - selector = newAllocSelector(m.index, storiface.FTUnsealed, storiface.PathSealing) - } - return -} - -func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) error { - log.Debugf("fetch and read piece in sector %d, offset %d, size %d", sector.ID, offset, size) - foundUnsealed, readOk, selector, err := m.tryReadUnsealedPiece(ctx, sink, sector, offset, size) - if err != nil { - return err - } - if readOk { - log.Debugf("completed read of unsealed piece in sector %d, offset %d, size %d", sector.ID, offset, size) - return nil - } +func (m *Manager) SectorsUnsealPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed *cid.Cid) error { ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -279,22 +213,16 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage. return xerrors.Errorf("acquiring unseal sector lock: %w", err) } - unsealFetch := func(ctx context.Context, worker Worker) error { + sealFetch := func(ctx context.Context, worker Worker) error { log.Debugf("copy sealed/cache sector data for sector %d", sector.ID) if _, err := m.waitSimpleCall(ctx)(worker.Fetch(ctx, sector, storiface.FTSealed|storiface.FTCache, storiface.PathSealing, storiface.AcquireCopy)); err != nil { return xerrors.Errorf("copy sealed/cache sector data: %w", err) } - if foundUnsealed { - log.Debugf("copy unsealed sector data for sector %d", sector.ID) - if _, err := m.waitSimpleCall(ctx)(worker.Fetch(ctx, sector, storiface.FTUnsealed, storiface.PathSealing, storiface.AcquireMove)); err != nil { - return xerrors.Errorf("copy unsealed sector data: %w", err) - } - } return nil } - if unsealed == cid.Undef { + if unsealed == nil { return xerrors.Errorf("cannot unseal piece (sector: %d, offset: %d size: %d) - unsealed cid is undefined", sector, offset, size) } @@ -303,15 +231,17 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage. return xerrors.Errorf("getting sector size: %w", err) } + selector := newExistingSelector(m.index, sector.ID, storiface.FTSealed|storiface.FTCache, true) + log.Debugf("schedule unseal for sector %d", sector.ID) - err = m.sched.Schedule(ctx, sector, sealtasks.TTUnseal, selector, unsealFetch, func(ctx context.Context, w Worker) error { + err = m.sched.Schedule(ctx, sector, sealtasks.TTUnseal, selector, sealFetch, func(ctx context.Context, w Worker) error { // TODO: make restartable // NOTE: we're unsealing the whole sector here as with SDR we can't really // unseal the sector partially. Requesting the whole sector here can // save us some work in case another piece is requested from here log.Debugf("unseal sector %d", sector.ID) - _, err := m.waitSimpleCall(ctx)(w.UnsealPiece(ctx, sector, 0, abi.PaddedPieceSize(ssize).Unpadded(), ticket, unsealed)) + _, err := m.waitSimpleCall(ctx)(w.UnsealPiece(ctx, sector, 0, abi.PaddedPieceSize(ssize).Unpadded(), ticket, *unsealed)) log.Debugf("completed unseal sector %d", sector.ID) return err }) @@ -319,20 +249,6 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage. return err } - selector = newExistingSelector(m.index, sector.ID, storiface.FTUnsealed, false) - - log.Debugf("schedule read piece for sector %d, offset %d, size %d", sector.ID, offset, size) - err = m.sched.Schedule(ctx, sector, sealtasks.TTReadUnsealed, selector, m.schedFetch(sector, storiface.FTUnsealed, storiface.PathSealing, storiface.AcquireMove), - m.readPiece(sink, sector, offset, size, &readOk)) - if err != nil { - return xerrors.Errorf("reading piece from sealed sector: %w", err) - } - - if !readOk { - return xerrors.Errorf("failed to read unsealed piece") - } - - log.Debugf("completed read of piece in sector %d, offset %d, size %d", sector.ID, offset, size) return nil } @@ -767,4 +683,5 @@ func (m *Manager) Close(ctx context.Context) error { return m.sched.Close(ctx) } +var _ Unsealer = &Manager{} var _ SectorManager = &Manager{} diff --git a/extern/sector-storage/ffiwrapper/partialfile.go b/extern/sector-storage/partialfile/partialfile.go similarity index 85% rename from extern/sector-storage/ffiwrapper/partialfile.go rename to extern/sector-storage/partialfile/partialfile.go index e19930ac1..2ef68de73 100644 --- a/extern/sector-storage/ffiwrapper/partialfile.go +++ b/extern/sector-storage/partialfile/partialfile.go @@ -1,4 +1,4 @@ -package ffiwrapper +package partialfile import ( "encoding/binary" @@ -7,6 +7,7 @@ import ( "syscall" "github.com/detailyang/go-fallocate" + logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" @@ -16,6 +17,8 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/storiface" ) +var log = logging.Logger("partialfile") + const veryLargeRle = 1 << 20 // Sectors can be partially unsealed. We support this by appending a small @@ -25,7 +28,7 @@ const veryLargeRle = 1 << 20 // unsealed sector files internally have this structure // [unpadded (raw) data][rle+][4B LE length fo the rle+ field] -type partialFile struct { +type PartialFile struct { maxPiece abi.PaddedPieceSize path string @@ -57,7 +60,7 @@ func writeTrailer(maxPieceSize int64, w *os.File, r rlepluslazy.RunIterator) err return w.Truncate(maxPieceSize + int64(rb) + 4) } -func createPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialFile, error) { +func CreatePartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*PartialFile, error) { f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644) // nolint if err != nil { return nil, xerrors.Errorf("openning partial file '%s': %w", path, err) @@ -89,10 +92,10 @@ func createPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialF return nil, xerrors.Errorf("close empty partial file: %w", err) } - return openPartialFile(maxPieceSize, path) + return OpenPartialFile(maxPieceSize, path) } -func openPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialFile, error) { +func OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*PartialFile, error) { f, err := os.OpenFile(path, os.O_RDWR, 0644) // nolint if err != nil { return nil, xerrors.Errorf("openning partial file '%s': %w", path, err) @@ -165,7 +168,7 @@ func openPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialFil return nil, err } - return &partialFile{ + return &PartialFile{ maxPiece: maxPieceSize, path: path, allocated: rle, @@ -173,11 +176,11 @@ func openPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialFil }, nil } -func (pf *partialFile) Close() error { +func (pf *PartialFile) Close() error { return pf.file.Close() } -func (pf *partialFile) Writer(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (io.Writer, error) { +func (pf *PartialFile) Writer(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (io.Writer, error) { if _, err := pf.file.Seek(int64(offset), io.SeekStart); err != nil { return nil, xerrors.Errorf("seek piece start: %w", err) } @@ -188,7 +191,7 @@ func (pf *partialFile) Writer(offset storiface.PaddedByteIndex, size abi.PaddedP return nil, err } - and, err := rlepluslazy.And(have, pieceRun(offset, size)) + and, err := rlepluslazy.And(have, PieceRun(offset, size)) if err != nil { return nil, err } @@ -206,13 +209,13 @@ func (pf *partialFile) Writer(offset storiface.PaddedByteIndex, size abi.PaddedP return pf.file, nil } -func (pf *partialFile) MarkAllocated(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) error { +func (pf *PartialFile) MarkAllocated(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) error { have, err := pf.allocated.RunIterator() if err != nil { return err } - ored, err := rlepluslazy.Or(have, pieceRun(offset, size)) + ored, err := rlepluslazy.Or(have, PieceRun(offset, size)) if err != nil { return err } @@ -224,7 +227,7 @@ func (pf *partialFile) MarkAllocated(offset storiface.PaddedByteIndex, size abi. return nil } -func (pf *partialFile) Free(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) error { +func (pf *PartialFile) Free(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) error { have, err := pf.allocated.RunIterator() if err != nil { return err @@ -234,7 +237,7 @@ func (pf *partialFile) Free(offset storiface.PaddedByteIndex, size abi.PaddedPie return xerrors.Errorf("deallocating: %w", err) } - s, err := rlepluslazy.Subtract(have, pieceRun(offset, size)) + s, err := rlepluslazy.Subtract(have, PieceRun(offset, size)) if err != nil { return err } @@ -246,7 +249,7 @@ func (pf *partialFile) Free(offset storiface.PaddedByteIndex, size abi.PaddedPie return nil } -func (pf *partialFile) Reader(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (*os.File, error) { +func (pf *PartialFile) Reader(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (*os.File, error) { if _, err := pf.file.Seek(int64(offset), io.SeekStart); err != nil { return nil, xerrors.Errorf("seek piece start: %w", err) } @@ -257,7 +260,7 @@ func (pf *partialFile) Reader(offset storiface.PaddedByteIndex, size abi.PaddedP return nil, err } - and, err := rlepluslazy.And(have, pieceRun(offset, size)) + and, err := rlepluslazy.And(have, PieceRun(offset, size)) if err != nil { return nil, err } @@ -275,17 +278,17 @@ func (pf *partialFile) Reader(offset storiface.PaddedByteIndex, size abi.PaddedP return pf.file, nil } -func (pf *partialFile) Allocated() (rlepluslazy.RunIterator, error) { +func (pf *PartialFile) Allocated() (rlepluslazy.RunIterator, error) { return pf.allocated.RunIterator() } -func (pf *partialFile) HasAllocated(offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { +func (pf *PartialFile) HasAllocated(offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { have, err := pf.Allocated() if err != nil { return false, err } - u, err := rlepluslazy.And(have, pieceRun(offset.Padded(), size.Padded())) + u, err := rlepluslazy.And(have, PieceRun(offset.Padded(), size.Padded())) if err != nil { return false, err } @@ -298,7 +301,7 @@ func (pf *partialFile) HasAllocated(offset storiface.UnpaddedByteIndex, size abi return abi.PaddedPieceSize(uc) == size.Padded(), nil } -func pieceRun(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) rlepluslazy.RunIterator { +func PieceRun(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) rlepluslazy.RunIterator { var runs []rlepluslazy.Run if offset > 0 { runs = append(runs, rlepluslazy.Run{ diff --git a/extern/sector-storage/piece_provider.go b/extern/sector-storage/piece_provider.go new file mode 100644 index 000000000..747d4c5c8 --- /dev/null +++ b/extern/sector-storage/piece_provider.go @@ -0,0 +1,117 @@ +package sectorstorage + +import ( + "bufio" + "context" + "io" + + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/specs-storage/storage" + + "github.com/filecoin-project/lotus/extern/sector-storage/fr32" + "github.com/filecoin-project/lotus/extern/sector-storage/stores" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" +) + +type Unsealer interface { + SectorsUnsealPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, commd *cid.Cid) error +} + +type PieceProvider interface { + ReadPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) (io.ReadCloser, bool, error) +} + +type pieceProvider struct { + storage *stores.Remote + index stores.SectorIndex + uns Unsealer +} + +func NewPieceProvider(storage *stores.Remote, index stores.SectorIndex, uns Unsealer) PieceProvider { + return &pieceProvider{ + storage: storage, + index: index, + uns: uns, + } +} + +func (p *pieceProvider) tryReadUnsealedPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (io.ReadCloser, context.CancelFunc, error) { + // acquire a lock purely for reading unsealed sectors + ctx, cancel := context.WithCancel(ctx) + if err := p.index.StorageLock(ctx, sector.ID, storiface.FTUnsealed, storiface.FTNone); err != nil { + cancel() + return nil, nil, xerrors.Errorf("acquiring read sector lock: %w", err) + } + + r, err := p.storage.Reader(ctx, sector, abi.PaddedPieceSize(offset.Padded()), size.Padded()) + if err != nil { + cancel() + return nil, nil, err + } + if r == nil { + cancel() + } + + return r, cancel, nil +} + +func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) (io.ReadCloser, bool, error) { + if err := offset.Valid(); err != nil { + return nil, false, xerrors.Errorf("offset is not valid: %w", err) + } + if err := size.Validate(); err != nil { + return nil, false, xerrors.Errorf("size is not a valid piece size: %w", err) + } + + r, unlock, err := p.tryReadUnsealedPiece(ctx, sector, offset, size) + if xerrors.Is(err, storiface.ErrSectorNotFound) { + err = nil + } + if err != nil { + return nil, false, err + } + + var uns bool + if r == nil { + uns = true + commd := &unsealed + if unsealed == cid.Undef { + commd = nil + } + if err := p.uns.SectorsUnsealPiece(ctx, sector, offset, size, ticket, commd); err != nil { + return nil, false, xerrors.Errorf("unsealing piece: %w", err) + } + + r, unlock, err = p.tryReadUnsealedPiece(ctx, sector, offset, size) + if err != nil { + return nil, true, xerrors.Errorf("read after unsealing: %w", err) + } + if r == nil { + return nil, true, xerrors.Errorf("got no reader after unsealing piece") + } + } + + upr, err := fr32.NewUnpadReader(r, size.Padded()) + if err != nil { + return nil, uns, xerrors.Errorf("creating unpadded reader: %w", err) + } + + return &funcCloser{ + Reader: bufio.NewReaderSize(upr, 127), + close: func() error { + err = r.Close() + unlock() + return err + }, + }, uns, nil +} + +type funcCloser struct { + io.Reader + close func() error +} + +func (fc *funcCloser) Close() error { return fc.close() } diff --git a/extern/sector-storage/stores/http_handler.go b/extern/sector-storage/stores/http_handler.go index 3e3468470..e11d853df 100644 --- a/extern/sector-storage/stores/http_handler.go +++ b/extern/sector-storage/stores/http_handler.go @@ -5,7 +5,10 @@ import ( "io" "net/http" "os" + "strconv" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" "github.com/gorilla/mux" logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" @@ -29,6 +32,8 @@ func (handler *FetchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/remote/{type}/{id}", handler.remoteGetSector).Methods("GET") mux.HandleFunc("/remote/{type}/{id}", handler.remoteDeleteSector).Methods("DELETE") + mux.HandleFunc("/remote/{type}/{id}/{spt}/allocated/{offset}/{size}", handler.remoteGetAllocated).Methods("GET") + mux.ServeHTTP(w, r) } @@ -73,7 +78,6 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ } // The caller has a lock on this sector already, no need to get one here - // passing 0 spt because we don't allocate anything si := storage.SectorRef{ ID: id, @@ -103,31 +107,29 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ return } - var rd io.Reader if stat.IsDir() { - rd, err = tarutil.TarDirectory(path) - w.Header().Set("Content-Type", "application/x-tar") - } else { - rd, err = os.OpenFile(path, os.O_RDONLY, 0644) // nolint - w.Header().Set("Content-Type", "application/octet-stream") - } - if err != nil { - log.Errorf("%+v", err) - w.WriteHeader(500) - return - } - if !stat.IsDir() { - defer func() { - if err := rd.(*os.File).Close(); err != nil { - log.Errorf("closing source file: %+v", err) - } - }() - } + if _, has := r.Header["Range"]; has { + log.Error("Range not supported on directories") + w.WriteHeader(500) + return + } - w.WriteHeader(200) - if _, err := io.CopyBuffer(w, rd, make([]byte, CopyBuf)); err != nil { - log.Errorf("%+v", err) - return + rd, err := tarutil.TarDirectory(path) + if err != nil { + log.Errorf("%+v", err) + w.WriteHeader(500) + return + } + + w.Header().Set("Content-Type", "application/x-tar") + w.WriteHeader(200) + if _, err := io.CopyBuffer(w, rd, make([]byte, CopyBuf)); err != nil { + log.Errorf("%+v", err) + return + } + } else { + w.Header().Set("Content-Type", "application/octet-stream") + http.ServeFile(w, r, path) } } @@ -156,6 +158,104 @@ func (handler *FetchHandler) remoteDeleteSector(w http.ResponseWriter, r *http.R } } +func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.Request) { + log.Infof("SERVE Alloc check %s", r.URL) + vars := mux.Vars(r) + + id, err := storiface.ParseSectorID(vars["id"]) + if err != nil { + log.Errorf("%+v", err) + w.WriteHeader(500) + return + } + + ft, err := ftFromString(vars["type"]) + if err != nil { + log.Errorf("%+v", err) + w.WriteHeader(500) + return + } + if ft != storiface.FTUnsealed { + log.Errorf("/allocated only supports unsealed sector files") + w.WriteHeader(500) + return + } + + spti, err := strconv.ParseInt(vars["spt"], 10, 64) + if err != nil { + log.Errorf("parsing spt: %+v", err) + w.WriteHeader(500) + return + } + spt := abi.RegisteredSealProof(spti) + ssize, err := spt.SectorSize() + if err != nil { + log.Errorf("%+v", err) + w.WriteHeader(500) + return + } + + offi, err := strconv.ParseInt(vars["offset"], 10, 64) + if err != nil { + log.Errorf("parsing offset: %+v", err) + w.WriteHeader(500) + return + } + szi, err := strconv.ParseInt(vars["size"], 10, 64) + if err != nil { + log.Errorf("parsing spt: %+v", err) + w.WriteHeader(500) + return + } + + // The caller has a lock on this sector already, no need to get one here + + // passing 0 spt because we don't allocate anything + si := storage.SectorRef{ + ID: id, + ProofType: 0, + } + + paths, _, err := handler.Local.AcquireSector(r.Context(), si, ft, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) + if err != nil { + log.Errorf("%+v", err) + w.WriteHeader(500) + return + } + + path := storiface.PathByType(paths, ft) + if path == "" { + log.Error("acquired path was empty") + w.WriteHeader(500) + return + } + + pf, err := partialfile.OpenPartialFile(abi.PaddedPieceSize(ssize), path) + if err != nil { + log.Error("opening partial file: ", err) + w.WriteHeader(500) + return + } + defer func() { + if err := pf.Close(); err != nil { + log.Error("close partial file: ", err) + } + }() + + has, err := pf.HasAllocated(storiface.UnpaddedByteIndex(offi), abi.UnpaddedPieceSize(szi)) + if err != nil { + log.Error("has allocated: ", err) + w.WriteHeader(500) + return + } + + if has { + w.WriteHeader(http.StatusOK) + return + } + w.WriteHeader(http.StatusRequestedRangeNotSatisfiable) +} + func ftFromString(t string) (storiface.SectorFileType, error) { switch t { case storiface.FTUnsealed.String(): diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index 4388a2ffb..b882eb052 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -3,6 +3,7 @@ package stores import ( "context" "encoding/json" + "fmt" "io" "io/ioutil" "math/bits" @@ -16,6 +17,7 @@ import ( "sync" "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" "github.com/filecoin-project/lotus/extern/sector-storage/storiface" "github.com/filecoin-project/lotus/extern/sector-storage/tarutil" @@ -415,4 +417,145 @@ func (r *Remote) FsStat(ctx context.Context, id ID) (fsutil.FsStat, error) { return out, nil } +func (r *Remote) checkAllocated(ctx context.Context, url string, spt abi.RegisteredSealProof, offset, size abi.PaddedPieceSize) (bool, error) { + url = fmt.Sprintf("%s/%d/allocated/%d/%d", url, spt, offset.Unpadded(), size.Unpadded()) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return false, xerrors.Errorf("request: %w", err) + } + req.Header = r.auth.Clone() + req = req.WithContext(ctx) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return false, xerrors.Errorf("do request: %w", err) + } + defer resp.Body.Close() // nolint + + switch resp.StatusCode { + case http.StatusOK: + return true, nil + case http.StatusRequestedRangeNotSatisfiable: + return false, nil + default: + return false, xerrors.Errorf("unexpected http response: %d", resp.StatusCode) + } +} + +func (r *Remote) readRemote(ctx context.Context, url string, offset, size abi.PaddedPieceSize) (io.ReadCloser, error) { + if len(r.limit) >= cap(r.limit) { + log.Infof("Throttling remote read, %d already running", len(r.limit)) + } + + // TODO: Smarter throttling + // * Priority (just going sequentially is still pretty good) + // * Per interface + // * Aware of remote load + select { + case r.limit <- struct{}{}: + defer func() { <-r.limit }() + case <-ctx.Done(): + return nil, xerrors.Errorf("context error while waiting for fetch limiter: %w", ctx.Err()) + } + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, xerrors.Errorf("request: %w", err) + } + req.Header = r.auth.Clone() + req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+size-1)) + req = req.WithContext(ctx) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, xerrors.Errorf("do request: %w", err) + } + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent { + resp.Body.Close() // nolint + return nil, xerrors.Errorf("non-200 code: %d", resp.StatusCode) + } + + return resp.Body, nil +} + +// Reader gets a reader for unsealed file range. Can return nil in case the requested range isn't allocated in the file +func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size abi.PaddedPieceSize) (io.ReadCloser, error) { + ft := storiface.FTUnsealed + + paths, _, err := r.local.AcquireSector(ctx, s, ft, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) + if err != nil { + return nil, xerrors.Errorf("acquire local: %w", err) + } + + path := storiface.PathByType(paths, ft) + var rd io.ReadCloser + if path == "" { + si, err := r.index.StorageFindSector(ctx, s.ID, ft, 0, false) + if err != nil { + return nil, err + } + + if len(si) == 0 { + return nil, xerrors.Errorf("failed to read sector %v from remote(%d): %w", s, ft, storiface.ErrSectorNotFound) + } + + // TODO Why are we sorting in ascending order here -> shouldn't we sort in descending order as higher weight means more preferred to store ? + sort.Slice(si, func(i, j int) bool { + return si[i].Weight < si[j].Weight + }) + + iloop: + for _, info := range si { + for _, url := range info.URLs { + ok, err := r.checkAllocated(ctx, url, s.ProofType, offset, size) + if err != nil { + log.Warnw("check if remote has piece", "url", url, "error", err) + continue + } + if !ok { + continue + } + + rd, err = r.readRemote(ctx, url, offset, size) + if err != nil { + log.Warnw("reading from remote", "url", url, "error", err) + continue + } + log.Infof("Read remote %s (+%d,%d)", url, offset, size) + break iloop + } + } + } else { + log.Infof("Read local %s (+%d,%d)", path, offset, size) + ssize, err := s.ProofType.SectorSize() + if err != nil { + return nil, err + } + + pf, err := partialfile.OpenPartialFile(abi.PaddedPieceSize(ssize), path) + if err != nil { + return nil, xerrors.Errorf("opening partial file: %w", err) + } + + has, err := pf.HasAllocated(storiface.UnpaddedByteIndex(offset.Unpadded()), size.Unpadded()) + if err != nil { + return nil, xerrors.Errorf("has allocated: %w", err) + } + + if !has { + if err := pf.Close(); err != nil { + return nil, xerrors.Errorf("close partial file: %w", err) + } + + return nil, nil + } + + return pf.Reader(storiface.PaddedByteIndex(offset), size) + } + + // note: rd can be nil + return rd, nil +} + var _ Store = &Remote{} diff --git a/extern/sector-storage/storiface/ffi.go b/extern/sector-storage/storiface/ffi.go index f6b2cbdd3..2b6df667a 100644 --- a/extern/sector-storage/storiface/ffi.go +++ b/extern/sector-storage/storiface/ffi.go @@ -5,6 +5,7 @@ import ( "errors" "github.com/ipfs/go-cid" + "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/abi" ) @@ -17,6 +18,14 @@ func (i UnpaddedByteIndex) Padded() PaddedByteIndex { return PaddedByteIndex(abi.UnpaddedPieceSize(i).Padded()) } +func (i UnpaddedByteIndex) Valid() error { + if i%127 != 0 { + return xerrors.Errorf("unpadded byte index must be a multiple of 127") + } + + return nil +} + type PaddedByteIndex uint64 type RGetter func(ctx context.Context, id abi.SectorID) (cid.Cid, error) diff --git a/markets/retrievaladapter/provider.go b/markets/retrievaladapter/provider.go index e58257c8a..c13a0b03d 100644 --- a/markets/retrievaladapter/provider.go +++ b/markets/retrievaladapter/provider.go @@ -5,6 +5,7 @@ import ( "io" "github.com/filecoin-project/lotus/api/v1api" + "golang.org/x/xerrors" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" @@ -25,15 +26,15 @@ import ( var log = logging.Logger("retrievaladapter") type retrievalProviderNode struct { - miner *storage.Miner - sealer sectorstorage.SectorManager - full v1api.FullNode + miner *storage.Miner + pp sectorstorage.PieceProvider + full v1api.FullNode } // NewRetrievalProviderNode returns a new node adapter for a retrieval provider that talks to the // Lotus Node -func NewRetrievalProviderNode(miner *storage.Miner, sealer sectorstorage.SectorManager, full v1api.FullNode) retrievalmarket.RetrievalProviderNode { - return &retrievalProviderNode{miner, sealer, full} +func NewRetrievalProviderNode(miner *storage.Miner, pp sectorstorage.PieceProvider, full v1api.FullNode) retrievalmarket.RetrievalProviderNode { + return &retrievalProviderNode{miner, pp, full} } func (rpn *retrievalProviderNode) GetMinerWorkerAddress(ctx context.Context, miner address.Address, tok shared.TipSetToken) (address.Address, error) { @@ -67,24 +68,18 @@ func (rpn *retrievalProviderNode) UnsealSector(ctx context.Context, sectorID abi ProofType: si.SectorType, } - // Set up a pipe so that data can be written from the unsealing process - // into the reader returned by this function - r, w := io.Pipe() - go func() { - var commD cid.Cid - if si.CommD != nil { - commD = *si.CommD - } + var commD cid.Cid + if si.CommD != nil { + commD = *si.CommD + } - // Read the piece into the pipe's writer, unsealing the piece if necessary - log.Debugf("read piece in sector %d, offset %d, length %d from miner %d", sectorID, offset, length, mid) - err := rpn.sealer.ReadPiece(ctx, w, ref, storiface.UnpaddedByteIndex(offset), length, si.TicketValue, commD) - if err != nil { - log.Errorf("failed to unseal piece from sector %d: %s", sectorID, err) - } - // Close the reader with any error that was returned while reading the piece - _ = w.CloseWithError(err) - }() + // Get a reader for the piece, unsealing the piece if necessary + log.Debugf("read piece in sector %d, offset %d, length %d from miner %d", sectorID, offset, length, mid) + r, unsealed, err := rpn.pp.ReadPiece(ctx, ref, storiface.UnpaddedByteIndex(offset), length, si.TicketValue, commD) + if err != nil { + return nil, xerrors.Errorf("failed to unseal piece from sector %d: %w", sectorID, err) + } + _ = unsealed // todo: use return r, nil } diff --git a/node/builder.go b/node/builder.go index 9d9c81a85..94f6c2e1e 100644 --- a/node/builder.go +++ b/node/builder.go @@ -378,6 +378,7 @@ var MinerNode = Options( Override(new(*sectorstorage.Manager), modules.SectorStorage), Override(new(sectorstorage.SectorManager), From(new(*sectorstorage.Manager))), Override(new(storiface.WorkerReturn), From(new(sectorstorage.SectorManager))), + Override(new(sectorstorage.Unsealer), From(new(*sectorstorage.Manager))), // Sector storage: Proofs Override(new(ffiwrapper.Verifier), ffiwrapper.ProofVerifier), @@ -405,6 +406,7 @@ var MinerNode = Options( Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks), // Markets (retrieval) + Override(new(sectorstorage.PieceProvider), sectorstorage.NewPieceProvider), Override(new(retrievalmarket.RetrievalProvider), modules.RetrievalProvider), Override(new(dtypes.RetrievalDealFilter), modules.RetrievalDealFilter(nil)), Override(HandleRetrievalKey, modules.HandleRetrieval), diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 711f1cbbe..dd9ad385c 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -643,11 +643,10 @@ func RetrievalProvider(h host.Host, pieceStore dtypes.ProviderPieceStore, mds dtypes.StagingMultiDstore, dt dtypes.ProviderDataTransfer, - onlineOk dtypes.ConsiderOnlineRetrievalDealsConfigFunc, - offlineOk dtypes.ConsiderOfflineRetrievalDealsConfigFunc, + pieceProvider sectorstorage.PieceProvider, userFilter dtypes.RetrievalDealFilter, ) (retrievalmarket.RetrievalProvider, error) { - adapter := retrievaladapter.NewRetrievalProviderNode(miner, sealer, full) + adapter := retrievaladapter.NewRetrievalProviderNode(miner, pieceProvider, full) maddr, err := minerAddrFromDS(ds) if err != nil { From 65eb610ec3116ae39c0aaa4d1783555a432f2921 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Tue, 18 May 2021 17:05:25 +0530 Subject: [PATCH 40/66] docs, logs and green ci --- cmd/lotus-storage-miner/init.go | 14 ++++++++-- extern/filecoin-ffi | 2 +- extern/sector-storage/manager.go | 20 ++++++++------ extern/sector-storage/piece_provider.go | 17 ++++++++++++ extern/sector-storage/stores/http_handler.go | 14 ++++++++++ extern/sector-storage/stores/remote.go | 28 +++++++++++++++++--- node/builder.go | 2 ++ node/modules/storageminer.go | 14 +++++++--- 8 files changed, 94 insertions(+), 17 deletions(-) diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 76451f418..2a50abc03 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -8,6 +8,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "net/http" "os" "path/filepath" "strconv" @@ -453,14 +454,23 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api v1api.FullNode wsts := statestore.New(namespace.Wrap(mds, modules.WorkerCallsPrefix)) smsts := statestore.New(namespace.Wrap(mds, modules.ManagerWorkPrefix)) - smgr, err := sectorstorage.New(ctx, lr, stores.NewIndex(), sectorstorage.SealerConfig{ + si := stores.NewIndex() + + lstor, err := stores.NewLocal(ctx, lr, si, nil) + if err != nil { + return err + } + stor := stores.NewRemote(lstor, si, http.Header(sa), 10) + + smgr, err := sectorstorage.New(ctx, lstor, stor, lr, si, sectorstorage.SealerConfig{ ParallelFetchLimit: 10, AllowAddPiece: true, AllowPreCommit1: true, AllowPreCommit2: true, AllowCommit: true, AllowUnseal: true, - }, nil, sa, wsts, smsts) + }, wsts, smsts) + if err != nil { return err } diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 8b97bd823..dc4e4e8dc 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 8b97bd8230b77bd32f4f27e4766a6d8a03b4e801 +Subproject commit dc4e4e8dc9554dedb6f48304f7f0c6328331f9ec diff --git a/extern/sector-storage/manager.go b/extern/sector-storage/manager.go index c4026eb04..385f8175b 100644 --- a/extern/sector-storage/manager.go +++ b/extern/sector-storage/manager.go @@ -103,19 +103,13 @@ type StorageAuth http.Header type WorkerStateStore *statestore.StateStore type ManagerStateStore *statestore.StateStore -func New(ctx context.Context, ls stores.LocalStorage, si stores.SectorIndex, sc SealerConfig, urls URLs, sa StorageAuth, wss WorkerStateStore, mss ManagerStateStore) (*Manager, error) { - lstor, err := stores.NewLocal(ctx, ls, si, urls) - if err != nil { - return nil, err - } +func New(ctx context.Context, lstor *stores.Local, stor *stores.Remote, ls stores.LocalStorage, si stores.SectorIndex, sc SealerConfig, wss WorkerStateStore, mss ManagerStateStore) (*Manager, error) { prover, err := ffiwrapper.New(&readonlyProvider{stor: lstor, index: si}) if err != nil { return nil, xerrors.Errorf("creating prover instance: %w", err) } - stor := stores.NewRemote(lstor, si, http.Header(sa), sc.ParallelFetchLimit) - m := &Manager{ ls: ls, storage: stor, @@ -204,6 +198,10 @@ func (m *Manager) schedFetch(sector storage.SectorRef, ft storiface.SectorFileTy } } +// SectorsUnsealPiece will Unseal the Sealed sector file for the given sector. +// It will schedule the Unsealing task on a worker that either already has the sealed sector files or has space in +// one of it's sealing scratch spaces to store them after fetching them from another worker. +// If the chosen worker already has the Unsealed sector file, we will NOT Unseal the sealed sector file again. func (m *Manager) SectorsUnsealPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed *cid.Cid) error { ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -213,6 +211,8 @@ func (m *Manager) SectorsUnsealPiece(ctx context.Context, sector storage.SectorR return xerrors.Errorf("acquiring unseal sector lock: %w", err) } + // if the selected worker does NOT have the sealed files for the sector, instruct it to fetch it from a worker that has them and + // put it in the sealing scratch space. sealFetch := func(ctx context.Context, worker Worker) error { log.Debugf("copy sealed/cache sector data for sector %d", sector.ID) if _, err := m.waitSimpleCall(ctx)(worker.Fetch(ctx, sector, storiface.FTSealed|storiface.FTCache, storiface.PathSealing, storiface.AcquireCopy)); err != nil { @@ -231,6 +231,8 @@ func (m *Manager) SectorsUnsealPiece(ctx context.Context, sector storage.SectorR return xerrors.Errorf("getting sector size: %w", err) } + // selector will schedule the Unseal task on a worker that either already has the sealed sector files or has space in + // one of it's sealing scratch spaces to store them after fetching them from another worker. selector := newExistingSelector(m.index, sector.ID, storiface.FTSealed|storiface.FTCache, true) log.Debugf("schedule unseal for sector %d", sector.ID) @@ -241,12 +243,14 @@ func (m *Manager) SectorsUnsealPiece(ctx context.Context, sector storage.SectorR // unseal the sector partially. Requesting the whole sector here can // save us some work in case another piece is requested from here log.Debugf("unseal sector %d", sector.ID) + + // Note: This unsealed call will essentially become a no-op of the worker already has an Unsealed sector file for the given sector. _, err := m.waitSimpleCall(ctx)(w.UnsealPiece(ctx, sector, 0, abi.PaddedPieceSize(ssize).Unpadded(), ticket, *unsealed)) log.Debugf("completed unseal sector %d", sector.ID) return err }) if err != nil { - return err + return xerrors.Errorf("worker UnsealPiece call: %s", err) } return nil diff --git a/extern/sector-storage/piece_provider.go b/extern/sector-storage/piece_provider.go index 747d4c5c8..f4e7439cd 100644 --- a/extern/sector-storage/piece_provider.go +++ b/extern/sector-storage/piece_provider.go @@ -17,10 +17,12 @@ import ( ) type Unsealer interface { + // SectorsUnsealPiece will Unseal a Sealed sector file for the given sector. SectorsUnsealPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, commd *cid.Cid) error } type PieceProvider interface { + // ReadPiece is used to read an Unsealed piece at the given offset and of the given size from a Sector ReadPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) (io.ReadCloser, bool, error) } @@ -38,6 +40,10 @@ func NewPieceProvider(storage *stores.Remote, index stores.SectorIndex, uns Unse } } +// tryReadUnsealedPiece will try to read the unsealed piece from an existing unsealed sector file for the given sector from any worker that has it. +// It will NOT try to schedule an Unseal of a sealed sector file for the read. +// +// Will return a nil reader if the piece does NOT exist in any unsealed file/there is not unsealed file for the given sector on any of the workers. func (p *pieceProvider) tryReadUnsealedPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (io.ReadCloser, context.CancelFunc, error) { // acquire a lock purely for reading unsealed sectors ctx, cancel := context.WithCancel(ctx) @@ -58,6 +64,9 @@ func (p *pieceProvider) tryReadUnsealedPiece(ctx context.Context, sector storage return r, cancel, nil } +// ReadPiece is used to read an Unsealed piece at the given offset and of the given size from a Sector +// If an Unsealed sector file exists with the Piece Unsealed in it, we'll use that for the read. +// Otherwise, we will Unseal a Sealed sector file for the given sector and read the Unsealed piece from it. func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) (io.ReadCloser, bool, error) { if err := offset.Valid(); err != nil { return nil, false, xerrors.Errorf("offset is not valid: %w", err) @@ -68,6 +77,7 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, r, unlock, err := p.tryReadUnsealedPiece(ctx, sector, offset, size) if xerrors.Is(err, storiface.ErrSectorNotFound) { + log.Debugf("no unsealed sector file with unsealed piece, sector=%+v, offset=%d, size=%d", sector, offset, size) err = nil } if err != nil { @@ -85,6 +95,8 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, return nil, false, xerrors.Errorf("unsealing piece: %w", err) } + log.Debugf("unsealed a sector file to read the piece, sector=%+v, offset=%d, size=%d", sector, offset, size) + r, unlock, err = p.tryReadUnsealedPiece(ctx, sector, offset, size) if err != nil { return nil, true, xerrors.Errorf("read after unsealing: %w", err) @@ -92,6 +104,9 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, if r == nil { return nil, true, xerrors.Errorf("got no reader after unsealing piece") } + log.Debugf("got a reader to read unsealed piece, sector=%+v, offset=%d, size=%d", sector, offset, size) + } else { + log.Debugf("unsealed piece already exists, no need to unseal, sector=%+v, offset=%d, size=%d", sector, offset, size) } upr, err := fr32.NewUnpadReader(r, size.Padded()) @@ -99,6 +114,8 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, return nil, uns, xerrors.Errorf("creating unpadded reader: %w", err) } + log.Debugf("returning reader to read unsealed piece, sector=%+v, offset=%d, size=%d", sector, offset, size) + return &funcCloser{ Reader: bufio.NewReaderSize(upr, 127), close: func() error { diff --git a/extern/sector-storage/stores/http_handler.go b/extern/sector-storage/stores/http_handler.go index e11d853df..813943fac 100644 --- a/extern/sector-storage/stores/http_handler.go +++ b/extern/sector-storage/stores/http_handler.go @@ -59,6 +59,8 @@ func (handler *FetchHandler) remoteStatFs(w http.ResponseWriter, r *http.Request } } +// remoteGetSector returns the sector file/tared directory byte stream for the sectorID and sector file type sent in the request. +// returns an error if it does NOT have the required sector file/dir. func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Request) { log.Infof("SERVE GET %s", r.URL) vars := mux.Vars(r) @@ -129,8 +131,11 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ } } else { w.Header().Set("Content-Type", "application/octet-stream") + // will do a ranged read over the file at the given path if the caller has asked for a ranged read in the request headers. http.ServeFile(w, r, path) } + + log.Debugf("served sector file/dir, sectorID=%+v, fileType=%s, path=%s", id, ft, path) } func (handler *FetchHandler) remoteDeleteSector(w http.ResponseWriter, r *http.Request) { @@ -158,6 +163,9 @@ func (handler *FetchHandler) remoteDeleteSector(w http.ResponseWriter, r *http.R } } +// remoteGetAllocated returns `http.StatusOK` if the worker already has an Unsealed sector file +// containing the Unsealed piece sent in the request. +// returns `http.StatusRequestedRangeNotSatisfiable` otherwise. func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.Request) { log.Infof("SERVE Alloc check %s", r.URL) vars := mux.Vars(r) @@ -216,6 +224,8 @@ func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.R ProofType: 0, } + // get the path of the local Unsealed file for the given sector. + // return error if we do NOT have it. paths, _, err := handler.Local.AcquireSector(r.Context(), si, ft, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) if err != nil { log.Errorf("%+v", err) @@ -230,6 +240,7 @@ func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.R return } + // open the Unsealed file and check if it has the Unsealed sector for the piece at the given offset and size. pf, err := partialfile.OpenPartialFile(abi.PaddedPieceSize(ssize), path) if err != nil { log.Error("opening partial file: ", err) @@ -250,9 +261,12 @@ func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.R } if has { + log.Debugf("returning ok: worker has unsealed file with unsealed piece, sector:%+v, offset:%d, size:%d", id, offi, szi) w.WriteHeader(http.StatusOK) return } + + log.Debugf("returning StatusRequestedRangeNotSatisfiable: worker does NOT have unsealed file with unsealed piece, sector:%+v, offset:%d, size:%d", id, offi, szi) w.WriteHeader(http.StatusRequestedRangeNotSatisfiable) } diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index b882eb052..2d409268b 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -479,10 +479,19 @@ func (r *Remote) readRemote(ctx context.Context, url string, offset, size abi.Pa return resp.Body, nil } -// Reader gets a reader for unsealed file range. Can return nil in case the requested range isn't allocated in the file +// Reader returns a reader for an unsealed piece at the given offset in the given sector. +// If the Miner has the unsealed piece locally, it will return a reader that reads from the local copy. +// If the Miner does NOT have the unsealed piece locally, it will query all workers that have the unsealed sector file +// to know if they have the unsealed piece and will then read the unsealed piece data from a worker that has it. +// +// Returns a nil reader if : +// 1. no worker(local worker included) has an unsealed file for the given sector OR +// 2. no worker(local worker included) has the unsealed piece in their unsealed sector file. +// Will return a nil reader and a nil error in such a case. func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size abi.PaddedPieceSize) (io.ReadCloser, error) { ft := storiface.FTUnsealed + // check if we have the unsealed sector file locally paths, _, err := r.local.AcquireSector(ctx, s, ft, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) if err != nil { return nil, xerrors.Errorf("acquire local: %w", err) @@ -490,7 +499,11 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a path := storiface.PathByType(paths, ft) var rd io.ReadCloser + if path == "" { + // if we don't have the unsealed sector file locally, we'll first lookup the Miner Sector Store Index + // to determine which workers have the unsealed file and then query those workers to know + // if they have the unsealed piece in the unsealed sector file. si, err := r.index.StorageFindSector(ctx, s.ID, ft, 0, false) if err != nil { return nil, err @@ -500,7 +513,7 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a return nil, xerrors.Errorf("failed to read sector %v from remote(%d): %w", s, ft, storiface.ErrSectorNotFound) } - // TODO Why are we sorting in ascending order here -> shouldn't we sort in descending order as higher weight means more preferred to store ? + // TODO Why are we sorting in ascending order here -> shouldn't we sort in descending order as higher weight means more likely to have the file ? sort.Slice(si, func(i, j int) bool { return si[i].Weight < si[j].Weight }) @@ -508,6 +521,8 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a iloop: for _, info := range si { for _, url := range info.URLs { + // checkAllocated makes a JSON RPC query to a remote worker to determine if it has + // unsealed piece in their unsealed sector file. ok, err := r.checkAllocated(ctx, url, s.ProofType, offset, size) if err != nil { log.Warnw("check if remote has piece", "url", url, "error", err) @@ -517,6 +532,8 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a continue } + // readRemote fetches a reader that we can used to read the unsealed piece from the remote worker. + // It uses a ranged HTTP query to ensure we ONLY read the unsealed piece and not the entire unsealed file. rd, err = r.readRemote(ctx, url, offset, size) if err != nil { log.Warnw("reading from remote", "url", url, "error", err) @@ -527,17 +544,22 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a } } } else { + // if we have the unsealed file locally, return a reader that can be used to read the contents of the + // unsealed piece. log.Infof("Read local %s (+%d,%d)", path, offset, size) ssize, err := s.ProofType.SectorSize() if err != nil { return nil, err } + // open the unsealed sector file for the given sector size located at the given path. pf, err := partialfile.OpenPartialFile(abi.PaddedPieceSize(ssize), path) if err != nil { return nil, xerrors.Errorf("opening partial file: %w", err) } + // even though we have an unsealed file for the given sector, we still need to determine if we have the unsealed piece + // in the unsealed sector file. That is what `HasAllocated` checks for. has, err := pf.HasAllocated(storiface.UnpaddedByteIndex(offset.Unpadded()), size.Unpadded()) if err != nil { return nil, xerrors.Errorf("has allocated: %w", err) @@ -547,10 +569,10 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a if err := pf.Close(); err != nil { return nil, xerrors.Errorf("close partial file: %w", err) } - return nil, nil } + log.Debugf("returning piece reader for local unsealed piece sector=%+v, (offset=%d, size=%d)", s.ID, offset, size) return pf.Reader(storiface.PaddedByteIndex(offset), size) } diff --git a/node/builder.go b/node/builder.go index 94f6c2e1e..f05dd8164 100644 --- a/node/builder.go +++ b/node/builder.go @@ -375,6 +375,8 @@ var MinerNode = Options( Override(new(*stores.Index), stores.NewIndex), Override(new(stores.SectorIndex), From(new(*stores.Index))), Override(new(stores.LocalStorage), From(new(repo.LockedRepo))), + Override(new(*stores.Local), modules.LocalStorage), + Override(new(*stores.Remote), modules.RemoteStorage), Override(new(*sectorstorage.Manager), modules.SectorStorage), Override(new(sectorstorage.SectorManager), From(new(*sectorstorage.Manager))), Override(new(storiface.WorkerReturn), From(new(sectorstorage.SectorManager))), diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index dd9ad385c..14b6774c6 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -637,7 +637,6 @@ func RetrievalDealFilter(userFilter dtypes.RetrievalDealFilter) func(onlineOk dt // RetrievalProvider creates a new retrieval provider attached to the provider blockstore func RetrievalProvider(h host.Host, miner *storage.Miner, - sealer sectorstorage.SectorManager, full v1api.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, @@ -662,13 +661,22 @@ func RetrievalProvider(h host.Host, var WorkerCallsPrefix = datastore.NewKey("/worker/calls") var ManagerWorkPrefix = datastore.NewKey("/stmgr/calls") -func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, ls stores.LocalStorage, si stores.SectorIndex, sc sectorstorage.SealerConfig, urls sectorstorage.URLs, sa sectorstorage.StorageAuth, ds dtypes.MetadataDS) (*sectorstorage.Manager, error) { +func LocalStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, ls stores.LocalStorage, si stores.SectorIndex, urls sectorstorage.URLs) (*stores.Local, error) { + ctx := helpers.LifecycleCtx(mctx, lc) + return stores.NewLocal(ctx, ls, si, urls) +} + +func RemoteStorage(lstor *stores.Local, si stores.SectorIndex, sa sectorstorage.StorageAuth, sc sectorstorage.SealerConfig) *stores.Remote { + return stores.NewRemote(lstor, si, http.Header(sa), sc.ParallelFetchLimit) +} + +func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, lstor *stores.Local, stor *stores.Remote, ls stores.LocalStorage, si stores.SectorIndex, sc sectorstorage.SealerConfig, ds dtypes.MetadataDS) (*sectorstorage.Manager, error) { ctx := helpers.LifecycleCtx(mctx, lc) wsts := statestore.New(namespace.Wrap(ds, WorkerCallsPrefix)) smsts := statestore.New(namespace.Wrap(ds, ManagerWorkPrefix)) - sst, err := sectorstorage.New(ctx, ls, si, sc, urls, sa, wsts, smsts) + sst, err := sectorstorage.New(ctx, lstor, stor, ls, si, sc, wsts, smsts) if err != nil { return nil, err } From c853350bdf9c962183631bd7f7b581531091842b Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 19 May 2021 11:17:56 +0530 Subject: [PATCH 41/66] Apply suggestions from code review Co-authored-by: dirkmc --- extern/sector-storage/manager.go | 2 +- extern/sector-storage/piece_provider.go | 2 +- extern/sector-storage/stores/http_handler.go | 2 +- extern/sector-storage/stores/remote.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extern/sector-storage/manager.go b/extern/sector-storage/manager.go index 385f8175b..f9ebc083c 100644 --- a/extern/sector-storage/manager.go +++ b/extern/sector-storage/manager.go @@ -244,7 +244,7 @@ func (m *Manager) SectorsUnsealPiece(ctx context.Context, sector storage.SectorR // save us some work in case another piece is requested from here log.Debugf("unseal sector %d", sector.ID) - // Note: This unsealed call will essentially become a no-op of the worker already has an Unsealed sector file for the given sector. + // Note: This unseal piece call will essentially become a no-op if the worker already has an Unsealed sector file for the given sector. _, err := m.waitSimpleCall(ctx)(w.UnsealPiece(ctx, sector, 0, abi.PaddedPieceSize(ssize).Unpadded(), ticket, *unsealed)) log.Debugf("completed unseal sector %d", sector.ID) return err diff --git a/extern/sector-storage/piece_provider.go b/extern/sector-storage/piece_provider.go index f4e7439cd..acc799273 100644 --- a/extern/sector-storage/piece_provider.go +++ b/extern/sector-storage/piece_provider.go @@ -43,7 +43,7 @@ func NewPieceProvider(storage *stores.Remote, index stores.SectorIndex, uns Unse // tryReadUnsealedPiece will try to read the unsealed piece from an existing unsealed sector file for the given sector from any worker that has it. // It will NOT try to schedule an Unseal of a sealed sector file for the read. // -// Will return a nil reader if the piece does NOT exist in any unsealed file/there is not unsealed file for the given sector on any of the workers. +// Returns a nil reader if the piece does NOT exist in any unsealed file or there is no unsealed file for the given sector on any of the workers. func (p *pieceProvider) tryReadUnsealedPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (io.ReadCloser, context.CancelFunc, error) { // acquire a lock purely for reading unsealed sectors ctx, cancel := context.WithCancel(ctx) diff --git a/extern/sector-storage/stores/http_handler.go b/extern/sector-storage/stores/http_handler.go index 813943fac..fef054e7b 100644 --- a/extern/sector-storage/stores/http_handler.go +++ b/extern/sector-storage/stores/http_handler.go @@ -249,7 +249,7 @@ func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.R } defer func() { if err := pf.Close(); err != nil { - log.Error("close partial file: ", err) + log.Error("closing partial file: ", err) } }() diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index 2d409268b..dc556ad92 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -532,7 +532,7 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a continue } - // readRemote fetches a reader that we can used to read the unsealed piece from the remote worker. + // readRemote fetches a reader that we can use to read the unsealed piece from the remote worker. // It uses a ranged HTTP query to ensure we ONLY read the unsealed piece and not the entire unsealed file. rd, err = r.readRemote(ctx, url, offset, size) if err != nil { From db5c88196d39beba6ae479b9f2155d0259cbc5bb Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 19 May 2021 11:36:37 +0530 Subject: [PATCH 42/66] address review comments --- extern/sector-storage/piece_provider.go | 8 +++ extern/sector-storage/stores/remote.go | 95 +++++++++++++------------ 2 files changed, 56 insertions(+), 47 deletions(-) diff --git a/extern/sector-storage/piece_provider.go b/extern/sector-storage/piece_provider.go index acc799273..fd54d2166 100644 --- a/extern/sector-storage/piece_provider.go +++ b/extern/sector-storage/piece_provider.go @@ -52,6 +52,9 @@ func (p *pieceProvider) tryReadUnsealedPiece(ctx context.Context, sector storage return nil, nil, xerrors.Errorf("acquiring read sector lock: %w", err) } + // Reader returns a reader for an unsealed piece at the given offset in the given sector. + // The returned reader will be nil if none of the workers has an unsealed sector file containing + // the unsealed piece. r, err := p.storage.Reader(ctx, sector, abi.PaddedPieceSize(offset.Padded()), size.Padded()) if err != nil { cancel() @@ -85,7 +88,11 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, } var uns bool + if r == nil { + // a nil reader means that none of the workers has an unsealed sector file + // containing the unsealed piece. + // we now need to unseal a sealed sector file for the given sector to read the unsealed piece from it. uns = true commd := &unsealed if unsealed == cid.Undef { @@ -111,6 +118,7 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, upr, err := fr32.NewUnpadReader(r, size.Padded()) if err != nil { + unlock() return nil, uns, xerrors.Errorf("creating unpadded reader: %w", err) } diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index dc556ad92..a09c87761 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -498,52 +498,8 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a } path := storiface.PathByType(paths, ft) - var rd io.ReadCloser - if path == "" { - // if we don't have the unsealed sector file locally, we'll first lookup the Miner Sector Store Index - // to determine which workers have the unsealed file and then query those workers to know - // if they have the unsealed piece in the unsealed sector file. - si, err := r.index.StorageFindSector(ctx, s.ID, ft, 0, false) - if err != nil { - return nil, err - } - - if len(si) == 0 { - return nil, xerrors.Errorf("failed to read sector %v from remote(%d): %w", s, ft, storiface.ErrSectorNotFound) - } - - // TODO Why are we sorting in ascending order here -> shouldn't we sort in descending order as higher weight means more likely to have the file ? - sort.Slice(si, func(i, j int) bool { - return si[i].Weight < si[j].Weight - }) - - iloop: - for _, info := range si { - for _, url := range info.URLs { - // checkAllocated makes a JSON RPC query to a remote worker to determine if it has - // unsealed piece in their unsealed sector file. - ok, err := r.checkAllocated(ctx, url, s.ProofType, offset, size) - if err != nil { - log.Warnw("check if remote has piece", "url", url, "error", err) - continue - } - if !ok { - continue - } - - // readRemote fetches a reader that we can use to read the unsealed piece from the remote worker. - // It uses a ranged HTTP query to ensure we ONLY read the unsealed piece and not the entire unsealed file. - rd, err = r.readRemote(ctx, url, offset, size) - if err != nil { - log.Warnw("reading from remote", "url", url, "error", err) - continue - } - log.Infof("Read remote %s (+%d,%d)", url, offset, size) - break iloop - } - } - } else { + if path != "" { // if we have the unsealed file locally, return a reader that can be used to read the contents of the // unsealed piece. log.Infof("Read local %s (+%d,%d)", path, offset, size) @@ -576,8 +532,53 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a return pf.Reader(storiface.PaddedByteIndex(offset), size) } - // note: rd can be nil - return rd, nil + // --- We don't have the unsealed sector file locally + + // if we don't have the unsealed sector file locally, we'll first lookup the Miner Sector Store Index + // to determine which workers have the unsealed file and then query those workers to know + // if they have the unsealed piece in the unsealed sector file. + si, err := r.index.StorageFindSector(ctx, s.ID, ft, 0, false) + if err != nil { + return nil, err + } + + if len(si) == 0 { + return nil, xerrors.Errorf("failed to read sector %v from remote(%d): %w", s, ft, storiface.ErrSectorNotFound) + } + + // TODO Why are we sorting in ascending order here -> shouldn't we sort in descending order as higher weight means more likely to have the file ? + sort.Slice(si, func(i, j int) bool { + return si[i].Weight < si[j].Weight + }) + + for _, info := range si { + for _, url := range info.URLs { + // checkAllocated makes a JSON RPC query to a remote worker to determine if it has + // unsealed piece in their unsealed sector file. + ok, err := r.checkAllocated(ctx, url, s.ProofType, offset, size) + if err != nil { + log.Warnw("check if remote has piece", "url", url, "error", err) + continue + } + if !ok { + continue + } + + // readRemote fetches a reader that we can use to read the unsealed piece from the remote worker. + // It uses a ranged HTTP query to ensure we ONLY read the unsealed piece and not the entire unsealed file. + rd, err := r.readRemote(ctx, url, offset, size) + if err != nil { + log.Warnw("reading from remote", "url", url, "error", err) + continue + } + log.Infof("Read remote %s (+%d,%d)", url, offset, size) + return rd, nil + } + } + + // we couldn't find a unsealed file with the unsealed piece, will return a nil reader. + log.Debugf("returning nil reader, did not find unsealed piece for %+v (+%d,%d)", s, offset, size) + return nil, nil } var _ Store = &Remote{} From 759d8f090b708fcc8064c0ae5084c4e9dd20c772 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 19 May 2021 19:20:48 +0530 Subject: [PATCH 43/66] test http handler --- cmd/lotus-seal-worker/main.go | 2 +- extern/sector-storage/manager.go | 2 +- extern/sector-storage/stores/http_handler.go | 38 +- .../stores/http_handler_test.go | 437 ++++++++++++++++++ extern/sector-storage/stores/interface.go | 12 + .../stores/mocks/PartialFileHandler.go | 61 +++ extern/sector-storage/stores/mocks/Store.go | 115 +++++ 7 files changed, 654 insertions(+), 13 deletions(-) create mode 100644 extern/sector-storage/stores/http_handler_test.go create mode 100644 extern/sector-storage/stores/mocks/PartialFileHandler.go create mode 100644 extern/sector-storage/stores/mocks/Store.go diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index df00928a5..899d9bbee 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -364,7 +364,7 @@ var runCmd = &cli.Command{ remote := stores.NewRemote(localStore, nodeApi, sminfo.AuthHeader(), cctx.Int("parallel-fetch-limit")) - fh := &stores.FetchHandler{Local: localStore} + fh := &stores.FetchHandler{Local: localStore, PfHandler: &stores.DefaultPartialFileHandler{}} remoteHandler := func(w http.ResponseWriter, r *http.Request) { if !auth.HasPerm(r.Context(), nil, api.PermAdmin) { w.WriteHeader(401) diff --git a/extern/sector-storage/manager.go b/extern/sector-storage/manager.go index f9ebc083c..8041304a7 100644 --- a/extern/sector-storage/manager.go +++ b/extern/sector-storage/manager.go @@ -114,7 +114,7 @@ func New(ctx context.Context, lstor *stores.Local, stor *stores.Remote, ls store ls: ls, storage: stor, localStore: lstor, - remoteHnd: &stores.FetchHandler{Local: lstor}, + remoteHnd: &stores.FetchHandler{Local: lstor, PfHandler: &stores.DefaultPartialFileHandler{}}, index: si, sched: newScheduler(), diff --git a/extern/sector-storage/stores/http_handler.go b/extern/sector-storage/stores/http_handler.go index fef054e7b..57d48f613 100644 --- a/extern/sector-storage/stores/http_handler.go +++ b/extern/sector-storage/stores/http_handler.go @@ -21,8 +21,23 @@ import ( var log = logging.Logger("stores") +var _ partialFileHandler = &DefaultPartialFileHandler{} + +// DefaultPartialFileHandler is the default implementation of the partialFileHandler interface. +// This is probably the only implementation we'll ever use because the purpose of the +// interface to is to mock out partial file related functionality during testing. +type DefaultPartialFileHandler struct{} + +func (d *DefaultPartialFileHandler) OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialfile.PartialFile, error) { + return partialfile.OpenPartialFile(maxPieceSize, path) +} +func (d *DefaultPartialFileHandler) HasAllocated(pf *partialfile.PartialFile, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { + return pf.HasAllocated(offset, size) +} + type FetchHandler struct { - *Local + Local Store + PfHandler partialFileHandler } func (handler *FetchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // /remote/ @@ -88,7 +103,7 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ paths, _, err := handler.Local.AcquireSector(r.Context(), si, ft, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) if err != nil { - log.Errorf("%+v", err) + log.Errorf("AcquireSector: %+v", err) w.WriteHeader(500) return } @@ -104,7 +119,7 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ stat, err := os.Stat(path) if err != nil { - log.Errorf("%+v", err) + log.Errorf("os.Stat: %+v", err) w.WriteHeader(500) return } @@ -131,6 +146,7 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ } } else { w.Header().Set("Content-Type", "application/octet-stream") + w.WriteHeader(200) // will do a ranged read over the file at the given path if the caller has asked for a ranged read in the request headers. http.ServeFile(w, r, path) } @@ -156,7 +172,7 @@ func (handler *FetchHandler) remoteDeleteSector(w http.ResponseWriter, r *http.R return } - if err := handler.Remove(r.Context(), id, ft, false); err != nil { + if err := handler.Local.Remove(r.Context(), id, ft, false); err != nil { log.Errorf("%+v", err) w.WriteHeader(500) return @@ -172,14 +188,14 @@ func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.R id, err := storiface.ParseSectorID(vars["id"]) if err != nil { - log.Errorf("%+v", err) + log.Errorf("parsing sectorID: %+v", err) w.WriteHeader(500) return } ft, err := ftFromString(vars["type"]) if err != nil { - log.Errorf("%+v", err) + log.Errorf("ftFromString: %+v", err) w.WriteHeader(500) return } @@ -198,7 +214,7 @@ func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.R spt := abi.RegisteredSealProof(spti) ssize, err := spt.SectorSize() if err != nil { - log.Errorf("%+v", err) + log.Errorf("spt.SectorSize(): %+v", err) w.WriteHeader(500) return } @@ -211,7 +227,7 @@ func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.R } szi, err := strconv.ParseInt(vars["size"], 10, 64) if err != nil { - log.Errorf("parsing spt: %+v", err) + log.Errorf("parsing size: %+v", err) w.WriteHeader(500) return } @@ -228,7 +244,7 @@ func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.R // return error if we do NOT have it. paths, _, err := handler.Local.AcquireSector(r.Context(), si, ft, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) if err != nil { - log.Errorf("%+v", err) + log.Errorf("AcquireSector: %+v", err) w.WriteHeader(500) return } @@ -241,7 +257,7 @@ func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.R } // open the Unsealed file and check if it has the Unsealed sector for the piece at the given offset and size. - pf, err := partialfile.OpenPartialFile(abi.PaddedPieceSize(ssize), path) + pf, err := handler.PfHandler.OpenPartialFile(abi.PaddedPieceSize(ssize), path) if err != nil { log.Error("opening partial file: ", err) w.WriteHeader(500) @@ -253,7 +269,7 @@ func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.R } }() - has, err := pf.HasAllocated(storiface.UnpaddedByteIndex(offi), abi.UnpaddedPieceSize(szi)) + has, err := handler.PfHandler.HasAllocated(pf, storiface.UnpaddedByteIndex(offi), abi.UnpaddedPieceSize(szi)) if err != nil { log.Error("has allocated: ", err) w.WriteHeader(500) diff --git a/extern/sector-storage/stores/http_handler_test.go b/extern/sector-storage/stores/http_handler_test.go new file mode 100644 index 000000000..1e7aed4b2 --- /dev/null +++ b/extern/sector-storage/stores/http_handler_test.go @@ -0,0 +1,437 @@ +package stores_test + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "testing" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" + "github.com/filecoin-project/lotus/extern/sector-storage/stores" + "github.com/filecoin-project/lotus/extern/sector-storage/stores/mocks" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" + "github.com/filecoin-project/specs-storage/storage" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "golang.org/x/xerrors" +) + +func TestRemoteGetAllocated(t *testing.T) { + + emptyPartialFile := &partialfile.PartialFile{} + pfPath := "path" + expectedSectorRef := storage.SectorRef{ + ID: abi.SectorID{ + 123, + 123, + }, + ProofType: 0, + } + + validSectorName := fmt.Sprintf("s-t0%d-%d", 123, 123) + validSectorFileType := storiface.FTUnsealed.String() + validSectorType := "1" + sectorSize := abi.SealProofInfos[1].SectorSize + + validOffset := "100" + validOffsetInt := 100 + + validSize := "1000" + validSizeInt := 1000 + + type pieceInfo struct { + sectorName string + fileType string + sectorType string + + // piece info + offset string + size string + } + validPieceInfo := pieceInfo{ + sectorName: validSectorName, + fileType: validSectorFileType, + sectorType: validSectorType, + offset: validOffset, + size: validSize, + } + + tcs := map[string]struct { + piFnc func(pi *pieceInfo) + storeFnc func(s *mocks.Store) + pfFunc func(s *mocks.PartialFileHandler) + + // expectation + expectedStatusCode int + }{ + "fails when sector name is invalid": { + piFnc: func(pi *pieceInfo) { + pi.sectorName = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + }, + "fails when file type is invalid": { + piFnc: func(pi *pieceInfo) { + pi.fileType = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + }, + "fails when sector proof type is invalid": { + piFnc: func(pi *pieceInfo) { + pi.sectorType = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + }, + "fails when offset is invalid": { + piFnc: func(pi *pieceInfo) { + pi.offset = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + }, + "fails when size is invalid": { + piFnc: func(pi *pieceInfo) { + pi.size = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + }, + "fails when errors out during acquiring unsealed sector file": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.Store) { + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: "path", + }, + storiface.SectorPaths{}, xerrors.New("some error")) + }, + }, + "fails when unsealed sector file is not found locally": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.Store) { + + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{}, + storiface.SectorPaths{}, nil) + }, + }, + "fails when partial file is not found locally": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.Store) { + // will return emppty paths + + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: pfPath, + }, + storiface.SectorPaths{}, nil) + }, + + pfFunc: func(pf *mocks.PartialFileHandler) { + //OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) + pf.On("OpenPartialFile", abi.PaddedPieceSize(sectorSize), pfPath).Return(&partialfile.PartialFile{}, + xerrors.New("some error")) + }, + }, + + "fails when determining partial file allocation returns an error": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.Store) { + // will return emppty paths + + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: pfPath, + }, + storiface.SectorPaths{}, nil) + }, + + pfFunc: func(pf *mocks.PartialFileHandler) { + pf.On("OpenPartialFile", abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, + nil) + pf.On("HasAllocated", emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), + abi.UnpaddedPieceSize(validSizeInt)).Return(true, xerrors.New("some error")) + }, + }, + "StatusRequestedRangeNotSatisfiable when piece is NOT allocated in partial file": { + expectedStatusCode: http.StatusRequestedRangeNotSatisfiable, + storeFnc: func(l *mocks.Store) { + // will return emppty paths + + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: pfPath, + }, + storiface.SectorPaths{}, nil) + }, + + pfFunc: func(pf *mocks.PartialFileHandler) { + pf.On("OpenPartialFile", abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, + nil) + pf.On("HasAllocated", emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), + abi.UnpaddedPieceSize(validSizeInt)).Return(false, nil) + }, + }, + "OK when piece is allocated in partial file": { + expectedStatusCode: http.StatusOK, + storeFnc: func(l *mocks.Store) { + // will return emppty paths + + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: pfPath, + }, + storiface.SectorPaths{}, nil) + }, + + pfFunc: func(pf *mocks.PartialFileHandler) { + pf.On("OpenPartialFile", abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, + nil) + pf.On("HasAllocated", emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), + abi.UnpaddedPieceSize(validSizeInt)).Return(true, nil) + }, + }, + } + + for name, tc := range tcs { + t.Run(name, func(t *testing.T) { + lstore := &mocks.Store{} + pfhandler := &mocks.PartialFileHandler{} + + handler := &stores.FetchHandler{ + lstore, + pfhandler, + } + + // run http server + ts := httptest.NewServer(handler) + defer ts.Close() + + pi := validPieceInfo + if tc.piFnc != nil { + tc.piFnc(&pi) + } + + if tc.storeFnc != nil { + tc.storeFnc(lstore) + } + if tc.pfFunc != nil { + tc.pfFunc(pfhandler) + } + + // call remoteGetAllocated + url := fmt.Sprintf("%s/remote/%s/%s/%s/allocated/%s/%s", + ts.URL, + pi.fileType, + pi.sectorName, + pi.sectorType, + pi.offset, + pi.size) + resp, err := http.Get(url) + require.NoError(t, err) + defer resp.Body.Close() + + // assert expected status code + require.Equal(t, tc.expectedStatusCode, resp.StatusCode) + + // assert expectations on the mocks + lstore.AssertExpectations(t) + }) + } +} + +func TestRemoteGetSector(t *testing.T) { + str := "hello-world" + fileBytes := []byte(str) + + validSectorName := fmt.Sprintf("s-t0%d-%d", 123, 123) + validSectorFileType := storiface.FTUnsealed.String() + expectedSectorRef := storage.SectorRef{ + ID: abi.SectorID{ + 123, + 123, + }, + ProofType: 0, + } + + type sectorInfo struct { + sectorName string + fileType string + } + validSectorInfo := sectorInfo{ + sectorName: validSectorName, + fileType: validSectorFileType, + } + + tcs := map[string]struct { + siFnc func(pi *sectorInfo) + storeFnc func(s *mocks.Store, path string) + + // reading a file or a dir + isDir bool + + // expectation + noResponseBytes bool + expectedContentType string + expectedStatusCode int + expectedResponseBytes []byte + }{ + "fails when sector name is invalid": { + siFnc: func(si *sectorInfo) { + si.sectorName = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + noResponseBytes: true, + }, + "fails when file type is invalid": { + siFnc: func(si *sectorInfo) { + si.fileType = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + noResponseBytes: true, + }, + "fails when error while acquiring sector file": { + storeFnc: func(l *mocks.Store, _ string) { + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: "path", + }, + storiface.SectorPaths{}, xerrors.New("some error")) + }, + expectedStatusCode: http.StatusInternalServerError, + noResponseBytes: true, + }, + "fails when acquired sector file path is empty": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.Store, _ string) { + + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{}, + storiface.SectorPaths{}, nil) + }, + noResponseBytes: true, + }, + "fails when acquired file does not exist": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.Store, _ string) { + + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: "path", + }, + storiface.SectorPaths{}, nil) + }, + noResponseBytes: true, + }, + "successfully read a sector file": { + storeFnc: func(l *mocks.Store, path string) { + + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: path, + }, + storiface.SectorPaths{}, nil) + }, + + noResponseBytes: false, + expectedContentType: "application/octet-stream", + expectedStatusCode: 200, + expectedResponseBytes: fileBytes, + }, + "successfully read a sector dir": { + storeFnc: func(l *mocks.Store, path string) { + + l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: path, + }, + storiface.SectorPaths{}, nil) + }, + + isDir: true, + noResponseBytes: false, + expectedContentType: "application/x-tar", + expectedStatusCode: 200, + expectedResponseBytes: fileBytes, + }, + } + + for name, tc := range tcs { + t.Run(name, func(t *testing.T) { + var path string + + if !tc.isDir { + // create file + tempFile, err := ioutil.TempFile("", "TestRemoteGetSector-") + require.NoError(t, err) + defer os.Remove(tempFile.Name()) + _, err = tempFile.Write(fileBytes) + require.NoError(t, err) + path = tempFile.Name() + } else { + // create dir with a file + tempFile2, err := ioutil.TempFile("", "TestRemoteGetSector-") + require.NoError(t, err) + defer os.Remove(tempFile2.Name()) + stat, err := os.Stat(tempFile2.Name()) + require.NoError(t, err) + tempDir, err := ioutil.TempDir("", "TestRemoteGetSector-") + require.NoError(t, err) + defer os.RemoveAll(tempDir) + require.NoError(t, os.Rename(tempFile2.Name(), filepath.Join(tempDir, stat.Name()))) + + path = tempDir + } + + lstore := &mocks.Store{} + pfhandler := &mocks.PartialFileHandler{} + + handler := &stores.FetchHandler{ + lstore, + pfhandler, + } + + // run http server + ts := httptest.NewServer(handler) + defer ts.Close() + + si := validSectorInfo + if tc.siFnc != nil { + tc.siFnc(&si) + } + + if tc.storeFnc != nil { + tc.storeFnc(lstore, path) + } + + // call remoteGetAllocated + url := fmt.Sprintf("%s/remote/%s/%s", + ts.URL, + si.fileType, + si.sectorName, + ) + resp, err := http.Get(url) + require.NoError(t, err) + defer resp.Body.Close() + + bz, err := ioutil.ReadAll(resp.Body) + require.NoError(t, err) + + // assert expected status code + require.Equal(t, tc.expectedStatusCode, resp.StatusCode) + + if !tc.noResponseBytes { + if !tc.isDir { + require.EqualValues(t, tc.expectedResponseBytes, bz) + } + } + + require.Equal(t, tc.expectedContentType, resp.Header.Get("Content-Type")) + + // assert expectations on the mocks + lstore.AssertExpectations(t) + }) + } +} diff --git a/extern/sector-storage/stores/interface.go b/extern/sector-storage/stores/interface.go index a997ad3d2..2c408cb0a 100644 --- a/extern/sector-storage/stores/interface.go +++ b/extern/sector-storage/stores/interface.go @@ -4,6 +4,7 @@ import ( "context" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" "github.com/filecoin-project/specs-storage/storage" @@ -11,6 +12,17 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/storiface" ) +// PartialFileHandler helps mock out the partial file functionality during testing. +type partialFileHandler interface { + // OpenPartialFile opens and returns a partial file at the given path and also verifies it has the given + // size + OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialfile.PartialFile, error) + + // HasAllocated returns true if the given partialfile has an unsealed piece starting at the given offset with the given size. + // returns false otherwise. + HasAllocated(pf *partialfile.PartialFile, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) +} + type Store interface { AcquireSector(ctx context.Context, s storage.SectorRef, existing storiface.SectorFileType, allocate storiface.SectorFileType, sealing storiface.PathType, op storiface.AcquireMode) (paths storiface.SectorPaths, stores storiface.SectorPaths, err error) Remove(ctx context.Context, s abi.SectorID, types storiface.SectorFileType, force bool) error diff --git a/extern/sector-storage/stores/mocks/PartialFileHandler.go b/extern/sector-storage/stores/mocks/PartialFileHandler.go new file mode 100644 index 000000000..d848732d6 --- /dev/null +++ b/extern/sector-storage/stores/mocks/PartialFileHandler.go @@ -0,0 +1,61 @@ +// Code generated by mockery 2.7.5. DO NOT EDIT. + +package mocks + +import ( + abi "github.com/filecoin-project/go-state-types/abi" + mock "github.com/stretchr/testify/mock" + + partialfile "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" + + storiface "github.com/filecoin-project/lotus/extern/sector-storage/storiface" +) + +// PartialFileHandler is an autogenerated mock type for the PartialFileHandler type +type PartialFileHandler struct { + mock.Mock +} + +// HasAllocated provides a mock function with given fields: pf, offset, size +func (_m *PartialFileHandler) HasAllocated(pf *partialfile.PartialFile, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { + ret := _m.Called(pf, offset, size) + + var r0 bool + if rf, ok := ret.Get(0).(func(*partialfile.PartialFile, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) bool); ok { + r0 = rf(pf, offset, size) + } else { + r0 = ret.Get(0).(bool) + } + + var r1 error + if rf, ok := ret.Get(1).(func(*partialfile.PartialFile, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error); ok { + r1 = rf(pf, offset, size) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OpenPartialFile provides a mock function with given fields: maxPieceSize, path +func (_m *PartialFileHandler) OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialfile.PartialFile, error) { + ret := _m.Called(maxPieceSize, path) + + var r0 *partialfile.PartialFile + if rf, ok := ret.Get(0).(func(abi.PaddedPieceSize, string) *partialfile.PartialFile); ok { + r0 = rf(maxPieceSize, path) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*partialfile.PartialFile) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(abi.PaddedPieceSize, string) error); ok { + r1 = rf(maxPieceSize, path) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/extern/sector-storage/stores/mocks/Store.go b/extern/sector-storage/stores/mocks/Store.go new file mode 100644 index 000000000..2be0a3075 --- /dev/null +++ b/extern/sector-storage/stores/mocks/Store.go @@ -0,0 +1,115 @@ +// Code generated by mockery 2.7.5. DO NOT EDIT. + +package mocks + +import ( + context "context" + + abi "github.com/filecoin-project/go-state-types/abi" + + fsutil "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" + + mock "github.com/stretchr/testify/mock" + + storage "github.com/filecoin-project/specs-storage/storage" + + stores "github.com/filecoin-project/lotus/extern/sector-storage/stores" + + storiface "github.com/filecoin-project/lotus/extern/sector-storage/storiface" +) + +// Store is an autogenerated mock type for the Store type +type Store struct { + mock.Mock +} + +// AcquireSector provides a mock function with given fields: ctx, s, existing, allocate, sealing, op +func (_m *Store) AcquireSector(ctx context.Context, s storage.SectorRef, existing storiface.SectorFileType, allocate storiface.SectorFileType, sealing storiface.PathType, op storiface.AcquireMode) (storiface.SectorPaths, storiface.SectorPaths, error) { + ret := _m.Called(ctx, s, existing, allocate, sealing, op) + + var r0 storiface.SectorPaths + if rf, ok := ret.Get(0).(func(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) storiface.SectorPaths); ok { + r0 = rf(ctx, s, existing, allocate, sealing, op) + } else { + r0 = ret.Get(0).(storiface.SectorPaths) + } + + var r1 storiface.SectorPaths + if rf, ok := ret.Get(1).(func(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) storiface.SectorPaths); ok { + r1 = rf(ctx, s, existing, allocate, sealing, op) + } else { + r1 = ret.Get(1).(storiface.SectorPaths) + } + + var r2 error + if rf, ok := ret.Get(2).(func(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) error); ok { + r2 = rf(ctx, s, existing, allocate, sealing, op) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// FsStat provides a mock function with given fields: ctx, id +func (_m *Store) FsStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) { + ret := _m.Called(ctx, id) + + var r0 fsutil.FsStat + if rf, ok := ret.Get(0).(func(context.Context, stores.ID) fsutil.FsStat); ok { + r0 = rf(ctx, id) + } else { + r0 = ret.Get(0).(fsutil.FsStat) + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, stores.ID) error); ok { + r1 = rf(ctx, id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MoveStorage provides a mock function with given fields: ctx, s, types +func (_m *Store) MoveStorage(ctx context.Context, s storage.SectorRef, types storiface.SectorFileType) error { + ret := _m.Called(ctx, s, types) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, storage.SectorRef, storiface.SectorFileType) error); ok { + r0 = rf(ctx, s, types) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Remove provides a mock function with given fields: ctx, s, types, force +func (_m *Store) Remove(ctx context.Context, s abi.SectorID, types storiface.SectorFileType, force bool) error { + ret := _m.Called(ctx, s, types, force) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, abi.SectorID, storiface.SectorFileType, bool) error); ok { + r0 = rf(ctx, s, types, force) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// RemoveCopies provides a mock function with given fields: ctx, s, types +func (_m *Store) RemoveCopies(ctx context.Context, s abi.SectorID, types storiface.SectorFileType) error { + ret := _m.Called(ctx, s, types) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, abi.SectorID, storiface.SectorFileType) error); ok { + r0 = rf(ctx, s, types) + } else { + r0 = ret.Error(0) + } + + return r0 +} From 74372d3e81e625b1435401a5b6d9ef41f7e12052 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 19 May 2021 19:39:37 +0530 Subject: [PATCH 44/66] fix linting problems --- .../stores/http_handler_test.go | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/extern/sector-storage/stores/http_handler_test.go b/extern/sector-storage/stores/http_handler_test.go index 1e7aed4b2..16703b465 100644 --- a/extern/sector-storage/stores/http_handler_test.go +++ b/extern/sector-storage/stores/http_handler_test.go @@ -26,8 +26,8 @@ func TestRemoteGetAllocated(t *testing.T) { pfPath := "path" expectedSectorRef := storage.SectorRef{ ID: abi.SectorID{ - 123, - 123, + Miner: 123, + Number: 123, }, ProofType: 0, } @@ -196,6 +196,7 @@ func TestRemoteGetAllocated(t *testing.T) { } for name, tc := range tcs { + tc := tc t.Run(name, func(t *testing.T) { lstore := &mocks.Store{} pfhandler := &mocks.PartialFileHandler{} @@ -210,6 +211,7 @@ func TestRemoteGetAllocated(t *testing.T) { defer ts.Close() pi := validPieceInfo + if tc.piFnc != nil { tc.piFnc(&pi) } @@ -231,7 +233,9 @@ func TestRemoteGetAllocated(t *testing.T) { pi.size) resp, err := http.Get(url) require.NoError(t, err) - defer resp.Body.Close() + defer func() { + _ = resp.Body.Close() + }() // assert expected status code require.Equal(t, tc.expectedStatusCode, resp.StatusCode) @@ -250,8 +254,8 @@ func TestRemoteGetSector(t *testing.T) { validSectorFileType := storiface.FTUnsealed.String() expectedSectorRef := storage.SectorRef{ ID: abi.SectorID{ - 123, - 123, + Miner: 123, + Number: 123, }, ProofType: 0, } @@ -359,6 +363,7 @@ func TestRemoteGetSector(t *testing.T) { } for name, tc := range tcs { + tc := tc t.Run(name, func(t *testing.T) { var path string @@ -366,7 +371,11 @@ func TestRemoteGetSector(t *testing.T) { // create file tempFile, err := ioutil.TempFile("", "TestRemoteGetSector-") require.NoError(t, err) - defer os.Remove(tempFile.Name()) + + defer func() { + _ = os.Remove(tempFile.Name()) + }() + _, err = tempFile.Write(fileBytes) require.NoError(t, err) path = tempFile.Name() @@ -374,12 +383,19 @@ func TestRemoteGetSector(t *testing.T) { // create dir with a file tempFile2, err := ioutil.TempFile("", "TestRemoteGetSector-") require.NoError(t, err) - defer os.Remove(tempFile2.Name()) + defer func() { + _ = os.Remove(tempFile2.Name()) + }() + stat, err := os.Stat(tempFile2.Name()) require.NoError(t, err) tempDir, err := ioutil.TempDir("", "TestRemoteGetSector-") require.NoError(t, err) - defer os.RemoveAll(tempDir) + + defer func() { + _ = os.RemoveAll(tempDir) + }() + require.NoError(t, os.Rename(tempFile2.Name(), filepath.Join(tempDir, stat.Name()))) path = tempDir @@ -414,7 +430,9 @@ func TestRemoteGetSector(t *testing.T) { ) resp, err := http.Get(url) require.NoError(t, err) - defer resp.Body.Close() + defer func() { + _ = resp.Body.Close() + }() bz, err := ioutil.ReadAll(resp.Body) require.NoError(t, err) From 6879ae9e6a72db11b68ddc06282fbddc1c781b5f Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Wed, 19 May 2021 14:36:13 -0600 Subject: [PATCH 45/66] feat: TestPieceProviderReadPiece --- extern/sector-storage/piece_provider_test.go | 118 +++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 extern/sector-storage/piece_provider_test.go diff --git a/extern/sector-storage/piece_provider_test.go b/extern/sector-storage/piece_provider_test.go new file mode 100644 index 000000000..08aadb78e --- /dev/null +++ b/extern/sector-storage/piece_provider_test.go @@ -0,0 +1,118 @@ +package sectorstorage + +import ( + "context" + "io/ioutil" + "strings" + "testing" + "time" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-statestore" + specstorage "github.com/filecoin-project/specs-storage/storage" + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/namespace" + ds_sync "github.com/ipfs/go-datastore/sync" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/lotus/extern/sector-storage/sealtasks" + "github.com/filecoin-project/lotus/extern/sector-storage/stores" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" +) + +// TestPieceProviderReadPiece verifies that the ReadPiece method works correctly +func TestPieceProviderReadPiece(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + defer cancel() + + runTest := func(t *testing.T, alreadyUnsealed bool) { + // Set up sector storage manager + storage := newTestStorage(t) + index := stores.NewIndex() + localStore, err := stores.NewLocal(ctx, storage, index, nil) + require.NoError(t, err) + remoteStore := stores.NewRemote(localStore, index, nil, 6000) + dstore := ds_sync.MutexWrap(datastore.NewMapDatastore()) + wsts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/worker/calls"))) + smsts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/stmgr/calls"))) + sealerCfg := SealerConfig{ + ParallelFetchLimit: 10, + AllowAddPiece: true, + AllowPreCommit1: true, + AllowPreCommit2: true, + AllowCommit: true, + AllowUnseal: true, + } + mgr, err := New(ctx, localStore, remoteStore, storage, index, sealerCfg, wsts, smsts) + require.NoError(t, err) + + // Set up worker + localTasks := []sealtasks.TaskType{ + sealtasks.TTAddPiece, sealtasks.TTPreCommit1, sealtasks.TTCommit1, sealtasks.TTFinalize, sealtasks.TTFetch, + } + testWorker := newTestWorker(WorkerConfig{ + TaskTypes: localTasks, + }, localStore, mgr) + err = mgr.AddWorker(ctx, testWorker) + require.NoError(t, err) + + // Create piece provider + pp := NewPieceProvider(remoteStore, index, mgr) + + // Mock sector + sector := specstorage.SectorRef{ + ID: abi.SectorID{ + Miner: 1000, + Number: 1, + }, + ProofType: abi.RegisteredSealProof_StackedDrg8MiBV1, + } + + // Create some data that when padded will be 8MB + pieceData := strings.Repeat("testthis", 127*1024*8) + size := abi.UnpaddedPieceSize(len(pieceData)) + pieceInfo, err := mgr.AddPiece(ctx, sector, nil, size, strings.NewReader(pieceData)) + require.NoError(t, err) + + // pre-commit 1 + pieces := []abi.PieceInfo{pieceInfo} + ticket := abi.SealRandomness{9, 9, 9, 9, 9, 9, 9, 9} + preCommit1, err := mgr.SealPreCommit1(ctx, sector, ticket, pieces) + require.NoError(t, err) + + // pre-commit 2 + sectorCids, err := mgr.SealPreCommit2(ctx, sector, preCommit1) + require.NoError(t, err) + commD := sectorCids.Unsealed + + // If we want to test what happens when the data must be unsealed + // (ie there is not an unsealed copy already available) + if !alreadyUnsealed { + // Remove the unsealed copy from local storage + err = localStore.Remove(ctx, sector.ID, storiface.FTUnsealed, false) + require.NoError(t, err) + } + + // Read the piece + offset := storiface.UnpaddedByteIndex(0) + require.NoError(t, err) + reader, unsealed, err := pp.ReadPiece(ctx, sector, offset, size, ticket, commD) + require.NoError(t, err) + requiresUnseal := !alreadyUnsealed + require.Equal(t, requiresUnseal, unsealed) + + defer func() { _ = reader.Close() }() + + // Make sure the input matches the output + readData, err := ioutil.ReadAll(reader) + require.NoError(t, err) + require.Equal(t, pieceData, string(readData)) + } + + t.Run("already unsealed", func(t *testing.T) { + runTest(t, true) + }) + t.Run("requires unseal", func(t *testing.T) { + runTest(t, false) + }) +} From 77b5e8d045c4a2eceff51e2081b0cc2d80aa272c Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Thu, 20 May 2021 10:03:56 +0530 Subject: [PATCH 46/66] use an actual worker in the integration tests --- extern/sector-storage/piece_provider_test.go | 12 +- extern/sector-storage/stores/mocks/Store.go | 115 ------------------- 2 files changed, 9 insertions(+), 118 deletions(-) delete mode 100644 extern/sector-storage/stores/mocks/Store.go diff --git a/extern/sector-storage/piece_provider_test.go b/extern/sector-storage/piece_provider_test.go index 08aadb78e..b6234d70a 100644 --- a/extern/sector-storage/piece_provider_test.go +++ b/extern/sector-storage/piece_provider_test.go @@ -50,10 +50,16 @@ func TestPieceProviderReadPiece(t *testing.T) { localTasks := []sealtasks.TaskType{ sealtasks.TTAddPiece, sealtasks.TTPreCommit1, sealtasks.TTCommit1, sealtasks.TTFinalize, sealtasks.TTFetch, } - testWorker := newTestWorker(WorkerConfig{ + + csts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/stmgr/calls"))) + + // passing a nil executor here mirrors an actual worker setup as it + // will initialize the worker to use the rust proofs lib under the hood + worker := newLocalWorker(nil, WorkerConfig{ TaskTypes: localTasks, - }, localStore, mgr) - err = mgr.AddWorker(ctx, testWorker) + }, remoteStore, localStore, index, mgr, csts) + + err = mgr.AddWorker(ctx, worker) require.NoError(t, err) // Create piece provider diff --git a/extern/sector-storage/stores/mocks/Store.go b/extern/sector-storage/stores/mocks/Store.go deleted file mode 100644 index 2be0a3075..000000000 --- a/extern/sector-storage/stores/mocks/Store.go +++ /dev/null @@ -1,115 +0,0 @@ -// Code generated by mockery 2.7.5. DO NOT EDIT. - -package mocks - -import ( - context "context" - - abi "github.com/filecoin-project/go-state-types/abi" - - fsutil "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" - - mock "github.com/stretchr/testify/mock" - - storage "github.com/filecoin-project/specs-storage/storage" - - stores "github.com/filecoin-project/lotus/extern/sector-storage/stores" - - storiface "github.com/filecoin-project/lotus/extern/sector-storage/storiface" -) - -// Store is an autogenerated mock type for the Store type -type Store struct { - mock.Mock -} - -// AcquireSector provides a mock function with given fields: ctx, s, existing, allocate, sealing, op -func (_m *Store) AcquireSector(ctx context.Context, s storage.SectorRef, existing storiface.SectorFileType, allocate storiface.SectorFileType, sealing storiface.PathType, op storiface.AcquireMode) (storiface.SectorPaths, storiface.SectorPaths, error) { - ret := _m.Called(ctx, s, existing, allocate, sealing, op) - - var r0 storiface.SectorPaths - if rf, ok := ret.Get(0).(func(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) storiface.SectorPaths); ok { - r0 = rf(ctx, s, existing, allocate, sealing, op) - } else { - r0 = ret.Get(0).(storiface.SectorPaths) - } - - var r1 storiface.SectorPaths - if rf, ok := ret.Get(1).(func(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) storiface.SectorPaths); ok { - r1 = rf(ctx, s, existing, allocate, sealing, op) - } else { - r1 = ret.Get(1).(storiface.SectorPaths) - } - - var r2 error - if rf, ok := ret.Get(2).(func(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) error); ok { - r2 = rf(ctx, s, existing, allocate, sealing, op) - } else { - r2 = ret.Error(2) - } - - return r0, r1, r2 -} - -// FsStat provides a mock function with given fields: ctx, id -func (_m *Store) FsStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) { - ret := _m.Called(ctx, id) - - var r0 fsutil.FsStat - if rf, ok := ret.Get(0).(func(context.Context, stores.ID) fsutil.FsStat); ok { - r0 = rf(ctx, id) - } else { - r0 = ret.Get(0).(fsutil.FsStat) - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, stores.ID) error); ok { - r1 = rf(ctx, id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MoveStorage provides a mock function with given fields: ctx, s, types -func (_m *Store) MoveStorage(ctx context.Context, s storage.SectorRef, types storiface.SectorFileType) error { - ret := _m.Called(ctx, s, types) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, storage.SectorRef, storiface.SectorFileType) error); ok { - r0 = rf(ctx, s, types) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Remove provides a mock function with given fields: ctx, s, types, force -func (_m *Store) Remove(ctx context.Context, s abi.SectorID, types storiface.SectorFileType, force bool) error { - ret := _m.Called(ctx, s, types, force) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, abi.SectorID, storiface.SectorFileType, bool) error); ok { - r0 = rf(ctx, s, types, force) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// RemoveCopies provides a mock function with given fields: ctx, s, types -func (_m *Store) RemoveCopies(ctx context.Context, s abi.SectorID, types storiface.SectorFileType) error { - ret := _m.Called(ctx, s, types) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, abi.SectorID, storiface.SectorFileType) error); ok { - r0 = rf(ctx, s, types) - } else { - r0 = ret.Error(0) - } - - return r0 -} From 0d88800eb9bfe9aa8de9e54273425b233603b74a Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Thu, 20 May 2021 10:38:22 +0530 Subject: [PATCH 47/66] use mockgen --- .../stores/http_handler_test.go | 133 +++++++------ extern/sector-storage/stores/interface.go | 2 + .../stores/mocks/PartialFileHandler.go | 61 ------ extern/sector-storage/stores/mocks/stores.go | 182 ++++++++++++++++++ extern/sector-storage/stores/remote.go | 4 + go.mod | 2 +- go.sum | 2 + 7 files changed, 261 insertions(+), 125 deletions(-) delete mode 100644 extern/sector-storage/stores/mocks/PartialFileHandler.go create mode 100644 extern/sector-storage/stores/mocks/stores.go diff --git a/extern/sector-storage/stores/http_handler_test.go b/extern/sector-storage/stores/http_handler_test.go index 16703b465..c943e36b6 100644 --- a/extern/sector-storage/stores/http_handler_test.go +++ b/extern/sector-storage/stores/http_handler_test.go @@ -15,7 +15,7 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/stores/mocks" "github.com/filecoin-project/lotus/extern/sector-storage/storiface" "github.com/filecoin-project/specs-storage/storage" - "github.com/stretchr/testify/mock" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "golang.org/x/xerrors" ) @@ -62,8 +62,8 @@ func TestRemoteGetAllocated(t *testing.T) { tcs := map[string]struct { piFnc func(pi *pieceInfo) - storeFnc func(s *mocks.Store) - pfFunc func(s *mocks.PartialFileHandler) + storeFnc func(s *mocks.MockStore) + pfFunc func(s *mocks.MockpartialFileHandler) // expectation expectedStatusCode int @@ -100,97 +100,101 @@ func TestRemoteGetAllocated(t *testing.T) { }, "fails when errors out during acquiring unsealed sector file": { expectedStatusCode: http.StatusInternalServerError, - storeFnc: func(l *mocks.Store) { - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storeFnc: func(l *mocks.MockStore) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ Unsealed: "path", }, - storiface.SectorPaths{}, xerrors.New("some error")) + storiface.SectorPaths{}, xerrors.New("some error")).Times(1) }, }, "fails when unsealed sector file is not found locally": { expectedStatusCode: http.StatusInternalServerError, - storeFnc: func(l *mocks.Store) { + storeFnc: func(l *mocks.MockStore) { - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{}, - storiface.SectorPaths{}, nil) + storiface.SectorPaths{}, nil).Times(1) }, }, "fails when partial file is not found locally": { expectedStatusCode: http.StatusInternalServerError, - storeFnc: func(l *mocks.Store) { + storeFnc: func(l *mocks.MockStore) { // will return emppty paths - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ Unsealed: pfPath, }, - storiface.SectorPaths{}, nil) + storiface.SectorPaths{}, nil).Times(1) }, - pfFunc: func(pf *mocks.PartialFileHandler) { + pfFunc: func(pf *mocks.MockpartialFileHandler) { //OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) - pf.On("OpenPartialFile", abi.PaddedPieceSize(sectorSize), pfPath).Return(&partialfile.PartialFile{}, - xerrors.New("some error")) + pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(&partialfile.PartialFile{}, + xerrors.New("some error")).Times(1) }, }, "fails when determining partial file allocation returns an error": { expectedStatusCode: http.StatusInternalServerError, - storeFnc: func(l *mocks.Store) { + storeFnc: func(l *mocks.MockStore) { // will return emppty paths - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ Unsealed: pfPath, }, - storiface.SectorPaths{}, nil) + storiface.SectorPaths{}, nil).Times(1) }, - pfFunc: func(pf *mocks.PartialFileHandler) { - pf.On("OpenPartialFile", abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, - nil) - pf.On("HasAllocated", emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), - abi.UnpaddedPieceSize(validSizeInt)).Return(true, xerrors.New("some error")) + pfFunc: func(pf *mocks.MockpartialFileHandler) { + pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, + nil).Times(1) + + pf.EXPECT().HasAllocated(emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), + abi.UnpaddedPieceSize(validSizeInt)).Return(true, xerrors.New("some error")).Times(1) }, }, "StatusRequestedRangeNotSatisfiable when piece is NOT allocated in partial file": { expectedStatusCode: http.StatusRequestedRangeNotSatisfiable, - storeFnc: func(l *mocks.Store) { + storeFnc: func(l *mocks.MockStore) { // will return emppty paths - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ Unsealed: pfPath, }, - storiface.SectorPaths{}, nil) + storiface.SectorPaths{}, nil).Times(1) }, - pfFunc: func(pf *mocks.PartialFileHandler) { - pf.On("OpenPartialFile", abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, - nil) - pf.On("HasAllocated", emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), - abi.UnpaddedPieceSize(validSizeInt)).Return(false, nil) + pfFunc: func(pf *mocks.MockpartialFileHandler) { + pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, + nil).Times(1) + + pf.EXPECT().HasAllocated(emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), + abi.UnpaddedPieceSize(validSizeInt)).Return(false, nil).Times(1) }, }, "OK when piece is allocated in partial file": { expectedStatusCode: http.StatusOK, - storeFnc: func(l *mocks.Store) { + storeFnc: func(l *mocks.MockStore) { // will return emppty paths - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ Unsealed: pfPath, }, - storiface.SectorPaths{}, nil) + storiface.SectorPaths{}, nil).Times(1) }, - pfFunc: func(pf *mocks.PartialFileHandler) { - pf.On("OpenPartialFile", abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, - nil) - pf.On("HasAllocated", emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), - abi.UnpaddedPieceSize(validSizeInt)).Return(true, nil) + pfFunc: func(pf *mocks.MockpartialFileHandler) { + pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, + nil).Times(1) + + pf.EXPECT().HasAllocated(emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), + abi.UnpaddedPieceSize(validSizeInt)).Return(true, nil).Times(1) }, }, } @@ -198,8 +202,13 @@ func TestRemoteGetAllocated(t *testing.T) { for name, tc := range tcs { tc := tc t.Run(name, func(t *testing.T) { - lstore := &mocks.Store{} - pfhandler := &mocks.PartialFileHandler{} + // create go mock controller here + mockCtrl := gomock.NewController(t) + // when test is done, assert expectations on all mock objects. + defer mockCtrl.Finish() + + lstore := mocks.NewMockStore(mockCtrl) + pfhandler := mocks.NewMockpartialFileHandler(mockCtrl) handler := &stores.FetchHandler{ lstore, @@ -239,9 +248,6 @@ func TestRemoteGetAllocated(t *testing.T) { // assert expected status code require.Equal(t, tc.expectedStatusCode, resp.StatusCode) - - // assert expectations on the mocks - lstore.AssertExpectations(t) }) } } @@ -271,7 +277,7 @@ func TestRemoteGetSector(t *testing.T) { tcs := map[string]struct { siFnc func(pi *sectorInfo) - storeFnc func(s *mocks.Store, path string) + storeFnc func(s *mocks.MockStore, path string) // reading a file or a dir isDir bool @@ -297,31 +303,32 @@ func TestRemoteGetSector(t *testing.T) { noResponseBytes: true, }, "fails when error while acquiring sector file": { - storeFnc: func(l *mocks.Store, _ string) { - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + storeFnc: func(l *mocks.MockStore, _ string) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ Unsealed: "path", }, - storiface.SectorPaths{}, xerrors.New("some error")) + storiface.SectorPaths{}, xerrors.New("some error")).Times(1) }, expectedStatusCode: http.StatusInternalServerError, noResponseBytes: true, }, "fails when acquired sector file path is empty": { expectedStatusCode: http.StatusInternalServerError, - storeFnc: func(l *mocks.Store, _ string) { + storeFnc: func(l *mocks.MockStore, _ string) { - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{}, - storiface.SectorPaths{}, nil) + storiface.SectorPaths{}, nil).Times(1) }, noResponseBytes: true, }, "fails when acquired file does not exist": { expectedStatusCode: http.StatusInternalServerError, - storeFnc: func(l *mocks.Store, _ string) { + storeFnc: func(l *mocks.MockStore, _ string) { - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ Unsealed: "path", }, @@ -330,9 +337,9 @@ func TestRemoteGetSector(t *testing.T) { noResponseBytes: true, }, "successfully read a sector file": { - storeFnc: func(l *mocks.Store, path string) { + storeFnc: func(l *mocks.MockStore, path string) { - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ Unsealed: path, }, @@ -345,9 +352,9 @@ func TestRemoteGetSector(t *testing.T) { expectedResponseBytes: fileBytes, }, "successfully read a sector dir": { - storeFnc: func(l *mocks.Store, path string) { + storeFnc: func(l *mocks.MockStore, path string) { - l.On("AcquireSector", mock.Anything, expectedSectorRef, storiface.FTUnsealed, + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ Unsealed: path, }, @@ -365,6 +372,12 @@ func TestRemoteGetSector(t *testing.T) { for name, tc := range tcs { tc := tc t.Run(name, func(t *testing.T) { + mockCtrl := gomock.NewController(t) + // when test is done, assert expectations on all mock objects. + defer mockCtrl.Finish() + lstore := mocks.NewMockStore(mockCtrl) + pfhandler := mocks.NewMockpartialFileHandler(mockCtrl) + var path string if !tc.isDir { @@ -401,9 +414,6 @@ func TestRemoteGetSector(t *testing.T) { path = tempDir } - lstore := &mocks.Store{} - pfhandler := &mocks.PartialFileHandler{} - handler := &stores.FetchHandler{ lstore, pfhandler, @@ -447,9 +457,6 @@ func TestRemoteGetSector(t *testing.T) { } require.Equal(t, tc.expectedContentType, resp.Header.Get("Content-Type")) - - // assert expectations on the mocks - lstore.AssertExpectations(t) }) } } diff --git a/extern/sector-storage/stores/interface.go b/extern/sector-storage/stores/interface.go index 2c408cb0a..6b970d920 100644 --- a/extern/sector-storage/stores/interface.go +++ b/extern/sector-storage/stores/interface.go @@ -35,4 +35,6 @@ type Store interface { MoveStorage(ctx context.Context, s storage.SectorRef, types storiface.SectorFileType) error FsStat(ctx context.Context, id ID) (fsutil.FsStat, error) + + Reserve(ctx context.Context, sid storage.SectorRef, ft storiface.SectorFileType, storageIDs storiface.SectorPaths, overheadTab map[storiface.SectorFileType]int) (func(), error) } diff --git a/extern/sector-storage/stores/mocks/PartialFileHandler.go b/extern/sector-storage/stores/mocks/PartialFileHandler.go deleted file mode 100644 index d848732d6..000000000 --- a/extern/sector-storage/stores/mocks/PartialFileHandler.go +++ /dev/null @@ -1,61 +0,0 @@ -// Code generated by mockery 2.7.5. DO NOT EDIT. - -package mocks - -import ( - abi "github.com/filecoin-project/go-state-types/abi" - mock "github.com/stretchr/testify/mock" - - partialfile "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" - - storiface "github.com/filecoin-project/lotus/extern/sector-storage/storiface" -) - -// PartialFileHandler is an autogenerated mock type for the PartialFileHandler type -type PartialFileHandler struct { - mock.Mock -} - -// HasAllocated provides a mock function with given fields: pf, offset, size -func (_m *PartialFileHandler) HasAllocated(pf *partialfile.PartialFile, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { - ret := _m.Called(pf, offset, size) - - var r0 bool - if rf, ok := ret.Get(0).(func(*partialfile.PartialFile, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) bool); ok { - r0 = rf(pf, offset, size) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func(*partialfile.PartialFile, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error); ok { - r1 = rf(pf, offset, size) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// OpenPartialFile provides a mock function with given fields: maxPieceSize, path -func (_m *PartialFileHandler) OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialfile.PartialFile, error) { - ret := _m.Called(maxPieceSize, path) - - var r0 *partialfile.PartialFile - if rf, ok := ret.Get(0).(func(abi.PaddedPieceSize, string) *partialfile.PartialFile); ok { - r0 = rf(maxPieceSize, path) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*partialfile.PartialFile) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(abi.PaddedPieceSize, string) error); ok { - r1 = rf(maxPieceSize, path) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} diff --git a/extern/sector-storage/stores/mocks/stores.go b/extern/sector-storage/stores/mocks/stores.go new file mode 100644 index 000000000..43455b7df --- /dev/null +++ b/extern/sector-storage/stores/mocks/stores.go @@ -0,0 +1,182 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: interface.go + +// Package mock_stores is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + abi "github.com/filecoin-project/go-state-types/abi" + fsutil "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" + partialfile "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" + stores "github.com/filecoin-project/lotus/extern/sector-storage/stores" + storiface "github.com/filecoin-project/lotus/extern/sector-storage/storiface" + storage "github.com/filecoin-project/specs-storage/storage" + gomock "github.com/golang/mock/gomock" +) + +// MockpartialFileHandler is a mock of partialFileHandler interface. +type MockpartialFileHandler struct { + ctrl *gomock.Controller + recorder *MockpartialFileHandlerMockRecorder +} + +// MockpartialFileHandlerMockRecorder is the mock recorder for MockpartialFileHandler. +type MockpartialFileHandlerMockRecorder struct { + mock *MockpartialFileHandler +} + +// NewMockpartialFileHandler creates a new mock instance. +func NewMockpartialFileHandler(ctrl *gomock.Controller) *MockpartialFileHandler { + mock := &MockpartialFileHandler{ctrl: ctrl} + mock.recorder = &MockpartialFileHandlerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockpartialFileHandler) EXPECT() *MockpartialFileHandlerMockRecorder { + return m.recorder +} + +// HasAllocated mocks base method. +func (m *MockpartialFileHandler) HasAllocated(pf *partialfile.PartialFile, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HasAllocated", pf, offset, size) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HasAllocated indicates an expected call of HasAllocated. +func (mr *MockpartialFileHandlerMockRecorder) HasAllocated(pf, offset, size interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasAllocated", reflect.TypeOf((*MockpartialFileHandler)(nil).HasAllocated), pf, offset, size) +} + +// OpenPartialFile mocks base method. +func (m *MockpartialFileHandler) OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialfile.PartialFile, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OpenPartialFile", maxPieceSize, path) + ret0, _ := ret[0].(*partialfile.PartialFile) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// OpenPartialFile indicates an expected call of OpenPartialFile. +func (mr *MockpartialFileHandlerMockRecorder) OpenPartialFile(maxPieceSize, path interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenPartialFile", reflect.TypeOf((*MockpartialFileHandler)(nil).OpenPartialFile), maxPieceSize, path) +} + +// MockStore is a mock of Store interface. +type MockStore struct { + ctrl *gomock.Controller + recorder *MockStoreMockRecorder +} + +// MockStoreMockRecorder is the mock recorder for MockStore. +type MockStoreMockRecorder struct { + mock *MockStore +} + +// NewMockStore creates a new mock instance. +func NewMockStore(ctrl *gomock.Controller) *MockStore { + mock := &MockStore{ctrl: ctrl} + mock.recorder = &MockStoreMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockStore) EXPECT() *MockStoreMockRecorder { + return m.recorder +} + +// AcquireSector mocks base method. +func (m *MockStore) AcquireSector(ctx context.Context, s storage.SectorRef, existing, allocate storiface.SectorFileType, sealing storiface.PathType, op storiface.AcquireMode) (storiface.SectorPaths, storiface.SectorPaths, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AcquireSector", ctx, s, existing, allocate, sealing, op) + ret0, _ := ret[0].(storiface.SectorPaths) + ret1, _ := ret[1].(storiface.SectorPaths) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// AcquireSector indicates an expected call of AcquireSector. +func (mr *MockStoreMockRecorder) AcquireSector(ctx, s, existing, allocate, sealing, op interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcquireSector", reflect.TypeOf((*MockStore)(nil).AcquireSector), ctx, s, existing, allocate, sealing, op) +} + +// FsStat mocks base method. +func (m *MockStore) FsStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FsStat", ctx, id) + ret0, _ := ret[0].(fsutil.FsStat) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FsStat indicates an expected call of FsStat. +func (mr *MockStoreMockRecorder) FsStat(ctx, id interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FsStat", reflect.TypeOf((*MockStore)(nil).FsStat), ctx, id) +} + +// MoveStorage mocks base method. +func (m *MockStore) MoveStorage(ctx context.Context, s storage.SectorRef, types storiface.SectorFileType) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MoveStorage", ctx, s, types) + ret0, _ := ret[0].(error) + return ret0 +} + +// MoveStorage indicates an expected call of MoveStorage. +func (mr *MockStoreMockRecorder) MoveStorage(ctx, s, types interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MoveStorage", reflect.TypeOf((*MockStore)(nil).MoveStorage), ctx, s, types) +} + +// Remove mocks base method. +func (m *MockStore) Remove(ctx context.Context, s abi.SectorID, types storiface.SectorFileType, force bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Remove", ctx, s, types, force) + ret0, _ := ret[0].(error) + return ret0 +} + +// Remove indicates an expected call of Remove. +func (mr *MockStoreMockRecorder) Remove(ctx, s, types, force interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockStore)(nil).Remove), ctx, s, types, force) +} + +// RemoveCopies mocks base method. +func (m *MockStore) RemoveCopies(ctx context.Context, s abi.SectorID, types storiface.SectorFileType) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveCopies", ctx, s, types) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveCopies indicates an expected call of RemoveCopies. +func (mr *MockStoreMockRecorder) RemoveCopies(ctx, s, types interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveCopies", reflect.TypeOf((*MockStore)(nil).RemoveCopies), ctx, s, types) +} + +// Reserve mocks base method. +func (m *MockStore) Reserve(ctx context.Context, sid storage.SectorRef, ft storiface.SectorFileType, storageIDs storiface.SectorPaths, overheadTab map[storiface.SectorFileType]int) (func(), error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Reserve", ctx, sid, ft, storageIDs, overheadTab) + ret0, _ := ret[0].(func()) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Reserve indicates an expected call of Reserve. +func (mr *MockStoreMockRecorder) Reserve(ctx, sid, ft, storageIDs, overheadTab interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reserve", reflect.TypeOf((*MockStore)(nil).Reserve), ctx, sid, ft, storageIDs, overheadTab) +} diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index a09c87761..1a30fac8f 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -581,4 +581,8 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a return nil, nil } +func (r *Remote) Reserve(ctx context.Context, sid storage.SectorRef, ft storiface.SectorFileType, storageIDs storiface.SectorPaths, overheadTab map[storiface.SectorFileType]int) (func(), error) { + panic("not implemented") +} + var _ Store = &Remote{} diff --git a/go.mod b/go.mod index 21421345c..f21b6760a 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,7 @@ require ( github.com/gdamore/tcell/v2 v2.2.0 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect - github.com/golang/mock v1.4.4 + github.com/golang/mock v1.5.0 github.com/google/uuid v1.1.2 github.com/gorilla/mux v1.7.4 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index 8510e0363..a8ac5e9d0 100644 --- a/go.sum +++ b/go.sum @@ -418,6 +418,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= From 4efaa8d6889d5f715e8597f77cad0d3cba491693 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Thu, 20 May 2021 16:31:25 +0530 Subject: [PATCH 48/66] unit tests for the remote store Reader --- cmd/lotus-seal-worker/main.go | 3 +- cmd/lotus-storage-miner/init.go | 2 +- extern/sector-storage/manager_test.go | 2 +- extern/sector-storage/piece_provider_test.go | 2 +- extern/sector-storage/stores/http_handler.go | 9 + .../stores/http_handler_test.go | 7 +- extern/sector-storage/stores/interface.go | 9 +- extern/sector-storage/stores/mocks/index.go | 169 +++++++ extern/sector-storage/stores/mocks/stores.go | 30 ++ extern/sector-storage/stores/remote.go | 26 +- extern/sector-storage/stores/remote_test.go | 418 ++++++++++++++++++ node/modules/storageminer.go | 2 +- 12 files changed, 656 insertions(+), 23 deletions(-) create mode 100644 extern/sector-storage/stores/mocks/index.go create mode 100644 extern/sector-storage/stores/remote_test.go diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index 899d9bbee..adcf0f869 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -362,7 +362,8 @@ var runCmd = &cli.Command{ return xerrors.Errorf("could not get api info: %w", err) } - remote := stores.NewRemote(localStore, nodeApi, sminfo.AuthHeader(), cctx.Int("parallel-fetch-limit")) + remote := stores.NewRemote(localStore, nodeApi, sminfo.AuthHeader(), cctx.Int("parallel-fetch-limit"), + &stores.DefaultPartialFileHandler{}) fh := &stores.FetchHandler{Local: localStore, PfHandler: &stores.DefaultPartialFileHandler{}} remoteHandler := func(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 2a50abc03..249f0ee03 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -460,7 +460,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api v1api.FullNode if err != nil { return err } - stor := stores.NewRemote(lstor, si, http.Header(sa), 10) + stor := stores.NewRemote(lstor, si, http.Header(sa), 10, &stores.DefaultPartialFileHandler{}) smgr, err := sectorstorage.New(ctx, lstor, stor, lr, si, sectorstorage.SealerConfig{ ParallelFetchLimit: 10, diff --git a/extern/sector-storage/manager_test.go b/extern/sector-storage/manager_test.go index 1cf9d0aad..d4044bbae 100644 --- a/extern/sector-storage/manager_test.go +++ b/extern/sector-storage/manager_test.go @@ -98,7 +98,7 @@ func newTestMgr(ctx context.Context, t *testing.T, ds datastore.Datastore) (*Man prover, err := ffiwrapper.New(&readonlyProvider{stor: lstor, index: si}) require.NoError(t, err) - stor := stores.NewRemote(lstor, si, nil, 6000) + stor := stores.NewRemote(lstor, si, nil, 6000, &stores.DefaultPartialFileHandler{}) m := &Manager{ ls: st, diff --git a/extern/sector-storage/piece_provider_test.go b/extern/sector-storage/piece_provider_test.go index b6234d70a..8636a11d6 100644 --- a/extern/sector-storage/piece_provider_test.go +++ b/extern/sector-storage/piece_provider_test.go @@ -31,7 +31,7 @@ func TestPieceProviderReadPiece(t *testing.T) { index := stores.NewIndex() localStore, err := stores.NewLocal(ctx, storage, index, nil) require.NoError(t, err) - remoteStore := stores.NewRemote(localStore, index, nil, 6000) + remoteStore := stores.NewRemote(localStore, index, nil, 6000, &stores.DefaultPartialFileHandler{}) dstore := ds_sync.MutexWrap(datastore.NewMapDatastore()) wsts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/worker/calls"))) smsts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/stmgr/calls"))) diff --git a/extern/sector-storage/stores/http_handler.go b/extern/sector-storage/stores/http_handler.go index 57d48f613..e195cd7a9 100644 --- a/extern/sector-storage/stores/http_handler.go +++ b/extern/sector-storage/stores/http_handler.go @@ -35,6 +35,15 @@ func (d *DefaultPartialFileHandler) HasAllocated(pf *partialfile.PartialFile, of return pf.HasAllocated(offset, size) } +func (d *DefaultPartialFileHandler) Reader(pf *partialfile.PartialFile, offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (*os.File, error) { + return pf.Reader(offset, size) +} + +// Close closes the partial file +func (d *DefaultPartialFileHandler) Close(pf *partialfile.PartialFile) error { + return pf.Close() +} + type FetchHandler struct { Local Store PfHandler partialFileHandler diff --git a/extern/sector-storage/stores/http_handler_test.go b/extern/sector-storage/stores/http_handler_test.go index c943e36b6..1258d8530 100644 --- a/extern/sector-storage/stores/http_handler_test.go +++ b/extern/sector-storage/stores/http_handler_test.go @@ -118,10 +118,9 @@ func TestRemoteGetAllocated(t *testing.T) { storiface.SectorPaths{}, nil).Times(1) }, }, - "fails when partial file is not found locally": { + "fails when error while opening partial file": { expectedStatusCode: http.StatusInternalServerError, storeFnc: func(l *mocks.MockStore) { - // will return emppty paths l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ @@ -131,7 +130,6 @@ func TestRemoteGetAllocated(t *testing.T) { }, pfFunc: func(pf *mocks.MockpartialFileHandler) { - //OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(&partialfile.PartialFile{}, xerrors.New("some error")).Times(1) }, @@ -140,7 +138,6 @@ func TestRemoteGetAllocated(t *testing.T) { "fails when determining partial file allocation returns an error": { expectedStatusCode: http.StatusInternalServerError, storeFnc: func(l *mocks.MockStore) { - // will return emppty paths l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ @@ -160,7 +157,6 @@ func TestRemoteGetAllocated(t *testing.T) { "StatusRequestedRangeNotSatisfiable when piece is NOT allocated in partial file": { expectedStatusCode: http.StatusRequestedRangeNotSatisfiable, storeFnc: func(l *mocks.MockStore) { - // will return emppty paths l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ @@ -180,7 +176,6 @@ func TestRemoteGetAllocated(t *testing.T) { "OK when piece is allocated in partial file": { expectedStatusCode: http.StatusOK, storeFnc: func(l *mocks.MockStore) { - // will return emppty paths l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ diff --git a/extern/sector-storage/stores/interface.go b/extern/sector-storage/stores/interface.go index 6b970d920..4986e6c80 100644 --- a/extern/sector-storage/stores/interface.go +++ b/extern/sector-storage/stores/interface.go @@ -2,6 +2,7 @@ package stores import ( "context" + "os" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" @@ -18,9 +19,15 @@ type partialFileHandler interface { // size OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialfile.PartialFile, error) - // HasAllocated returns true if the given partialfile has an unsealed piece starting at the given offset with the given size. + // HasAllocated returns true if the given partial file has an unsealed piece starting at the given offset with the given size. // returns false otherwise. HasAllocated(pf *partialfile.PartialFile, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) + + // Reader returns a file from which we can read the unsealed piece in the partial file. + Reader(pf *partialfile.PartialFile, offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (*os.File, error) + + // Close closes the partial file + Close(pf *partialfile.PartialFile) error } type Store interface { diff --git a/extern/sector-storage/stores/mocks/index.go b/extern/sector-storage/stores/mocks/index.go new file mode 100644 index 000000000..e06fa70cc --- /dev/null +++ b/extern/sector-storage/stores/mocks/index.go @@ -0,0 +1,169 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: index.go + +// Package mock_stores is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + abi "github.com/filecoin-project/go-state-types/abi" + fsutil "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" + stores "github.com/filecoin-project/lotus/extern/sector-storage/stores" + storiface "github.com/filecoin-project/lotus/extern/sector-storage/storiface" + gomock "github.com/golang/mock/gomock" +) + +// MockSectorIndex is a mock of SectorIndex interface. +type MockSectorIndex struct { + ctrl *gomock.Controller + recorder *MockSectorIndexMockRecorder +} + +// MockSectorIndexMockRecorder is the mock recorder for MockSectorIndex. +type MockSectorIndexMockRecorder struct { + mock *MockSectorIndex +} + +// NewMockSectorIndex creates a new mock instance. +func NewMockSectorIndex(ctrl *gomock.Controller) *MockSectorIndex { + mock := &MockSectorIndex{ctrl: ctrl} + mock.recorder = &MockSectorIndexMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSectorIndex) EXPECT() *MockSectorIndexMockRecorder { + return m.recorder +} + +// StorageAttach mocks base method. +func (m *MockSectorIndex) StorageAttach(arg0 context.Context, arg1 stores.StorageInfo, arg2 fsutil.FsStat) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageAttach", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// StorageAttach indicates an expected call of StorageAttach. +func (mr *MockSectorIndexMockRecorder) StorageAttach(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageAttach", reflect.TypeOf((*MockSectorIndex)(nil).StorageAttach), arg0, arg1, arg2) +} + +// StorageBestAlloc mocks base method. +func (m *MockSectorIndex) StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pathType storiface.PathType) ([]stores.StorageInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageBestAlloc", ctx, allocate, ssize, pathType) + ret0, _ := ret[0].([]stores.StorageInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StorageBestAlloc indicates an expected call of StorageBestAlloc. +func (mr *MockSectorIndexMockRecorder) StorageBestAlloc(ctx, allocate, ssize, pathType interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageBestAlloc", reflect.TypeOf((*MockSectorIndex)(nil).StorageBestAlloc), ctx, allocate, ssize, pathType) +} + +// StorageDeclareSector mocks base method. +func (m *MockSectorIndex) StorageDeclareSector(ctx context.Context, storageID stores.ID, s abi.SectorID, ft storiface.SectorFileType, primary bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageDeclareSector", ctx, storageID, s, ft, primary) + ret0, _ := ret[0].(error) + return ret0 +} + +// StorageDeclareSector indicates an expected call of StorageDeclareSector. +func (mr *MockSectorIndexMockRecorder) StorageDeclareSector(ctx, storageID, s, ft, primary interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageDeclareSector", reflect.TypeOf((*MockSectorIndex)(nil).StorageDeclareSector), ctx, storageID, s, ft, primary) +} + +// StorageDropSector mocks base method. +func (m *MockSectorIndex) StorageDropSector(ctx context.Context, storageID stores.ID, s abi.SectorID, ft storiface.SectorFileType) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageDropSector", ctx, storageID, s, ft) + ret0, _ := ret[0].(error) + return ret0 +} + +// StorageDropSector indicates an expected call of StorageDropSector. +func (mr *MockSectorIndexMockRecorder) StorageDropSector(ctx, storageID, s, ft interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageDropSector", reflect.TypeOf((*MockSectorIndex)(nil).StorageDropSector), ctx, storageID, s, ft) +} + +// StorageFindSector mocks base method. +func (m *MockSectorIndex) StorageFindSector(ctx context.Context, sector abi.SectorID, ft storiface.SectorFileType, ssize abi.SectorSize, allowFetch bool) ([]stores.SectorStorageInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageFindSector", ctx, sector, ft, ssize, allowFetch) + ret0, _ := ret[0].([]stores.SectorStorageInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StorageFindSector indicates an expected call of StorageFindSector. +func (mr *MockSectorIndexMockRecorder) StorageFindSector(ctx, sector, ft, ssize, allowFetch interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageFindSector", reflect.TypeOf((*MockSectorIndex)(nil).StorageFindSector), ctx, sector, ft, ssize, allowFetch) +} + +// StorageInfo mocks base method. +func (m *MockSectorIndex) StorageInfo(arg0 context.Context, arg1 stores.ID) (stores.StorageInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageInfo", arg0, arg1) + ret0, _ := ret[0].(stores.StorageInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StorageInfo indicates an expected call of StorageInfo. +func (mr *MockSectorIndexMockRecorder) StorageInfo(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageInfo", reflect.TypeOf((*MockSectorIndex)(nil).StorageInfo), arg0, arg1) +} + +// StorageLock mocks base method. +func (m *MockSectorIndex) StorageLock(ctx context.Context, sector abi.SectorID, read, write storiface.SectorFileType) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageLock", ctx, sector, read, write) + ret0, _ := ret[0].(error) + return ret0 +} + +// StorageLock indicates an expected call of StorageLock. +func (mr *MockSectorIndexMockRecorder) StorageLock(ctx, sector, read, write interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageLock", reflect.TypeOf((*MockSectorIndex)(nil).StorageLock), ctx, sector, read, write) +} + +// StorageReportHealth mocks base method. +func (m *MockSectorIndex) StorageReportHealth(arg0 context.Context, arg1 stores.ID, arg2 stores.HealthReport) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageReportHealth", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// StorageReportHealth indicates an expected call of StorageReportHealth. +func (mr *MockSectorIndexMockRecorder) StorageReportHealth(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageReportHealth", reflect.TypeOf((*MockSectorIndex)(nil).StorageReportHealth), arg0, arg1, arg2) +} + +// StorageTryLock mocks base method. +func (m *MockSectorIndex) StorageTryLock(ctx context.Context, sector abi.SectorID, read, write storiface.SectorFileType) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageTryLock", ctx, sector, read, write) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StorageTryLock indicates an expected call of StorageTryLock. +func (mr *MockSectorIndexMockRecorder) StorageTryLock(ctx, sector, read, write interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageTryLock", reflect.TypeOf((*MockSectorIndex)(nil).StorageTryLock), ctx, sector, read, write) +} diff --git a/extern/sector-storage/stores/mocks/stores.go b/extern/sector-storage/stores/mocks/stores.go index 43455b7df..a408419a9 100644 --- a/extern/sector-storage/stores/mocks/stores.go +++ b/extern/sector-storage/stores/mocks/stores.go @@ -6,6 +6,7 @@ package mocks import ( context "context" + os "os" reflect "reflect" abi "github.com/filecoin-project/go-state-types/abi" @@ -40,6 +41,20 @@ func (m *MockpartialFileHandler) EXPECT() *MockpartialFileHandlerMockRecorder { return m.recorder } +// Close mocks base method. +func (m *MockpartialFileHandler) Close(pf *partialfile.PartialFile) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close", pf) + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockpartialFileHandlerMockRecorder) Close(pf interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockpartialFileHandler)(nil).Close), pf) +} + // HasAllocated mocks base method. func (m *MockpartialFileHandler) HasAllocated(pf *partialfile.PartialFile, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { m.ctrl.T.Helper() @@ -70,6 +85,21 @@ func (mr *MockpartialFileHandlerMockRecorder) OpenPartialFile(maxPieceSize, path return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenPartialFile", reflect.TypeOf((*MockpartialFileHandler)(nil).OpenPartialFile), maxPieceSize, path) } +// Reader mocks base method. +func (m *MockpartialFileHandler) Reader(pf *partialfile.PartialFile, offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (*os.File, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Reader", pf, offset, size) + ret0, _ := ret[0].(*os.File) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Reader indicates an expected call of Reader. +func (mr *MockpartialFileHandlerMockRecorder) Reader(pf, offset, size interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reader", reflect.TypeOf((*MockpartialFileHandler)(nil).Reader), pf, offset, size) +} + // MockStore is a mock of Store interface. type MockStore struct { ctrl *gomock.Controller diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index 1a30fac8f..7400c6ee0 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -17,7 +17,6 @@ import ( "sync" "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" - "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" "github.com/filecoin-project/lotus/extern/sector-storage/storiface" "github.com/filecoin-project/lotus/extern/sector-storage/tarutil" @@ -33,7 +32,7 @@ var FetchTempSubdir = "fetching" var CopyBuf = 1 << 20 type Remote struct { - local *Local + local Store index SectorIndex auth http.Header @@ -41,6 +40,8 @@ type Remote struct { fetchLk sync.Mutex fetching map[abi.SectorID]chan struct{} + + pfHandler partialFileHandler } func (r *Remote) RemoveCopies(ctx context.Context, s abi.SectorID, types storiface.SectorFileType) error { @@ -51,7 +52,7 @@ func (r *Remote) RemoveCopies(ctx context.Context, s abi.SectorID, types storifa return r.local.RemoveCopies(ctx, s, types) } -func NewRemote(local *Local, index SectorIndex, auth http.Header, fetchLimit int) *Remote { +func NewRemote(local Store, index SectorIndex, auth http.Header, fetchLimit int, pfHandler partialFileHandler) *Remote { return &Remote{ local: local, index: index, @@ -59,7 +60,8 @@ func NewRemote(local *Local, index SectorIndex, auth http.Header, fetchLimit int limit: make(chan struct{}, fetchLimit), - fetching: map[abi.SectorID]chan struct{}{}, + fetching: map[abi.SectorID]chan struct{}{}, + pfHandler: pfHandler, } } @@ -462,7 +464,10 @@ func (r *Remote) readRemote(ctx context.Context, url string, offset, size abi.Pa if err != nil { return nil, xerrors.Errorf("request: %w", err) } - req.Header = r.auth.Clone() + + if r.auth != nil { + req.Header = r.auth.Clone() + } req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+size-1)) req = req.WithContext(ctx) @@ -509,27 +514,27 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a } // open the unsealed sector file for the given sector size located at the given path. - pf, err := partialfile.OpenPartialFile(abi.PaddedPieceSize(ssize), path) + pf, err := r.pfHandler.OpenPartialFile(abi.PaddedPieceSize(ssize), path) if err != nil { return nil, xerrors.Errorf("opening partial file: %w", err) } // even though we have an unsealed file for the given sector, we still need to determine if we have the unsealed piece // in the unsealed sector file. That is what `HasAllocated` checks for. - has, err := pf.HasAllocated(storiface.UnpaddedByteIndex(offset.Unpadded()), size.Unpadded()) + has, err := r.pfHandler.HasAllocated(pf, storiface.UnpaddedByteIndex(offset.Unpadded()), size.Unpadded()) if err != nil { return nil, xerrors.Errorf("has allocated: %w", err) } if !has { - if err := pf.Close(); err != nil { + if err := r.pfHandler.Close(pf); err != nil { return nil, xerrors.Errorf("close partial file: %w", err) } return nil, nil } log.Debugf("returning piece reader for local unsealed piece sector=%+v, (offset=%d, size=%d)", s.ID, offset, size) - return pf.Reader(storiface.PaddedByteIndex(offset), size) + return r.pfHandler.Reader(pf, storiface.PaddedByteIndex(offset), size) } // --- We don't have the unsealed sector file locally @@ -546,9 +551,8 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a return nil, xerrors.Errorf("failed to read sector %v from remote(%d): %w", s, ft, storiface.ErrSectorNotFound) } - // TODO Why are we sorting in ascending order here -> shouldn't we sort in descending order as higher weight means more likely to have the file ? sort.Slice(si, func(i, j int) bool { - return si[i].Weight < si[j].Weight + return si[i].Weight > si[j].Weight }) for _, info := range si { diff --git a/extern/sector-storage/stores/remote_test.go b/extern/sector-storage/stores/remote_test.go new file mode 100644 index 000000000..8495fd0a8 --- /dev/null +++ b/extern/sector-storage/stores/remote_test.go @@ -0,0 +1,418 @@ +package stores_test + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" + "github.com/filecoin-project/lotus/extern/sector-storage/stores" + "github.com/filecoin-project/lotus/extern/sector-storage/stores/mocks" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" + "github.com/filecoin-project/specs-storage/storage" + "github.com/golang/mock/gomock" + "github.com/gorilla/mux" + logging "github.com/ipfs/go-log" + "github.com/stretchr/testify/require" + "golang.org/x/xerrors" +) + +func TestReader(t *testing.T) { + logging.SetAllLoggers(logging.LevelDebug) + bz := []byte("Hello World") + + pfPath := "path" + ft := storiface.FTUnsealed + emptyPartialFile := &partialfile.PartialFile{} + + sectorRef := storage.SectorRef{ + ID: abi.SectorID{ + Miner: 123, + Number: 123, + }, + ProofType: 1, + } + sectorSize := abi.SealProofInfos[1].SectorSize + + offset := abi.PaddedPieceSize(100) + size := abi.PaddedPieceSize(1000) + ctx := context.Background() + + tcs := map[string]struct { + storeFnc func(s *mocks.MockStore) + pfFunc func(s *mocks.MockpartialFileHandler) + indexFnc func(s *mocks.MockSectorIndex, serverURL string) + + needHttpServer bool + + getAllocatedReturnCode int + getSectorReturnCode int + + serverUrl string + + // expectation + errStr string + expectedNonNilReader bool + expectedSectorBytes []byte + }{ + + // -------- have the unsealed file locally + "fails when error while acquiring unsealed file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, xerrors.New("acquire error")) + }, + + errStr: "acquire error", + }, + + "fails when error while opening local partial (unsealed) file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, xerrors.New("pf open error")) + }, + errStr: "pf open error", + }, + + "fails when error while checking if local unsealed file has piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + true, xerrors.New("piece check error")) + }, + + errStr: "piece check error", + }, + + "fails when error while closing local unsealed file that does not have the piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + false, nil) + pf.EXPECT().Close(emptyPartialFile).Return(xerrors.New("close error")).Times(1) + }, + errStr: "close error", + }, + + "fails when error while fetching reader for the local unsealed file that has the unsealed piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + true, nil) + mockPfReader(pf, emptyPartialFile, offset, size, nil, xerrors.New("reader error")) + + }, + errStr: "reader error", + }, + + // ------------------- don't have the unsealed file locally + + "fails when error while finding sector": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, _ string) { + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return(nil, xerrors.New("find sector error")) + }, + errStr: "find sector error", + }, + + "fails when no worker has unsealed file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, _ string) { + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return(nil, nil) + }, + errStr: storiface.ErrSectorNotFound.Error(), + }, + + // --- nil reader when local unsealed file does NOT have unsealed piece + "nil reader when local unsealed file does not have the piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + false, nil) + + pf.EXPECT().Close(emptyPartialFile).Return(nil).Times(1) + }, + }, + + // ---- nil reader when none of the remote unsealed file has unsealed piece + "nil reader when none of the worker has the unsealed piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getAllocatedReturnCode: 500, + }, + + "nil reader when none of the worker is able to serve the unsealed piece even though they have it": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getSectorReturnCode: 500, + getAllocatedReturnCode: 200, + }, + + // ---- Success for local unsealed file + "successfully fetches reader for piece from local unsealed file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + true, nil) + + f, err := ioutil.TempFile("", "TestReader-") + require.NoError(t, err) + _, err = f.Write(bz) + require.NoError(t, err) + require.NoError(t, f.Close()) + f, err = os.Open(f.Name()) + require.NoError(t, err) + + mockPfReader(pf, emptyPartialFile, offset, size, f, nil) + + }, + + expectedNonNilReader: true, + expectedSectorBytes: bz, + }, + + // --- Success for remote unsealed file + "successfully fetches reader for piece from remote unsealed piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getSectorReturnCode: 200, + getAllocatedReturnCode: 200, + expectedSectorBytes: bz, + expectedNonNilReader: true, + }, + } + + for name, tc := range tcs { + tc := tc + t.Run(name, func(t *testing.T) { + // create go mock controller here + mockCtrl := gomock.NewController(t) + // when test is done, assert expectations on all mock objects. + defer mockCtrl.Finish() + + // create them mocks + lstore := mocks.NewMockStore(mockCtrl) + pfhandler := mocks.NewMockpartialFileHandler(mockCtrl) + index := mocks.NewMockSectorIndex(mockCtrl) + + if tc.storeFnc != nil { + tc.storeFnc(lstore) + } + if tc.pfFunc != nil { + tc.pfFunc(pfhandler) + } + + if tc.needHttpServer { + // run http server + ts := httptest.NewServer(&mockHttpServer{ + expectedSectorName: storiface.SectorName(sectorRef.ID), + expectedFileType: ft.String(), + expectedOffset: fmt.Sprintf("%d", offset.Unpadded()), + expectedSize: fmt.Sprintf("%d", size.Unpadded()), + expectedSectorType: fmt.Sprintf("%d", sectorRef.ProofType), + + getAllocatedReturnCode: tc.getAllocatedReturnCode, + getSectorReturnCode: tc.getSectorReturnCode, + getSectorBytes: tc.expectedSectorBytes, + }) + defer ts.Close() + tc.serverUrl = fmt.Sprintf("%s/remote/%s/%s", ts.URL, ft.String(), storiface.SectorName(sectorRef.ID)) + } + if tc.indexFnc != nil { + tc.indexFnc(index, tc.serverUrl) + } + + remoteStore := stores.NewRemote(lstore, index, nil, 6000, pfhandler) + + rd, err := remoteStore.Reader(ctx, sectorRef, offset, size) + + if tc.errStr != "" { + require.Error(t, err) + require.Nil(t, rd) + require.Contains(t, err.Error(), tc.errStr) + } else { + require.NoError(t, err) + } + + if !tc.expectedNonNilReader { + require.Nil(t, rd) + } else { + require.NotNil(t, rd) + defer func() { + require.NoError(t, rd.Close()) + }() + + if f, ok := rd.(*os.File); ok { + require.NoError(t, os.Remove(f.Name())) + } + + bz, err := ioutil.ReadAll(rd) + require.NoError(t, err) + require.Equal(t, tc.expectedSectorBytes, bz) + } + + }) + } +} + +func mockSectorAcquire(l *mocks.MockStore, sectorRef storage.SectorRef, pfPath string, err error) { + l.EXPECT().AcquireSector(gomock.Any(), sectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: pfPath, + }, + storiface.SectorPaths{}, err).Times(1) +} + +func mockPartialFileOpen(pf *mocks.MockpartialFileHandler, sectorSize abi.SectorSize, pfPath string, err error) { + pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(&partialfile.PartialFile{}, + err).Times(1) +} + +func mockCheckAllocation(pf *mocks.MockpartialFileHandler, offset, size abi.PaddedPieceSize, file *partialfile.PartialFile, + out bool, err error) { + pf.EXPECT().HasAllocated(file, storiface.UnpaddedByteIndex(offset.Unpadded()), + size.Unpadded()).Return(out, err).Times(1) +} + +func mockPfReader(pf *mocks.MockpartialFileHandler, file *partialfile.PartialFile, offset, size abi.PaddedPieceSize, + outFile *os.File, err error) { + pf.EXPECT().Reader(file, storiface.PaddedByteIndex(offset), size).Return(outFile, err) +} + +type mockHttpServer struct { + expectedSectorName string + expectedFileType string + expectedOffset string + expectedSize string + expectedSectorType string + + getAllocatedReturnCode int + getSectorReturnCode int + getSectorBytes []byte +} + +func (m *mockHttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + mux := mux.NewRouter() + mux.HandleFunc("/remote/{type}/{id}", m.getSector).Methods("GET") + mux.HandleFunc("/remote/{type}/{id}/{spt}/allocated/{offset}/{size}", m.getAllocated).Methods("GET") + mux.ServeHTTP(w, r) +} + +func (m *mockHttpServer) getAllocated(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + if vars["id"] != m.expectedSectorName { + w.WriteHeader(http.StatusBadRequest) + return + } + + if vars["type"] != m.expectedFileType { + w.WriteHeader(http.StatusBadRequest) + return + } + + if vars["spt"] != m.expectedSectorType { + w.WriteHeader(http.StatusBadRequest) + return + } + + if vars["offset"] != m.expectedOffset { + w.WriteHeader(http.StatusBadRequest) + return + } + + if vars["size"] != m.expectedSize { + w.WriteHeader(http.StatusBadRequest) + return + } + + w.WriteHeader(m.getAllocatedReturnCode) +} + +func (m *mockHttpServer) getSector(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + if vars["id"] != m.expectedSectorName { + w.WriteHeader(http.StatusBadRequest) + return + } + + if vars["type"] != m.expectedFileType { + w.WriteHeader(http.StatusBadRequest) + return + } + + w.WriteHeader(m.getSectorReturnCode) + _, _ = w.Write(m.getSectorBytes) +} diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 14b6774c6..e91a0df77 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -667,7 +667,7 @@ func LocalStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, ls stores.LocalStora } func RemoteStorage(lstor *stores.Local, si stores.SectorIndex, sa sectorstorage.StorageAuth, sc sectorstorage.SealerConfig) *stores.Remote { - return stores.NewRemote(lstor, si, http.Header(sa), sc.ParallelFetchLimit) + return stores.NewRemote(lstor, si, http.Header(sa), sc.ParallelFetchLimit, &stores.DefaultPartialFileHandler{}) } func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, lstor *stores.Local, stor *stores.Remote, ls stores.LocalStorage, si stores.SectorIndex, sc sectorstorage.SealerConfig, ds dtypes.MetadataDS) (*sectorstorage.Manager, error) { From 35a0dbfa8c072377012a98561fca96aa6240a908 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Thu, 20 May 2021 17:21:14 +0530 Subject: [PATCH 49/66] fix go mod --- extern/sector-storage/stores/remote_test.go | 2 +- go.sum | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/extern/sector-storage/stores/remote_test.go b/extern/sector-storage/stores/remote_test.go index 8495fd0a8..eb06a713d 100644 --- a/extern/sector-storage/stores/remote_test.go +++ b/extern/sector-storage/stores/remote_test.go @@ -17,7 +17,7 @@ import ( "github.com/filecoin-project/specs-storage/storage" "github.com/golang/mock/gomock" "github.com/gorilla/mux" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" "golang.org/x/xerrors" ) diff --git a/go.sum b/go.sum index a8ac5e9d0..63998058c 100644 --- a/go.sum +++ b/go.sum @@ -416,7 +416,6 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= From ad4b182bfedccafc93669be1e6cbff6a2024bc16 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Thu, 20 May 2021 21:55:49 +0530 Subject: [PATCH 50/66] remove read task type and run gen and docsgen --- api/api_worker.go | 2 - api/proxy_gen.go | 11 ----- cli/servicesmock_test.go | 51 ++++++++++++----------- documentation/en/api-v0-methods-worker.md | 37 ---------------- extern/sector-storage/manager.go | 2 +- extern/sector-storage/resources.go | 1 - extern/sector-storage/sealtasks/task.go | 27 ++++++------ extern/sector-storage/stores/util_unix.go | 10 ++++- extern/sector-storage/storiface/worker.go | 2 - extern/sector-storage/worker_local.go | 13 ------ extern/sector-storage/worker_tracked.go | 5 --- 11 files changed, 48 insertions(+), 113 deletions(-) diff --git a/api/api_worker.go b/api/api_worker.go index e834b792c..4553c30e0 100644 --- a/api/api_worker.go +++ b/api/api_worker.go @@ -2,7 +2,6 @@ package api import ( "context" - "io" "github.com/google/uuid" "github.com/ipfs/go-cid" @@ -43,7 +42,6 @@ type Worker interface { ReleaseUnsealed(ctx context.Context, sector storage.SectorRef, safeToFree []storage.Range) (storiface.CallID, error) //perm:admin MoveStorage(ctx context.Context, sector storage.SectorRef, types storiface.SectorFileType) (storiface.CallID, error) //perm:admin UnsealPiece(context.Context, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (storiface.CallID, error) //perm:admin - ReadPiece(context.Context, io.Writer, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (storiface.CallID, error) //perm:admin Fetch(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) (storiface.CallID, error) //perm:admin TaskDisable(ctx context.Context, tt sealtasks.TaskType) error //perm:admin diff --git a/api/proxy_gen.go b/api/proxy_gen.go index db3492d1b..6540ae7cd 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -4,7 +4,6 @@ package api import ( "context" - "io" "time" "github.com/filecoin-project/go-address" @@ -781,8 +780,6 @@ type WorkerStruct struct { ProcessSession func(p0 context.Context) (uuid.UUID, error) `perm:"admin"` - ReadPiece func(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) `perm:"admin"` - ReleaseUnsealed func(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) `perm:"admin"` Remove func(p0 context.Context, p1 abi.SectorID) error `perm:"admin"` @@ -3554,14 +3551,6 @@ func (s *WorkerStub) ProcessSession(p0 context.Context) (uuid.UUID, error) { return *new(uuid.UUID), xerrors.New("method not supported") } -func (s *WorkerStruct) ReadPiece(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) { - return s.Internal.ReadPiece(p0, p1, p2, p3, p4) -} - -func (s *WorkerStub) ReadPiece(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") -} - func (s *WorkerStruct) ReleaseUnsealed(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { return s.Internal.ReleaseUnsealed(p0, p1, p2) } diff --git a/cli/servicesmock_test.go b/cli/servicesmock_test.go index 4bd4b79c9..5bae52a5e 100644 --- a/cli/servicesmock_test.go +++ b/cli/servicesmock_test.go @@ -6,39 +6,40 @@ package cli import ( context "context" + reflect "reflect" + go_address "github.com/filecoin-project/go-address" abi "github.com/filecoin-project/go-state-types/abi" big "github.com/filecoin-project/go-state-types/big" api "github.com/filecoin-project/lotus/api" types "github.com/filecoin-project/lotus/chain/types" gomock "github.com/golang/mock/gomock" - reflect "reflect" ) -// MockServicesAPI is a mock of ServicesAPI interface +// MockServicesAPI is a mock of ServicesAPI interface. type MockServicesAPI struct { ctrl *gomock.Controller recorder *MockServicesAPIMockRecorder } -// MockServicesAPIMockRecorder is the mock recorder for MockServicesAPI +// MockServicesAPIMockRecorder is the mock recorder for MockServicesAPI. type MockServicesAPIMockRecorder struct { mock *MockServicesAPI } -// NewMockServicesAPI creates a new mock instance +// NewMockServicesAPI creates a new mock instance. func NewMockServicesAPI(ctrl *gomock.Controller) *MockServicesAPI { mock := &MockServicesAPI{ctrl: ctrl} mock.recorder = &MockServicesAPIMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockServicesAPI) EXPECT() *MockServicesAPIMockRecorder { return m.recorder } -// Close mocks base method +// Close mocks base method. func (m *MockServicesAPI) Close() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Close") @@ -46,13 +47,13 @@ func (m *MockServicesAPI) Close() error { return ret0 } -// Close indicates an expected call of Close +// Close indicates an expected call of Close. func (mr *MockServicesAPIMockRecorder) Close() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockServicesAPI)(nil).Close)) } -// DecodeTypedParamsFromJSON mocks base method +// DecodeTypedParamsFromJSON mocks base method. func (m *MockServicesAPI) DecodeTypedParamsFromJSON(arg0 context.Context, arg1 go_address.Address, arg2 abi.MethodNum, arg3 string) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DecodeTypedParamsFromJSON", arg0, arg1, arg2, arg3) @@ -61,13 +62,13 @@ func (m *MockServicesAPI) DecodeTypedParamsFromJSON(arg0 context.Context, arg1 g return ret0, ret1 } -// DecodeTypedParamsFromJSON indicates an expected call of DecodeTypedParamsFromJSON +// DecodeTypedParamsFromJSON indicates an expected call of DecodeTypedParamsFromJSON. func (mr *MockServicesAPIMockRecorder) DecodeTypedParamsFromJSON(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeTypedParamsFromJSON", reflect.TypeOf((*MockServicesAPI)(nil).DecodeTypedParamsFromJSON), arg0, arg1, arg2, arg3) } -// FullNodeAPI mocks base method +// FullNodeAPI mocks base method. func (m *MockServicesAPI) FullNodeAPI() api.FullNode { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FullNodeAPI") @@ -75,13 +76,13 @@ func (m *MockServicesAPI) FullNodeAPI() api.FullNode { return ret0 } -// FullNodeAPI indicates an expected call of FullNodeAPI +// FullNodeAPI indicates an expected call of FullNodeAPI. func (mr *MockServicesAPIMockRecorder) FullNodeAPI() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullNodeAPI", reflect.TypeOf((*MockServicesAPI)(nil).FullNodeAPI)) } -// GetBaseFee mocks base method +// GetBaseFee mocks base method. func (m *MockServicesAPI) GetBaseFee(arg0 context.Context) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBaseFee", arg0) @@ -90,13 +91,13 @@ func (m *MockServicesAPI) GetBaseFee(arg0 context.Context) (big.Int, error) { return ret0, ret1 } -// GetBaseFee indicates an expected call of GetBaseFee +// GetBaseFee indicates an expected call of GetBaseFee. func (mr *MockServicesAPIMockRecorder) GetBaseFee(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockServicesAPI)(nil).GetBaseFee), arg0) } -// LocalAddresses mocks base method +// LocalAddresses mocks base method. func (m *MockServicesAPI) LocalAddresses(arg0 context.Context) (go_address.Address, []go_address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LocalAddresses", arg0) @@ -106,13 +107,13 @@ func (m *MockServicesAPI) LocalAddresses(arg0 context.Context) (go_address.Addre return ret0, ret1, ret2 } -// LocalAddresses indicates an expected call of LocalAddresses +// LocalAddresses indicates an expected call of LocalAddresses. func (mr *MockServicesAPIMockRecorder) LocalAddresses(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddresses", reflect.TypeOf((*MockServicesAPI)(nil).LocalAddresses), arg0) } -// MessageForSend mocks base method +// MessageForSend mocks base method. func (m *MockServicesAPI) MessageForSend(arg0 context.Context, arg1 SendParams) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MessageForSend", arg0, arg1) @@ -121,13 +122,13 @@ func (m *MockServicesAPI) MessageForSend(arg0 context.Context, arg1 SendParams) return ret0, ret1 } -// MessageForSend indicates an expected call of MessageForSend +// MessageForSend indicates an expected call of MessageForSend. func (mr *MockServicesAPIMockRecorder) MessageForSend(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MessageForSend", reflect.TypeOf((*MockServicesAPI)(nil).MessageForSend), arg0, arg1) } -// MpoolCheckPendingMessages mocks base method +// MpoolCheckPendingMessages mocks base method. func (m *MockServicesAPI) MpoolCheckPendingMessages(arg0 context.Context, arg1 go_address.Address) ([][]api.MessageCheckStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolCheckPendingMessages", arg0, arg1) @@ -136,13 +137,13 @@ func (m *MockServicesAPI) MpoolCheckPendingMessages(arg0 context.Context, arg1 g return ret0, ret1 } -// MpoolCheckPendingMessages indicates an expected call of MpoolCheckPendingMessages +// MpoolCheckPendingMessages indicates an expected call of MpoolCheckPendingMessages. func (mr *MockServicesAPIMockRecorder) MpoolCheckPendingMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckPendingMessages", reflect.TypeOf((*MockServicesAPI)(nil).MpoolCheckPendingMessages), arg0, arg1) } -// MpoolPendingFilter mocks base method +// MpoolPendingFilter mocks base method. func (m *MockServicesAPI) MpoolPendingFilter(arg0 context.Context, arg1 func(*types.SignedMessage) bool, arg2 types.TipSetKey) ([]*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolPendingFilter", arg0, arg1, arg2) @@ -151,13 +152,13 @@ func (m *MockServicesAPI) MpoolPendingFilter(arg0 context.Context, arg1 func(*ty return ret0, ret1 } -// MpoolPendingFilter indicates an expected call of MpoolPendingFilter +// MpoolPendingFilter indicates an expected call of MpoolPendingFilter. func (mr *MockServicesAPIMockRecorder) MpoolPendingFilter(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPendingFilter", reflect.TypeOf((*MockServicesAPI)(nil).MpoolPendingFilter), arg0, arg1, arg2) } -// PublishMessage mocks base method +// PublishMessage mocks base method. func (m *MockServicesAPI) PublishMessage(arg0 context.Context, arg1 *api.MessagePrototype, arg2 bool) (*types.SignedMessage, [][]api.MessageCheckStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PublishMessage", arg0, arg1, arg2) @@ -167,13 +168,13 @@ func (m *MockServicesAPI) PublishMessage(arg0 context.Context, arg1 *api.Message return ret0, ret1, ret2 } -// PublishMessage indicates an expected call of PublishMessage +// PublishMessage indicates an expected call of PublishMessage. func (mr *MockServicesAPIMockRecorder) PublishMessage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublishMessage", reflect.TypeOf((*MockServicesAPI)(nil).PublishMessage), arg0, arg1, arg2) } -// RunChecksForPrototype mocks base method +// RunChecksForPrototype mocks base method. func (m *MockServicesAPI) RunChecksForPrototype(arg0 context.Context, arg1 *api.MessagePrototype) ([][]api.MessageCheckStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RunChecksForPrototype", arg0, arg1) @@ -182,7 +183,7 @@ func (m *MockServicesAPI) RunChecksForPrototype(arg0 context.Context, arg1 *api. return ret0, ret1 } -// RunChecksForPrototype indicates an expected call of RunChecksForPrototype +// RunChecksForPrototype indicates an expected call of RunChecksForPrototype. func (mr *MockServicesAPIMockRecorder) RunChecksForPrototype(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunChecksForPrototype", reflect.TypeOf((*MockServicesAPI)(nil).RunChecksForPrototype), arg0, arg1) diff --git a/documentation/en/api-v0-methods-worker.md b/documentation/en/api-v0-methods-worker.md index b0130a2a0..925f8934b 100644 --- a/documentation/en/api-v0-methods-worker.md +++ b/documentation/en/api-v0-methods-worker.md @@ -15,8 +15,6 @@ * [MoveStorage](#MoveStorage) * [Process](#Process) * [ProcessSession](#ProcessSession) -* [Read](#Read) - * [ReadPiece](#ReadPiece) * [Release](#Release) * [ReleaseUnsealed](#ReleaseUnsealed) * [Seal](#Seal) @@ -263,41 +261,6 @@ Inputs: `null` Response: `"07070707-0707-0707-0707-070707070707"` -## Read - - -### ReadPiece - - -Perms: admin - -Inputs: -```json -[ - {}, - { - "ID": { - "Miner": 1000, - "Number": 9 - }, - "ProofType": 8 - }, - 1040384, - 1024 -] -``` - -Response: -```json -{ - "Sector": { - "Miner": 1000, - "Number": 9 - }, - "ID": "07070707-0707-0707-0707-070707070707" -} -``` - ## Release diff --git a/extern/sector-storage/manager.go b/extern/sector-storage/manager.go index 8041304a7..2b7e85e3c 100644 --- a/extern/sector-storage/manager.go +++ b/extern/sector-storage/manager.go @@ -133,7 +133,7 @@ func New(ctx context.Context, lstor *stores.Local, stor *stores.Remote, ls store go m.sched.runSched() localTasks := []sealtasks.TaskType{ - sealtasks.TTCommit1, sealtasks.TTFinalize, sealtasks.TTFetch, sealtasks.TTReadUnsealed, + sealtasks.TTCommit1, sealtasks.TTFinalize, sealtasks.TTFetch, } if sc.AllowAddPiece { localTasks = append(localTasks, sealtasks.TTAddPiece) diff --git a/extern/sector-storage/resources.go b/extern/sector-storage/resources.go index 7da3e96a6..2e989fdf4 100644 --- a/extern/sector-storage/resources.go +++ b/extern/sector-storage/resources.go @@ -313,7 +313,6 @@ var ResourceTable = map[sealtasks.TaskType]map[abi.RegisteredSealProof]Resources func init() { ResourceTable[sealtasks.TTUnseal] = ResourceTable[sealtasks.TTPreCommit1] // TODO: measure accurately - ResourceTable[sealtasks.TTReadUnsealed] = ResourceTable[sealtasks.TTFetch] // V1_1 is the same as V1 for _, m := range ResourceTable { diff --git a/extern/sector-storage/sealtasks/task.go b/extern/sector-storage/sealtasks/task.go index 8dd14ca34..6d341a4b3 100644 --- a/extern/sector-storage/sealtasks/task.go +++ b/extern/sector-storage/sealtasks/task.go @@ -11,21 +11,19 @@ const ( TTFinalize TaskType = "seal/v0/finalize" - TTFetch TaskType = "seal/v0/fetch" - TTUnseal TaskType = "seal/v0/unseal" - TTReadUnsealed TaskType = "seal/v0/unsealread" + TTFetch TaskType = "seal/v0/fetch" + TTUnseal TaskType = "seal/v0/unseal" ) var order = map[TaskType]int{ - TTAddPiece: 6, // least priority - TTPreCommit1: 5, - TTPreCommit2: 4, - TTCommit2: 3, - TTCommit1: 2, - TTUnseal: 1, - TTFetch: -1, - TTReadUnsealed: -1, - TTFinalize: -2, // most priority + TTAddPiece: 6, // least priority + TTPreCommit1: 5, + TTPreCommit2: 4, + TTCommit2: 3, + TTCommit1: 2, + TTUnseal: 1, + TTFetch: -1, + TTFinalize: -2, // most priority } var shortNames = map[TaskType]string{ @@ -38,9 +36,8 @@ var shortNames = map[TaskType]string{ TTFinalize: "FIN", - TTFetch: "GET", - TTUnseal: "UNS", - TTReadUnsealed: "RD", + TTFetch: "GET", + TTUnseal: "UNS", } func (a TaskType) MuchLess(b TaskType) (bool, bool) { diff --git a/extern/sector-storage/stores/util_unix.go b/extern/sector-storage/stores/util_unix.go index 2b057468d..9da38c05a 100644 --- a/extern/sector-storage/stores/util_unix.go +++ b/extern/sector-storage/stores/util_unix.go @@ -4,6 +4,7 @@ import ( "bytes" "os/exec" "path/filepath" + "runtime" "strings" "github.com/mitchellh/go-homedir" @@ -33,7 +34,14 @@ func move(from, to string) error { // can do better var errOut bytes.Buffer - cmd := exec.Command("/usr/bin/env", "mv", "-t", toDir, from) // nolint + + var cmd *exec.Cmd + if runtime.GOOS == "darwin" { + cmd = exec.Command("/usr/bin/env", "mv", from, toDir) // nolint + } else { + cmd = exec.Command("/usr/bin/env", "mv", "-t", toDir, from) // nolint + } + cmd.Stderr = &errOut if err := cmd.Run(); err != nil { return xerrors.Errorf("exec mv (stderr: %s): %w", strings.TrimSpace(errOut.String()), err) diff --git a/extern/sector-storage/storiface/worker.go b/extern/sector-storage/storiface/worker.go index 49d1de357..d3f4a2cd1 100644 --- a/extern/sector-storage/storiface/worker.go +++ b/extern/sector-storage/storiface/worker.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io" "time" "github.com/google/uuid" @@ -87,7 +86,6 @@ type WorkerCalls interface { ReleaseUnsealed(ctx context.Context, sector storage.SectorRef, safeToFree []storage.Range) (CallID, error) MoveStorage(ctx context.Context, sector storage.SectorRef, types SectorFileType) (CallID, error) UnsealPiece(context.Context, storage.SectorRef, UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (CallID, error) - ReadPiece(context.Context, io.Writer, storage.SectorRef, UnpaddedByteIndex, abi.UnpaddedPieceSize) (CallID, error) Fetch(context.Context, storage.SectorRef, SectorFileType, PathType, AcquireMode) (CallID, error) } diff --git a/extern/sector-storage/worker_local.go b/extern/sector-storage/worker_local.go index abbad4d9c..63342ffb7 100644 --- a/extern/sector-storage/worker_local.go +++ b/extern/sector-storage/worker_local.go @@ -161,7 +161,6 @@ const ( ReleaseUnsealed ReturnType = "ReleaseUnsealed" MoveStorage ReturnType = "MoveStorage" UnsealPiece ReturnType = "UnsealPiece" - ReadPiece ReturnType = "ReadPiece" Fetch ReturnType = "Fetch" ) @@ -209,7 +208,6 @@ var returnFunc = map[ReturnType]func(context.Context, storiface.CallID, storifac ReleaseUnsealed: rfunc(storiface.WorkerReturn.ReturnReleaseUnsealed), MoveStorage: rfunc(storiface.WorkerReturn.ReturnMoveStorage), UnsealPiece: rfunc(storiface.WorkerReturn.ReturnUnsealPiece), - ReadPiece: rfunc(storiface.WorkerReturn.ReturnReadPiece), Fetch: rfunc(storiface.WorkerReturn.ReturnFetch), } @@ -446,17 +444,6 @@ func (l *LocalWorker) UnsealPiece(ctx context.Context, sector storage.SectorRef, }) } -func (l *LocalWorker) ReadPiece(ctx context.Context, writer io.Writer, sector storage.SectorRef, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (storiface.CallID, error) { - sb, err := l.executor() - if err != nil { - return storiface.UndefCall, err - } - - return l.asyncCall(ctx, sector, ReadPiece, func(ctx context.Context, ci storiface.CallID) (interface{}, error) { - return sb.ReadPiece(ctx, writer, sector, index, size) - }) -} - func (l *LocalWorker) TaskTypes(context.Context) (map[sealtasks.TaskType]struct{}, error) { l.taskLk.Lock() defer l.taskLk.Unlock() diff --git a/extern/sector-storage/worker_tracked.go b/extern/sector-storage/worker_tracked.go index aeb3eea74..2160dd8e6 100644 --- a/extern/sector-storage/worker_tracked.go +++ b/extern/sector-storage/worker_tracked.go @@ -2,7 +2,6 @@ package sectorstorage import ( "context" - "io" "sync" "time" @@ -156,8 +155,4 @@ func (t *trackedWorker) UnsealPiece(ctx context.Context, id storage.SectorRef, i return t.tracker.track(ctx, t.wid, t.workerInfo, id, sealtasks.TTUnseal)(t.Worker.UnsealPiece(ctx, id, index, size, randomness, cid)) } -func (t *trackedWorker) ReadPiece(ctx context.Context, writer io.Writer, id storage.SectorRef, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (storiface.CallID, error) { - return t.tracker.track(ctx, t.wid, t.workerInfo, id, sealtasks.TTReadUnsealed)(t.Worker.ReadPiece(ctx, writer, id, index, size)) -} - var _ Worker = &trackedWorker{} From acfa3d7370e29be877bef8ab5afe3bfed7b4ec5b Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 21 May 2021 11:00:17 +0530 Subject: [PATCH 51/66] finish integration tests --- extern/sector-storage/piece_provider_test.go | 338 +++++++++++++++---- 1 file changed, 269 insertions(+), 69 deletions(-) diff --git a/extern/sector-storage/piece_provider_test.go b/extern/sector-storage/piece_provider_test.go index 8636a11d6..88872aac2 100644 --- a/extern/sector-storage/piece_provider_test.go +++ b/extern/sector-storage/piece_provider_test.go @@ -1,40 +1,36 @@ package sectorstorage import ( + "bytes" "context" "io/ioutil" - "strings" + "math/rand" + "net" + "net/http" "testing" - "time" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-statestore" + "github.com/filecoin-project/lotus/extern/sector-storage/sealtasks" specstorage "github.com/filecoin-project/specs-storage/storage" + "github.com/gorilla/mux" + "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" ds_sync "github.com/ipfs/go-datastore/sync" + logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" - "github.com/filecoin-project/lotus/extern/sector-storage/sealtasks" "github.com/filecoin-project/lotus/extern/sector-storage/stores" "github.com/filecoin-project/lotus/extern/sector-storage/storiface" ) // TestPieceProviderReadPiece verifies that the ReadPiece method works correctly -func TestPieceProviderReadPiece(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) - defer cancel() +// only uses miner and does NOT use any remote worker. +func TestPieceProviderSimpleNoRemoteWorker(t *testing.T) { runTest := func(t *testing.T, alreadyUnsealed bool) { // Set up sector storage manager - storage := newTestStorage(t) - index := stores.NewIndex() - localStore, err := stores.NewLocal(ctx, storage, index, nil) - require.NoError(t, err) - remoteStore := stores.NewRemote(localStore, index, nil, 6000, &stores.DefaultPartialFileHandler{}) - dstore := ds_sync.MutexWrap(datastore.NewMapDatastore()) - wsts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/worker/calls"))) - smsts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/stmgr/calls"))) sealerCfg := SealerConfig{ ParallelFetchLimit: 10, AllowAddPiece: true, @@ -43,76 +39,31 @@ func TestPieceProviderReadPiece(t *testing.T) { AllowCommit: true, AllowUnseal: true, } - mgr, err := New(ctx, localStore, remoteStore, storage, index, sealerCfg, wsts, smsts) - require.NoError(t, err) - // Set up worker - localTasks := []sealtasks.TaskType{ - sealtasks.TTAddPiece, sealtasks.TTPreCommit1, sealtasks.TTCommit1, sealtasks.TTFinalize, sealtasks.TTFetch, - } + ppt := newPieceProviderTestHarness(t, sealerCfg, abi.RegisteredSealProof_StackedDrg8MiBV1) + defer ppt.shutdown(t) - csts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/stmgr/calls"))) - - // passing a nil executor here mirrors an actual worker setup as it - // will initialize the worker to use the rust proofs lib under the hood - worker := newLocalWorker(nil, WorkerConfig{ - TaskTypes: localTasks, - }, remoteStore, localStore, index, mgr, csts) - - err = mgr.AddWorker(ctx, worker) - require.NoError(t, err) - - // Create piece provider - pp := NewPieceProvider(remoteStore, index, mgr) - - // Mock sector - sector := specstorage.SectorRef{ - ID: abi.SectorID{ - Miner: 1000, - Number: 1, - }, - ProofType: abi.RegisteredSealProof_StackedDrg8MiBV1, - } - - // Create some data that when padded will be 8MB - pieceData := strings.Repeat("testthis", 127*1024*8) + // Create some padded data that aligns with the piece boundaries. + pieceData := generatePieceData(8 * 127 * 1024 * 8) size := abi.UnpaddedPieceSize(len(pieceData)) - pieceInfo, err := mgr.AddPiece(ctx, sector, nil, size, strings.NewReader(pieceData)) - require.NoError(t, err) + ppt.addPiece(t, pieceData) // pre-commit 1 - pieces := []abi.PieceInfo{pieceInfo} - ticket := abi.SealRandomness{9, 9, 9, 9, 9, 9, 9, 9} - preCommit1, err := mgr.SealPreCommit1(ctx, sector, ticket, pieces) - require.NoError(t, err) + preCommit1 := ppt.preCommit1(t) // pre-commit 2 - sectorCids, err := mgr.SealPreCommit2(ctx, sector, preCommit1) - require.NoError(t, err) - commD := sectorCids.Unsealed + ppt.preCommit2(t, preCommit1) // If we want to test what happens when the data must be unsealed // (ie there is not an unsealed copy already available) if !alreadyUnsealed { // Remove the unsealed copy from local storage - err = localStore.Remove(ctx, sector.ID, storiface.FTUnsealed, false) - require.NoError(t, err) + ppt.removeAllUnsealedSectorFiles(t) } // Read the piece - offset := storiface.UnpaddedByteIndex(0) - require.NoError(t, err) - reader, unsealed, err := pp.ReadPiece(ctx, sector, offset, size, ticket, commD) - require.NoError(t, err) - requiresUnseal := !alreadyUnsealed - require.Equal(t, requiresUnseal, unsealed) - - defer func() { _ = reader.Close() }() - - // Make sure the input matches the output - readData, err := ioutil.ReadAll(reader) - require.NoError(t, err) - require.Equal(t, pieceData, string(readData)) + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + !alreadyUnsealed, pieceData) } t.Run("already unsealed", func(t *testing.T) { @@ -122,3 +73,252 @@ func TestPieceProviderReadPiece(t *testing.T) { runTest(t, false) }) } + +func TestReadPieceRemoteWorkers(t *testing.T) { + logging.SetAllLoggers(logging.LevelDebug) + + // miner's worker can only add pieces to an unsealed sector. + sealerCfg := SealerConfig{ + ParallelFetchLimit: 10, + AllowAddPiece: true, + AllowPreCommit1: false, + AllowPreCommit2: false, + AllowCommit: false, + AllowUnseal: false, + } + + // test harness for an 8M sector. + ppt := newPieceProviderTestHarness(t, sealerCfg, abi.RegisteredSealProof_StackedDrg8MiBV1) + defer ppt.shutdown(t) + + // worker 2 will ONLY help with the sealing by first fetching + // the unsealed file from the miner. + ppt.addRemoteWorker(t, []sealtasks.TaskType{ + sealtasks.TTPreCommit1, sealtasks.TTPreCommit2, sealtasks.TTCommit1, + sealtasks.TTFetch, sealtasks.TTFinalize, + }) + + // create a worker that can ONLY unseal and fetch + ppt.addRemoteWorker(t, []sealtasks.TaskType{ + sealtasks.TTUnseal, sealtasks.TTFetch, + }) + + // run the test + + // add one piece that aligns with the padding/piece boundaries. + pd1 := generatePieceData(8 * 127 * 4 * 1024) + pi1 := ppt.addPiece(t, pd1) + pd1size := pi1.Size.Unpadded() + + pd2 := generatePieceData(8 * 127 * 4 * 1024) + pi2 := ppt.addPiece(t, pd2) + pd2size := pi2.Size.Unpadded() + + // pre-commit 1 + pC1 := ppt.preCommit1(t) + + // pre-commit 2 + ppt.preCommit2(t, pC1) + + // finalize the sector so we declare to the index we have the sealed file + // so the unsealing worker can later look it up and fetch it if needed + // sending nil here will remove all unsealed files after sector is finalized. + ppt.finalizeSector(t, nil) + + // Read the piece -> have to unseal since we removed the file. + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), pd1size, + true, pd1) + + // Read the same piece again -> will NOT have to unseal. + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), pd1size, false, pd1) + + // remove the unsealed file and read again -> will have to unseal. + ppt.removeAllUnsealedSectorFiles(t) + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), pd1size, + true, pd1) + + // Read Piece 2 -> no unsealing as it got unsealed above. + ppt.readPiece(t, storiface.UnpaddedByteIndex(pd1size), pd2size, false, pd2) + + // remove all unseal files -> Read Piece 2 -> will have to Unseal. + ppt.removeAllUnsealedSectorFiles(t) + ppt.readPiece(t, storiface.UnpaddedByteIndex(pd1size), pd2size, true, pd2) +} + +type pieceProviderTestHarness struct { + ctx context.Context + index *stores.Index + pp PieceProvider + sector specstorage.SectorRef + mgr *Manager + ticket abi.SealRandomness + commD cid.Cid + localStores []*stores.Local + + servers []*http.Server + + addedPieces []abi.PieceInfo +} + +func generatePieceData(size uint64) []byte { + bz := make([]byte, size) + rand.Read(bz) + return bz +} + +func newPieceProviderTestHarness(t *testing.T, mgrConfig SealerConfig, sectorProofType abi.RegisteredSealProof) *pieceProviderTestHarness { + ctx := context.Background() + // listen on tcp socket to create an http server later + address := "0.0.0.0:0" + nl, err := net.Listen("tcp", address) + require.NoError(t, err) + + // create index, storage, local store & remote store. + index := stores.NewIndex() + storage := newTestStorage(t) + localStore, err := stores.NewLocal(ctx, storage, index, []string{"http://" + nl.Addr().String() + "/remote"}) + require.NoError(t, err) + remoteStore := stores.NewRemote(localStore, index, nil, 6000, &stores.DefaultPartialFileHandler{}) + + // data stores for state tracking. + dstore := ds_sync.MutexWrap(datastore.NewMapDatastore()) + wsts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/worker/calls"))) + smsts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/stmgr/calls"))) + + mgr, err := New(ctx, localStore, remoteStore, storage, index, mgrConfig, wsts, smsts) + require.NoError(t, err) + + // start a http server on the manager to serve sector file requests. + svc := &http.Server{ + Addr: nl.Addr().String(), + Handler: mgr, + } + go func() { + _ = svc.Serve(nl) + }() + + pp := NewPieceProvider(remoteStore, index, mgr) + + sector := specstorage.SectorRef{ + ID: abi.SectorID{ + Miner: 100, + Number: 10, + }, + ProofType: sectorProofType, + } + + ticket := abi.SealRandomness{9, 9, 9, 9, 9, 9, 9, 9} + + ppt := &pieceProviderTestHarness{ + ctx: ctx, + index: index, + pp: pp, + sector: sector, + mgr: mgr, + ticket: ticket, + } + ppt.servers = append(ppt.servers, svc) + ppt.localStores = append(ppt.localStores, localStore) + return ppt +} + +func (p *pieceProviderTestHarness) addRemoteWorker(t *testing.T, tasks []sealtasks.TaskType) { + // start an http Server + address := "0.0.0.0:0" + nl, err := net.Listen("tcp", address) + require.NoError(t, err) + + localStore, err := stores.NewLocal(p.ctx, newTestStorage(t), p.index, []string{"http://" + nl.Addr().String() + "/remote"}) + require.NoError(t, err) + + fh := &stores.FetchHandler{ + Local: localStore, + PfHandler: &stores.DefaultPartialFileHandler{}, + } + + mux := mux.NewRouter() + mux.PathPrefix("/remote").HandlerFunc(fh.ServeHTTP) + svc := &http.Server{ + Addr: nl.Addr().String(), + Handler: mux, + } + + go func() { + _ = svc.Serve(nl) + }() + + remote := stores.NewRemote(localStore, p.index, nil, 1000, + &stores.DefaultPartialFileHandler{}) + + dstore := ds_sync.MutexWrap(datastore.NewMapDatastore()) + csts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/stmgr/calls"))) + + worker := newLocalWorker(nil, WorkerConfig{ + TaskTypes: tasks, + }, remote, localStore, p.index, p.mgr, csts) + + p.servers = append(p.servers, svc) + p.localStores = append(p.localStores, localStore) + + // register self with manager + require.NoError(t, p.mgr.AddWorker(p.ctx, worker)) +} + +func (p *pieceProviderTestHarness) removeAllUnsealedSectorFiles(t *testing.T) { + for i := range p.localStores { + ls := p.localStores[i] + require.NoError(t, ls.Remove(p.ctx, p.sector.ID, storiface.FTUnsealed, false)) + } +} + +func (p *pieceProviderTestHarness) addPiece(t *testing.T, pieceData []byte) abi.PieceInfo { + var existing []abi.UnpaddedPieceSize + for _, pi := range p.addedPieces { + existing = append(existing, pi.Size.Unpadded()) + } + + size := abi.UnpaddedPieceSize(len(pieceData)) + pieceInfo, err := p.mgr.AddPiece(p.ctx, p.sector, existing, size, bytes.NewReader(pieceData)) + require.NoError(t, err) + + p.addedPieces = append(p.addedPieces, pieceInfo) + return pieceInfo +} + +func (p *pieceProviderTestHarness) preCommit1(t *testing.T) specstorage.PreCommit1Out { + preCommit1, err := p.mgr.SealPreCommit1(p.ctx, p.sector, p.ticket, p.addedPieces) + require.NoError(t, err) + return preCommit1 +} + +func (p *pieceProviderTestHarness) preCommit2(t *testing.T, pc1 specstorage.PreCommit1Out) { + sectorCids, err := p.mgr.SealPreCommit2(p.ctx, p.sector, pc1) + require.NoError(t, err) + commD := sectorCids.Unsealed + p.commD = commD +} + +func (p *pieceProviderTestHarness) readPiece(t *testing.T, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, + expectedHadToUnseal bool, expectedBytes []byte) { + rd, isUnsealed, err := p.pp.ReadPiece(p.ctx, p.sector, offset, size, p.ticket, p.commD) + require.NoError(t, err) + require.NotNil(t, rd) + require.Equal(t, expectedHadToUnseal, isUnsealed) + defer func() { _ = rd.Close() }() + + // Make sure the input matches the output + readData, err := ioutil.ReadAll(rd) + require.NoError(t, err) + require.Equal(t, expectedBytes, readData) +} + +func (p *pieceProviderTestHarness) finalizeSector(t *testing.T, keepUnseal []specstorage.Range) { + require.NoError(t, p.mgr.FinalizeSector(p.ctx, p.sector, keepUnseal)) +} + +func (p *pieceProviderTestHarness) shutdown(t *testing.T) { + for _, svc := range p.servers { + s := svc + require.NoError(t, s.Shutdown(p.ctx)) + } +} From 22f36483cb57caa5884aa6b8ed46e2504460d8b7 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 21 May 2021 14:56:37 +0530 Subject: [PATCH 52/66] more logging --- extern/sector-storage/piece_provider.go | 1 + extern/sector-storage/stores/remote.go | 2 ++ 2 files changed, 3 insertions(+) diff --git a/extern/sector-storage/piece_provider.go b/extern/sector-storage/piece_provider.go index fd54d2166..9d7ff907b 100644 --- a/extern/sector-storage/piece_provider.go +++ b/extern/sector-storage/piece_provider.go @@ -57,6 +57,7 @@ func (p *pieceProvider) tryReadUnsealedPiece(ctx context.Context, sector storage // the unsealed piece. r, err := p.storage.Reader(ctx, sector, abi.PaddedPieceSize(offset.Padded()), size.Padded()) if err != nil { + log.Debugf("failed storage reader;sector=%+v, err:%s", sector.ID, err) cancel() return nil, nil, err } diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index 7400c6ee0..741928fdf 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -510,6 +510,7 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a log.Infof("Read local %s (+%d,%d)", path, offset, size) ssize, err := s.ProofType.SectorSize() if err != nil { + log.Debugf("failed to get sectorsize: %s", err) return nil, err } @@ -530,6 +531,7 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a if err := r.pfHandler.Close(pf); err != nil { return nil, xerrors.Errorf("close partial file: %w", err) } + log.Debugf("miner has unsealed file but not unseal piece, %s (+%d,%d)", path, offset, size) return nil, nil } From 3b792a32c37ede32172ae1ccf2e0e742f7a874cb Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 21 May 2021 15:16:20 +0530 Subject: [PATCH 53/66] better logging --- extern/sector-storage/piece_provider.go | 3 +++ extern/sector-storage/stores/remote.go | 7 +++++-- extern/sector-storage/worker_local.go | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/extern/sector-storage/piece_provider.go b/extern/sector-storage/piece_provider.go index 9d7ff907b..209989ae4 100644 --- a/extern/sector-storage/piece_provider.go +++ b/extern/sector-storage/piece_provider.go @@ -80,6 +80,9 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, } r, unlock, err := p.tryReadUnsealedPiece(ctx, sector, offset, size) + + log.Infof("tryReadUnsealedPiece result: r=%+v, err=%s", r, err) + if xerrors.Is(err, storiface.ErrSectorNotFound) { log.Debugf("no unsealed sector file with unsealed piece, sector=%+v, offset=%d, size=%d", sector, offset, size) err = nil diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index 741928fdf..cd2848537 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -513,12 +513,14 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a log.Debugf("failed to get sectorsize: %s", err) return nil, err } + log.Infof("fetched sector size %s (+%d,%d)", path, offset, size) // open the unsealed sector file for the given sector size located at the given path. pf, err := r.pfHandler.OpenPartialFile(abi.PaddedPieceSize(ssize), path) if err != nil { return nil, xerrors.Errorf("opening partial file: %w", err) } + log.Infof("partial file opened %s (+%d,%d)", path, offset, size) // even though we have an unsealed file for the given sector, we still need to determine if we have the unsealed piece // in the unsealed sector file. That is what `HasAllocated` checks for. @@ -526,16 +528,17 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a if err != nil { return nil, xerrors.Errorf("has allocated: %w", err) } + log.Infof("partial file is allocated %s (+%d,%d)", path, offset, size) if !has { + log.Infof("miner has unsealed file but not unseal piece, %s (+%d,%d)", path, offset, size) if err := r.pfHandler.Close(pf); err != nil { return nil, xerrors.Errorf("close partial file: %w", err) } - log.Debugf("miner has unsealed file but not unseal piece, %s (+%d,%d)", path, offset, size) return nil, nil } - log.Debugf("returning piece reader for local unsealed piece sector=%+v, (offset=%d, size=%d)", s.ID, offset, size) + log.Infof("returning piece reader for local unsealed piece sector=%+v, (offset=%d, size=%d)", s.ID, offset, size) return r.pfHandler.Reader(pf, storiface.PaddedByteIndex(offset), size) } diff --git a/extern/sector-storage/worker_local.go b/extern/sector-storage/worker_local.go index 63342ffb7..e278739db 100644 --- a/extern/sector-storage/worker_local.go +++ b/extern/sector-storage/worker_local.go @@ -428,6 +428,7 @@ func (l *LocalWorker) UnsealPiece(ctx context.Context, sector storage.SectorRef, } return l.asyncCall(ctx, sector, UnsealPiece, func(ctx context.Context, ci storiface.CallID) (interface{}, error) { + log.Debugf("worker will unseal piece now, sector=%+v", sector.ID) if err = sb.UnsealPiece(ctx, sector, index, size, randomness, cid); err != nil { return nil, xerrors.Errorf("unsealing sector: %w", err) } From 73f7825fbb3bea015cbb3c6c5e44217c35387ce4 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 21 May 2021 15:50:25 +0530 Subject: [PATCH 54/66] clean up logging --- extern/sector-storage/piece_provider.go | 2 +- extern/sector-storage/stores/remote.go | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/extern/sector-storage/piece_provider.go b/extern/sector-storage/piece_provider.go index 209989ae4..34ef44df5 100644 --- a/extern/sector-storage/piece_provider.go +++ b/extern/sector-storage/piece_provider.go @@ -81,7 +81,7 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, r, unlock, err := p.tryReadUnsealedPiece(ctx, sector, offset, size) - log.Infof("tryReadUnsealedPiece result: r=%+v, err=%s", r, err) + log.Debugf("result of tryReadUnsealedPiece: r=%+v, err=%s", r, err) if xerrors.Is(err, storiface.ErrSectorNotFound) { log.Debugf("no unsealed sector file with unsealed piece, sector=%+v, offset=%d, size=%d", sector, offset, size) diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index cd2848537..1bb6b041b 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -510,17 +510,16 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a log.Infof("Read local %s (+%d,%d)", path, offset, size) ssize, err := s.ProofType.SectorSize() if err != nil { - log.Debugf("failed to get sectorsize: %s", err) return nil, err } - log.Infof("fetched sector size %s (+%d,%d)", path, offset, size) + log.Debugf("fetched sector size %s (+%d,%d)", path, offset, size) // open the unsealed sector file for the given sector size located at the given path. pf, err := r.pfHandler.OpenPartialFile(abi.PaddedPieceSize(ssize), path) if err != nil { return nil, xerrors.Errorf("opening partial file: %w", err) } - log.Infof("partial file opened %s (+%d,%d)", path, offset, size) + log.Debugf("local partial file opened %s (+%d,%d)", path, offset, size) // even though we have an unsealed file for the given sector, we still need to determine if we have the unsealed piece // in the unsealed sector file. That is what `HasAllocated` checks for. @@ -528,10 +527,10 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a if err != nil { return nil, xerrors.Errorf("has allocated: %w", err) } - log.Infof("partial file is allocated %s (+%d,%d)", path, offset, size) + log.Debugf("check if partial file is allocated %s (+%d,%d)", path, offset, size) if !has { - log.Infof("miner has unsealed file but not unseal piece, %s (+%d,%d)", path, offset, size) + log.Debugf("miner has unsealed file but not unseal piece, %s (+%d,%d)", path, offset, size) if err := r.pfHandler.Close(pf); err != nil { return nil, xerrors.Errorf("close partial file: %w", err) } From 207f0d901abf50fa8606c2219075054a7a156d49 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 21 May 2021 16:15:08 +0530 Subject: [PATCH 55/66] integration test should remove unsealed files --- extern/sector-storage/piece_provider_test.go | 94 +++++++++++--------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/extern/sector-storage/piece_provider_test.go b/extern/sector-storage/piece_provider_test.go index 88872aac2..6a58ad945 100644 --- a/extern/sector-storage/piece_provider_test.go +++ b/extern/sector-storage/piece_provider_test.go @@ -28,52 +28,54 @@ import ( // TestPieceProviderReadPiece verifies that the ReadPiece method works correctly // only uses miner and does NOT use any remote worker. func TestPieceProviderSimpleNoRemoteWorker(t *testing.T) { - - runTest := func(t *testing.T, alreadyUnsealed bool) { - // Set up sector storage manager - sealerCfg := SealerConfig{ - ParallelFetchLimit: 10, - AllowAddPiece: true, - AllowPreCommit1: true, - AllowPreCommit2: true, - AllowCommit: true, - AllowUnseal: true, - } - - ppt := newPieceProviderTestHarness(t, sealerCfg, abi.RegisteredSealProof_StackedDrg8MiBV1) - defer ppt.shutdown(t) - - // Create some padded data that aligns with the piece boundaries. - pieceData := generatePieceData(8 * 127 * 1024 * 8) - size := abi.UnpaddedPieceSize(len(pieceData)) - ppt.addPiece(t, pieceData) - - // pre-commit 1 - preCommit1 := ppt.preCommit1(t) - - // pre-commit 2 - ppt.preCommit2(t, preCommit1) - - // If we want to test what happens when the data must be unsealed - // (ie there is not an unsealed copy already available) - if !alreadyUnsealed { - // Remove the unsealed copy from local storage - ppt.removeAllUnsealedSectorFiles(t) - } - - // Read the piece - ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, - !alreadyUnsealed, pieceData) + // Set up sector storage manager + sealerCfg := SealerConfig{ + ParallelFetchLimit: 10, + AllowAddPiece: true, + AllowPreCommit1: true, + AllowPreCommit2: true, + AllowCommit: true, + AllowUnseal: true, } - t.Run("already unsealed", func(t *testing.T) { - runTest(t, true) - }) - t.Run("requires unseal", func(t *testing.T) { - runTest(t, false) - }) -} + ppt := newPieceProviderTestHarness(t, sealerCfg, abi.RegisteredSealProof_StackedDrg8MiBV1) + defer ppt.shutdown(t) + // Create some padded data that aligns with the piece boundaries. + pieceData := generatePieceData(8 * 127 * 1024 * 8) + size := abi.UnpaddedPieceSize(len(pieceData)) + ppt.addPiece(t, pieceData) + + // read piece + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + false, pieceData) + + // pre-commit 1 + preCommit1 := ppt.preCommit1(t) + + // read piece + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + false, pieceData) + + // pre-commit 2 + ppt.preCommit2(t, preCommit1) + + // read piece + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + false, pieceData) + + // finalize -> nil here will remove unsealed file + ppt.finalizeSector(t, nil) + + // Read the piece -> will have to unseal + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + true, pieceData) + + // read the piece -> will not have to unseal + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + false, pieceData) + +} func TestReadPieceRemoteWorkers(t *testing.T) { logging.SetAllLoggers(logging.LevelDebug) @@ -116,9 +118,15 @@ func TestReadPieceRemoteWorkers(t *testing.T) { // pre-commit 1 pC1 := ppt.preCommit1(t) + // Read the piece -> no need to unseal + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), pd1size, + false, pd1) // pre-commit 2 ppt.preCommit2(t, pC1) + // Read the piece -> no need to unseal + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), pd1size, + false, pd1) // finalize the sector so we declare to the index we have the sealed file // so the unsealing worker can later look it up and fetch it if needed From ec6a49693f3f44197cee75ed2653e244a5e13bc5 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 21 May 2021 19:01:17 +0530 Subject: [PATCH 56/66] logs to debug read and unseal --- extern/sector-storage/manager.go | 4 ++-- extern/sector-storage/piece_provider.go | 8 ++++++-- extern/sector-storage/stores/remote.go | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/extern/sector-storage/manager.go b/extern/sector-storage/manager.go index 2b7e85e3c..51558aaad 100644 --- a/extern/sector-storage/manager.go +++ b/extern/sector-storage/manager.go @@ -235,14 +235,14 @@ func (m *Manager) SectorsUnsealPiece(ctx context.Context, sector storage.SectorR // one of it's sealing scratch spaces to store them after fetching them from another worker. selector := newExistingSelector(m.index, sector.ID, storiface.FTSealed|storiface.FTCache, true) - log.Debugf("schedule unseal for sector %d", sector.ID) + log.Debugf("will schedule unseal for sector %d", sector.ID) err = m.sched.Schedule(ctx, sector, sealtasks.TTUnseal, selector, sealFetch, func(ctx context.Context, w Worker) error { // TODO: make restartable // NOTE: we're unsealing the whole sector here as with SDR we can't really // unseal the sector partially. Requesting the whole sector here can // save us some work in case another piece is requested from here - log.Debugf("unseal sector %d", sector.ID) + log.Debugf("calling unseal sector on worker, sectoID=%d", sector.ID) // Note: This unseal piece call will essentially become a no-op if the worker already has an Unsealed sector file for the given sector. _, err := m.waitSimpleCall(ctx)(w.UnsealPiece(ctx, sector, 0, abi.PaddedPieceSize(ssize).Unpadded(), ticket, *unsealed)) diff --git a/extern/sector-storage/piece_provider.go b/extern/sector-storage/piece_provider.go index 34ef44df5..7d46ed92a 100644 --- a/extern/sector-storage/piece_provider.go +++ b/extern/sector-storage/piece_provider.go @@ -57,7 +57,7 @@ func (p *pieceProvider) tryReadUnsealedPiece(ctx context.Context, sector storage // the unsealed piece. r, err := p.storage.Reader(ctx, sector, abi.PaddedPieceSize(offset.Padded()), size.Padded()) if err != nil { - log.Debugf("failed storage reader;sector=%+v, err:%s", sector.ID, err) + log.Debugf("did not get storage reader;sector=%+v, err:%s", sector.ID, err) cancel() return nil, nil, err } @@ -81,13 +81,14 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, r, unlock, err := p.tryReadUnsealedPiece(ctx, sector, offset, size) - log.Debugf("result of tryReadUnsealedPiece: r=%+v, err=%s", r, err) + log.Debugf("result of first tryReadUnsealedPiece: r=%+v, err=%s", r, err) if xerrors.Is(err, storiface.ErrSectorNotFound) { log.Debugf("no unsealed sector file with unsealed piece, sector=%+v, offset=%d, size=%d", sector, offset, size) err = nil } if err != nil { + log.Errorf("returning error from ReadPiece:%s", err) return nil, false, err } @@ -103,6 +104,7 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, commd = nil } if err := p.uns.SectorsUnsealPiece(ctx, sector, offset, size, ticket, commd); err != nil { + log.Errorf("failed to SectorsUnsealPiece: %s", err) return nil, false, xerrors.Errorf("unsealing piece: %w", err) } @@ -110,9 +112,11 @@ func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, r, unlock, err = p.tryReadUnsealedPiece(ctx, sector, offset, size) if err != nil { + log.Errorf("failed to tryReadUnsealedPiece after SectorsUnsealPiece: %s", err) return nil, true, xerrors.Errorf("read after unsealing: %w", err) } if r == nil { + log.Errorf("got no reader after unsealing piece") return nil, true, xerrors.Errorf("got no reader after unsealing piece") } log.Debugf("got a reader to read unsealed piece, sector=%+v, offset=%d, size=%d", sector, offset, size) diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index 1bb6b041b..2906756de 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -548,6 +548,7 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a // if they have the unsealed piece in the unsealed sector file. si, err := r.index.StorageFindSector(ctx, s.ID, ft, 0, false) if err != nil { + log.Debugf("Reader, did not find unsealed file on any of the workers %s (+%d,%d)", path, offset, size) return nil, err } From 2a134887c3efda2dbd8d61c6bc3e2e91ebfd21ac Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 21 May 2021 19:02:37 +0530 Subject: [PATCH 57/66] logs to debug read & unseal --- extern/sector-storage/worker_local.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extern/sector-storage/worker_local.go b/extern/sector-storage/worker_local.go index e278739db..2bb0f8300 100644 --- a/extern/sector-storage/worker_local.go +++ b/extern/sector-storage/worker_local.go @@ -441,6 +441,8 @@ func (l *LocalWorker) UnsealPiece(ctx context.Context, sector storage.SectorRef, return nil, xerrors.Errorf("removing source data: %w", err) } + log.Debugf("worker has unsealed piece, sector=%+v", sector.ID) + return nil, nil }) } From 8d9cef17afb9abf732802efd28e0bd040298fde5 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 21 May 2021 19:15:05 +0530 Subject: [PATCH 58/66] changes as per review --- extern/sector-storage/piece_provider.go | 3 +++ extern/sector-storage/stores/http_handler.go | 1 - extern/sector-storage/stores/remote.go | 10 ++++++++-- extern/sector-storage/stores/util_unix.go | 5 +++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/extern/sector-storage/piece_provider.go b/extern/sector-storage/piece_provider.go index 7d46ed92a..553dcb952 100644 --- a/extern/sector-storage/piece_provider.go +++ b/extern/sector-storage/piece_provider.go @@ -71,6 +71,9 @@ func (p *pieceProvider) tryReadUnsealedPiece(ctx context.Context, sector storage // ReadPiece is used to read an Unsealed piece at the given offset and of the given size from a Sector // If an Unsealed sector file exists with the Piece Unsealed in it, we'll use that for the read. // Otherwise, we will Unseal a Sealed sector file for the given sector and read the Unsealed piece from it. +// If we do NOT have an existing unsealed file containing the given piece thus causing us to schedule an Unseal, +// the returned boolean parameter will be set to true. +// If we have an existing unsealed file containing the given piece, the returned boolean will be set to false. func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) (io.ReadCloser, bool, error) { if err := offset.Valid(); err != nil { return nil, false, xerrors.Errorf("offset is not valid: %w", err) diff --git a/extern/sector-storage/stores/http_handler.go b/extern/sector-storage/stores/http_handler.go index e195cd7a9..dc7797157 100644 --- a/extern/sector-storage/stores/http_handler.go +++ b/extern/sector-storage/stores/http_handler.go @@ -155,7 +155,6 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ } } else { w.Header().Set("Content-Type", "application/octet-stream") - w.WriteHeader(200) // will do a ranged read over the file at the given path if the caller has asked for a ranged read in the request headers. http.ServeFile(w, r, path) } diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index 2906756de..18e20ee37 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -560,6 +560,7 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a return si[i].Weight > si[j].Weight }) + var lastErr error for _, info := range si { for _, url := range info.URLs { // checkAllocated makes a JSON RPC query to a remote worker to determine if it has @@ -567,6 +568,7 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a ok, err := r.checkAllocated(ctx, url, s.ProofType, offset, size) if err != nil { log.Warnw("check if remote has piece", "url", url, "error", err) + lastErr = err continue } if !ok { @@ -578,6 +580,7 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a rd, err := r.readRemote(ctx, url, offset, size) if err != nil { log.Warnw("reading from remote", "url", url, "error", err) + lastErr = err continue } log.Infof("Read remote %s (+%d,%d)", url, offset, size) @@ -586,12 +589,15 @@ func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size a } // we couldn't find a unsealed file with the unsealed piece, will return a nil reader. - log.Debugf("returning nil reader, did not find unsealed piece for %+v (+%d,%d)", s, offset, size) + log.Debugf("returning nil reader, did not find unsealed piece for %+v (+%d,%d), last error=%s", s, offset, size, lastErr) return nil, nil } func (r *Remote) Reserve(ctx context.Context, sid storage.SectorRef, ft storiface.SectorFileType, storageIDs storiface.SectorPaths, overheadTab map[storiface.SectorFileType]int) (func(), error) { - panic("not implemented") + log.Warnf("reserve called on remote store, sectorID: %v", sid.ID) + return func() { + + }, nil } var _ Store = &Remote{} diff --git a/extern/sector-storage/stores/util_unix.go b/extern/sector-storage/stores/util_unix.go index 9da38c05a..943681b49 100644 --- a/extern/sector-storage/stores/util_unix.go +++ b/extern/sector-storage/stores/util_unix.go @@ -2,6 +2,7 @@ package stores import ( "bytes" + "os" "os/exec" "path/filepath" "runtime" @@ -37,6 +38,10 @@ func move(from, to string) error { var cmd *exec.Cmd if runtime.GOOS == "darwin" { + if err := os.MkdirAll(toDir, 0777); err != nil { + return xerrors.Errorf("failed exec MkdirAll: %s", err) + } + cmd = exec.Command("/usr/bin/env", "mv", from, toDir) // nolint } else { cmd = exec.Command("/usr/bin/env", "mv", "-t", toDir, from) // nolint From 21e6b50294fe673903700fafa7238ce129c7e610 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 7 Jun 2021 16:02:15 +0530 Subject: [PATCH 59/66] finished rebasing PR --- api/mocks/mock_full.go | 820 ++++++++++++++++----------------- api/v0api/v0mocks/mock_full.go | 816 ++++++++++++++++---------------- build/openrpc/full.json.gz | Bin 23440 -> 23436 bytes build/openrpc/miner.json.gz | Bin 8089 -> 8088 bytes build/openrpc/worker.json.gz | Bin 2580 -> 2497 bytes node/test/builder.go | 14 +- 6 files changed, 830 insertions(+), 820 deletions(-) diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 71c621846..bb83a88a2 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -37,30 +37,30 @@ import ( protocol "github.com/libp2p/go-libp2p-core/protocol" ) -// MockFullNode is a mock of FullNode interface +// MockFullNode is a mock of FullNode interface. type MockFullNode struct { ctrl *gomock.Controller recorder *MockFullNodeMockRecorder } -// MockFullNodeMockRecorder is the mock recorder for MockFullNode +// MockFullNodeMockRecorder is the mock recorder for MockFullNode. type MockFullNodeMockRecorder struct { mock *MockFullNode } -// NewMockFullNode creates a new mock instance +// NewMockFullNode creates a new mock instance. func NewMockFullNode(ctrl *gomock.Controller) *MockFullNode { mock := &MockFullNode{ctrl: ctrl} mock.recorder = &MockFullNodeMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockFullNode) EXPECT() *MockFullNodeMockRecorder { return m.recorder } -// AuthNew mocks base method +// AuthNew mocks base method. func (m *MockFullNode) AuthNew(arg0 context.Context, arg1 []auth.Permission) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AuthNew", arg0, arg1) @@ -69,13 +69,13 @@ func (m *MockFullNode) AuthNew(arg0 context.Context, arg1 []auth.Permission) ([] return ret0, ret1 } -// AuthNew indicates an expected call of AuthNew +// AuthNew indicates an expected call of AuthNew. func (mr *MockFullNodeMockRecorder) AuthNew(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthNew", reflect.TypeOf((*MockFullNode)(nil).AuthNew), arg0, arg1) } -// AuthVerify mocks base method +// AuthVerify mocks base method. func (m *MockFullNode) AuthVerify(arg0 context.Context, arg1 string) ([]auth.Permission, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AuthVerify", arg0, arg1) @@ -84,13 +84,13 @@ func (m *MockFullNode) AuthVerify(arg0 context.Context, arg1 string) ([]auth.Per return ret0, ret1 } -// AuthVerify indicates an expected call of AuthVerify +// AuthVerify indicates an expected call of AuthVerify. func (mr *MockFullNodeMockRecorder) AuthVerify(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthVerify", reflect.TypeOf((*MockFullNode)(nil).AuthVerify), arg0, arg1) } -// BeaconGetEntry mocks base method +// BeaconGetEntry mocks base method. func (m *MockFullNode) BeaconGetEntry(arg0 context.Context, arg1 abi.ChainEpoch) (*types.BeaconEntry, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BeaconGetEntry", arg0, arg1) @@ -99,13 +99,13 @@ func (m *MockFullNode) BeaconGetEntry(arg0 context.Context, arg1 abi.ChainEpoch) return ret0, ret1 } -// BeaconGetEntry indicates an expected call of BeaconGetEntry +// BeaconGetEntry indicates an expected call of BeaconGetEntry. func (mr *MockFullNodeMockRecorder) BeaconGetEntry(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconGetEntry", reflect.TypeOf((*MockFullNode)(nil).BeaconGetEntry), arg0, arg1) } -// ChainDeleteObj mocks base method +// ChainDeleteObj mocks base method. func (m *MockFullNode) ChainDeleteObj(arg0 context.Context, arg1 cid.Cid) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainDeleteObj", arg0, arg1) @@ -113,13 +113,13 @@ func (m *MockFullNode) ChainDeleteObj(arg0 context.Context, arg1 cid.Cid) error return ret0 } -// ChainDeleteObj indicates an expected call of ChainDeleteObj +// ChainDeleteObj indicates an expected call of ChainDeleteObj. func (mr *MockFullNodeMockRecorder) ChainDeleteObj(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainDeleteObj", reflect.TypeOf((*MockFullNode)(nil).ChainDeleteObj), arg0, arg1) } -// ChainExport mocks base method +// ChainExport mocks base method. func (m *MockFullNode) ChainExport(arg0 context.Context, arg1 abi.ChainEpoch, arg2 bool, arg3 types.TipSetKey) (<-chan []byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainExport", arg0, arg1, arg2, arg3) @@ -128,13 +128,13 @@ func (m *MockFullNode) ChainExport(arg0 context.Context, arg1 abi.ChainEpoch, ar return ret0, ret1 } -// ChainExport indicates an expected call of ChainExport +// ChainExport indicates an expected call of ChainExport. func (mr *MockFullNodeMockRecorder) ChainExport(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainExport", reflect.TypeOf((*MockFullNode)(nil).ChainExport), arg0, arg1, arg2, arg3) } -// ChainGetBlock mocks base method +// ChainGetBlock mocks base method. func (m *MockFullNode) ChainGetBlock(arg0 context.Context, arg1 cid.Cid) (*types.BlockHeader, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetBlock", arg0, arg1) @@ -143,13 +143,13 @@ func (m *MockFullNode) ChainGetBlock(arg0 context.Context, arg1 cid.Cid) (*types return ret0, ret1 } -// ChainGetBlock indicates an expected call of ChainGetBlock +// ChainGetBlock indicates an expected call of ChainGetBlock. func (mr *MockFullNodeMockRecorder) ChainGetBlock(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetBlock", reflect.TypeOf((*MockFullNode)(nil).ChainGetBlock), arg0, arg1) } -// ChainGetBlockMessages mocks base method +// ChainGetBlockMessages mocks base method. func (m *MockFullNode) ChainGetBlockMessages(arg0 context.Context, arg1 cid.Cid) (*api.BlockMessages, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetBlockMessages", arg0, arg1) @@ -158,13 +158,13 @@ func (m *MockFullNode) ChainGetBlockMessages(arg0 context.Context, arg1 cid.Cid) return ret0, ret1 } -// ChainGetBlockMessages indicates an expected call of ChainGetBlockMessages +// ChainGetBlockMessages indicates an expected call of ChainGetBlockMessages. func (mr *MockFullNodeMockRecorder) ChainGetBlockMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetBlockMessages", reflect.TypeOf((*MockFullNode)(nil).ChainGetBlockMessages), arg0, arg1) } -// ChainGetGenesis mocks base method +// ChainGetGenesis mocks base method. func (m *MockFullNode) ChainGetGenesis(arg0 context.Context) (*types.TipSet, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetGenesis", arg0) @@ -173,13 +173,13 @@ func (m *MockFullNode) ChainGetGenesis(arg0 context.Context) (*types.TipSet, err return ret0, ret1 } -// ChainGetGenesis indicates an expected call of ChainGetGenesis +// ChainGetGenesis indicates an expected call of ChainGetGenesis. func (mr *MockFullNodeMockRecorder) ChainGetGenesis(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetGenesis", reflect.TypeOf((*MockFullNode)(nil).ChainGetGenesis), arg0) } -// ChainGetMessage mocks base method +// ChainGetMessage mocks base method. func (m *MockFullNode) ChainGetMessage(arg0 context.Context, arg1 cid.Cid) (*types.Message, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetMessage", arg0, arg1) @@ -188,13 +188,13 @@ func (m *MockFullNode) ChainGetMessage(arg0 context.Context, arg1 cid.Cid) (*typ return ret0, ret1 } -// ChainGetMessage indicates an expected call of ChainGetMessage +// ChainGetMessage indicates an expected call of ChainGetMessage. func (mr *MockFullNodeMockRecorder) ChainGetMessage(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetMessage", reflect.TypeOf((*MockFullNode)(nil).ChainGetMessage), arg0, arg1) } -// ChainGetNode mocks base method +// ChainGetNode mocks base method. func (m *MockFullNode) ChainGetNode(arg0 context.Context, arg1 string) (*api.IpldObject, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetNode", arg0, arg1) @@ -203,13 +203,13 @@ func (m *MockFullNode) ChainGetNode(arg0 context.Context, arg1 string) (*api.Ipl return ret0, ret1 } -// ChainGetNode indicates an expected call of ChainGetNode +// ChainGetNode indicates an expected call of ChainGetNode. func (mr *MockFullNodeMockRecorder) ChainGetNode(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetNode", reflect.TypeOf((*MockFullNode)(nil).ChainGetNode), arg0, arg1) } -// ChainGetParentMessages mocks base method +// ChainGetParentMessages mocks base method. func (m *MockFullNode) ChainGetParentMessages(arg0 context.Context, arg1 cid.Cid) ([]api.Message, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetParentMessages", arg0, arg1) @@ -218,13 +218,13 @@ func (m *MockFullNode) ChainGetParentMessages(arg0 context.Context, arg1 cid.Cid return ret0, ret1 } -// ChainGetParentMessages indicates an expected call of ChainGetParentMessages +// ChainGetParentMessages indicates an expected call of ChainGetParentMessages. func (mr *MockFullNodeMockRecorder) ChainGetParentMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetParentMessages", reflect.TypeOf((*MockFullNode)(nil).ChainGetParentMessages), arg0, arg1) } -// ChainGetParentReceipts mocks base method +// ChainGetParentReceipts mocks base method. func (m *MockFullNode) ChainGetParentReceipts(arg0 context.Context, arg1 cid.Cid) ([]*types.MessageReceipt, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetParentReceipts", arg0, arg1) @@ -233,13 +233,13 @@ func (m *MockFullNode) ChainGetParentReceipts(arg0 context.Context, arg1 cid.Cid return ret0, ret1 } -// ChainGetParentReceipts indicates an expected call of ChainGetParentReceipts +// ChainGetParentReceipts indicates an expected call of ChainGetParentReceipts. func (mr *MockFullNodeMockRecorder) ChainGetParentReceipts(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetParentReceipts", reflect.TypeOf((*MockFullNode)(nil).ChainGetParentReceipts), arg0, arg1) } -// ChainGetPath mocks base method +// ChainGetPath mocks base method. func (m *MockFullNode) ChainGetPath(arg0 context.Context, arg1, arg2 types.TipSetKey) ([]*api.HeadChange, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetPath", arg0, arg1, arg2) @@ -248,13 +248,13 @@ func (m *MockFullNode) ChainGetPath(arg0 context.Context, arg1, arg2 types.TipSe return ret0, ret1 } -// ChainGetPath indicates an expected call of ChainGetPath +// ChainGetPath indicates an expected call of ChainGetPath. func (mr *MockFullNodeMockRecorder) ChainGetPath(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetPath", reflect.TypeOf((*MockFullNode)(nil).ChainGetPath), arg0, arg1, arg2) } -// ChainGetRandomnessFromBeacon mocks base method +// ChainGetRandomnessFromBeacon mocks base method. func (m *MockFullNode) ChainGetRandomnessFromBeacon(arg0 context.Context, arg1 types.TipSetKey, arg2 crypto.DomainSeparationTag, arg3 abi.ChainEpoch, arg4 []byte) (abi.Randomness, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetRandomnessFromBeacon", arg0, arg1, arg2, arg3, arg4) @@ -263,13 +263,13 @@ func (m *MockFullNode) ChainGetRandomnessFromBeacon(arg0 context.Context, arg1 t return ret0, ret1 } -// ChainGetRandomnessFromBeacon indicates an expected call of ChainGetRandomnessFromBeacon +// ChainGetRandomnessFromBeacon indicates an expected call of ChainGetRandomnessFromBeacon. func (mr *MockFullNodeMockRecorder) ChainGetRandomnessFromBeacon(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetRandomnessFromBeacon", reflect.TypeOf((*MockFullNode)(nil).ChainGetRandomnessFromBeacon), arg0, arg1, arg2, arg3, arg4) } -// ChainGetRandomnessFromTickets mocks base method +// ChainGetRandomnessFromTickets mocks base method. func (m *MockFullNode) ChainGetRandomnessFromTickets(arg0 context.Context, arg1 types.TipSetKey, arg2 crypto.DomainSeparationTag, arg3 abi.ChainEpoch, arg4 []byte) (abi.Randomness, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetRandomnessFromTickets", arg0, arg1, arg2, arg3, arg4) @@ -278,13 +278,13 @@ func (m *MockFullNode) ChainGetRandomnessFromTickets(arg0 context.Context, arg1 return ret0, ret1 } -// ChainGetRandomnessFromTickets indicates an expected call of ChainGetRandomnessFromTickets +// ChainGetRandomnessFromTickets indicates an expected call of ChainGetRandomnessFromTickets. func (mr *MockFullNodeMockRecorder) ChainGetRandomnessFromTickets(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetRandomnessFromTickets", reflect.TypeOf((*MockFullNode)(nil).ChainGetRandomnessFromTickets), arg0, arg1, arg2, arg3, arg4) } -// ChainGetTipSet mocks base method +// ChainGetTipSet mocks base method. func (m *MockFullNode) ChainGetTipSet(arg0 context.Context, arg1 types.TipSetKey) (*types.TipSet, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetTipSet", arg0, arg1) @@ -293,13 +293,13 @@ func (m *MockFullNode) ChainGetTipSet(arg0 context.Context, arg1 types.TipSetKey return ret0, ret1 } -// ChainGetTipSet indicates an expected call of ChainGetTipSet +// ChainGetTipSet indicates an expected call of ChainGetTipSet. func (mr *MockFullNodeMockRecorder) ChainGetTipSet(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetTipSet", reflect.TypeOf((*MockFullNode)(nil).ChainGetTipSet), arg0, arg1) } -// ChainGetTipSetByHeight mocks base method +// ChainGetTipSetByHeight mocks base method. func (m *MockFullNode) ChainGetTipSetByHeight(arg0 context.Context, arg1 abi.ChainEpoch, arg2 types.TipSetKey) (*types.TipSet, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetTipSetByHeight", arg0, arg1, arg2) @@ -308,13 +308,13 @@ func (m *MockFullNode) ChainGetTipSetByHeight(arg0 context.Context, arg1 abi.Cha return ret0, ret1 } -// ChainGetTipSetByHeight indicates an expected call of ChainGetTipSetByHeight +// ChainGetTipSetByHeight indicates an expected call of ChainGetTipSetByHeight. func (mr *MockFullNodeMockRecorder) ChainGetTipSetByHeight(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetTipSetByHeight", reflect.TypeOf((*MockFullNode)(nil).ChainGetTipSetByHeight), arg0, arg1, arg2) } -// ChainHasObj mocks base method +// ChainHasObj mocks base method. func (m *MockFullNode) ChainHasObj(arg0 context.Context, arg1 cid.Cid) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainHasObj", arg0, arg1) @@ -323,13 +323,13 @@ func (m *MockFullNode) ChainHasObj(arg0 context.Context, arg1 cid.Cid) (bool, er return ret0, ret1 } -// ChainHasObj indicates an expected call of ChainHasObj +// ChainHasObj indicates an expected call of ChainHasObj. func (mr *MockFullNodeMockRecorder) ChainHasObj(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHasObj", reflect.TypeOf((*MockFullNode)(nil).ChainHasObj), arg0, arg1) } -// ChainHead mocks base method +// ChainHead mocks base method. func (m *MockFullNode) ChainHead(arg0 context.Context) (*types.TipSet, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainHead", arg0) @@ -338,13 +338,13 @@ func (m *MockFullNode) ChainHead(arg0 context.Context) (*types.TipSet, error) { return ret0, ret1 } -// ChainHead indicates an expected call of ChainHead +// ChainHead indicates an expected call of ChainHead. func (mr *MockFullNodeMockRecorder) ChainHead(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHead", reflect.TypeOf((*MockFullNode)(nil).ChainHead), arg0) } -// ChainNotify mocks base method +// ChainNotify mocks base method. func (m *MockFullNode) ChainNotify(arg0 context.Context) (<-chan []*api.HeadChange, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainNotify", arg0) @@ -353,13 +353,13 @@ func (m *MockFullNode) ChainNotify(arg0 context.Context) (<-chan []*api.HeadChan return ret0, ret1 } -// ChainNotify indicates an expected call of ChainNotify +// ChainNotify indicates an expected call of ChainNotify. func (mr *MockFullNodeMockRecorder) ChainNotify(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainNotify", reflect.TypeOf((*MockFullNode)(nil).ChainNotify), arg0) } -// ChainReadObj mocks base method +// ChainReadObj mocks base method. func (m *MockFullNode) ChainReadObj(arg0 context.Context, arg1 cid.Cid) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainReadObj", arg0, arg1) @@ -368,13 +368,13 @@ func (m *MockFullNode) ChainReadObj(arg0 context.Context, arg1 cid.Cid) ([]byte, return ret0, ret1 } -// ChainReadObj indicates an expected call of ChainReadObj +// ChainReadObj indicates an expected call of ChainReadObj. func (mr *MockFullNodeMockRecorder) ChainReadObj(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainReadObj", reflect.TypeOf((*MockFullNode)(nil).ChainReadObj), arg0, arg1) } -// ChainSetHead mocks base method +// ChainSetHead mocks base method. func (m *MockFullNode) ChainSetHead(arg0 context.Context, arg1 types.TipSetKey) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainSetHead", arg0, arg1) @@ -382,13 +382,13 @@ func (m *MockFullNode) ChainSetHead(arg0 context.Context, arg1 types.TipSetKey) return ret0 } -// ChainSetHead indicates an expected call of ChainSetHead +// ChainSetHead indicates an expected call of ChainSetHead. func (mr *MockFullNodeMockRecorder) ChainSetHead(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainSetHead", reflect.TypeOf((*MockFullNode)(nil).ChainSetHead), arg0, arg1) } -// ChainStatObj mocks base method +// ChainStatObj mocks base method. func (m *MockFullNode) ChainStatObj(arg0 context.Context, arg1, arg2 cid.Cid) (api.ObjStat, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainStatObj", arg0, arg1, arg2) @@ -397,13 +397,13 @@ func (m *MockFullNode) ChainStatObj(arg0 context.Context, arg1, arg2 cid.Cid) (a return ret0, ret1 } -// ChainStatObj indicates an expected call of ChainStatObj +// ChainStatObj indicates an expected call of ChainStatObj. func (mr *MockFullNodeMockRecorder) ChainStatObj(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainStatObj", reflect.TypeOf((*MockFullNode)(nil).ChainStatObj), arg0, arg1, arg2) } -// ChainTipSetWeight mocks base method +// ChainTipSetWeight mocks base method. func (m *MockFullNode) ChainTipSetWeight(arg0 context.Context, arg1 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainTipSetWeight", arg0, arg1) @@ -412,13 +412,13 @@ func (m *MockFullNode) ChainTipSetWeight(arg0 context.Context, arg1 types.TipSet return ret0, ret1 } -// ChainTipSetWeight indicates an expected call of ChainTipSetWeight +// ChainTipSetWeight indicates an expected call of ChainTipSetWeight. func (mr *MockFullNodeMockRecorder) ChainTipSetWeight(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainTipSetWeight", reflect.TypeOf((*MockFullNode)(nil).ChainTipSetWeight), arg0, arg1) } -// ClientCalcCommP mocks base method +// ClientCalcCommP mocks base method. func (m *MockFullNode) ClientCalcCommP(arg0 context.Context, arg1 string) (*api.CommPRet, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientCalcCommP", arg0, arg1) @@ -427,13 +427,13 @@ func (m *MockFullNode) ClientCalcCommP(arg0 context.Context, arg1 string) (*api. return ret0, ret1 } -// ClientCalcCommP indicates an expected call of ClientCalcCommP +// ClientCalcCommP indicates an expected call of ClientCalcCommP. func (mr *MockFullNodeMockRecorder) ClientCalcCommP(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCalcCommP", reflect.TypeOf((*MockFullNode)(nil).ClientCalcCommP), arg0, arg1) } -// ClientCancelDataTransfer mocks base method +// ClientCancelDataTransfer mocks base method. func (m *MockFullNode) ClientCancelDataTransfer(arg0 context.Context, arg1 datatransfer.TransferID, arg2 peer.ID, arg3 bool) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientCancelDataTransfer", arg0, arg1, arg2, arg3) @@ -441,13 +441,13 @@ func (m *MockFullNode) ClientCancelDataTransfer(arg0 context.Context, arg1 datat return ret0 } -// ClientCancelDataTransfer indicates an expected call of ClientCancelDataTransfer +// ClientCancelDataTransfer indicates an expected call of ClientCancelDataTransfer. func (mr *MockFullNodeMockRecorder) ClientCancelDataTransfer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelDataTransfer", reflect.TypeOf((*MockFullNode)(nil).ClientCancelDataTransfer), arg0, arg1, arg2, arg3) } -// ClientCancelRetrievalDeal mocks base method +// ClientCancelRetrievalDeal mocks base method. func (m *MockFullNode) ClientCancelRetrievalDeal(arg0 context.Context, arg1 retrievalmarket.DealID) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientCancelRetrievalDeal", arg0, arg1) @@ -455,13 +455,13 @@ func (m *MockFullNode) ClientCancelRetrievalDeal(arg0 context.Context, arg1 retr return ret0 } -// ClientCancelRetrievalDeal indicates an expected call of ClientCancelRetrievalDeal +// ClientCancelRetrievalDeal indicates an expected call of ClientCancelRetrievalDeal. func (mr *MockFullNodeMockRecorder) ClientCancelRetrievalDeal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelRetrievalDeal", reflect.TypeOf((*MockFullNode)(nil).ClientCancelRetrievalDeal), arg0, arg1) } -// ClientDataTransferUpdates mocks base method +// ClientDataTransferUpdates mocks base method. func (m *MockFullNode) ClientDataTransferUpdates(arg0 context.Context) (<-chan api.DataTransferChannel, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientDataTransferUpdates", arg0) @@ -470,13 +470,13 @@ func (m *MockFullNode) ClientDataTransferUpdates(arg0 context.Context) (<-chan a return ret0, ret1 } -// ClientDataTransferUpdates indicates an expected call of ClientDataTransferUpdates +// ClientDataTransferUpdates indicates an expected call of ClientDataTransferUpdates. func (mr *MockFullNodeMockRecorder) ClientDataTransferUpdates(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDataTransferUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientDataTransferUpdates), arg0) } -// ClientDealPieceCID mocks base method +// ClientDealPieceCID mocks base method. func (m *MockFullNode) ClientDealPieceCID(arg0 context.Context, arg1 cid.Cid) (api.DataCIDSize, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientDealPieceCID", arg0, arg1) @@ -485,13 +485,13 @@ func (m *MockFullNode) ClientDealPieceCID(arg0 context.Context, arg1 cid.Cid) (a return ret0, ret1 } -// ClientDealPieceCID indicates an expected call of ClientDealPieceCID +// ClientDealPieceCID indicates an expected call of ClientDealPieceCID. func (mr *MockFullNodeMockRecorder) ClientDealPieceCID(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDealPieceCID", reflect.TypeOf((*MockFullNode)(nil).ClientDealPieceCID), arg0, arg1) } -// ClientDealSize mocks base method +// ClientDealSize mocks base method. func (m *MockFullNode) ClientDealSize(arg0 context.Context, arg1 cid.Cid) (api.DataSize, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientDealSize", arg0, arg1) @@ -500,13 +500,13 @@ func (m *MockFullNode) ClientDealSize(arg0 context.Context, arg1 cid.Cid) (api.D return ret0, ret1 } -// ClientDealSize indicates an expected call of ClientDealSize +// ClientDealSize indicates an expected call of ClientDealSize. func (mr *MockFullNodeMockRecorder) ClientDealSize(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDealSize", reflect.TypeOf((*MockFullNode)(nil).ClientDealSize), arg0, arg1) } -// ClientFindData mocks base method +// ClientFindData mocks base method. func (m *MockFullNode) ClientFindData(arg0 context.Context, arg1 cid.Cid, arg2 *cid.Cid) ([]api.QueryOffer, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientFindData", arg0, arg1, arg2) @@ -515,13 +515,13 @@ func (m *MockFullNode) ClientFindData(arg0 context.Context, arg1 cid.Cid, arg2 * return ret0, ret1 } -// ClientFindData indicates an expected call of ClientFindData +// ClientFindData indicates an expected call of ClientFindData. func (mr *MockFullNodeMockRecorder) ClientFindData(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientFindData", reflect.TypeOf((*MockFullNode)(nil).ClientFindData), arg0, arg1, arg2) } -// ClientGenCar mocks base method +// ClientGenCar mocks base method. func (m *MockFullNode) ClientGenCar(arg0 context.Context, arg1 api.FileRef, arg2 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientGenCar", arg0, arg1, arg2) @@ -529,13 +529,13 @@ func (m *MockFullNode) ClientGenCar(arg0 context.Context, arg1 api.FileRef, arg2 return ret0 } -// ClientGenCar indicates an expected call of ClientGenCar +// ClientGenCar indicates an expected call of ClientGenCar. func (mr *MockFullNodeMockRecorder) ClientGenCar(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGenCar", reflect.TypeOf((*MockFullNode)(nil).ClientGenCar), arg0, arg1, arg2) } -// ClientGetDealInfo mocks base method +// ClientGetDealInfo mocks base method. func (m *MockFullNode) ClientGetDealInfo(arg0 context.Context, arg1 cid.Cid) (*api.DealInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientGetDealInfo", arg0, arg1) @@ -544,13 +544,13 @@ func (m *MockFullNode) ClientGetDealInfo(arg0 context.Context, arg1 cid.Cid) (*a return ret0, ret1 } -// ClientGetDealInfo indicates an expected call of ClientGetDealInfo +// ClientGetDealInfo indicates an expected call of ClientGetDealInfo. func (mr *MockFullNodeMockRecorder) ClientGetDealInfo(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealInfo", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealInfo), arg0, arg1) } -// ClientGetDealStatus mocks base method +// ClientGetDealStatus mocks base method. func (m *MockFullNode) ClientGetDealStatus(arg0 context.Context, arg1 uint64) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientGetDealStatus", arg0, arg1) @@ -559,13 +559,13 @@ func (m *MockFullNode) ClientGetDealStatus(arg0 context.Context, arg1 uint64) (s return ret0, ret1 } -// ClientGetDealStatus indicates an expected call of ClientGetDealStatus +// ClientGetDealStatus indicates an expected call of ClientGetDealStatus. func (mr *MockFullNodeMockRecorder) ClientGetDealStatus(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealStatus", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealStatus), arg0, arg1) } -// ClientGetDealUpdates mocks base method +// ClientGetDealUpdates mocks base method. func (m *MockFullNode) ClientGetDealUpdates(arg0 context.Context) (<-chan api.DealInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientGetDealUpdates", arg0) @@ -574,13 +574,13 @@ func (m *MockFullNode) ClientGetDealUpdates(arg0 context.Context) (<-chan api.De return ret0, ret1 } -// ClientGetDealUpdates indicates an expected call of ClientGetDealUpdates +// ClientGetDealUpdates indicates an expected call of ClientGetDealUpdates. func (mr *MockFullNodeMockRecorder) ClientGetDealUpdates(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealUpdates), arg0) } -// ClientGetRetrievalUpdates mocks base method +// ClientGetRetrievalUpdates mocks base method. func (m *MockFullNode) ClientGetRetrievalUpdates(arg0 context.Context) (<-chan api.RetrievalInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientGetRetrievalUpdates", arg0) @@ -589,13 +589,13 @@ func (m *MockFullNode) ClientGetRetrievalUpdates(arg0 context.Context) (<-chan a return ret0, ret1 } -// ClientGetRetrievalUpdates indicates an expected call of ClientGetRetrievalUpdates +// ClientGetRetrievalUpdates indicates an expected call of ClientGetRetrievalUpdates. func (mr *MockFullNodeMockRecorder) ClientGetRetrievalUpdates(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetRetrievalUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetRetrievalUpdates), arg0) } -// ClientHasLocal mocks base method +// ClientHasLocal mocks base method. func (m *MockFullNode) ClientHasLocal(arg0 context.Context, arg1 cid.Cid) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientHasLocal", arg0, arg1) @@ -604,13 +604,13 @@ func (m *MockFullNode) ClientHasLocal(arg0 context.Context, arg1 cid.Cid) (bool, return ret0, ret1 } -// ClientHasLocal indicates an expected call of ClientHasLocal +// ClientHasLocal indicates an expected call of ClientHasLocal. func (mr *MockFullNodeMockRecorder) ClientHasLocal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientHasLocal", reflect.TypeOf((*MockFullNode)(nil).ClientHasLocal), arg0, arg1) } -// ClientImport mocks base method +// ClientImport mocks base method. func (m *MockFullNode) ClientImport(arg0 context.Context, arg1 api.FileRef) (*api.ImportRes, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientImport", arg0, arg1) @@ -619,13 +619,13 @@ func (m *MockFullNode) ClientImport(arg0 context.Context, arg1 api.FileRef) (*ap return ret0, ret1 } -// ClientImport indicates an expected call of ClientImport +// ClientImport indicates an expected call of ClientImport. func (mr *MockFullNodeMockRecorder) ClientImport(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientImport", reflect.TypeOf((*MockFullNode)(nil).ClientImport), arg0, arg1) } -// ClientListDataTransfers mocks base method +// ClientListDataTransfers mocks base method. func (m *MockFullNode) ClientListDataTransfers(arg0 context.Context) ([]api.DataTransferChannel, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientListDataTransfers", arg0) @@ -634,13 +634,13 @@ func (m *MockFullNode) ClientListDataTransfers(arg0 context.Context) ([]api.Data return ret0, ret1 } -// ClientListDataTransfers indicates an expected call of ClientListDataTransfers +// ClientListDataTransfers indicates an expected call of ClientListDataTransfers. func (mr *MockFullNodeMockRecorder) ClientListDataTransfers(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListDataTransfers", reflect.TypeOf((*MockFullNode)(nil).ClientListDataTransfers), arg0) } -// ClientListDeals mocks base method +// ClientListDeals mocks base method. func (m *MockFullNode) ClientListDeals(arg0 context.Context) ([]api.DealInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientListDeals", arg0) @@ -649,13 +649,13 @@ func (m *MockFullNode) ClientListDeals(arg0 context.Context) ([]api.DealInfo, er return ret0, ret1 } -// ClientListDeals indicates an expected call of ClientListDeals +// ClientListDeals indicates an expected call of ClientListDeals. func (mr *MockFullNodeMockRecorder) ClientListDeals(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListDeals", reflect.TypeOf((*MockFullNode)(nil).ClientListDeals), arg0) } -// ClientListImports mocks base method +// ClientListImports mocks base method. func (m *MockFullNode) ClientListImports(arg0 context.Context) ([]api.Import, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientListImports", arg0) @@ -664,13 +664,13 @@ func (m *MockFullNode) ClientListImports(arg0 context.Context) ([]api.Import, er return ret0, ret1 } -// ClientListImports indicates an expected call of ClientListImports +// ClientListImports indicates an expected call of ClientListImports. func (mr *MockFullNodeMockRecorder) ClientListImports(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListImports", reflect.TypeOf((*MockFullNode)(nil).ClientListImports), arg0) } -// ClientListRetrievals mocks base method +// ClientListRetrievals mocks base method. func (m *MockFullNode) ClientListRetrievals(arg0 context.Context) ([]api.RetrievalInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientListRetrievals", arg0) @@ -679,13 +679,13 @@ func (m *MockFullNode) ClientListRetrievals(arg0 context.Context) ([]api.Retriev return ret0, ret1 } -// ClientListRetrievals indicates an expected call of ClientListRetrievals +// ClientListRetrievals indicates an expected call of ClientListRetrievals. func (mr *MockFullNodeMockRecorder) ClientListRetrievals(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListRetrievals", reflect.TypeOf((*MockFullNode)(nil).ClientListRetrievals), arg0) } -// ClientMinerQueryOffer mocks base method +// ClientMinerQueryOffer mocks base method. func (m *MockFullNode) ClientMinerQueryOffer(arg0 context.Context, arg1 address.Address, arg2 cid.Cid, arg3 *cid.Cid) (api.QueryOffer, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientMinerQueryOffer", arg0, arg1, arg2, arg3) @@ -694,13 +694,13 @@ func (m *MockFullNode) ClientMinerQueryOffer(arg0 context.Context, arg1 address. return ret0, ret1 } -// ClientMinerQueryOffer indicates an expected call of ClientMinerQueryOffer +// ClientMinerQueryOffer indicates an expected call of ClientMinerQueryOffer. func (mr *MockFullNodeMockRecorder) ClientMinerQueryOffer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientMinerQueryOffer", reflect.TypeOf((*MockFullNode)(nil).ClientMinerQueryOffer), arg0, arg1, arg2, arg3) } -// ClientQueryAsk mocks base method +// ClientQueryAsk mocks base method. func (m *MockFullNode) ClientQueryAsk(arg0 context.Context, arg1 peer.ID, arg2 address.Address) (*storagemarket.StorageAsk, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientQueryAsk", arg0, arg1, arg2) @@ -709,13 +709,13 @@ func (m *MockFullNode) ClientQueryAsk(arg0 context.Context, arg1 peer.ID, arg2 a return ret0, ret1 } -// ClientQueryAsk indicates an expected call of ClientQueryAsk +// ClientQueryAsk indicates an expected call of ClientQueryAsk. func (mr *MockFullNodeMockRecorder) ClientQueryAsk(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientQueryAsk", reflect.TypeOf((*MockFullNode)(nil).ClientQueryAsk), arg0, arg1, arg2) } -// ClientRemoveImport mocks base method +// ClientRemoveImport mocks base method. func (m *MockFullNode) ClientRemoveImport(arg0 context.Context, arg1 multistore.StoreID) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientRemoveImport", arg0, arg1) @@ -723,13 +723,13 @@ func (m *MockFullNode) ClientRemoveImport(arg0 context.Context, arg1 multistore. return ret0 } -// ClientRemoveImport indicates an expected call of ClientRemoveImport +// ClientRemoveImport indicates an expected call of ClientRemoveImport. func (mr *MockFullNodeMockRecorder) ClientRemoveImport(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRemoveImport", reflect.TypeOf((*MockFullNode)(nil).ClientRemoveImport), arg0, arg1) } -// ClientRestartDataTransfer mocks base method +// ClientRestartDataTransfer mocks base method. func (m *MockFullNode) ClientRestartDataTransfer(arg0 context.Context, arg1 datatransfer.TransferID, arg2 peer.ID, arg3 bool) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientRestartDataTransfer", arg0, arg1, arg2, arg3) @@ -737,13 +737,13 @@ func (m *MockFullNode) ClientRestartDataTransfer(arg0 context.Context, arg1 data return ret0 } -// ClientRestartDataTransfer indicates an expected call of ClientRestartDataTransfer +// ClientRestartDataTransfer indicates an expected call of ClientRestartDataTransfer. func (mr *MockFullNodeMockRecorder) ClientRestartDataTransfer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRestartDataTransfer", reflect.TypeOf((*MockFullNode)(nil).ClientRestartDataTransfer), arg0, arg1, arg2, arg3) } -// ClientRetrieve mocks base method +// ClientRetrieve mocks base method. func (m *MockFullNode) ClientRetrieve(arg0 context.Context, arg1 api.RetrievalOrder, arg2 *api.FileRef) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientRetrieve", arg0, arg1, arg2) @@ -751,13 +751,13 @@ func (m *MockFullNode) ClientRetrieve(arg0 context.Context, arg1 api.RetrievalOr return ret0 } -// ClientRetrieve indicates an expected call of ClientRetrieve +// ClientRetrieve indicates an expected call of ClientRetrieve. func (mr *MockFullNodeMockRecorder) ClientRetrieve(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieve", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieve), arg0, arg1, arg2) } -// ClientRetrieveTryRestartInsufficientFunds mocks base method +// ClientRetrieveTryRestartInsufficientFunds mocks base method. func (m *MockFullNode) ClientRetrieveTryRestartInsufficientFunds(arg0 context.Context, arg1 address.Address) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientRetrieveTryRestartInsufficientFunds", arg0, arg1) @@ -765,13 +765,13 @@ func (m *MockFullNode) ClientRetrieveTryRestartInsufficientFunds(arg0 context.Co return ret0 } -// ClientRetrieveTryRestartInsufficientFunds indicates an expected call of ClientRetrieveTryRestartInsufficientFunds +// ClientRetrieveTryRestartInsufficientFunds indicates an expected call of ClientRetrieveTryRestartInsufficientFunds. func (mr *MockFullNodeMockRecorder) ClientRetrieveTryRestartInsufficientFunds(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieveTryRestartInsufficientFunds", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieveTryRestartInsufficientFunds), arg0, arg1) } -// ClientRetrieveWithEvents mocks base method +// ClientRetrieveWithEvents mocks base method. func (m *MockFullNode) ClientRetrieveWithEvents(arg0 context.Context, arg1 api.RetrievalOrder, arg2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientRetrieveWithEvents", arg0, arg1, arg2) @@ -780,13 +780,13 @@ func (m *MockFullNode) ClientRetrieveWithEvents(arg0 context.Context, arg1 api.R return ret0, ret1 } -// ClientRetrieveWithEvents indicates an expected call of ClientRetrieveWithEvents +// ClientRetrieveWithEvents indicates an expected call of ClientRetrieveWithEvents. func (mr *MockFullNodeMockRecorder) ClientRetrieveWithEvents(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieveWithEvents", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieveWithEvents), arg0, arg1, arg2) } -// ClientStartDeal mocks base method +// ClientStartDeal mocks base method. func (m *MockFullNode) ClientStartDeal(arg0 context.Context, arg1 *api.StartDealParams) (*cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientStartDeal", arg0, arg1) @@ -795,13 +795,13 @@ func (m *MockFullNode) ClientStartDeal(arg0 context.Context, arg1 *api.StartDeal return ret0, ret1 } -// ClientStartDeal indicates an expected call of ClientStartDeal +// ClientStartDeal indicates an expected call of ClientStartDeal. func (mr *MockFullNodeMockRecorder) ClientStartDeal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStartDeal", reflect.TypeOf((*MockFullNode)(nil).ClientStartDeal), arg0, arg1) } -// ClientStatelessDeal mocks base method +// ClientStatelessDeal mocks base method. func (m *MockFullNode) ClientStatelessDeal(arg0 context.Context, arg1 *api.StartDealParams) (*cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientStatelessDeal", arg0, arg1) @@ -810,13 +810,13 @@ func (m *MockFullNode) ClientStatelessDeal(arg0 context.Context, arg1 *api.Start return ret0, ret1 } -// ClientStatelessDeal indicates an expected call of ClientStatelessDeal +// ClientStatelessDeal indicates an expected call of ClientStatelessDeal. func (mr *MockFullNodeMockRecorder) ClientStatelessDeal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStatelessDeal", reflect.TypeOf((*MockFullNode)(nil).ClientStatelessDeal), arg0, arg1) } -// Closing mocks base method +// Closing mocks base method. func (m *MockFullNode) Closing(arg0 context.Context) (<-chan struct{}, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Closing", arg0) @@ -825,13 +825,13 @@ func (m *MockFullNode) Closing(arg0 context.Context) (<-chan struct{}, error) { return ret0, ret1 } -// Closing indicates an expected call of Closing +// Closing indicates an expected call of Closing. func (mr *MockFullNodeMockRecorder) Closing(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Closing", reflect.TypeOf((*MockFullNode)(nil).Closing), arg0) } -// CreateBackup mocks base method +// CreateBackup mocks base method. func (m *MockFullNode) CreateBackup(arg0 context.Context, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateBackup", arg0, arg1) @@ -839,13 +839,13 @@ func (m *MockFullNode) CreateBackup(arg0 context.Context, arg1 string) error { return ret0 } -// CreateBackup indicates an expected call of CreateBackup +// CreateBackup indicates an expected call of CreateBackup. func (mr *MockFullNodeMockRecorder) CreateBackup(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBackup", reflect.TypeOf((*MockFullNode)(nil).CreateBackup), arg0, arg1) } -// Discover mocks base method +// Discover mocks base method. func (m *MockFullNode) Discover(arg0 context.Context) (apitypes.OpenRPCDocument, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Discover", arg0) @@ -854,13 +854,13 @@ func (m *MockFullNode) Discover(arg0 context.Context) (apitypes.OpenRPCDocument, return ret0, ret1 } -// Discover indicates an expected call of Discover +// Discover indicates an expected call of Discover. func (mr *MockFullNodeMockRecorder) Discover(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Discover", reflect.TypeOf((*MockFullNode)(nil).Discover), arg0) } -// GasEstimateFeeCap mocks base method +// GasEstimateFeeCap mocks base method. func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Message, arg2 int64, arg3 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GasEstimateFeeCap", arg0, arg1, arg2, arg3) @@ -869,13 +869,13 @@ func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Messa return ret0, ret1 } -// GasEstimateFeeCap indicates an expected call of GasEstimateFeeCap +// GasEstimateFeeCap indicates an expected call of GasEstimateFeeCap. func (mr *MockFullNodeMockRecorder) GasEstimateFeeCap(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateFeeCap", reflect.TypeOf((*MockFullNode)(nil).GasEstimateFeeCap), arg0, arg1, arg2, arg3) } -// GasEstimateGasLimit mocks base method +// GasEstimateGasLimit mocks base method. func (m *MockFullNode) GasEstimateGasLimit(arg0 context.Context, arg1 *types.Message, arg2 types.TipSetKey) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GasEstimateGasLimit", arg0, arg1, arg2) @@ -884,13 +884,13 @@ func (m *MockFullNode) GasEstimateGasLimit(arg0 context.Context, arg1 *types.Mes return ret0, ret1 } -// GasEstimateGasLimit indicates an expected call of GasEstimateGasLimit +// GasEstimateGasLimit indicates an expected call of GasEstimateGasLimit. func (mr *MockFullNodeMockRecorder) GasEstimateGasLimit(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateGasLimit", reflect.TypeOf((*MockFullNode)(nil).GasEstimateGasLimit), arg0, arg1, arg2) } -// GasEstimateGasPremium mocks base method +// GasEstimateGasPremium mocks base method. func (m *MockFullNode) GasEstimateGasPremium(arg0 context.Context, arg1 uint64, arg2 address.Address, arg3 int64, arg4 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GasEstimateGasPremium", arg0, arg1, arg2, arg3, arg4) @@ -899,13 +899,13 @@ func (m *MockFullNode) GasEstimateGasPremium(arg0 context.Context, arg1 uint64, return ret0, ret1 } -// GasEstimateGasPremium indicates an expected call of GasEstimateGasPremium +// GasEstimateGasPremium indicates an expected call of GasEstimateGasPremium. func (mr *MockFullNodeMockRecorder) GasEstimateGasPremium(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateGasPremium", reflect.TypeOf((*MockFullNode)(nil).GasEstimateGasPremium), arg0, arg1, arg2, arg3, arg4) } -// GasEstimateMessageGas mocks base method +// GasEstimateMessageGas mocks base method. func (m *MockFullNode) GasEstimateMessageGas(arg0 context.Context, arg1 *types.Message, arg2 *api.MessageSendSpec, arg3 types.TipSetKey) (*types.Message, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GasEstimateMessageGas", arg0, arg1, arg2, arg3) @@ -914,13 +914,13 @@ func (m *MockFullNode) GasEstimateMessageGas(arg0 context.Context, arg1 *types.M return ret0, ret1 } -// GasEstimateMessageGas indicates an expected call of GasEstimateMessageGas +// GasEstimateMessageGas indicates an expected call of GasEstimateMessageGas. func (mr *MockFullNodeMockRecorder) GasEstimateMessageGas(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateMessageGas", reflect.TypeOf((*MockFullNode)(nil).GasEstimateMessageGas), arg0, arg1, arg2, arg3) } -// ID mocks base method +// ID mocks base method. func (m *MockFullNode) ID(arg0 context.Context) (peer.ID, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ID", arg0) @@ -929,13 +929,13 @@ func (m *MockFullNode) ID(arg0 context.Context) (peer.ID, error) { return ret0, ret1 } -// ID indicates an expected call of ID +// ID indicates an expected call of ID. func (mr *MockFullNodeMockRecorder) ID(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockFullNode)(nil).ID), arg0) } -// LogList mocks base method +// LogList mocks base method. func (m *MockFullNode) LogList(arg0 context.Context) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LogList", arg0) @@ -944,13 +944,13 @@ func (m *MockFullNode) LogList(arg0 context.Context) ([]string, error) { return ret0, ret1 } -// LogList indicates an expected call of LogList +// LogList indicates an expected call of LogList. func (mr *MockFullNodeMockRecorder) LogList(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogList", reflect.TypeOf((*MockFullNode)(nil).LogList), arg0) } -// LogSetLevel mocks base method +// LogSetLevel mocks base method. func (m *MockFullNode) LogSetLevel(arg0 context.Context, arg1, arg2 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LogSetLevel", arg0, arg1, arg2) @@ -958,13 +958,13 @@ func (m *MockFullNode) LogSetLevel(arg0 context.Context, arg1, arg2 string) erro return ret0 } -// LogSetLevel indicates an expected call of LogSetLevel +// LogSetLevel indicates an expected call of LogSetLevel. func (mr *MockFullNodeMockRecorder) LogSetLevel(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogSetLevel", reflect.TypeOf((*MockFullNode)(nil).LogSetLevel), arg0, arg1, arg2) } -// MarketAddBalance mocks base method +// MarketAddBalance mocks base method. func (m *MockFullNode) MarketAddBalance(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarketAddBalance", arg0, arg1, arg2, arg3) @@ -973,13 +973,13 @@ func (m *MockFullNode) MarketAddBalance(arg0 context.Context, arg1, arg2 address return ret0, ret1 } -// MarketAddBalance indicates an expected call of MarketAddBalance +// MarketAddBalance indicates an expected call of MarketAddBalance. func (mr *MockFullNodeMockRecorder) MarketAddBalance(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketAddBalance", reflect.TypeOf((*MockFullNode)(nil).MarketAddBalance), arg0, arg1, arg2, arg3) } -// MarketGetReserved mocks base method +// MarketGetReserved mocks base method. func (m *MockFullNode) MarketGetReserved(arg0 context.Context, arg1 address.Address) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarketGetReserved", arg0, arg1) @@ -988,13 +988,13 @@ func (m *MockFullNode) MarketGetReserved(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// MarketGetReserved indicates an expected call of MarketGetReserved +// MarketGetReserved indicates an expected call of MarketGetReserved. func (mr *MockFullNodeMockRecorder) MarketGetReserved(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketGetReserved", reflect.TypeOf((*MockFullNode)(nil).MarketGetReserved), arg0, arg1) } -// MarketReleaseFunds mocks base method +// MarketReleaseFunds mocks base method. func (m *MockFullNode) MarketReleaseFunds(arg0 context.Context, arg1 address.Address, arg2 big.Int) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarketReleaseFunds", arg0, arg1, arg2) @@ -1002,13 +1002,13 @@ func (m *MockFullNode) MarketReleaseFunds(arg0 context.Context, arg1 address.Add return ret0 } -// MarketReleaseFunds indicates an expected call of MarketReleaseFunds +// MarketReleaseFunds indicates an expected call of MarketReleaseFunds. func (mr *MockFullNodeMockRecorder) MarketReleaseFunds(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketReleaseFunds", reflect.TypeOf((*MockFullNode)(nil).MarketReleaseFunds), arg0, arg1, arg2) } -// MarketReserveFunds mocks base method +// MarketReserveFunds mocks base method. func (m *MockFullNode) MarketReserveFunds(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarketReserveFunds", arg0, arg1, arg2, arg3) @@ -1017,13 +1017,13 @@ func (m *MockFullNode) MarketReserveFunds(arg0 context.Context, arg1, arg2 addre return ret0, ret1 } -// MarketReserveFunds indicates an expected call of MarketReserveFunds +// MarketReserveFunds indicates an expected call of MarketReserveFunds. func (mr *MockFullNodeMockRecorder) MarketReserveFunds(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketReserveFunds", reflect.TypeOf((*MockFullNode)(nil).MarketReserveFunds), arg0, arg1, arg2, arg3) } -// MarketWithdraw mocks base method +// MarketWithdraw mocks base method. func (m *MockFullNode) MarketWithdraw(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarketWithdraw", arg0, arg1, arg2, arg3) @@ -1032,13 +1032,13 @@ func (m *MockFullNode) MarketWithdraw(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MarketWithdraw indicates an expected call of MarketWithdraw +// MarketWithdraw indicates an expected call of MarketWithdraw. func (mr *MockFullNodeMockRecorder) MarketWithdraw(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketWithdraw", reflect.TypeOf((*MockFullNode)(nil).MarketWithdraw), arg0, arg1, arg2, arg3) } -// MinerCreateBlock mocks base method +// MinerCreateBlock mocks base method. func (m *MockFullNode) MinerCreateBlock(arg0 context.Context, arg1 *api.BlockTemplate) (*types.BlockMsg, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MinerCreateBlock", arg0, arg1) @@ -1047,13 +1047,13 @@ func (m *MockFullNode) MinerCreateBlock(arg0 context.Context, arg1 *api.BlockTem return ret0, ret1 } -// MinerCreateBlock indicates an expected call of MinerCreateBlock +// MinerCreateBlock indicates an expected call of MinerCreateBlock. func (mr *MockFullNodeMockRecorder) MinerCreateBlock(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinerCreateBlock", reflect.TypeOf((*MockFullNode)(nil).MinerCreateBlock), arg0, arg1) } -// MinerGetBaseInfo mocks base method +// MinerGetBaseInfo mocks base method. func (m *MockFullNode) MinerGetBaseInfo(arg0 context.Context, arg1 address.Address, arg2 abi.ChainEpoch, arg3 types.TipSetKey) (*api.MiningBaseInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MinerGetBaseInfo", arg0, arg1, arg2, arg3) @@ -1062,13 +1062,13 @@ func (m *MockFullNode) MinerGetBaseInfo(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// MinerGetBaseInfo indicates an expected call of MinerGetBaseInfo +// MinerGetBaseInfo indicates an expected call of MinerGetBaseInfo. func (mr *MockFullNodeMockRecorder) MinerGetBaseInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinerGetBaseInfo", reflect.TypeOf((*MockFullNode)(nil).MinerGetBaseInfo), arg0, arg1, arg2, arg3) } -// MpoolBatchPush mocks base method +// MpoolBatchPush mocks base method. func (m *MockFullNode) MpoolBatchPush(arg0 context.Context, arg1 []*types.SignedMessage) ([]cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolBatchPush", arg0, arg1) @@ -1077,13 +1077,13 @@ func (m *MockFullNode) MpoolBatchPush(arg0 context.Context, arg1 []*types.Signed return ret0, ret1 } -// MpoolBatchPush indicates an expected call of MpoolBatchPush +// MpoolBatchPush indicates an expected call of MpoolBatchPush. func (mr *MockFullNodeMockRecorder) MpoolBatchPush(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPush", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPush), arg0, arg1) } -// MpoolBatchPushMessage mocks base method +// MpoolBatchPushMessage mocks base method. func (m *MockFullNode) MpoolBatchPushMessage(arg0 context.Context, arg1 []*types.Message, arg2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolBatchPushMessage", arg0, arg1, arg2) @@ -1092,13 +1092,13 @@ func (m *MockFullNode) MpoolBatchPushMessage(arg0 context.Context, arg1 []*types return ret0, ret1 } -// MpoolBatchPushMessage indicates an expected call of MpoolBatchPushMessage +// MpoolBatchPushMessage indicates an expected call of MpoolBatchPushMessage. func (mr *MockFullNodeMockRecorder) MpoolBatchPushMessage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPushMessage", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPushMessage), arg0, arg1, arg2) } -// MpoolBatchPushUntrusted mocks base method +// MpoolBatchPushUntrusted mocks base method. func (m *MockFullNode) MpoolBatchPushUntrusted(arg0 context.Context, arg1 []*types.SignedMessage) ([]cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolBatchPushUntrusted", arg0, arg1) @@ -1107,13 +1107,13 @@ func (m *MockFullNode) MpoolBatchPushUntrusted(arg0 context.Context, arg1 []*typ return ret0, ret1 } -// MpoolBatchPushUntrusted indicates an expected call of MpoolBatchPushUntrusted +// MpoolBatchPushUntrusted indicates an expected call of MpoolBatchPushUntrusted. func (mr *MockFullNodeMockRecorder) MpoolBatchPushUntrusted(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPushUntrusted", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPushUntrusted), arg0, arg1) } -// MpoolCheckMessages mocks base method +// MpoolCheckMessages mocks base method. func (m *MockFullNode) MpoolCheckMessages(arg0 context.Context, arg1 []*api.MessagePrototype) ([][]api.MessageCheckStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolCheckMessages", arg0, arg1) @@ -1122,13 +1122,13 @@ func (m *MockFullNode) MpoolCheckMessages(arg0 context.Context, arg1 []*api.Mess return ret0, ret1 } -// MpoolCheckMessages indicates an expected call of MpoolCheckMessages +// MpoolCheckMessages indicates an expected call of MpoolCheckMessages. func (mr *MockFullNodeMockRecorder) MpoolCheckMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckMessages", reflect.TypeOf((*MockFullNode)(nil).MpoolCheckMessages), arg0, arg1) } -// MpoolCheckPendingMessages mocks base method +// MpoolCheckPendingMessages mocks base method. func (m *MockFullNode) MpoolCheckPendingMessages(arg0 context.Context, arg1 address.Address) ([][]api.MessageCheckStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolCheckPendingMessages", arg0, arg1) @@ -1137,13 +1137,13 @@ func (m *MockFullNode) MpoolCheckPendingMessages(arg0 context.Context, arg1 addr return ret0, ret1 } -// MpoolCheckPendingMessages indicates an expected call of MpoolCheckPendingMessages +// MpoolCheckPendingMessages indicates an expected call of MpoolCheckPendingMessages. func (mr *MockFullNodeMockRecorder) MpoolCheckPendingMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckPendingMessages", reflect.TypeOf((*MockFullNode)(nil).MpoolCheckPendingMessages), arg0, arg1) } -// MpoolCheckReplaceMessages mocks base method +// MpoolCheckReplaceMessages mocks base method. func (m *MockFullNode) MpoolCheckReplaceMessages(arg0 context.Context, arg1 []*types.Message) ([][]api.MessageCheckStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolCheckReplaceMessages", arg0, arg1) @@ -1152,13 +1152,13 @@ func (m *MockFullNode) MpoolCheckReplaceMessages(arg0 context.Context, arg1 []*t return ret0, ret1 } -// MpoolCheckReplaceMessages indicates an expected call of MpoolCheckReplaceMessages +// MpoolCheckReplaceMessages indicates an expected call of MpoolCheckReplaceMessages. func (mr *MockFullNodeMockRecorder) MpoolCheckReplaceMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckReplaceMessages", reflect.TypeOf((*MockFullNode)(nil).MpoolCheckReplaceMessages), arg0, arg1) } -// MpoolClear mocks base method +// MpoolClear mocks base method. func (m *MockFullNode) MpoolClear(arg0 context.Context, arg1 bool) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolClear", arg0, arg1) @@ -1166,13 +1166,13 @@ func (m *MockFullNode) MpoolClear(arg0 context.Context, arg1 bool) error { return ret0 } -// MpoolClear indicates an expected call of MpoolClear +// MpoolClear indicates an expected call of MpoolClear. func (mr *MockFullNodeMockRecorder) MpoolClear(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolClear", reflect.TypeOf((*MockFullNode)(nil).MpoolClear), arg0, arg1) } -// MpoolGetConfig mocks base method +// MpoolGetConfig mocks base method. func (m *MockFullNode) MpoolGetConfig(arg0 context.Context) (*types.MpoolConfig, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolGetConfig", arg0) @@ -1181,13 +1181,13 @@ func (m *MockFullNode) MpoolGetConfig(arg0 context.Context) (*types.MpoolConfig, return ret0, ret1 } -// MpoolGetConfig indicates an expected call of MpoolGetConfig +// MpoolGetConfig indicates an expected call of MpoolGetConfig. func (mr *MockFullNodeMockRecorder) MpoolGetConfig(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolGetConfig", reflect.TypeOf((*MockFullNode)(nil).MpoolGetConfig), arg0) } -// MpoolGetNonce mocks base method +// MpoolGetNonce mocks base method. func (m *MockFullNode) MpoolGetNonce(arg0 context.Context, arg1 address.Address) (uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolGetNonce", arg0, arg1) @@ -1196,13 +1196,13 @@ func (m *MockFullNode) MpoolGetNonce(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// MpoolGetNonce indicates an expected call of MpoolGetNonce +// MpoolGetNonce indicates an expected call of MpoolGetNonce. func (mr *MockFullNodeMockRecorder) MpoolGetNonce(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolGetNonce", reflect.TypeOf((*MockFullNode)(nil).MpoolGetNonce), arg0, arg1) } -// MpoolPending mocks base method +// MpoolPending mocks base method. func (m *MockFullNode) MpoolPending(arg0 context.Context, arg1 types.TipSetKey) ([]*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolPending", arg0, arg1) @@ -1211,13 +1211,13 @@ func (m *MockFullNode) MpoolPending(arg0 context.Context, arg1 types.TipSetKey) return ret0, ret1 } -// MpoolPending indicates an expected call of MpoolPending +// MpoolPending indicates an expected call of MpoolPending. func (mr *MockFullNodeMockRecorder) MpoolPending(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPending", reflect.TypeOf((*MockFullNode)(nil).MpoolPending), arg0, arg1) } -// MpoolPush mocks base method +// MpoolPush mocks base method. func (m *MockFullNode) MpoolPush(arg0 context.Context, arg1 *types.SignedMessage) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolPush", arg0, arg1) @@ -1226,13 +1226,13 @@ func (m *MockFullNode) MpoolPush(arg0 context.Context, arg1 *types.SignedMessage return ret0, ret1 } -// MpoolPush indicates an expected call of MpoolPush +// MpoolPush indicates an expected call of MpoolPush. func (mr *MockFullNodeMockRecorder) MpoolPush(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPush", reflect.TypeOf((*MockFullNode)(nil).MpoolPush), arg0, arg1) } -// MpoolPushMessage mocks base method +// MpoolPushMessage mocks base method. func (m *MockFullNode) MpoolPushMessage(arg0 context.Context, arg1 *types.Message, arg2 *api.MessageSendSpec) (*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolPushMessage", arg0, arg1, arg2) @@ -1241,13 +1241,13 @@ func (m *MockFullNode) MpoolPushMessage(arg0 context.Context, arg1 *types.Messag return ret0, ret1 } -// MpoolPushMessage indicates an expected call of MpoolPushMessage +// MpoolPushMessage indicates an expected call of MpoolPushMessage. func (mr *MockFullNodeMockRecorder) MpoolPushMessage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPushMessage", reflect.TypeOf((*MockFullNode)(nil).MpoolPushMessage), arg0, arg1, arg2) } -// MpoolPushUntrusted mocks base method +// MpoolPushUntrusted mocks base method. func (m *MockFullNode) MpoolPushUntrusted(arg0 context.Context, arg1 *types.SignedMessage) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolPushUntrusted", arg0, arg1) @@ -1256,13 +1256,13 @@ func (m *MockFullNode) MpoolPushUntrusted(arg0 context.Context, arg1 *types.Sign return ret0, ret1 } -// MpoolPushUntrusted indicates an expected call of MpoolPushUntrusted +// MpoolPushUntrusted indicates an expected call of MpoolPushUntrusted. func (mr *MockFullNodeMockRecorder) MpoolPushUntrusted(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPushUntrusted", reflect.TypeOf((*MockFullNode)(nil).MpoolPushUntrusted), arg0, arg1) } -// MpoolSelect mocks base method +// MpoolSelect mocks base method. func (m *MockFullNode) MpoolSelect(arg0 context.Context, arg1 types.TipSetKey, arg2 float64) ([]*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolSelect", arg0, arg1, arg2) @@ -1271,13 +1271,13 @@ func (m *MockFullNode) MpoolSelect(arg0 context.Context, arg1 types.TipSetKey, a return ret0, ret1 } -// MpoolSelect indicates an expected call of MpoolSelect +// MpoolSelect indicates an expected call of MpoolSelect. func (mr *MockFullNodeMockRecorder) MpoolSelect(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSelect", reflect.TypeOf((*MockFullNode)(nil).MpoolSelect), arg0, arg1, arg2) } -// MpoolSetConfig mocks base method +// MpoolSetConfig mocks base method. func (m *MockFullNode) MpoolSetConfig(arg0 context.Context, arg1 *types.MpoolConfig) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolSetConfig", arg0, arg1) @@ -1285,13 +1285,13 @@ func (m *MockFullNode) MpoolSetConfig(arg0 context.Context, arg1 *types.MpoolCon return ret0 } -// MpoolSetConfig indicates an expected call of MpoolSetConfig +// MpoolSetConfig indicates an expected call of MpoolSetConfig. func (mr *MockFullNodeMockRecorder) MpoolSetConfig(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSetConfig", reflect.TypeOf((*MockFullNode)(nil).MpoolSetConfig), arg0, arg1) } -// MpoolSub mocks base method +// MpoolSub mocks base method. func (m *MockFullNode) MpoolSub(arg0 context.Context) (<-chan api.MpoolUpdate, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolSub", arg0) @@ -1300,13 +1300,13 @@ func (m *MockFullNode) MpoolSub(arg0 context.Context) (<-chan api.MpoolUpdate, e return ret0, ret1 } -// MpoolSub indicates an expected call of MpoolSub +// MpoolSub indicates an expected call of MpoolSub. func (mr *MockFullNodeMockRecorder) MpoolSub(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSub", reflect.TypeOf((*MockFullNode)(nil).MpoolSub), arg0) } -// MsigAddApprove mocks base method +// MsigAddApprove mocks base method. func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address, arg6 bool) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigAddApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6) @@ -1315,13 +1315,13 @@ func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MsigAddApprove indicates an expected call of MsigAddApprove +// MsigAddApprove indicates an expected call of MsigAddApprove. func (mr *MockFullNodeMockRecorder) MsigAddApprove(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddApprove", reflect.TypeOf((*MockFullNode)(nil).MsigAddApprove), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } -// MsigAddCancel mocks base method +// MsigAddCancel mocks base method. func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4 address.Address, arg5 bool) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigAddCancel", arg0, arg1, arg2, arg3, arg4, arg5) @@ -1330,13 +1330,13 @@ func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Ad return ret0, ret1 } -// MsigAddCancel indicates an expected call of MsigAddCancel +// MsigAddCancel indicates an expected call of MsigAddCancel. func (mr *MockFullNodeMockRecorder) MsigAddCancel(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddCancel", reflect.TypeOf((*MockFullNode)(nil).MsigAddCancel), arg0, arg1, arg2, arg3, arg4, arg5) } -// MsigAddPropose mocks base method +// MsigAddPropose mocks base method. func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigAddPropose", arg0, arg1, arg2, arg3, arg4) @@ -1345,13 +1345,13 @@ func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 add return ret0, ret1 } -// MsigAddPropose indicates an expected call of MsigAddPropose +// MsigAddPropose indicates an expected call of MsigAddPropose. func (mr *MockFullNodeMockRecorder) MsigAddPropose(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddPropose", reflect.TypeOf((*MockFullNode)(nil).MsigAddPropose), arg0, arg1, arg2, arg3, arg4) } -// MsigApprove mocks base method +// MsigApprove mocks base method. func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigApprove", arg0, arg1, arg2, arg3) @@ -1360,13 +1360,13 @@ func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, a return ret0, ret1 } -// MsigApprove indicates an expected call of MsigApprove +// MsigApprove indicates an expected call of MsigApprove. func (mr *MockFullNodeMockRecorder) MsigApprove(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigApprove", reflect.TypeOf((*MockFullNode)(nil).MsigApprove), arg0, arg1, arg2, arg3) } -// MsigApproveTxnHash mocks base method +// MsigApproveTxnHash mocks base method. func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3, arg4 address.Address, arg5 big.Int, arg6 address.Address, arg7 uint64, arg8 []byte) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigApproveTxnHash", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) @@ -1375,13 +1375,13 @@ func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// MsigApproveTxnHash indicates an expected call of MsigApproveTxnHash +// MsigApproveTxnHash indicates an expected call of MsigApproveTxnHash. func (mr *MockFullNodeMockRecorder) MsigApproveTxnHash(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigApproveTxnHash", reflect.TypeOf((*MockFullNode)(nil).MsigApproveTxnHash), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) } -// MsigCancel mocks base method +// MsigCancel mocks base method. func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address, arg4 big.Int, arg5 address.Address, arg6 uint64, arg7 []byte) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigCancel", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) @@ -1390,13 +1390,13 @@ func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, ar return ret0, ret1 } -// MsigCancel indicates an expected call of MsigCancel +// MsigCancel indicates an expected call of MsigCancel. func (mr *MockFullNodeMockRecorder) MsigCancel(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigCancel", reflect.TypeOf((*MockFullNode)(nil).MsigCancel), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) } -// MsigCreate mocks base method +// MsigCreate mocks base method. func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []address.Address, arg3 abi.ChainEpoch, arg4 big.Int, arg5 address.Address, arg6 big.Int) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigCreate", arg0, arg1, arg2, arg3, arg4, arg5, arg6) @@ -1405,13 +1405,13 @@ func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []addr return ret0, ret1 } -// MsigCreate indicates an expected call of MsigCreate +// MsigCreate indicates an expected call of MsigCreate. func (mr *MockFullNodeMockRecorder) MsigCreate(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigCreate", reflect.TypeOf((*MockFullNode)(nil).MsigCreate), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } -// MsigGetAvailableBalance mocks base method +// MsigGetAvailableBalance mocks base method. func (m *MockFullNode) MsigGetAvailableBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigGetAvailableBalance", arg0, arg1, arg2) @@ -1420,13 +1420,13 @@ func (m *MockFullNode) MsigGetAvailableBalance(arg0 context.Context, arg1 addres return ret0, ret1 } -// MsigGetAvailableBalance indicates an expected call of MsigGetAvailableBalance +// MsigGetAvailableBalance indicates an expected call of MsigGetAvailableBalance. func (mr *MockFullNodeMockRecorder) MsigGetAvailableBalance(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetAvailableBalance", reflect.TypeOf((*MockFullNode)(nil).MsigGetAvailableBalance), arg0, arg1, arg2) } -// MsigGetPending mocks base method +// MsigGetPending mocks base method. func (m *MockFullNode) MsigGetPending(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]*api.MsigTransaction, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigGetPending", arg0, arg1, arg2) @@ -1435,13 +1435,13 @@ func (m *MockFullNode) MsigGetPending(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// MsigGetPending indicates an expected call of MsigGetPending +// MsigGetPending indicates an expected call of MsigGetPending. func (mr *MockFullNodeMockRecorder) MsigGetPending(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetPending", reflect.TypeOf((*MockFullNode)(nil).MsigGetPending), arg0, arg1, arg2) } -// MsigGetVested mocks base method +// MsigGetVested mocks base method. func (m *MockFullNode) MsigGetVested(arg0 context.Context, arg1 address.Address, arg2, arg3 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigGetVested", arg0, arg1, arg2, arg3) @@ -1450,13 +1450,13 @@ func (m *MockFullNode) MsigGetVested(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// MsigGetVested indicates an expected call of MsigGetVested +// MsigGetVested indicates an expected call of MsigGetVested. func (mr *MockFullNodeMockRecorder) MsigGetVested(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetVested", reflect.TypeOf((*MockFullNode)(nil).MsigGetVested), arg0, arg1, arg2, arg3) } -// MsigGetVestingSchedule mocks base method +// MsigGetVestingSchedule mocks base method. func (m *MockFullNode) MsigGetVestingSchedule(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MsigVesting, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigGetVestingSchedule", arg0, arg1, arg2) @@ -1465,13 +1465,13 @@ func (m *MockFullNode) MsigGetVestingSchedule(arg0 context.Context, arg1 address return ret0, ret1 } -// MsigGetVestingSchedule indicates an expected call of MsigGetVestingSchedule +// MsigGetVestingSchedule indicates an expected call of MsigGetVestingSchedule. func (mr *MockFullNodeMockRecorder) MsigGetVestingSchedule(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetVestingSchedule", reflect.TypeOf((*MockFullNode)(nil).MsigGetVestingSchedule), arg0, arg1, arg2) } -// MsigPropose mocks base method +// MsigPropose mocks base method. func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int, arg4 address.Address, arg5 uint64, arg6 []byte) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigPropose", arg0, arg1, arg2, arg3, arg4, arg5, arg6) @@ -1480,13 +1480,13 @@ func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Addr return ret0, ret1 } -// MsigPropose indicates an expected call of MsigPropose +// MsigPropose indicates an expected call of MsigPropose. func (mr *MockFullNodeMockRecorder) MsigPropose(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigPropose", reflect.TypeOf((*MockFullNode)(nil).MsigPropose), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } -// MsigRemoveSigner mocks base method +// MsigRemoveSigner mocks base method. func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigRemoveSigner", arg0, arg1, arg2, arg3, arg4) @@ -1495,13 +1495,13 @@ func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 a return ret0, ret1 } -// MsigRemoveSigner indicates an expected call of MsigRemoveSigner +// MsigRemoveSigner indicates an expected call of MsigRemoveSigner. func (mr *MockFullNodeMockRecorder) MsigRemoveSigner(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigRemoveSigner", reflect.TypeOf((*MockFullNode)(nil).MsigRemoveSigner), arg0, arg1, arg2, arg3, arg4) } -// MsigSwapApprove mocks base method +// MsigSwapApprove mocks base method. func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5, arg6 address.Address) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigSwapApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6) @@ -1510,13 +1510,13 @@ func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address. return ret0, ret1 } -// MsigSwapApprove indicates an expected call of MsigSwapApprove +// MsigSwapApprove indicates an expected call of MsigSwapApprove. func (mr *MockFullNodeMockRecorder) MsigSwapApprove(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapApprove", reflect.TypeOf((*MockFullNode)(nil).MsigSwapApprove), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } -// MsigSwapCancel mocks base method +// MsigSwapCancel mocks base method. func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigSwapCancel", arg0, arg1, arg2, arg3, arg4, arg5) @@ -1525,13 +1525,13 @@ func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MsigSwapCancel indicates an expected call of MsigSwapCancel +// MsigSwapCancel indicates an expected call of MsigSwapCancel. func (mr *MockFullNodeMockRecorder) MsigSwapCancel(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapCancel", reflect.TypeOf((*MockFullNode)(nil).MsigSwapCancel), arg0, arg1, arg2, arg3, arg4, arg5) } -// MsigSwapPropose mocks base method +// MsigSwapPropose mocks base method. func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, arg4 address.Address) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigSwapPropose", arg0, arg1, arg2, arg3, arg4) @@ -1540,13 +1540,13 @@ func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, a return ret0, ret1 } -// MsigSwapPropose indicates an expected call of MsigSwapPropose +// MsigSwapPropose indicates an expected call of MsigSwapPropose. func (mr *MockFullNodeMockRecorder) MsigSwapPropose(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapPropose", reflect.TypeOf((*MockFullNode)(nil).MsigSwapPropose), arg0, arg1, arg2, arg3, arg4) } -// NetAddrsListen mocks base method +// NetAddrsListen mocks base method. func (m *MockFullNode) NetAddrsListen(arg0 context.Context) (peer.AddrInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetAddrsListen", arg0) @@ -1555,13 +1555,13 @@ func (m *MockFullNode) NetAddrsListen(arg0 context.Context) (peer.AddrInfo, erro return ret0, ret1 } -// NetAddrsListen indicates an expected call of NetAddrsListen +// NetAddrsListen indicates an expected call of NetAddrsListen. func (mr *MockFullNodeMockRecorder) NetAddrsListen(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAddrsListen", reflect.TypeOf((*MockFullNode)(nil).NetAddrsListen), arg0) } -// NetAgentVersion mocks base method +// NetAgentVersion mocks base method. func (m *MockFullNode) NetAgentVersion(arg0 context.Context, arg1 peer.ID) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetAgentVersion", arg0, arg1) @@ -1570,13 +1570,13 @@ func (m *MockFullNode) NetAgentVersion(arg0 context.Context, arg1 peer.ID) (stri return ret0, ret1 } -// NetAgentVersion indicates an expected call of NetAgentVersion +// NetAgentVersion indicates an expected call of NetAgentVersion. func (mr *MockFullNodeMockRecorder) NetAgentVersion(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAgentVersion", reflect.TypeOf((*MockFullNode)(nil).NetAgentVersion), arg0, arg1) } -// NetAutoNatStatus mocks base method +// NetAutoNatStatus mocks base method. func (m *MockFullNode) NetAutoNatStatus(arg0 context.Context) (api.NatInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetAutoNatStatus", arg0) @@ -1585,13 +1585,13 @@ func (m *MockFullNode) NetAutoNatStatus(arg0 context.Context) (api.NatInfo, erro return ret0, ret1 } -// NetAutoNatStatus indicates an expected call of NetAutoNatStatus +// NetAutoNatStatus indicates an expected call of NetAutoNatStatus. func (mr *MockFullNodeMockRecorder) NetAutoNatStatus(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAutoNatStatus", reflect.TypeOf((*MockFullNode)(nil).NetAutoNatStatus), arg0) } -// NetBandwidthStats mocks base method +// NetBandwidthStats mocks base method. func (m *MockFullNode) NetBandwidthStats(arg0 context.Context) (metrics.Stats, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBandwidthStats", arg0) @@ -1600,13 +1600,13 @@ func (m *MockFullNode) NetBandwidthStats(arg0 context.Context) (metrics.Stats, e return ret0, ret1 } -// NetBandwidthStats indicates an expected call of NetBandwidthStats +// NetBandwidthStats indicates an expected call of NetBandwidthStats. func (mr *MockFullNodeMockRecorder) NetBandwidthStats(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStats", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStats), arg0) } -// NetBandwidthStatsByPeer mocks base method +// NetBandwidthStatsByPeer mocks base method. func (m *MockFullNode) NetBandwidthStatsByPeer(arg0 context.Context) (map[string]metrics.Stats, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBandwidthStatsByPeer", arg0) @@ -1615,13 +1615,13 @@ func (m *MockFullNode) NetBandwidthStatsByPeer(arg0 context.Context) (map[string return ret0, ret1 } -// NetBandwidthStatsByPeer indicates an expected call of NetBandwidthStatsByPeer +// NetBandwidthStatsByPeer indicates an expected call of NetBandwidthStatsByPeer. func (mr *MockFullNodeMockRecorder) NetBandwidthStatsByPeer(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStatsByPeer", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStatsByPeer), arg0) } -// NetBandwidthStatsByProtocol mocks base method +// NetBandwidthStatsByProtocol mocks base method. func (m *MockFullNode) NetBandwidthStatsByProtocol(arg0 context.Context) (map[protocol.ID]metrics.Stats, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBandwidthStatsByProtocol", arg0) @@ -1630,13 +1630,13 @@ func (m *MockFullNode) NetBandwidthStatsByProtocol(arg0 context.Context) (map[pr return ret0, ret1 } -// NetBandwidthStatsByProtocol indicates an expected call of NetBandwidthStatsByProtocol +// NetBandwidthStatsByProtocol indicates an expected call of NetBandwidthStatsByProtocol. func (mr *MockFullNodeMockRecorder) NetBandwidthStatsByProtocol(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStatsByProtocol", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStatsByProtocol), arg0) } -// NetBlockAdd mocks base method +// NetBlockAdd mocks base method. func (m *MockFullNode) NetBlockAdd(arg0 context.Context, arg1 api.NetBlockList) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBlockAdd", arg0, arg1) @@ -1644,13 +1644,13 @@ func (m *MockFullNode) NetBlockAdd(arg0 context.Context, arg1 api.NetBlockList) return ret0 } -// NetBlockAdd indicates an expected call of NetBlockAdd +// NetBlockAdd indicates an expected call of NetBlockAdd. func (mr *MockFullNodeMockRecorder) NetBlockAdd(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockAdd", reflect.TypeOf((*MockFullNode)(nil).NetBlockAdd), arg0, arg1) } -// NetBlockList mocks base method +// NetBlockList mocks base method. func (m *MockFullNode) NetBlockList(arg0 context.Context) (api.NetBlockList, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBlockList", arg0) @@ -1659,13 +1659,13 @@ func (m *MockFullNode) NetBlockList(arg0 context.Context) (api.NetBlockList, err return ret0, ret1 } -// NetBlockList indicates an expected call of NetBlockList +// NetBlockList indicates an expected call of NetBlockList. func (mr *MockFullNodeMockRecorder) NetBlockList(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockList", reflect.TypeOf((*MockFullNode)(nil).NetBlockList), arg0) } -// NetBlockRemove mocks base method +// NetBlockRemove mocks base method. func (m *MockFullNode) NetBlockRemove(arg0 context.Context, arg1 api.NetBlockList) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBlockRemove", arg0, arg1) @@ -1673,13 +1673,13 @@ func (m *MockFullNode) NetBlockRemove(arg0 context.Context, arg1 api.NetBlockLis return ret0 } -// NetBlockRemove indicates an expected call of NetBlockRemove +// NetBlockRemove indicates an expected call of NetBlockRemove. func (mr *MockFullNodeMockRecorder) NetBlockRemove(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockRemove", reflect.TypeOf((*MockFullNode)(nil).NetBlockRemove), arg0, arg1) } -// NetConnect mocks base method +// NetConnect mocks base method. func (m *MockFullNode) NetConnect(arg0 context.Context, arg1 peer.AddrInfo) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetConnect", arg0, arg1) @@ -1687,13 +1687,13 @@ func (m *MockFullNode) NetConnect(arg0 context.Context, arg1 peer.AddrInfo) erro return ret0 } -// NetConnect indicates an expected call of NetConnect +// NetConnect indicates an expected call of NetConnect. func (mr *MockFullNodeMockRecorder) NetConnect(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetConnect", reflect.TypeOf((*MockFullNode)(nil).NetConnect), arg0, arg1) } -// NetConnectedness mocks base method +// NetConnectedness mocks base method. func (m *MockFullNode) NetConnectedness(arg0 context.Context, arg1 peer.ID) (network0.Connectedness, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetConnectedness", arg0, arg1) @@ -1702,13 +1702,13 @@ func (m *MockFullNode) NetConnectedness(arg0 context.Context, arg1 peer.ID) (net return ret0, ret1 } -// NetConnectedness indicates an expected call of NetConnectedness +// NetConnectedness indicates an expected call of NetConnectedness. func (mr *MockFullNodeMockRecorder) NetConnectedness(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetConnectedness", reflect.TypeOf((*MockFullNode)(nil).NetConnectedness), arg0, arg1) } -// NetDisconnect mocks base method +// NetDisconnect mocks base method. func (m *MockFullNode) NetDisconnect(arg0 context.Context, arg1 peer.ID) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetDisconnect", arg0, arg1) @@ -1716,13 +1716,13 @@ func (m *MockFullNode) NetDisconnect(arg0 context.Context, arg1 peer.ID) error { return ret0 } -// NetDisconnect indicates an expected call of NetDisconnect +// NetDisconnect indicates an expected call of NetDisconnect. func (mr *MockFullNodeMockRecorder) NetDisconnect(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetDisconnect", reflect.TypeOf((*MockFullNode)(nil).NetDisconnect), arg0, arg1) } -// NetFindPeer mocks base method +// NetFindPeer mocks base method. func (m *MockFullNode) NetFindPeer(arg0 context.Context, arg1 peer.ID) (peer.AddrInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetFindPeer", arg0, arg1) @@ -1731,13 +1731,13 @@ func (m *MockFullNode) NetFindPeer(arg0 context.Context, arg1 peer.ID) (peer.Add return ret0, ret1 } -// NetFindPeer indicates an expected call of NetFindPeer +// NetFindPeer indicates an expected call of NetFindPeer. func (mr *MockFullNodeMockRecorder) NetFindPeer(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetFindPeer", reflect.TypeOf((*MockFullNode)(nil).NetFindPeer), arg0, arg1) } -// NetPeerInfo mocks base method +// NetPeerInfo mocks base method. func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetPeerInfo", arg0, arg1) @@ -1746,13 +1746,13 @@ func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.Ext return ret0, ret1 } -// NetPeerInfo indicates an expected call of NetPeerInfo +// NetPeerInfo indicates an expected call of NetPeerInfo. func (mr *MockFullNodeMockRecorder) NetPeerInfo(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeerInfo", reflect.TypeOf((*MockFullNode)(nil).NetPeerInfo), arg0, arg1) } -// NetPeers mocks base method +// NetPeers mocks base method. func (m *MockFullNode) NetPeers(arg0 context.Context) ([]peer.AddrInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetPeers", arg0) @@ -1761,13 +1761,13 @@ func (m *MockFullNode) NetPeers(arg0 context.Context) ([]peer.AddrInfo, error) { return ret0, ret1 } -// NetPeers indicates an expected call of NetPeers +// NetPeers indicates an expected call of NetPeers. func (mr *MockFullNodeMockRecorder) NetPeers(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeers", reflect.TypeOf((*MockFullNode)(nil).NetPeers), arg0) } -// NetPubsubScores mocks base method +// NetPubsubScores mocks base method. func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetPubsubScores", arg0) @@ -1776,13 +1776,13 @@ func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, return ret0, ret1 } -// NetPubsubScores indicates an expected call of NetPubsubScores +// NetPubsubScores indicates an expected call of NetPubsubScores. func (mr *MockFullNodeMockRecorder) NetPubsubScores(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0) } -// NodeStatus mocks base method +// NodeStatus mocks base method. func (m *MockFullNode) NodeStatus(arg0 context.Context, arg1 bool) (api.NodeStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NodeStatus", arg0, arg1) @@ -1791,13 +1791,13 @@ func (m *MockFullNode) NodeStatus(arg0 context.Context, arg1 bool) (api.NodeStat return ret0, ret1 } -// NodeStatus indicates an expected call of NodeStatus +// NodeStatus indicates an expected call of NodeStatus. func (mr *MockFullNodeMockRecorder) NodeStatus(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeStatus", reflect.TypeOf((*MockFullNode)(nil).NodeStatus), arg0, arg1) } -// PaychAllocateLane mocks base method +// PaychAllocateLane mocks base method. func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Address) (uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychAllocateLane", arg0, arg1) @@ -1806,13 +1806,13 @@ func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// PaychAllocateLane indicates an expected call of PaychAllocateLane +// PaychAllocateLane indicates an expected call of PaychAllocateLane. func (mr *MockFullNodeMockRecorder) PaychAllocateLane(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAllocateLane", reflect.TypeOf((*MockFullNode)(nil).PaychAllocateLane), arg0, arg1) } -// PaychAvailableFunds mocks base method +// PaychAvailableFunds mocks base method. func (m *MockFullNode) PaychAvailableFunds(arg0 context.Context, arg1 address.Address) (*api.ChannelAvailableFunds, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychAvailableFunds", arg0, arg1) @@ -1821,13 +1821,13 @@ func (m *MockFullNode) PaychAvailableFunds(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// PaychAvailableFunds indicates an expected call of PaychAvailableFunds +// PaychAvailableFunds indicates an expected call of PaychAvailableFunds. func (mr *MockFullNodeMockRecorder) PaychAvailableFunds(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAvailableFunds", reflect.TypeOf((*MockFullNode)(nil).PaychAvailableFunds), arg0, arg1) } -// PaychAvailableFundsByFromTo mocks base method +// PaychAvailableFundsByFromTo mocks base method. func (m *MockFullNode) PaychAvailableFundsByFromTo(arg0 context.Context, arg1, arg2 address.Address) (*api.ChannelAvailableFunds, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychAvailableFundsByFromTo", arg0, arg1, arg2) @@ -1836,13 +1836,13 @@ func (m *MockFullNode) PaychAvailableFundsByFromTo(arg0 context.Context, arg1, a return ret0, ret1 } -// PaychAvailableFundsByFromTo indicates an expected call of PaychAvailableFundsByFromTo +// PaychAvailableFundsByFromTo indicates an expected call of PaychAvailableFundsByFromTo. func (mr *MockFullNodeMockRecorder) PaychAvailableFundsByFromTo(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAvailableFundsByFromTo", reflect.TypeOf((*MockFullNode)(nil).PaychAvailableFundsByFromTo), arg0, arg1, arg2) } -// PaychCollect mocks base method +// PaychCollect mocks base method. func (m *MockFullNode) PaychCollect(arg0 context.Context, arg1 address.Address) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychCollect", arg0, arg1) @@ -1851,13 +1851,13 @@ func (m *MockFullNode) PaychCollect(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// PaychCollect indicates an expected call of PaychCollect +// PaychCollect indicates an expected call of PaychCollect. func (mr *MockFullNodeMockRecorder) PaychCollect(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychCollect", reflect.TypeOf((*MockFullNode)(nil).PaychCollect), arg0, arg1) } -// PaychGet mocks base method +// PaychGet mocks base method. func (m *MockFullNode) PaychGet(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (*api.ChannelInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychGet", arg0, arg1, arg2, arg3) @@ -1866,13 +1866,13 @@ func (m *MockFullNode) PaychGet(arg0 context.Context, arg1, arg2 address.Address return ret0, ret1 } -// PaychGet indicates an expected call of PaychGet +// PaychGet indicates an expected call of PaychGet. func (mr *MockFullNodeMockRecorder) PaychGet(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychGet", reflect.TypeOf((*MockFullNode)(nil).PaychGet), arg0, arg1, arg2, arg3) } -// PaychGetWaitReady mocks base method +// PaychGetWaitReady mocks base method. func (m *MockFullNode) PaychGetWaitReady(arg0 context.Context, arg1 cid.Cid) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychGetWaitReady", arg0, arg1) @@ -1881,13 +1881,13 @@ func (m *MockFullNode) PaychGetWaitReady(arg0 context.Context, arg1 cid.Cid) (ad return ret0, ret1 } -// PaychGetWaitReady indicates an expected call of PaychGetWaitReady +// PaychGetWaitReady indicates an expected call of PaychGetWaitReady. func (mr *MockFullNodeMockRecorder) PaychGetWaitReady(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychGetWaitReady", reflect.TypeOf((*MockFullNode)(nil).PaychGetWaitReady), arg0, arg1) } -// PaychList mocks base method +// PaychList mocks base method. func (m *MockFullNode) PaychList(arg0 context.Context) ([]address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychList", arg0) @@ -1896,13 +1896,13 @@ func (m *MockFullNode) PaychList(arg0 context.Context) ([]address.Address, error return ret0, ret1 } -// PaychList indicates an expected call of PaychList +// PaychList indicates an expected call of PaychList. func (mr *MockFullNodeMockRecorder) PaychList(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychList", reflect.TypeOf((*MockFullNode)(nil).PaychList), arg0) } -// PaychNewPayment mocks base method +// PaychNewPayment mocks base method. func (m *MockFullNode) PaychNewPayment(arg0 context.Context, arg1, arg2 address.Address, arg3 []api.VoucherSpec) (*api.PaymentInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychNewPayment", arg0, arg1, arg2, arg3) @@ -1911,13 +1911,13 @@ func (m *MockFullNode) PaychNewPayment(arg0 context.Context, arg1, arg2 address. return ret0, ret1 } -// PaychNewPayment indicates an expected call of PaychNewPayment +// PaychNewPayment indicates an expected call of PaychNewPayment. func (mr *MockFullNodeMockRecorder) PaychNewPayment(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychNewPayment", reflect.TypeOf((*MockFullNode)(nil).PaychNewPayment), arg0, arg1, arg2, arg3) } -// PaychSettle mocks base method +// PaychSettle mocks base method. func (m *MockFullNode) PaychSettle(arg0 context.Context, arg1 address.Address) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychSettle", arg0, arg1) @@ -1926,13 +1926,13 @@ func (m *MockFullNode) PaychSettle(arg0 context.Context, arg1 address.Address) ( return ret0, ret1 } -// PaychSettle indicates an expected call of PaychSettle +// PaychSettle indicates an expected call of PaychSettle. func (mr *MockFullNodeMockRecorder) PaychSettle(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychSettle", reflect.TypeOf((*MockFullNode)(nil).PaychSettle), arg0, arg1) } -// PaychStatus mocks base method +// PaychStatus mocks base method. func (m *MockFullNode) PaychStatus(arg0 context.Context, arg1 address.Address) (*api.PaychStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychStatus", arg0, arg1) @@ -1941,13 +1941,13 @@ func (m *MockFullNode) PaychStatus(arg0 context.Context, arg1 address.Address) ( return ret0, ret1 } -// PaychStatus indicates an expected call of PaychStatus +// PaychStatus indicates an expected call of PaychStatus. func (mr *MockFullNodeMockRecorder) PaychStatus(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychStatus", reflect.TypeOf((*MockFullNode)(nil).PaychStatus), arg0, arg1) } -// PaychVoucherAdd mocks base method +// PaychVoucherAdd mocks base method. func (m *MockFullNode) PaychVoucherAdd(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3 []byte, arg4 big.Int) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherAdd", arg0, arg1, arg2, arg3, arg4) @@ -1956,13 +1956,13 @@ func (m *MockFullNode) PaychVoucherAdd(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// PaychVoucherAdd indicates an expected call of PaychVoucherAdd +// PaychVoucherAdd indicates an expected call of PaychVoucherAdd. func (mr *MockFullNodeMockRecorder) PaychVoucherAdd(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherAdd", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherAdd), arg0, arg1, arg2, arg3, arg4) } -// PaychVoucherCheckSpendable mocks base method +// PaychVoucherCheckSpendable mocks base method. func (m *MockFullNode) PaychVoucherCheckSpendable(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3, arg4 []byte) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherCheckSpendable", arg0, arg1, arg2, arg3, arg4) @@ -1971,13 +1971,13 @@ func (m *MockFullNode) PaychVoucherCheckSpendable(arg0 context.Context, arg1 add return ret0, ret1 } -// PaychVoucherCheckSpendable indicates an expected call of PaychVoucherCheckSpendable +// PaychVoucherCheckSpendable indicates an expected call of PaychVoucherCheckSpendable. func (mr *MockFullNodeMockRecorder) PaychVoucherCheckSpendable(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCheckSpendable", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCheckSpendable), arg0, arg1, arg2, arg3, arg4) } -// PaychVoucherCheckValid mocks base method +// PaychVoucherCheckValid mocks base method. func (m *MockFullNode) PaychVoucherCheckValid(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherCheckValid", arg0, arg1, arg2) @@ -1985,13 +1985,13 @@ func (m *MockFullNode) PaychVoucherCheckValid(arg0 context.Context, arg1 address return ret0 } -// PaychVoucherCheckValid indicates an expected call of PaychVoucherCheckValid +// PaychVoucherCheckValid indicates an expected call of PaychVoucherCheckValid. func (mr *MockFullNodeMockRecorder) PaychVoucherCheckValid(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCheckValid", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCheckValid), arg0, arg1, arg2) } -// PaychVoucherCreate mocks base method +// PaychVoucherCreate mocks base method. func (m *MockFullNode) PaychVoucherCreate(arg0 context.Context, arg1 address.Address, arg2 big.Int, arg3 uint64) (*api.VoucherCreateResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherCreate", arg0, arg1, arg2, arg3) @@ -2000,13 +2000,13 @@ func (m *MockFullNode) PaychVoucherCreate(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// PaychVoucherCreate indicates an expected call of PaychVoucherCreate +// PaychVoucherCreate indicates an expected call of PaychVoucherCreate. func (mr *MockFullNodeMockRecorder) PaychVoucherCreate(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCreate", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCreate), arg0, arg1, arg2, arg3) } -// PaychVoucherList mocks base method +// PaychVoucherList mocks base method. func (m *MockFullNode) PaychVoucherList(arg0 context.Context, arg1 address.Address) ([]*paych.SignedVoucher, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherList", arg0, arg1) @@ -2015,13 +2015,13 @@ func (m *MockFullNode) PaychVoucherList(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// PaychVoucherList indicates an expected call of PaychVoucherList +// PaychVoucherList indicates an expected call of PaychVoucherList. func (mr *MockFullNodeMockRecorder) PaychVoucherList(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherList", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherList), arg0, arg1) } -// PaychVoucherSubmit mocks base method +// PaychVoucherSubmit mocks base method. func (m *MockFullNode) PaychVoucherSubmit(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3, arg4 []byte) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherSubmit", arg0, arg1, arg2, arg3, arg4) @@ -2030,13 +2030,13 @@ func (m *MockFullNode) PaychVoucherSubmit(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// PaychVoucherSubmit indicates an expected call of PaychVoucherSubmit +// PaychVoucherSubmit indicates an expected call of PaychVoucherSubmit. func (mr *MockFullNodeMockRecorder) PaychVoucherSubmit(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherSubmit", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherSubmit), arg0, arg1, arg2, arg3, arg4) } -// Session mocks base method +// Session mocks base method. func (m *MockFullNode) Session(arg0 context.Context) (uuid.UUID, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Session", arg0) @@ -2045,13 +2045,13 @@ func (m *MockFullNode) Session(arg0 context.Context) (uuid.UUID, error) { return ret0, ret1 } -// Session indicates an expected call of Session +// Session indicates an expected call of Session. func (mr *MockFullNodeMockRecorder) Session(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Session", reflect.TypeOf((*MockFullNode)(nil).Session), arg0) } -// Shutdown mocks base method +// Shutdown mocks base method. func (m *MockFullNode) Shutdown(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Shutdown", arg0) @@ -2059,13 +2059,13 @@ func (m *MockFullNode) Shutdown(arg0 context.Context) error { return ret0 } -// Shutdown indicates an expected call of Shutdown +// Shutdown indicates an expected call of Shutdown. func (mr *MockFullNodeMockRecorder) Shutdown(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shutdown", reflect.TypeOf((*MockFullNode)(nil).Shutdown), arg0) } -// StateAccountKey mocks base method +// StateAccountKey mocks base method. func (m *MockFullNode) StateAccountKey(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateAccountKey", arg0, arg1, arg2) @@ -2074,13 +2074,13 @@ func (m *MockFullNode) StateAccountKey(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// StateAccountKey indicates an expected call of StateAccountKey +// StateAccountKey indicates an expected call of StateAccountKey. func (mr *MockFullNodeMockRecorder) StateAccountKey(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateAccountKey", reflect.TypeOf((*MockFullNode)(nil).StateAccountKey), arg0, arg1, arg2) } -// StateAllMinerFaults mocks base method +// StateAllMinerFaults mocks base method. func (m *MockFullNode) StateAllMinerFaults(arg0 context.Context, arg1 abi.ChainEpoch, arg2 types.TipSetKey) ([]*api.Fault, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateAllMinerFaults", arg0, arg1, arg2) @@ -2089,13 +2089,13 @@ func (m *MockFullNode) StateAllMinerFaults(arg0 context.Context, arg1 abi.ChainE return ret0, ret1 } -// StateAllMinerFaults indicates an expected call of StateAllMinerFaults +// StateAllMinerFaults indicates an expected call of StateAllMinerFaults. func (mr *MockFullNodeMockRecorder) StateAllMinerFaults(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateAllMinerFaults", reflect.TypeOf((*MockFullNode)(nil).StateAllMinerFaults), arg0, arg1, arg2) } -// StateCall mocks base method +// StateCall mocks base method. func (m *MockFullNode) StateCall(arg0 context.Context, arg1 *types.Message, arg2 types.TipSetKey) (*api.InvocResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateCall", arg0, arg1, arg2) @@ -2104,13 +2104,13 @@ func (m *MockFullNode) StateCall(arg0 context.Context, arg1 *types.Message, arg2 return ret0, ret1 } -// StateCall indicates an expected call of StateCall +// StateCall indicates an expected call of StateCall. func (mr *MockFullNodeMockRecorder) StateCall(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCall", reflect.TypeOf((*MockFullNode)(nil).StateCall), arg0, arg1, arg2) } -// StateChangedActors mocks base method +// StateChangedActors mocks base method. func (m *MockFullNode) StateChangedActors(arg0 context.Context, arg1, arg2 cid.Cid) (map[string]types.Actor, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateChangedActors", arg0, arg1, arg2) @@ -2119,13 +2119,13 @@ func (m *MockFullNode) StateChangedActors(arg0 context.Context, arg1, arg2 cid.C return ret0, ret1 } -// StateChangedActors indicates an expected call of StateChangedActors +// StateChangedActors indicates an expected call of StateChangedActors. func (mr *MockFullNodeMockRecorder) StateChangedActors(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateChangedActors", reflect.TypeOf((*MockFullNode)(nil).StateChangedActors), arg0, arg1, arg2) } -// StateCirculatingSupply mocks base method +// StateCirculatingSupply mocks base method. func (m *MockFullNode) StateCirculatingSupply(arg0 context.Context, arg1 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateCirculatingSupply", arg0, arg1) @@ -2134,13 +2134,13 @@ func (m *MockFullNode) StateCirculatingSupply(arg0 context.Context, arg1 types.T return ret0, ret1 } -// StateCirculatingSupply indicates an expected call of StateCirculatingSupply +// StateCirculatingSupply indicates an expected call of StateCirculatingSupply. func (mr *MockFullNodeMockRecorder) StateCirculatingSupply(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCirculatingSupply", reflect.TypeOf((*MockFullNode)(nil).StateCirculatingSupply), arg0, arg1) } -// StateCompute mocks base method +// StateCompute mocks base method. func (m *MockFullNode) StateCompute(arg0 context.Context, arg1 abi.ChainEpoch, arg2 []*types.Message, arg3 types.TipSetKey) (*api.ComputeStateOutput, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateCompute", arg0, arg1, arg2, arg3) @@ -2149,13 +2149,13 @@ func (m *MockFullNode) StateCompute(arg0 context.Context, arg1 abi.ChainEpoch, a return ret0, ret1 } -// StateCompute indicates an expected call of StateCompute +// StateCompute indicates an expected call of StateCompute. func (mr *MockFullNodeMockRecorder) StateCompute(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCompute", reflect.TypeOf((*MockFullNode)(nil).StateCompute), arg0, arg1, arg2, arg3) } -// StateDealProviderCollateralBounds mocks base method +// StateDealProviderCollateralBounds mocks base method. func (m *MockFullNode) StateDealProviderCollateralBounds(arg0 context.Context, arg1 abi.PaddedPieceSize, arg2 bool, arg3 types.TipSetKey) (api.DealCollateralBounds, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateDealProviderCollateralBounds", arg0, arg1, arg2, arg3) @@ -2164,13 +2164,13 @@ func (m *MockFullNode) StateDealProviderCollateralBounds(arg0 context.Context, a return ret0, ret1 } -// StateDealProviderCollateralBounds indicates an expected call of StateDealProviderCollateralBounds +// StateDealProviderCollateralBounds indicates an expected call of StateDealProviderCollateralBounds. func (mr *MockFullNodeMockRecorder) StateDealProviderCollateralBounds(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateDealProviderCollateralBounds", reflect.TypeOf((*MockFullNode)(nil).StateDealProviderCollateralBounds), arg0, arg1, arg2, arg3) } -// StateDecodeParams mocks base method +// StateDecodeParams mocks base method. func (m *MockFullNode) StateDecodeParams(arg0 context.Context, arg1 address.Address, arg2 abi.MethodNum, arg3 []byte, arg4 types.TipSetKey) (interface{}, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateDecodeParams", arg0, arg1, arg2, arg3, arg4) @@ -2179,13 +2179,13 @@ func (m *MockFullNode) StateDecodeParams(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// StateDecodeParams indicates an expected call of StateDecodeParams +// StateDecodeParams indicates an expected call of StateDecodeParams. func (mr *MockFullNodeMockRecorder) StateDecodeParams(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateDecodeParams", reflect.TypeOf((*MockFullNode)(nil).StateDecodeParams), arg0, arg1, arg2, arg3, arg4) } -// StateGetActor mocks base method +// StateGetActor mocks base method. func (m *MockFullNode) StateGetActor(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*types.Actor, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateGetActor", arg0, arg1, arg2) @@ -2194,13 +2194,13 @@ func (m *MockFullNode) StateGetActor(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// StateGetActor indicates an expected call of StateGetActor +// StateGetActor indicates an expected call of StateGetActor. func (mr *MockFullNodeMockRecorder) StateGetActor(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetActor", reflect.TypeOf((*MockFullNode)(nil).StateGetActor), arg0, arg1, arg2) } -// StateListActors mocks base method +// StateListActors mocks base method. func (m *MockFullNode) StateListActors(arg0 context.Context, arg1 types.TipSetKey) ([]address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateListActors", arg0, arg1) @@ -2209,13 +2209,13 @@ func (m *MockFullNode) StateListActors(arg0 context.Context, arg1 types.TipSetKe return ret0, ret1 } -// StateListActors indicates an expected call of StateListActors +// StateListActors indicates an expected call of StateListActors. func (mr *MockFullNodeMockRecorder) StateListActors(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListActors", reflect.TypeOf((*MockFullNode)(nil).StateListActors), arg0, arg1) } -// StateListMessages mocks base method +// StateListMessages mocks base method. func (m *MockFullNode) StateListMessages(arg0 context.Context, arg1 *api.MessageMatch, arg2 types.TipSetKey, arg3 abi.ChainEpoch) ([]cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateListMessages", arg0, arg1, arg2, arg3) @@ -2224,13 +2224,13 @@ func (m *MockFullNode) StateListMessages(arg0 context.Context, arg1 *api.Message return ret0, ret1 } -// StateListMessages indicates an expected call of StateListMessages +// StateListMessages indicates an expected call of StateListMessages. func (mr *MockFullNodeMockRecorder) StateListMessages(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListMessages", reflect.TypeOf((*MockFullNode)(nil).StateListMessages), arg0, arg1, arg2, arg3) } -// StateListMiners mocks base method +// StateListMiners mocks base method. func (m *MockFullNode) StateListMiners(arg0 context.Context, arg1 types.TipSetKey) ([]address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateListMiners", arg0, arg1) @@ -2239,13 +2239,13 @@ func (m *MockFullNode) StateListMiners(arg0 context.Context, arg1 types.TipSetKe return ret0, ret1 } -// StateListMiners indicates an expected call of StateListMiners +// StateListMiners indicates an expected call of StateListMiners. func (mr *MockFullNodeMockRecorder) StateListMiners(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListMiners", reflect.TypeOf((*MockFullNode)(nil).StateListMiners), arg0, arg1) } -// StateLookupID mocks base method +// StateLookupID mocks base method. func (m *MockFullNode) StateLookupID(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateLookupID", arg0, arg1, arg2) @@ -2254,13 +2254,13 @@ func (m *MockFullNode) StateLookupID(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// StateLookupID indicates an expected call of StateLookupID +// StateLookupID indicates an expected call of StateLookupID. func (mr *MockFullNodeMockRecorder) StateLookupID(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateLookupID", reflect.TypeOf((*MockFullNode)(nil).StateLookupID), arg0, arg1, arg2) } -// StateMarketBalance mocks base method +// StateMarketBalance mocks base method. func (m *MockFullNode) StateMarketBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MarketBalance, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMarketBalance", arg0, arg1, arg2) @@ -2269,13 +2269,13 @@ func (m *MockFullNode) StateMarketBalance(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// StateMarketBalance indicates an expected call of StateMarketBalance +// StateMarketBalance indicates an expected call of StateMarketBalance. func (mr *MockFullNodeMockRecorder) StateMarketBalance(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketBalance", reflect.TypeOf((*MockFullNode)(nil).StateMarketBalance), arg0, arg1, arg2) } -// StateMarketDeals mocks base method +// StateMarketDeals mocks base method. func (m *MockFullNode) StateMarketDeals(arg0 context.Context, arg1 types.TipSetKey) (map[string]api.MarketDeal, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMarketDeals", arg0, arg1) @@ -2284,13 +2284,13 @@ func (m *MockFullNode) StateMarketDeals(arg0 context.Context, arg1 types.TipSetK return ret0, ret1 } -// StateMarketDeals indicates an expected call of StateMarketDeals +// StateMarketDeals indicates an expected call of StateMarketDeals. func (mr *MockFullNodeMockRecorder) StateMarketDeals(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketDeals", reflect.TypeOf((*MockFullNode)(nil).StateMarketDeals), arg0, arg1) } -// StateMarketParticipants mocks base method +// StateMarketParticipants mocks base method. func (m *MockFullNode) StateMarketParticipants(arg0 context.Context, arg1 types.TipSetKey) (map[string]api.MarketBalance, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMarketParticipants", arg0, arg1) @@ -2299,13 +2299,13 @@ func (m *MockFullNode) StateMarketParticipants(arg0 context.Context, arg1 types. return ret0, ret1 } -// StateMarketParticipants indicates an expected call of StateMarketParticipants +// StateMarketParticipants indicates an expected call of StateMarketParticipants. func (mr *MockFullNodeMockRecorder) StateMarketParticipants(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketParticipants", reflect.TypeOf((*MockFullNode)(nil).StateMarketParticipants), arg0, arg1) } -// StateMarketStorageDeal mocks base method +// StateMarketStorageDeal mocks base method. func (m *MockFullNode) StateMarketStorageDeal(arg0 context.Context, arg1 abi.DealID, arg2 types.TipSetKey) (*api.MarketDeal, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMarketStorageDeal", arg0, arg1, arg2) @@ -2314,13 +2314,13 @@ func (m *MockFullNode) StateMarketStorageDeal(arg0 context.Context, arg1 abi.Dea return ret0, ret1 } -// StateMarketStorageDeal indicates an expected call of StateMarketStorageDeal +// StateMarketStorageDeal indicates an expected call of StateMarketStorageDeal. func (mr *MockFullNodeMockRecorder) StateMarketStorageDeal(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketStorageDeal", reflect.TypeOf((*MockFullNode)(nil).StateMarketStorageDeal), arg0, arg1, arg2) } -// StateMinerActiveSectors mocks base method +// StateMinerActiveSectors mocks base method. func (m *MockFullNode) StateMinerActiveSectors(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerActiveSectors", arg0, arg1, arg2) @@ -2329,13 +2329,13 @@ func (m *MockFullNode) StateMinerActiveSectors(arg0 context.Context, arg1 addres return ret0, ret1 } -// StateMinerActiveSectors indicates an expected call of StateMinerActiveSectors +// StateMinerActiveSectors indicates an expected call of StateMinerActiveSectors. func (mr *MockFullNodeMockRecorder) StateMinerActiveSectors(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerActiveSectors", reflect.TypeOf((*MockFullNode)(nil).StateMinerActiveSectors), arg0, arg1, arg2) } -// StateMinerAvailableBalance mocks base method +// StateMinerAvailableBalance mocks base method. func (m *MockFullNode) StateMinerAvailableBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerAvailableBalance", arg0, arg1, arg2) @@ -2344,13 +2344,13 @@ func (m *MockFullNode) StateMinerAvailableBalance(arg0 context.Context, arg1 add return ret0, ret1 } -// StateMinerAvailableBalance indicates an expected call of StateMinerAvailableBalance +// StateMinerAvailableBalance indicates an expected call of StateMinerAvailableBalance. func (mr *MockFullNodeMockRecorder) StateMinerAvailableBalance(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerAvailableBalance", reflect.TypeOf((*MockFullNode)(nil).StateMinerAvailableBalance), arg0, arg1, arg2) } -// StateMinerDeadlines mocks base method +// StateMinerDeadlines mocks base method. func (m *MockFullNode) StateMinerDeadlines(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]api.Deadline, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerDeadlines", arg0, arg1, arg2) @@ -2359,13 +2359,13 @@ func (m *MockFullNode) StateMinerDeadlines(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// StateMinerDeadlines indicates an expected call of StateMinerDeadlines +// StateMinerDeadlines indicates an expected call of StateMinerDeadlines. func (mr *MockFullNodeMockRecorder) StateMinerDeadlines(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerDeadlines", reflect.TypeOf((*MockFullNode)(nil).StateMinerDeadlines), arg0, arg1, arg2) } -// StateMinerFaults mocks base method +// StateMinerFaults mocks base method. func (m *MockFullNode) StateMinerFaults(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (bitfield.BitField, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerFaults", arg0, arg1, arg2) @@ -2374,13 +2374,13 @@ func (m *MockFullNode) StateMinerFaults(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// StateMinerFaults indicates an expected call of StateMinerFaults +// StateMinerFaults indicates an expected call of StateMinerFaults. func (mr *MockFullNodeMockRecorder) StateMinerFaults(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerFaults", reflect.TypeOf((*MockFullNode)(nil).StateMinerFaults), arg0, arg1, arg2) } -// StateMinerInfo mocks base method +// StateMinerInfo mocks base method. func (m *MockFullNode) StateMinerInfo(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (miner.MinerInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerInfo", arg0, arg1, arg2) @@ -2389,13 +2389,13 @@ func (m *MockFullNode) StateMinerInfo(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// StateMinerInfo indicates an expected call of StateMinerInfo +// StateMinerInfo indicates an expected call of StateMinerInfo. func (mr *MockFullNodeMockRecorder) StateMinerInfo(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInfo", reflect.TypeOf((*MockFullNode)(nil).StateMinerInfo), arg0, arg1, arg2) } -// StateMinerInitialPledgeCollateral mocks base method +// StateMinerInitialPledgeCollateral mocks base method. func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerInitialPledgeCollateral", arg0, arg1, arg2, arg3) @@ -2404,13 +2404,13 @@ func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, a return ret0, ret1 } -// StateMinerInitialPledgeCollateral indicates an expected call of StateMinerInitialPledgeCollateral +// StateMinerInitialPledgeCollateral indicates an expected call of StateMinerInitialPledgeCollateral. func (mr *MockFullNodeMockRecorder) StateMinerInitialPledgeCollateral(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInitialPledgeCollateral", reflect.TypeOf((*MockFullNode)(nil).StateMinerInitialPledgeCollateral), arg0, arg1, arg2, arg3) } -// StateMinerPartitions mocks base method +// StateMinerPartitions mocks base method. func (m *MockFullNode) StateMinerPartitions(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 types.TipSetKey) ([]api.Partition, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerPartitions", arg0, arg1, arg2, arg3) @@ -2419,13 +2419,13 @@ func (m *MockFullNode) StateMinerPartitions(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateMinerPartitions indicates an expected call of StateMinerPartitions +// StateMinerPartitions indicates an expected call of StateMinerPartitions. func (mr *MockFullNodeMockRecorder) StateMinerPartitions(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPartitions", reflect.TypeOf((*MockFullNode)(nil).StateMinerPartitions), arg0, arg1, arg2, arg3) } -// StateMinerPower mocks base method +// StateMinerPower mocks base method. func (m *MockFullNode) StateMinerPower(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*api.MinerPower, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerPower", arg0, arg1, arg2) @@ -2434,13 +2434,13 @@ func (m *MockFullNode) StateMinerPower(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// StateMinerPower indicates an expected call of StateMinerPower +// StateMinerPower indicates an expected call of StateMinerPower. func (mr *MockFullNodeMockRecorder) StateMinerPower(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPower", reflect.TypeOf((*MockFullNode)(nil).StateMinerPower), arg0, arg1, arg2) } -// StateMinerPreCommitDepositForPower mocks base method +// StateMinerPreCommitDepositForPower mocks base method. func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerPreCommitDepositForPower", arg0, arg1, arg2, arg3) @@ -2449,13 +2449,13 @@ func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, return ret0, ret1 } -// StateMinerPreCommitDepositForPower indicates an expected call of StateMinerPreCommitDepositForPower +// StateMinerPreCommitDepositForPower indicates an expected call of StateMinerPreCommitDepositForPower. func (mr *MockFullNodeMockRecorder) StateMinerPreCommitDepositForPower(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPreCommitDepositForPower", reflect.TypeOf((*MockFullNode)(nil).StateMinerPreCommitDepositForPower), arg0, arg1, arg2, arg3) } -// StateMinerProvingDeadline mocks base method +// StateMinerProvingDeadline mocks base method. func (m *MockFullNode) StateMinerProvingDeadline(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*dline.Info, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerProvingDeadline", arg0, arg1, arg2) @@ -2464,13 +2464,13 @@ func (m *MockFullNode) StateMinerProvingDeadline(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateMinerProvingDeadline indicates an expected call of StateMinerProvingDeadline +// StateMinerProvingDeadline indicates an expected call of StateMinerProvingDeadline. func (mr *MockFullNodeMockRecorder) StateMinerProvingDeadline(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerProvingDeadline", reflect.TypeOf((*MockFullNode)(nil).StateMinerProvingDeadline), arg0, arg1, arg2) } -// StateMinerRecoveries mocks base method +// StateMinerRecoveries mocks base method. func (m *MockFullNode) StateMinerRecoveries(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (bitfield.BitField, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerRecoveries", arg0, arg1, arg2) @@ -2479,13 +2479,13 @@ func (m *MockFullNode) StateMinerRecoveries(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateMinerRecoveries indicates an expected call of StateMinerRecoveries +// StateMinerRecoveries indicates an expected call of StateMinerRecoveries. func (mr *MockFullNodeMockRecorder) StateMinerRecoveries(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerRecoveries", reflect.TypeOf((*MockFullNode)(nil).StateMinerRecoveries), arg0, arg1, arg2) } -// StateMinerSectorAllocated mocks base method +// StateMinerSectorAllocated mocks base method. func (m *MockFullNode) StateMinerSectorAllocated(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerSectorAllocated", arg0, arg1, arg2, arg3) @@ -2494,13 +2494,13 @@ func (m *MockFullNode) StateMinerSectorAllocated(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateMinerSectorAllocated indicates an expected call of StateMinerSectorAllocated +// StateMinerSectorAllocated indicates an expected call of StateMinerSectorAllocated. func (mr *MockFullNodeMockRecorder) StateMinerSectorAllocated(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectorAllocated", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectorAllocated), arg0, arg1, arg2, arg3) } -// StateMinerSectorCount mocks base method +// StateMinerSectorCount mocks base method. func (m *MockFullNode) StateMinerSectorCount(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MinerSectors, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerSectorCount", arg0, arg1, arg2) @@ -2509,13 +2509,13 @@ func (m *MockFullNode) StateMinerSectorCount(arg0 context.Context, arg1 address. return ret0, ret1 } -// StateMinerSectorCount indicates an expected call of StateMinerSectorCount +// StateMinerSectorCount indicates an expected call of StateMinerSectorCount. func (mr *MockFullNodeMockRecorder) StateMinerSectorCount(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectorCount", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectorCount), arg0, arg1, arg2) } -// StateMinerSectors mocks base method +// StateMinerSectors mocks base method. func (m *MockFullNode) StateMinerSectors(arg0 context.Context, arg1 address.Address, arg2 *bitfield.BitField, arg3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerSectors", arg0, arg1, arg2, arg3) @@ -2524,13 +2524,13 @@ func (m *MockFullNode) StateMinerSectors(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// StateMinerSectors indicates an expected call of StateMinerSectors +// StateMinerSectors indicates an expected call of StateMinerSectors. func (mr *MockFullNodeMockRecorder) StateMinerSectors(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectors", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectors), arg0, arg1, arg2, arg3) } -// StateNetworkName mocks base method +// StateNetworkName mocks base method. func (m *MockFullNode) StateNetworkName(arg0 context.Context) (dtypes.NetworkName, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateNetworkName", arg0) @@ -2539,13 +2539,13 @@ func (m *MockFullNode) StateNetworkName(arg0 context.Context) (dtypes.NetworkNam return ret0, ret1 } -// StateNetworkName indicates an expected call of StateNetworkName +// StateNetworkName indicates an expected call of StateNetworkName. func (mr *MockFullNodeMockRecorder) StateNetworkName(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateNetworkName", reflect.TypeOf((*MockFullNode)(nil).StateNetworkName), arg0) } -// StateNetworkVersion mocks base method +// StateNetworkVersion mocks base method. func (m *MockFullNode) StateNetworkVersion(arg0 context.Context, arg1 types.TipSetKey) (network.Version, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateNetworkVersion", arg0, arg1) @@ -2554,13 +2554,13 @@ func (m *MockFullNode) StateNetworkVersion(arg0 context.Context, arg1 types.TipS return ret0, ret1 } -// StateNetworkVersion indicates an expected call of StateNetworkVersion +// StateNetworkVersion indicates an expected call of StateNetworkVersion. func (mr *MockFullNodeMockRecorder) StateNetworkVersion(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateNetworkVersion", reflect.TypeOf((*MockFullNode)(nil).StateNetworkVersion), arg0, arg1) } -// StateReadState mocks base method +// StateReadState mocks base method. func (m *MockFullNode) StateReadState(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*api.ActorState, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateReadState", arg0, arg1, arg2) @@ -2569,13 +2569,13 @@ func (m *MockFullNode) StateReadState(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// StateReadState indicates an expected call of StateReadState +// StateReadState indicates an expected call of StateReadState. func (mr *MockFullNodeMockRecorder) StateReadState(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateReadState", reflect.TypeOf((*MockFullNode)(nil).StateReadState), arg0, arg1, arg2) } -// StateReplay mocks base method +// StateReplay mocks base method. func (m *MockFullNode) StateReplay(arg0 context.Context, arg1 types.TipSetKey, arg2 cid.Cid) (*api.InvocResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateReplay", arg0, arg1, arg2) @@ -2584,13 +2584,13 @@ func (m *MockFullNode) StateReplay(arg0 context.Context, arg1 types.TipSetKey, a return ret0, ret1 } -// StateReplay indicates an expected call of StateReplay +// StateReplay indicates an expected call of StateReplay. func (mr *MockFullNodeMockRecorder) StateReplay(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateReplay", reflect.TypeOf((*MockFullNode)(nil).StateReplay), arg0, arg1, arg2) } -// StateSearchMsg mocks base method +// StateSearchMsg mocks base method. func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 types.TipSetKey, arg2 cid.Cid, arg3 abi.ChainEpoch, arg4 bool) (*api.MsgLookup, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSearchMsg", arg0, arg1, arg2, arg3, arg4) @@ -2599,13 +2599,13 @@ func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 types.TipSetKey return ret0, ret1 } -// StateSearchMsg indicates an expected call of StateSearchMsg +// StateSearchMsg indicates an expected call of StateSearchMsg. func (mr *MockFullNodeMockRecorder) StateSearchMsg(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsg", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsg), arg0, arg1, arg2, arg3, arg4) } -// StateSectorExpiration mocks base method +// StateSectorExpiration mocks base method. func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorExpiration, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorExpiration", arg0, arg1, arg2, arg3) @@ -2614,13 +2614,13 @@ func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address. return ret0, ret1 } -// StateSectorExpiration indicates an expected call of StateSectorExpiration +// StateSectorExpiration indicates an expected call of StateSectorExpiration. func (mr *MockFullNodeMockRecorder) StateSectorExpiration(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorExpiration", reflect.TypeOf((*MockFullNode)(nil).StateSectorExpiration), arg0, arg1, arg2, arg3) } -// StateSectorGetInfo mocks base method +// StateSectorGetInfo mocks base method. func (m *MockFullNode) StateSectorGetInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorGetInfo", arg0, arg1, arg2, arg3) @@ -2629,13 +2629,13 @@ func (m *MockFullNode) StateSectorGetInfo(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// StateSectorGetInfo indicates an expected call of StateSectorGetInfo +// StateSectorGetInfo indicates an expected call of StateSectorGetInfo. func (mr *MockFullNodeMockRecorder) StateSectorGetInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorGetInfo", reflect.TypeOf((*MockFullNode)(nil).StateSectorGetInfo), arg0, arg1, arg2, arg3) } -// StateSectorPartition mocks base method +// StateSectorPartition mocks base method. func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorLocation, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorPartition", arg0, arg1, arg2, arg3) @@ -2644,13 +2644,13 @@ func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateSectorPartition indicates an expected call of StateSectorPartition +// StateSectorPartition indicates an expected call of StateSectorPartition. func (mr *MockFullNodeMockRecorder) StateSectorPartition(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorPartition", reflect.TypeOf((*MockFullNode)(nil).StateSectorPartition), arg0, arg1, arg2, arg3) } -// StateSectorPreCommitInfo mocks base method +// StateSectorPreCommitInfo mocks base method. func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorPreCommitInfo", arg0, arg1, arg2, arg3) @@ -2659,13 +2659,13 @@ func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 addre return ret0, ret1 } -// StateSectorPreCommitInfo indicates an expected call of StateSectorPreCommitInfo +// StateSectorPreCommitInfo indicates an expected call of StateSectorPreCommitInfo. func (mr *MockFullNodeMockRecorder) StateSectorPreCommitInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorPreCommitInfo", reflect.TypeOf((*MockFullNode)(nil).StateSectorPreCommitInfo), arg0, arg1, arg2, arg3) } -// StateVMCirculatingSupplyInternal mocks base method +// StateVMCirculatingSupplyInternal mocks base method. func (m *MockFullNode) StateVMCirculatingSupplyInternal(arg0 context.Context, arg1 types.TipSetKey) (api.CirculatingSupply, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateVMCirculatingSupplyInternal", arg0, arg1) @@ -2674,13 +2674,13 @@ func (m *MockFullNode) StateVMCirculatingSupplyInternal(arg0 context.Context, ar return ret0, ret1 } -// StateVMCirculatingSupplyInternal indicates an expected call of StateVMCirculatingSupplyInternal +// StateVMCirculatingSupplyInternal indicates an expected call of StateVMCirculatingSupplyInternal. func (mr *MockFullNodeMockRecorder) StateVMCirculatingSupplyInternal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVMCirculatingSupplyInternal", reflect.TypeOf((*MockFullNode)(nil).StateVMCirculatingSupplyInternal), arg0, arg1) } -// StateVerifiedClientStatus mocks base method +// StateVerifiedClientStatus mocks base method. func (m *MockFullNode) StateVerifiedClientStatus(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateVerifiedClientStatus", arg0, arg1, arg2) @@ -2689,13 +2689,13 @@ func (m *MockFullNode) StateVerifiedClientStatus(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateVerifiedClientStatus indicates an expected call of StateVerifiedClientStatus +// StateVerifiedClientStatus indicates an expected call of StateVerifiedClientStatus. func (mr *MockFullNodeMockRecorder) StateVerifiedClientStatus(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifiedClientStatus", reflect.TypeOf((*MockFullNode)(nil).StateVerifiedClientStatus), arg0, arg1, arg2) } -// StateVerifiedRegistryRootKey mocks base method +// StateVerifiedRegistryRootKey mocks base method. func (m *MockFullNode) StateVerifiedRegistryRootKey(arg0 context.Context, arg1 types.TipSetKey) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateVerifiedRegistryRootKey", arg0, arg1) @@ -2704,13 +2704,13 @@ func (m *MockFullNode) StateVerifiedRegistryRootKey(arg0 context.Context, arg1 t return ret0, ret1 } -// StateVerifiedRegistryRootKey indicates an expected call of StateVerifiedRegistryRootKey +// StateVerifiedRegistryRootKey indicates an expected call of StateVerifiedRegistryRootKey. func (mr *MockFullNodeMockRecorder) StateVerifiedRegistryRootKey(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifiedRegistryRootKey", reflect.TypeOf((*MockFullNode)(nil).StateVerifiedRegistryRootKey), arg0, arg1) } -// StateVerifierStatus mocks base method +// StateVerifierStatus mocks base method. func (m *MockFullNode) StateVerifierStatus(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateVerifierStatus", arg0, arg1, arg2) @@ -2719,13 +2719,13 @@ func (m *MockFullNode) StateVerifierStatus(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// StateVerifierStatus indicates an expected call of StateVerifierStatus +// StateVerifierStatus indicates an expected call of StateVerifierStatus. func (mr *MockFullNodeMockRecorder) StateVerifierStatus(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifierStatus", reflect.TypeOf((*MockFullNode)(nil).StateVerifierStatus), arg0, arg1, arg2) } -// StateWaitMsg mocks base method +// StateWaitMsg mocks base method. func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uint64, arg3 abi.ChainEpoch, arg4 bool) (*api.MsgLookup, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateWaitMsg", arg0, arg1, arg2, arg3, arg4) @@ -2734,13 +2734,13 @@ func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uin return ret0, ret1 } -// StateWaitMsg indicates an expected call of StateWaitMsg +// StateWaitMsg indicates an expected call of StateWaitMsg. func (mr *MockFullNodeMockRecorder) StateWaitMsg(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsg", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsg), arg0, arg1, arg2, arg3, arg4) } -// SyncCheckBad mocks base method +// SyncCheckBad mocks base method. func (m *MockFullNode) SyncCheckBad(arg0 context.Context, arg1 cid.Cid) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncCheckBad", arg0, arg1) @@ -2749,13 +2749,13 @@ func (m *MockFullNode) SyncCheckBad(arg0 context.Context, arg1 cid.Cid) (string, return ret0, ret1 } -// SyncCheckBad indicates an expected call of SyncCheckBad +// SyncCheckBad indicates an expected call of SyncCheckBad. func (mr *MockFullNodeMockRecorder) SyncCheckBad(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncCheckBad", reflect.TypeOf((*MockFullNode)(nil).SyncCheckBad), arg0, arg1) } -// SyncCheckpoint mocks base method +// SyncCheckpoint mocks base method. func (m *MockFullNode) SyncCheckpoint(arg0 context.Context, arg1 types.TipSetKey) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncCheckpoint", arg0, arg1) @@ -2763,13 +2763,13 @@ func (m *MockFullNode) SyncCheckpoint(arg0 context.Context, arg1 types.TipSetKey return ret0 } -// SyncCheckpoint indicates an expected call of SyncCheckpoint +// SyncCheckpoint indicates an expected call of SyncCheckpoint. func (mr *MockFullNodeMockRecorder) SyncCheckpoint(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncCheckpoint", reflect.TypeOf((*MockFullNode)(nil).SyncCheckpoint), arg0, arg1) } -// SyncIncomingBlocks mocks base method +// SyncIncomingBlocks mocks base method. func (m *MockFullNode) SyncIncomingBlocks(arg0 context.Context) (<-chan *types.BlockHeader, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncIncomingBlocks", arg0) @@ -2778,13 +2778,13 @@ func (m *MockFullNode) SyncIncomingBlocks(arg0 context.Context) (<-chan *types.B return ret0, ret1 } -// SyncIncomingBlocks indicates an expected call of SyncIncomingBlocks +// SyncIncomingBlocks indicates an expected call of SyncIncomingBlocks. func (mr *MockFullNodeMockRecorder) SyncIncomingBlocks(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncIncomingBlocks", reflect.TypeOf((*MockFullNode)(nil).SyncIncomingBlocks), arg0) } -// SyncMarkBad mocks base method +// SyncMarkBad mocks base method. func (m *MockFullNode) SyncMarkBad(arg0 context.Context, arg1 cid.Cid) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncMarkBad", arg0, arg1) @@ -2792,13 +2792,13 @@ func (m *MockFullNode) SyncMarkBad(arg0 context.Context, arg1 cid.Cid) error { return ret0 } -// SyncMarkBad indicates an expected call of SyncMarkBad +// SyncMarkBad indicates an expected call of SyncMarkBad. func (mr *MockFullNodeMockRecorder) SyncMarkBad(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncMarkBad", reflect.TypeOf((*MockFullNode)(nil).SyncMarkBad), arg0, arg1) } -// SyncState mocks base method +// SyncState mocks base method. func (m *MockFullNode) SyncState(arg0 context.Context) (*api.SyncState, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncState", arg0) @@ -2807,13 +2807,13 @@ func (m *MockFullNode) SyncState(arg0 context.Context) (*api.SyncState, error) { return ret0, ret1 } -// SyncState indicates an expected call of SyncState +// SyncState indicates an expected call of SyncState. func (mr *MockFullNodeMockRecorder) SyncState(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncState", reflect.TypeOf((*MockFullNode)(nil).SyncState), arg0) } -// SyncSubmitBlock mocks base method +// SyncSubmitBlock mocks base method. func (m *MockFullNode) SyncSubmitBlock(arg0 context.Context, arg1 *types.BlockMsg) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncSubmitBlock", arg0, arg1) @@ -2821,13 +2821,13 @@ func (m *MockFullNode) SyncSubmitBlock(arg0 context.Context, arg1 *types.BlockMs return ret0 } -// SyncSubmitBlock indicates an expected call of SyncSubmitBlock +// SyncSubmitBlock indicates an expected call of SyncSubmitBlock. func (mr *MockFullNodeMockRecorder) SyncSubmitBlock(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncSubmitBlock", reflect.TypeOf((*MockFullNode)(nil).SyncSubmitBlock), arg0, arg1) } -// SyncUnmarkAllBad mocks base method +// SyncUnmarkAllBad mocks base method. func (m *MockFullNode) SyncUnmarkAllBad(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncUnmarkAllBad", arg0) @@ -2835,13 +2835,13 @@ func (m *MockFullNode) SyncUnmarkAllBad(arg0 context.Context) error { return ret0 } -// SyncUnmarkAllBad indicates an expected call of SyncUnmarkAllBad +// SyncUnmarkAllBad indicates an expected call of SyncUnmarkAllBad. func (mr *MockFullNodeMockRecorder) SyncUnmarkAllBad(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncUnmarkAllBad", reflect.TypeOf((*MockFullNode)(nil).SyncUnmarkAllBad), arg0) } -// SyncUnmarkBad mocks base method +// SyncUnmarkBad mocks base method. func (m *MockFullNode) SyncUnmarkBad(arg0 context.Context, arg1 cid.Cid) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncUnmarkBad", arg0, arg1) @@ -2849,13 +2849,13 @@ func (m *MockFullNode) SyncUnmarkBad(arg0 context.Context, arg1 cid.Cid) error { return ret0 } -// SyncUnmarkBad indicates an expected call of SyncUnmarkBad +// SyncUnmarkBad indicates an expected call of SyncUnmarkBad. func (mr *MockFullNodeMockRecorder) SyncUnmarkBad(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncUnmarkBad", reflect.TypeOf((*MockFullNode)(nil).SyncUnmarkBad), arg0, arg1) } -// SyncValidateTipset mocks base method +// SyncValidateTipset mocks base method. func (m *MockFullNode) SyncValidateTipset(arg0 context.Context, arg1 types.TipSetKey) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncValidateTipset", arg0, arg1) @@ -2864,13 +2864,13 @@ func (m *MockFullNode) SyncValidateTipset(arg0 context.Context, arg1 types.TipSe return ret0, ret1 } -// SyncValidateTipset indicates an expected call of SyncValidateTipset +// SyncValidateTipset indicates an expected call of SyncValidateTipset. func (mr *MockFullNodeMockRecorder) SyncValidateTipset(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncValidateTipset", reflect.TypeOf((*MockFullNode)(nil).SyncValidateTipset), arg0, arg1) } -// Version mocks base method +// Version mocks base method. func (m *MockFullNode) Version(arg0 context.Context) (api.APIVersion, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Version", arg0) @@ -2879,13 +2879,13 @@ func (m *MockFullNode) Version(arg0 context.Context) (api.APIVersion, error) { return ret0, ret1 } -// Version indicates an expected call of Version +// Version indicates an expected call of Version. func (mr *MockFullNodeMockRecorder) Version(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockFullNode)(nil).Version), arg0) } -// WalletBalance mocks base method +// WalletBalance mocks base method. func (m *MockFullNode) WalletBalance(arg0 context.Context, arg1 address.Address) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletBalance", arg0, arg1) @@ -2894,13 +2894,13 @@ func (m *MockFullNode) WalletBalance(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// WalletBalance indicates an expected call of WalletBalance +// WalletBalance indicates an expected call of WalletBalance. func (mr *MockFullNodeMockRecorder) WalletBalance(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletBalance", reflect.TypeOf((*MockFullNode)(nil).WalletBalance), arg0, arg1) } -// WalletDefaultAddress mocks base method +// WalletDefaultAddress mocks base method. func (m *MockFullNode) WalletDefaultAddress(arg0 context.Context) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletDefaultAddress", arg0) @@ -2909,13 +2909,13 @@ func (m *MockFullNode) WalletDefaultAddress(arg0 context.Context) (address.Addre return ret0, ret1 } -// WalletDefaultAddress indicates an expected call of WalletDefaultAddress +// WalletDefaultAddress indicates an expected call of WalletDefaultAddress. func (mr *MockFullNodeMockRecorder) WalletDefaultAddress(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletDefaultAddress", reflect.TypeOf((*MockFullNode)(nil).WalletDefaultAddress), arg0) } -// WalletDelete mocks base method +// WalletDelete mocks base method. func (m *MockFullNode) WalletDelete(arg0 context.Context, arg1 address.Address) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletDelete", arg0, arg1) @@ -2923,13 +2923,13 @@ func (m *MockFullNode) WalletDelete(arg0 context.Context, arg1 address.Address) return ret0 } -// WalletDelete indicates an expected call of WalletDelete +// WalletDelete indicates an expected call of WalletDelete. func (mr *MockFullNodeMockRecorder) WalletDelete(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletDelete", reflect.TypeOf((*MockFullNode)(nil).WalletDelete), arg0, arg1) } -// WalletExport mocks base method +// WalletExport mocks base method. func (m *MockFullNode) WalletExport(arg0 context.Context, arg1 address.Address) (*types.KeyInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletExport", arg0, arg1) @@ -2938,13 +2938,13 @@ func (m *MockFullNode) WalletExport(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// WalletExport indicates an expected call of WalletExport +// WalletExport indicates an expected call of WalletExport. func (mr *MockFullNodeMockRecorder) WalletExport(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletExport", reflect.TypeOf((*MockFullNode)(nil).WalletExport), arg0, arg1) } -// WalletHas mocks base method +// WalletHas mocks base method. func (m *MockFullNode) WalletHas(arg0 context.Context, arg1 address.Address) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletHas", arg0, arg1) @@ -2953,13 +2953,13 @@ func (m *MockFullNode) WalletHas(arg0 context.Context, arg1 address.Address) (bo return ret0, ret1 } -// WalletHas indicates an expected call of WalletHas +// WalletHas indicates an expected call of WalletHas. func (mr *MockFullNodeMockRecorder) WalletHas(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletHas", reflect.TypeOf((*MockFullNode)(nil).WalletHas), arg0, arg1) } -// WalletImport mocks base method +// WalletImport mocks base method. func (m *MockFullNode) WalletImport(arg0 context.Context, arg1 *types.KeyInfo) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletImport", arg0, arg1) @@ -2968,13 +2968,13 @@ func (m *MockFullNode) WalletImport(arg0 context.Context, arg1 *types.KeyInfo) ( return ret0, ret1 } -// WalletImport indicates an expected call of WalletImport +// WalletImport indicates an expected call of WalletImport. func (mr *MockFullNodeMockRecorder) WalletImport(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletImport", reflect.TypeOf((*MockFullNode)(nil).WalletImport), arg0, arg1) } -// WalletList mocks base method +// WalletList mocks base method. func (m *MockFullNode) WalletList(arg0 context.Context) ([]address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletList", arg0) @@ -2983,13 +2983,13 @@ func (m *MockFullNode) WalletList(arg0 context.Context) ([]address.Address, erro return ret0, ret1 } -// WalletList indicates an expected call of WalletList +// WalletList indicates an expected call of WalletList. func (mr *MockFullNodeMockRecorder) WalletList(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletList", reflect.TypeOf((*MockFullNode)(nil).WalletList), arg0) } -// WalletNew mocks base method +// WalletNew mocks base method. func (m *MockFullNode) WalletNew(arg0 context.Context, arg1 types.KeyType) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletNew", arg0, arg1) @@ -2998,13 +2998,13 @@ func (m *MockFullNode) WalletNew(arg0 context.Context, arg1 types.KeyType) (addr return ret0, ret1 } -// WalletNew indicates an expected call of WalletNew +// WalletNew indicates an expected call of WalletNew. func (mr *MockFullNodeMockRecorder) WalletNew(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletNew", reflect.TypeOf((*MockFullNode)(nil).WalletNew), arg0, arg1) } -// WalletSetDefault mocks base method +// WalletSetDefault mocks base method. func (m *MockFullNode) WalletSetDefault(arg0 context.Context, arg1 address.Address) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletSetDefault", arg0, arg1) @@ -3012,13 +3012,13 @@ func (m *MockFullNode) WalletSetDefault(arg0 context.Context, arg1 address.Addre return ret0 } -// WalletSetDefault indicates an expected call of WalletSetDefault +// WalletSetDefault indicates an expected call of WalletSetDefault. func (mr *MockFullNodeMockRecorder) WalletSetDefault(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSetDefault", reflect.TypeOf((*MockFullNode)(nil).WalletSetDefault), arg0, arg1) } -// WalletSign mocks base method +// WalletSign mocks base method. func (m *MockFullNode) WalletSign(arg0 context.Context, arg1 address.Address, arg2 []byte) (*crypto.Signature, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletSign", arg0, arg1, arg2) @@ -3027,13 +3027,13 @@ func (m *MockFullNode) WalletSign(arg0 context.Context, arg1 address.Address, ar return ret0, ret1 } -// WalletSign indicates an expected call of WalletSign +// WalletSign indicates an expected call of WalletSign. func (mr *MockFullNodeMockRecorder) WalletSign(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSign", reflect.TypeOf((*MockFullNode)(nil).WalletSign), arg0, arg1, arg2) } -// WalletSignMessage mocks base method +// WalletSignMessage mocks base method. func (m *MockFullNode) WalletSignMessage(arg0 context.Context, arg1 address.Address, arg2 *types.Message) (*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletSignMessage", arg0, arg1, arg2) @@ -3042,13 +3042,13 @@ func (m *MockFullNode) WalletSignMessage(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// WalletSignMessage indicates an expected call of WalletSignMessage +// WalletSignMessage indicates an expected call of WalletSignMessage. func (mr *MockFullNodeMockRecorder) WalletSignMessage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSignMessage", reflect.TypeOf((*MockFullNode)(nil).WalletSignMessage), arg0, arg1, arg2) } -// WalletValidateAddress mocks base method +// WalletValidateAddress mocks base method. func (m *MockFullNode) WalletValidateAddress(arg0 context.Context, arg1 string) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletValidateAddress", arg0, arg1) @@ -3057,13 +3057,13 @@ func (m *MockFullNode) WalletValidateAddress(arg0 context.Context, arg1 string) return ret0, ret1 } -// WalletValidateAddress indicates an expected call of WalletValidateAddress +// WalletValidateAddress indicates an expected call of WalletValidateAddress. func (mr *MockFullNodeMockRecorder) WalletValidateAddress(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletValidateAddress", reflect.TypeOf((*MockFullNode)(nil).WalletValidateAddress), arg0, arg1) } -// WalletVerify mocks base method +// WalletVerify mocks base method. func (m *MockFullNode) WalletVerify(arg0 context.Context, arg1 address.Address, arg2 []byte, arg3 *crypto.Signature) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletVerify", arg0, arg1, arg2, arg3) @@ -3072,7 +3072,7 @@ func (m *MockFullNode) WalletVerify(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// WalletVerify indicates an expected call of WalletVerify +// WalletVerify indicates an expected call of WalletVerify. func (mr *MockFullNodeMockRecorder) WalletVerify(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletVerify", reflect.TypeOf((*MockFullNode)(nil).WalletVerify), arg0, arg1, arg2, arg3) diff --git a/api/v0api/v0mocks/mock_full.go b/api/v0api/v0mocks/mock_full.go index 7bcfaf47c..a268d4a8a 100644 --- a/api/v0api/v0mocks/mock_full.go +++ b/api/v0api/v0mocks/mock_full.go @@ -37,30 +37,30 @@ import ( protocol "github.com/libp2p/go-libp2p-core/protocol" ) -// MockFullNode is a mock of FullNode interface +// MockFullNode is a mock of FullNode interface. type MockFullNode struct { ctrl *gomock.Controller recorder *MockFullNodeMockRecorder } -// MockFullNodeMockRecorder is the mock recorder for MockFullNode +// MockFullNodeMockRecorder is the mock recorder for MockFullNode. type MockFullNodeMockRecorder struct { mock *MockFullNode } -// NewMockFullNode creates a new mock instance +// NewMockFullNode creates a new mock instance. func NewMockFullNode(ctrl *gomock.Controller) *MockFullNode { mock := &MockFullNode{ctrl: ctrl} mock.recorder = &MockFullNodeMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockFullNode) EXPECT() *MockFullNodeMockRecorder { return m.recorder } -// AuthNew mocks base method +// AuthNew mocks base method. func (m *MockFullNode) AuthNew(arg0 context.Context, arg1 []auth.Permission) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AuthNew", arg0, arg1) @@ -69,13 +69,13 @@ func (m *MockFullNode) AuthNew(arg0 context.Context, arg1 []auth.Permission) ([] return ret0, ret1 } -// AuthNew indicates an expected call of AuthNew +// AuthNew indicates an expected call of AuthNew. func (mr *MockFullNodeMockRecorder) AuthNew(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthNew", reflect.TypeOf((*MockFullNode)(nil).AuthNew), arg0, arg1) } -// AuthVerify mocks base method +// AuthVerify mocks base method. func (m *MockFullNode) AuthVerify(arg0 context.Context, arg1 string) ([]auth.Permission, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AuthVerify", arg0, arg1) @@ -84,13 +84,13 @@ func (m *MockFullNode) AuthVerify(arg0 context.Context, arg1 string) ([]auth.Per return ret0, ret1 } -// AuthVerify indicates an expected call of AuthVerify +// AuthVerify indicates an expected call of AuthVerify. func (mr *MockFullNodeMockRecorder) AuthVerify(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthVerify", reflect.TypeOf((*MockFullNode)(nil).AuthVerify), arg0, arg1) } -// BeaconGetEntry mocks base method +// BeaconGetEntry mocks base method. func (m *MockFullNode) BeaconGetEntry(arg0 context.Context, arg1 abi.ChainEpoch) (*types.BeaconEntry, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BeaconGetEntry", arg0, arg1) @@ -99,13 +99,13 @@ func (m *MockFullNode) BeaconGetEntry(arg0 context.Context, arg1 abi.ChainEpoch) return ret0, ret1 } -// BeaconGetEntry indicates an expected call of BeaconGetEntry +// BeaconGetEntry indicates an expected call of BeaconGetEntry. func (mr *MockFullNodeMockRecorder) BeaconGetEntry(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconGetEntry", reflect.TypeOf((*MockFullNode)(nil).BeaconGetEntry), arg0, arg1) } -// ChainDeleteObj mocks base method +// ChainDeleteObj mocks base method. func (m *MockFullNode) ChainDeleteObj(arg0 context.Context, arg1 cid.Cid) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainDeleteObj", arg0, arg1) @@ -113,13 +113,13 @@ func (m *MockFullNode) ChainDeleteObj(arg0 context.Context, arg1 cid.Cid) error return ret0 } -// ChainDeleteObj indicates an expected call of ChainDeleteObj +// ChainDeleteObj indicates an expected call of ChainDeleteObj. func (mr *MockFullNodeMockRecorder) ChainDeleteObj(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainDeleteObj", reflect.TypeOf((*MockFullNode)(nil).ChainDeleteObj), arg0, arg1) } -// ChainExport mocks base method +// ChainExport mocks base method. func (m *MockFullNode) ChainExport(arg0 context.Context, arg1 abi.ChainEpoch, arg2 bool, arg3 types.TipSetKey) (<-chan []byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainExport", arg0, arg1, arg2, arg3) @@ -128,13 +128,13 @@ func (m *MockFullNode) ChainExport(arg0 context.Context, arg1 abi.ChainEpoch, ar return ret0, ret1 } -// ChainExport indicates an expected call of ChainExport +// ChainExport indicates an expected call of ChainExport. func (mr *MockFullNodeMockRecorder) ChainExport(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainExport", reflect.TypeOf((*MockFullNode)(nil).ChainExport), arg0, arg1, arg2, arg3) } -// ChainGetBlock mocks base method +// ChainGetBlock mocks base method. func (m *MockFullNode) ChainGetBlock(arg0 context.Context, arg1 cid.Cid) (*types.BlockHeader, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetBlock", arg0, arg1) @@ -143,13 +143,13 @@ func (m *MockFullNode) ChainGetBlock(arg0 context.Context, arg1 cid.Cid) (*types return ret0, ret1 } -// ChainGetBlock indicates an expected call of ChainGetBlock +// ChainGetBlock indicates an expected call of ChainGetBlock. func (mr *MockFullNodeMockRecorder) ChainGetBlock(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetBlock", reflect.TypeOf((*MockFullNode)(nil).ChainGetBlock), arg0, arg1) } -// ChainGetBlockMessages mocks base method +// ChainGetBlockMessages mocks base method. func (m *MockFullNode) ChainGetBlockMessages(arg0 context.Context, arg1 cid.Cid) (*api.BlockMessages, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetBlockMessages", arg0, arg1) @@ -158,13 +158,13 @@ func (m *MockFullNode) ChainGetBlockMessages(arg0 context.Context, arg1 cid.Cid) return ret0, ret1 } -// ChainGetBlockMessages indicates an expected call of ChainGetBlockMessages +// ChainGetBlockMessages indicates an expected call of ChainGetBlockMessages. func (mr *MockFullNodeMockRecorder) ChainGetBlockMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetBlockMessages", reflect.TypeOf((*MockFullNode)(nil).ChainGetBlockMessages), arg0, arg1) } -// ChainGetGenesis mocks base method +// ChainGetGenesis mocks base method. func (m *MockFullNode) ChainGetGenesis(arg0 context.Context) (*types.TipSet, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetGenesis", arg0) @@ -173,13 +173,13 @@ func (m *MockFullNode) ChainGetGenesis(arg0 context.Context) (*types.TipSet, err return ret0, ret1 } -// ChainGetGenesis indicates an expected call of ChainGetGenesis +// ChainGetGenesis indicates an expected call of ChainGetGenesis. func (mr *MockFullNodeMockRecorder) ChainGetGenesis(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetGenesis", reflect.TypeOf((*MockFullNode)(nil).ChainGetGenesis), arg0) } -// ChainGetMessage mocks base method +// ChainGetMessage mocks base method. func (m *MockFullNode) ChainGetMessage(arg0 context.Context, arg1 cid.Cid) (*types.Message, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetMessage", arg0, arg1) @@ -188,13 +188,13 @@ func (m *MockFullNode) ChainGetMessage(arg0 context.Context, arg1 cid.Cid) (*typ return ret0, ret1 } -// ChainGetMessage indicates an expected call of ChainGetMessage +// ChainGetMessage indicates an expected call of ChainGetMessage. func (mr *MockFullNodeMockRecorder) ChainGetMessage(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetMessage", reflect.TypeOf((*MockFullNode)(nil).ChainGetMessage), arg0, arg1) } -// ChainGetNode mocks base method +// ChainGetNode mocks base method. func (m *MockFullNode) ChainGetNode(arg0 context.Context, arg1 string) (*api.IpldObject, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetNode", arg0, arg1) @@ -203,13 +203,13 @@ func (m *MockFullNode) ChainGetNode(arg0 context.Context, arg1 string) (*api.Ipl return ret0, ret1 } -// ChainGetNode indicates an expected call of ChainGetNode +// ChainGetNode indicates an expected call of ChainGetNode. func (mr *MockFullNodeMockRecorder) ChainGetNode(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetNode", reflect.TypeOf((*MockFullNode)(nil).ChainGetNode), arg0, arg1) } -// ChainGetParentMessages mocks base method +// ChainGetParentMessages mocks base method. func (m *MockFullNode) ChainGetParentMessages(arg0 context.Context, arg1 cid.Cid) ([]api.Message, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetParentMessages", arg0, arg1) @@ -218,13 +218,13 @@ func (m *MockFullNode) ChainGetParentMessages(arg0 context.Context, arg1 cid.Cid return ret0, ret1 } -// ChainGetParentMessages indicates an expected call of ChainGetParentMessages +// ChainGetParentMessages indicates an expected call of ChainGetParentMessages. func (mr *MockFullNodeMockRecorder) ChainGetParentMessages(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetParentMessages", reflect.TypeOf((*MockFullNode)(nil).ChainGetParentMessages), arg0, arg1) } -// ChainGetParentReceipts mocks base method +// ChainGetParentReceipts mocks base method. func (m *MockFullNode) ChainGetParentReceipts(arg0 context.Context, arg1 cid.Cid) ([]*types.MessageReceipt, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetParentReceipts", arg0, arg1) @@ -233,13 +233,13 @@ func (m *MockFullNode) ChainGetParentReceipts(arg0 context.Context, arg1 cid.Cid return ret0, ret1 } -// ChainGetParentReceipts indicates an expected call of ChainGetParentReceipts +// ChainGetParentReceipts indicates an expected call of ChainGetParentReceipts. func (mr *MockFullNodeMockRecorder) ChainGetParentReceipts(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetParentReceipts", reflect.TypeOf((*MockFullNode)(nil).ChainGetParentReceipts), arg0, arg1) } -// ChainGetPath mocks base method +// ChainGetPath mocks base method. func (m *MockFullNode) ChainGetPath(arg0 context.Context, arg1, arg2 types.TipSetKey) ([]*api.HeadChange, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetPath", arg0, arg1, arg2) @@ -248,13 +248,13 @@ func (m *MockFullNode) ChainGetPath(arg0 context.Context, arg1, arg2 types.TipSe return ret0, ret1 } -// ChainGetPath indicates an expected call of ChainGetPath +// ChainGetPath indicates an expected call of ChainGetPath. func (mr *MockFullNodeMockRecorder) ChainGetPath(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetPath", reflect.TypeOf((*MockFullNode)(nil).ChainGetPath), arg0, arg1, arg2) } -// ChainGetRandomnessFromBeacon mocks base method +// ChainGetRandomnessFromBeacon mocks base method. func (m *MockFullNode) ChainGetRandomnessFromBeacon(arg0 context.Context, arg1 types.TipSetKey, arg2 crypto.DomainSeparationTag, arg3 abi.ChainEpoch, arg4 []byte) (abi.Randomness, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetRandomnessFromBeacon", arg0, arg1, arg2, arg3, arg4) @@ -263,13 +263,13 @@ func (m *MockFullNode) ChainGetRandomnessFromBeacon(arg0 context.Context, arg1 t return ret0, ret1 } -// ChainGetRandomnessFromBeacon indicates an expected call of ChainGetRandomnessFromBeacon +// ChainGetRandomnessFromBeacon indicates an expected call of ChainGetRandomnessFromBeacon. func (mr *MockFullNodeMockRecorder) ChainGetRandomnessFromBeacon(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetRandomnessFromBeacon", reflect.TypeOf((*MockFullNode)(nil).ChainGetRandomnessFromBeacon), arg0, arg1, arg2, arg3, arg4) } -// ChainGetRandomnessFromTickets mocks base method +// ChainGetRandomnessFromTickets mocks base method. func (m *MockFullNode) ChainGetRandomnessFromTickets(arg0 context.Context, arg1 types.TipSetKey, arg2 crypto.DomainSeparationTag, arg3 abi.ChainEpoch, arg4 []byte) (abi.Randomness, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetRandomnessFromTickets", arg0, arg1, arg2, arg3, arg4) @@ -278,13 +278,13 @@ func (m *MockFullNode) ChainGetRandomnessFromTickets(arg0 context.Context, arg1 return ret0, ret1 } -// ChainGetRandomnessFromTickets indicates an expected call of ChainGetRandomnessFromTickets +// ChainGetRandomnessFromTickets indicates an expected call of ChainGetRandomnessFromTickets. func (mr *MockFullNodeMockRecorder) ChainGetRandomnessFromTickets(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetRandomnessFromTickets", reflect.TypeOf((*MockFullNode)(nil).ChainGetRandomnessFromTickets), arg0, arg1, arg2, arg3, arg4) } -// ChainGetTipSet mocks base method +// ChainGetTipSet mocks base method. func (m *MockFullNode) ChainGetTipSet(arg0 context.Context, arg1 types.TipSetKey) (*types.TipSet, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetTipSet", arg0, arg1) @@ -293,13 +293,13 @@ func (m *MockFullNode) ChainGetTipSet(arg0 context.Context, arg1 types.TipSetKey return ret0, ret1 } -// ChainGetTipSet indicates an expected call of ChainGetTipSet +// ChainGetTipSet indicates an expected call of ChainGetTipSet. func (mr *MockFullNodeMockRecorder) ChainGetTipSet(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetTipSet", reflect.TypeOf((*MockFullNode)(nil).ChainGetTipSet), arg0, arg1) } -// ChainGetTipSetByHeight mocks base method +// ChainGetTipSetByHeight mocks base method. func (m *MockFullNode) ChainGetTipSetByHeight(arg0 context.Context, arg1 abi.ChainEpoch, arg2 types.TipSetKey) (*types.TipSet, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainGetTipSetByHeight", arg0, arg1, arg2) @@ -308,13 +308,13 @@ func (m *MockFullNode) ChainGetTipSetByHeight(arg0 context.Context, arg1 abi.Cha return ret0, ret1 } -// ChainGetTipSetByHeight indicates an expected call of ChainGetTipSetByHeight +// ChainGetTipSetByHeight indicates an expected call of ChainGetTipSetByHeight. func (mr *MockFullNodeMockRecorder) ChainGetTipSetByHeight(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetTipSetByHeight", reflect.TypeOf((*MockFullNode)(nil).ChainGetTipSetByHeight), arg0, arg1, arg2) } -// ChainHasObj mocks base method +// ChainHasObj mocks base method. func (m *MockFullNode) ChainHasObj(arg0 context.Context, arg1 cid.Cid) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainHasObj", arg0, arg1) @@ -323,13 +323,13 @@ func (m *MockFullNode) ChainHasObj(arg0 context.Context, arg1 cid.Cid) (bool, er return ret0, ret1 } -// ChainHasObj indicates an expected call of ChainHasObj +// ChainHasObj indicates an expected call of ChainHasObj. func (mr *MockFullNodeMockRecorder) ChainHasObj(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHasObj", reflect.TypeOf((*MockFullNode)(nil).ChainHasObj), arg0, arg1) } -// ChainHead mocks base method +// ChainHead mocks base method. func (m *MockFullNode) ChainHead(arg0 context.Context) (*types.TipSet, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainHead", arg0) @@ -338,13 +338,13 @@ func (m *MockFullNode) ChainHead(arg0 context.Context) (*types.TipSet, error) { return ret0, ret1 } -// ChainHead indicates an expected call of ChainHead +// ChainHead indicates an expected call of ChainHead. func (mr *MockFullNodeMockRecorder) ChainHead(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHead", reflect.TypeOf((*MockFullNode)(nil).ChainHead), arg0) } -// ChainNotify mocks base method +// ChainNotify mocks base method. func (m *MockFullNode) ChainNotify(arg0 context.Context) (<-chan []*api.HeadChange, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainNotify", arg0) @@ -353,13 +353,13 @@ func (m *MockFullNode) ChainNotify(arg0 context.Context) (<-chan []*api.HeadChan return ret0, ret1 } -// ChainNotify indicates an expected call of ChainNotify +// ChainNotify indicates an expected call of ChainNotify. func (mr *MockFullNodeMockRecorder) ChainNotify(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainNotify", reflect.TypeOf((*MockFullNode)(nil).ChainNotify), arg0) } -// ChainReadObj mocks base method +// ChainReadObj mocks base method. func (m *MockFullNode) ChainReadObj(arg0 context.Context, arg1 cid.Cid) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainReadObj", arg0, arg1) @@ -368,13 +368,13 @@ func (m *MockFullNode) ChainReadObj(arg0 context.Context, arg1 cid.Cid) ([]byte, return ret0, ret1 } -// ChainReadObj indicates an expected call of ChainReadObj +// ChainReadObj indicates an expected call of ChainReadObj. func (mr *MockFullNodeMockRecorder) ChainReadObj(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainReadObj", reflect.TypeOf((*MockFullNode)(nil).ChainReadObj), arg0, arg1) } -// ChainSetHead mocks base method +// ChainSetHead mocks base method. func (m *MockFullNode) ChainSetHead(arg0 context.Context, arg1 types.TipSetKey) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainSetHead", arg0, arg1) @@ -382,13 +382,13 @@ func (m *MockFullNode) ChainSetHead(arg0 context.Context, arg1 types.TipSetKey) return ret0 } -// ChainSetHead indicates an expected call of ChainSetHead +// ChainSetHead indicates an expected call of ChainSetHead. func (mr *MockFullNodeMockRecorder) ChainSetHead(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainSetHead", reflect.TypeOf((*MockFullNode)(nil).ChainSetHead), arg0, arg1) } -// ChainStatObj mocks base method +// ChainStatObj mocks base method. func (m *MockFullNode) ChainStatObj(arg0 context.Context, arg1, arg2 cid.Cid) (api.ObjStat, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainStatObj", arg0, arg1, arg2) @@ -397,13 +397,13 @@ func (m *MockFullNode) ChainStatObj(arg0 context.Context, arg1, arg2 cid.Cid) (a return ret0, ret1 } -// ChainStatObj indicates an expected call of ChainStatObj +// ChainStatObj indicates an expected call of ChainStatObj. func (mr *MockFullNodeMockRecorder) ChainStatObj(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainStatObj", reflect.TypeOf((*MockFullNode)(nil).ChainStatObj), arg0, arg1, arg2) } -// ChainTipSetWeight mocks base method +// ChainTipSetWeight mocks base method. func (m *MockFullNode) ChainTipSetWeight(arg0 context.Context, arg1 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChainTipSetWeight", arg0, arg1) @@ -412,13 +412,13 @@ func (m *MockFullNode) ChainTipSetWeight(arg0 context.Context, arg1 types.TipSet return ret0, ret1 } -// ChainTipSetWeight indicates an expected call of ChainTipSetWeight +// ChainTipSetWeight indicates an expected call of ChainTipSetWeight. func (mr *MockFullNodeMockRecorder) ChainTipSetWeight(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainTipSetWeight", reflect.TypeOf((*MockFullNode)(nil).ChainTipSetWeight), arg0, arg1) } -// ClientCalcCommP mocks base method +// ClientCalcCommP mocks base method. func (m *MockFullNode) ClientCalcCommP(arg0 context.Context, arg1 string) (*api.CommPRet, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientCalcCommP", arg0, arg1) @@ -427,13 +427,13 @@ func (m *MockFullNode) ClientCalcCommP(arg0 context.Context, arg1 string) (*api. return ret0, ret1 } -// ClientCalcCommP indicates an expected call of ClientCalcCommP +// ClientCalcCommP indicates an expected call of ClientCalcCommP. func (mr *MockFullNodeMockRecorder) ClientCalcCommP(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCalcCommP", reflect.TypeOf((*MockFullNode)(nil).ClientCalcCommP), arg0, arg1) } -// ClientCancelDataTransfer mocks base method +// ClientCancelDataTransfer mocks base method. func (m *MockFullNode) ClientCancelDataTransfer(arg0 context.Context, arg1 datatransfer.TransferID, arg2 peer.ID, arg3 bool) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientCancelDataTransfer", arg0, arg1, arg2, arg3) @@ -441,13 +441,13 @@ func (m *MockFullNode) ClientCancelDataTransfer(arg0 context.Context, arg1 datat return ret0 } -// ClientCancelDataTransfer indicates an expected call of ClientCancelDataTransfer +// ClientCancelDataTransfer indicates an expected call of ClientCancelDataTransfer. func (mr *MockFullNodeMockRecorder) ClientCancelDataTransfer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelDataTransfer", reflect.TypeOf((*MockFullNode)(nil).ClientCancelDataTransfer), arg0, arg1, arg2, arg3) } -// ClientCancelRetrievalDeal mocks base method +// ClientCancelRetrievalDeal mocks base method. func (m *MockFullNode) ClientCancelRetrievalDeal(arg0 context.Context, arg1 retrievalmarket.DealID) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientCancelRetrievalDeal", arg0, arg1) @@ -455,13 +455,13 @@ func (m *MockFullNode) ClientCancelRetrievalDeal(arg0 context.Context, arg1 retr return ret0 } -// ClientCancelRetrievalDeal indicates an expected call of ClientCancelRetrievalDeal +// ClientCancelRetrievalDeal indicates an expected call of ClientCancelRetrievalDeal. func (mr *MockFullNodeMockRecorder) ClientCancelRetrievalDeal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelRetrievalDeal", reflect.TypeOf((*MockFullNode)(nil).ClientCancelRetrievalDeal), arg0, arg1) } -// ClientDataTransferUpdates mocks base method +// ClientDataTransferUpdates mocks base method. func (m *MockFullNode) ClientDataTransferUpdates(arg0 context.Context) (<-chan api.DataTransferChannel, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientDataTransferUpdates", arg0) @@ -470,13 +470,13 @@ func (m *MockFullNode) ClientDataTransferUpdates(arg0 context.Context) (<-chan a return ret0, ret1 } -// ClientDataTransferUpdates indicates an expected call of ClientDataTransferUpdates +// ClientDataTransferUpdates indicates an expected call of ClientDataTransferUpdates. func (mr *MockFullNodeMockRecorder) ClientDataTransferUpdates(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDataTransferUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientDataTransferUpdates), arg0) } -// ClientDealPieceCID mocks base method +// ClientDealPieceCID mocks base method. func (m *MockFullNode) ClientDealPieceCID(arg0 context.Context, arg1 cid.Cid) (api.DataCIDSize, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientDealPieceCID", arg0, arg1) @@ -485,13 +485,13 @@ func (m *MockFullNode) ClientDealPieceCID(arg0 context.Context, arg1 cid.Cid) (a return ret0, ret1 } -// ClientDealPieceCID indicates an expected call of ClientDealPieceCID +// ClientDealPieceCID indicates an expected call of ClientDealPieceCID. func (mr *MockFullNodeMockRecorder) ClientDealPieceCID(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDealPieceCID", reflect.TypeOf((*MockFullNode)(nil).ClientDealPieceCID), arg0, arg1) } -// ClientDealSize mocks base method +// ClientDealSize mocks base method. func (m *MockFullNode) ClientDealSize(arg0 context.Context, arg1 cid.Cid) (api.DataSize, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientDealSize", arg0, arg1) @@ -500,13 +500,13 @@ func (m *MockFullNode) ClientDealSize(arg0 context.Context, arg1 cid.Cid) (api.D return ret0, ret1 } -// ClientDealSize indicates an expected call of ClientDealSize +// ClientDealSize indicates an expected call of ClientDealSize. func (mr *MockFullNodeMockRecorder) ClientDealSize(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDealSize", reflect.TypeOf((*MockFullNode)(nil).ClientDealSize), arg0, arg1) } -// ClientFindData mocks base method +// ClientFindData mocks base method. func (m *MockFullNode) ClientFindData(arg0 context.Context, arg1 cid.Cid, arg2 *cid.Cid) ([]api.QueryOffer, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientFindData", arg0, arg1, arg2) @@ -515,13 +515,13 @@ func (m *MockFullNode) ClientFindData(arg0 context.Context, arg1 cid.Cid, arg2 * return ret0, ret1 } -// ClientFindData indicates an expected call of ClientFindData +// ClientFindData indicates an expected call of ClientFindData. func (mr *MockFullNodeMockRecorder) ClientFindData(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientFindData", reflect.TypeOf((*MockFullNode)(nil).ClientFindData), arg0, arg1, arg2) } -// ClientGenCar mocks base method +// ClientGenCar mocks base method. func (m *MockFullNode) ClientGenCar(arg0 context.Context, arg1 api.FileRef, arg2 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientGenCar", arg0, arg1, arg2) @@ -529,13 +529,13 @@ func (m *MockFullNode) ClientGenCar(arg0 context.Context, arg1 api.FileRef, arg2 return ret0 } -// ClientGenCar indicates an expected call of ClientGenCar +// ClientGenCar indicates an expected call of ClientGenCar. func (mr *MockFullNodeMockRecorder) ClientGenCar(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGenCar", reflect.TypeOf((*MockFullNode)(nil).ClientGenCar), arg0, arg1, arg2) } -// ClientGetDealInfo mocks base method +// ClientGetDealInfo mocks base method. func (m *MockFullNode) ClientGetDealInfo(arg0 context.Context, arg1 cid.Cid) (*api.DealInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientGetDealInfo", arg0, arg1) @@ -544,13 +544,13 @@ func (m *MockFullNode) ClientGetDealInfo(arg0 context.Context, arg1 cid.Cid) (*a return ret0, ret1 } -// ClientGetDealInfo indicates an expected call of ClientGetDealInfo +// ClientGetDealInfo indicates an expected call of ClientGetDealInfo. func (mr *MockFullNodeMockRecorder) ClientGetDealInfo(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealInfo", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealInfo), arg0, arg1) } -// ClientGetDealStatus mocks base method +// ClientGetDealStatus mocks base method. func (m *MockFullNode) ClientGetDealStatus(arg0 context.Context, arg1 uint64) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientGetDealStatus", arg0, arg1) @@ -559,13 +559,13 @@ func (m *MockFullNode) ClientGetDealStatus(arg0 context.Context, arg1 uint64) (s return ret0, ret1 } -// ClientGetDealStatus indicates an expected call of ClientGetDealStatus +// ClientGetDealStatus indicates an expected call of ClientGetDealStatus. func (mr *MockFullNodeMockRecorder) ClientGetDealStatus(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealStatus", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealStatus), arg0, arg1) } -// ClientGetDealUpdates mocks base method +// ClientGetDealUpdates mocks base method. func (m *MockFullNode) ClientGetDealUpdates(arg0 context.Context) (<-chan api.DealInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientGetDealUpdates", arg0) @@ -574,13 +574,13 @@ func (m *MockFullNode) ClientGetDealUpdates(arg0 context.Context) (<-chan api.De return ret0, ret1 } -// ClientGetDealUpdates indicates an expected call of ClientGetDealUpdates +// ClientGetDealUpdates indicates an expected call of ClientGetDealUpdates. func (mr *MockFullNodeMockRecorder) ClientGetDealUpdates(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealUpdates), arg0) } -// ClientGetRetrievalUpdates mocks base method +// ClientGetRetrievalUpdates mocks base method. func (m *MockFullNode) ClientGetRetrievalUpdates(arg0 context.Context) (<-chan api.RetrievalInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientGetRetrievalUpdates", arg0) @@ -589,13 +589,13 @@ func (m *MockFullNode) ClientGetRetrievalUpdates(arg0 context.Context) (<-chan a return ret0, ret1 } -// ClientGetRetrievalUpdates indicates an expected call of ClientGetRetrievalUpdates +// ClientGetRetrievalUpdates indicates an expected call of ClientGetRetrievalUpdates. func (mr *MockFullNodeMockRecorder) ClientGetRetrievalUpdates(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetRetrievalUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetRetrievalUpdates), arg0) } -// ClientHasLocal mocks base method +// ClientHasLocal mocks base method. func (m *MockFullNode) ClientHasLocal(arg0 context.Context, arg1 cid.Cid) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientHasLocal", arg0, arg1) @@ -604,13 +604,13 @@ func (m *MockFullNode) ClientHasLocal(arg0 context.Context, arg1 cid.Cid) (bool, return ret0, ret1 } -// ClientHasLocal indicates an expected call of ClientHasLocal +// ClientHasLocal indicates an expected call of ClientHasLocal. func (mr *MockFullNodeMockRecorder) ClientHasLocal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientHasLocal", reflect.TypeOf((*MockFullNode)(nil).ClientHasLocal), arg0, arg1) } -// ClientImport mocks base method +// ClientImport mocks base method. func (m *MockFullNode) ClientImport(arg0 context.Context, arg1 api.FileRef) (*api.ImportRes, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientImport", arg0, arg1) @@ -619,13 +619,13 @@ func (m *MockFullNode) ClientImport(arg0 context.Context, arg1 api.FileRef) (*ap return ret0, ret1 } -// ClientImport indicates an expected call of ClientImport +// ClientImport indicates an expected call of ClientImport. func (mr *MockFullNodeMockRecorder) ClientImport(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientImport", reflect.TypeOf((*MockFullNode)(nil).ClientImport), arg0, arg1) } -// ClientListDataTransfers mocks base method +// ClientListDataTransfers mocks base method. func (m *MockFullNode) ClientListDataTransfers(arg0 context.Context) ([]api.DataTransferChannel, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientListDataTransfers", arg0) @@ -634,13 +634,13 @@ func (m *MockFullNode) ClientListDataTransfers(arg0 context.Context) ([]api.Data return ret0, ret1 } -// ClientListDataTransfers indicates an expected call of ClientListDataTransfers +// ClientListDataTransfers indicates an expected call of ClientListDataTransfers. func (mr *MockFullNodeMockRecorder) ClientListDataTransfers(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListDataTransfers", reflect.TypeOf((*MockFullNode)(nil).ClientListDataTransfers), arg0) } -// ClientListDeals mocks base method +// ClientListDeals mocks base method. func (m *MockFullNode) ClientListDeals(arg0 context.Context) ([]api.DealInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientListDeals", arg0) @@ -649,13 +649,13 @@ func (m *MockFullNode) ClientListDeals(arg0 context.Context) ([]api.DealInfo, er return ret0, ret1 } -// ClientListDeals indicates an expected call of ClientListDeals +// ClientListDeals indicates an expected call of ClientListDeals. func (mr *MockFullNodeMockRecorder) ClientListDeals(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListDeals", reflect.TypeOf((*MockFullNode)(nil).ClientListDeals), arg0) } -// ClientListImports mocks base method +// ClientListImports mocks base method. func (m *MockFullNode) ClientListImports(arg0 context.Context) ([]api.Import, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientListImports", arg0) @@ -664,13 +664,13 @@ func (m *MockFullNode) ClientListImports(arg0 context.Context) ([]api.Import, er return ret0, ret1 } -// ClientListImports indicates an expected call of ClientListImports +// ClientListImports indicates an expected call of ClientListImports. func (mr *MockFullNodeMockRecorder) ClientListImports(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListImports", reflect.TypeOf((*MockFullNode)(nil).ClientListImports), arg0) } -// ClientListRetrievals mocks base method +// ClientListRetrievals mocks base method. func (m *MockFullNode) ClientListRetrievals(arg0 context.Context) ([]api.RetrievalInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientListRetrievals", arg0) @@ -679,13 +679,13 @@ func (m *MockFullNode) ClientListRetrievals(arg0 context.Context) ([]api.Retriev return ret0, ret1 } -// ClientListRetrievals indicates an expected call of ClientListRetrievals +// ClientListRetrievals indicates an expected call of ClientListRetrievals. func (mr *MockFullNodeMockRecorder) ClientListRetrievals(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListRetrievals", reflect.TypeOf((*MockFullNode)(nil).ClientListRetrievals), arg0) } -// ClientMinerQueryOffer mocks base method +// ClientMinerQueryOffer mocks base method. func (m *MockFullNode) ClientMinerQueryOffer(arg0 context.Context, arg1 address.Address, arg2 cid.Cid, arg3 *cid.Cid) (api.QueryOffer, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientMinerQueryOffer", arg0, arg1, arg2, arg3) @@ -694,13 +694,13 @@ func (m *MockFullNode) ClientMinerQueryOffer(arg0 context.Context, arg1 address. return ret0, ret1 } -// ClientMinerQueryOffer indicates an expected call of ClientMinerQueryOffer +// ClientMinerQueryOffer indicates an expected call of ClientMinerQueryOffer. func (mr *MockFullNodeMockRecorder) ClientMinerQueryOffer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientMinerQueryOffer", reflect.TypeOf((*MockFullNode)(nil).ClientMinerQueryOffer), arg0, arg1, arg2, arg3) } -// ClientQueryAsk mocks base method +// ClientQueryAsk mocks base method. func (m *MockFullNode) ClientQueryAsk(arg0 context.Context, arg1 peer.ID, arg2 address.Address) (*storagemarket.StorageAsk, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientQueryAsk", arg0, arg1, arg2) @@ -709,13 +709,13 @@ func (m *MockFullNode) ClientQueryAsk(arg0 context.Context, arg1 peer.ID, arg2 a return ret0, ret1 } -// ClientQueryAsk indicates an expected call of ClientQueryAsk +// ClientQueryAsk indicates an expected call of ClientQueryAsk. func (mr *MockFullNodeMockRecorder) ClientQueryAsk(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientQueryAsk", reflect.TypeOf((*MockFullNode)(nil).ClientQueryAsk), arg0, arg1, arg2) } -// ClientRemoveImport mocks base method +// ClientRemoveImport mocks base method. func (m *MockFullNode) ClientRemoveImport(arg0 context.Context, arg1 multistore.StoreID) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientRemoveImport", arg0, arg1) @@ -723,13 +723,13 @@ func (m *MockFullNode) ClientRemoveImport(arg0 context.Context, arg1 multistore. return ret0 } -// ClientRemoveImport indicates an expected call of ClientRemoveImport +// ClientRemoveImport indicates an expected call of ClientRemoveImport. func (mr *MockFullNodeMockRecorder) ClientRemoveImport(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRemoveImport", reflect.TypeOf((*MockFullNode)(nil).ClientRemoveImport), arg0, arg1) } -// ClientRestartDataTransfer mocks base method +// ClientRestartDataTransfer mocks base method. func (m *MockFullNode) ClientRestartDataTransfer(arg0 context.Context, arg1 datatransfer.TransferID, arg2 peer.ID, arg3 bool) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientRestartDataTransfer", arg0, arg1, arg2, arg3) @@ -737,13 +737,13 @@ func (m *MockFullNode) ClientRestartDataTransfer(arg0 context.Context, arg1 data return ret0 } -// ClientRestartDataTransfer indicates an expected call of ClientRestartDataTransfer +// ClientRestartDataTransfer indicates an expected call of ClientRestartDataTransfer. func (mr *MockFullNodeMockRecorder) ClientRestartDataTransfer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRestartDataTransfer", reflect.TypeOf((*MockFullNode)(nil).ClientRestartDataTransfer), arg0, arg1, arg2, arg3) } -// ClientRetrieve mocks base method +// ClientRetrieve mocks base method. func (m *MockFullNode) ClientRetrieve(arg0 context.Context, arg1 api.RetrievalOrder, arg2 *api.FileRef) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientRetrieve", arg0, arg1, arg2) @@ -751,13 +751,13 @@ func (m *MockFullNode) ClientRetrieve(arg0 context.Context, arg1 api.RetrievalOr return ret0 } -// ClientRetrieve indicates an expected call of ClientRetrieve +// ClientRetrieve indicates an expected call of ClientRetrieve. func (mr *MockFullNodeMockRecorder) ClientRetrieve(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieve", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieve), arg0, arg1, arg2) } -// ClientRetrieveTryRestartInsufficientFunds mocks base method +// ClientRetrieveTryRestartInsufficientFunds mocks base method. func (m *MockFullNode) ClientRetrieveTryRestartInsufficientFunds(arg0 context.Context, arg1 address.Address) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientRetrieveTryRestartInsufficientFunds", arg0, arg1) @@ -765,13 +765,13 @@ func (m *MockFullNode) ClientRetrieveTryRestartInsufficientFunds(arg0 context.Co return ret0 } -// ClientRetrieveTryRestartInsufficientFunds indicates an expected call of ClientRetrieveTryRestartInsufficientFunds +// ClientRetrieveTryRestartInsufficientFunds indicates an expected call of ClientRetrieveTryRestartInsufficientFunds. func (mr *MockFullNodeMockRecorder) ClientRetrieveTryRestartInsufficientFunds(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieveTryRestartInsufficientFunds", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieveTryRestartInsufficientFunds), arg0, arg1) } -// ClientRetrieveWithEvents mocks base method +// ClientRetrieveWithEvents mocks base method. func (m *MockFullNode) ClientRetrieveWithEvents(arg0 context.Context, arg1 api.RetrievalOrder, arg2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientRetrieveWithEvents", arg0, arg1, arg2) @@ -780,13 +780,13 @@ func (m *MockFullNode) ClientRetrieveWithEvents(arg0 context.Context, arg1 api.R return ret0, ret1 } -// ClientRetrieveWithEvents indicates an expected call of ClientRetrieveWithEvents +// ClientRetrieveWithEvents indicates an expected call of ClientRetrieveWithEvents. func (mr *MockFullNodeMockRecorder) ClientRetrieveWithEvents(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieveWithEvents", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieveWithEvents), arg0, arg1, arg2) } -// ClientStartDeal mocks base method +// ClientStartDeal mocks base method. func (m *MockFullNode) ClientStartDeal(arg0 context.Context, arg1 *api.StartDealParams) (*cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientStartDeal", arg0, arg1) @@ -795,13 +795,13 @@ func (m *MockFullNode) ClientStartDeal(arg0 context.Context, arg1 *api.StartDeal return ret0, ret1 } -// ClientStartDeal indicates an expected call of ClientStartDeal +// ClientStartDeal indicates an expected call of ClientStartDeal. func (mr *MockFullNodeMockRecorder) ClientStartDeal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStartDeal", reflect.TypeOf((*MockFullNode)(nil).ClientStartDeal), arg0, arg1) } -// ClientStatelessDeal mocks base method +// ClientStatelessDeal mocks base method. func (m *MockFullNode) ClientStatelessDeal(arg0 context.Context, arg1 *api.StartDealParams) (*cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientStatelessDeal", arg0, arg1) @@ -810,13 +810,13 @@ func (m *MockFullNode) ClientStatelessDeal(arg0 context.Context, arg1 *api.Start return ret0, ret1 } -// ClientStatelessDeal indicates an expected call of ClientStatelessDeal +// ClientStatelessDeal indicates an expected call of ClientStatelessDeal. func (mr *MockFullNodeMockRecorder) ClientStatelessDeal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStatelessDeal", reflect.TypeOf((*MockFullNode)(nil).ClientStatelessDeal), arg0, arg1) } -// Closing mocks base method +// Closing mocks base method. func (m *MockFullNode) Closing(arg0 context.Context) (<-chan struct{}, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Closing", arg0) @@ -825,13 +825,13 @@ func (m *MockFullNode) Closing(arg0 context.Context) (<-chan struct{}, error) { return ret0, ret1 } -// Closing indicates an expected call of Closing +// Closing indicates an expected call of Closing. func (mr *MockFullNodeMockRecorder) Closing(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Closing", reflect.TypeOf((*MockFullNode)(nil).Closing), arg0) } -// CreateBackup mocks base method +// CreateBackup mocks base method. func (m *MockFullNode) CreateBackup(arg0 context.Context, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateBackup", arg0, arg1) @@ -839,13 +839,13 @@ func (m *MockFullNode) CreateBackup(arg0 context.Context, arg1 string) error { return ret0 } -// CreateBackup indicates an expected call of CreateBackup +// CreateBackup indicates an expected call of CreateBackup. func (mr *MockFullNodeMockRecorder) CreateBackup(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBackup", reflect.TypeOf((*MockFullNode)(nil).CreateBackup), arg0, arg1) } -// Discover mocks base method +// Discover mocks base method. func (m *MockFullNode) Discover(arg0 context.Context) (apitypes.OpenRPCDocument, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Discover", arg0) @@ -854,13 +854,13 @@ func (m *MockFullNode) Discover(arg0 context.Context) (apitypes.OpenRPCDocument, return ret0, ret1 } -// Discover indicates an expected call of Discover +// Discover indicates an expected call of Discover. func (mr *MockFullNodeMockRecorder) Discover(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Discover", reflect.TypeOf((*MockFullNode)(nil).Discover), arg0) } -// GasEstimateFeeCap mocks base method +// GasEstimateFeeCap mocks base method. func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Message, arg2 int64, arg3 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GasEstimateFeeCap", arg0, arg1, arg2, arg3) @@ -869,13 +869,13 @@ func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Messa return ret0, ret1 } -// GasEstimateFeeCap indicates an expected call of GasEstimateFeeCap +// GasEstimateFeeCap indicates an expected call of GasEstimateFeeCap. func (mr *MockFullNodeMockRecorder) GasEstimateFeeCap(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateFeeCap", reflect.TypeOf((*MockFullNode)(nil).GasEstimateFeeCap), arg0, arg1, arg2, arg3) } -// GasEstimateGasLimit mocks base method +// GasEstimateGasLimit mocks base method. func (m *MockFullNode) GasEstimateGasLimit(arg0 context.Context, arg1 *types.Message, arg2 types.TipSetKey) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GasEstimateGasLimit", arg0, arg1, arg2) @@ -884,13 +884,13 @@ func (m *MockFullNode) GasEstimateGasLimit(arg0 context.Context, arg1 *types.Mes return ret0, ret1 } -// GasEstimateGasLimit indicates an expected call of GasEstimateGasLimit +// GasEstimateGasLimit indicates an expected call of GasEstimateGasLimit. func (mr *MockFullNodeMockRecorder) GasEstimateGasLimit(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateGasLimit", reflect.TypeOf((*MockFullNode)(nil).GasEstimateGasLimit), arg0, arg1, arg2) } -// GasEstimateGasPremium mocks base method +// GasEstimateGasPremium mocks base method. func (m *MockFullNode) GasEstimateGasPremium(arg0 context.Context, arg1 uint64, arg2 address.Address, arg3 int64, arg4 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GasEstimateGasPremium", arg0, arg1, arg2, arg3, arg4) @@ -899,13 +899,13 @@ func (m *MockFullNode) GasEstimateGasPremium(arg0 context.Context, arg1 uint64, return ret0, ret1 } -// GasEstimateGasPremium indicates an expected call of GasEstimateGasPremium +// GasEstimateGasPremium indicates an expected call of GasEstimateGasPremium. func (mr *MockFullNodeMockRecorder) GasEstimateGasPremium(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateGasPremium", reflect.TypeOf((*MockFullNode)(nil).GasEstimateGasPremium), arg0, arg1, arg2, arg3, arg4) } -// GasEstimateMessageGas mocks base method +// GasEstimateMessageGas mocks base method. func (m *MockFullNode) GasEstimateMessageGas(arg0 context.Context, arg1 *types.Message, arg2 *api.MessageSendSpec, arg3 types.TipSetKey) (*types.Message, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GasEstimateMessageGas", arg0, arg1, arg2, arg3) @@ -914,13 +914,13 @@ func (m *MockFullNode) GasEstimateMessageGas(arg0 context.Context, arg1 *types.M return ret0, ret1 } -// GasEstimateMessageGas indicates an expected call of GasEstimateMessageGas +// GasEstimateMessageGas indicates an expected call of GasEstimateMessageGas. func (mr *MockFullNodeMockRecorder) GasEstimateMessageGas(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateMessageGas", reflect.TypeOf((*MockFullNode)(nil).GasEstimateMessageGas), arg0, arg1, arg2, arg3) } -// ID mocks base method +// ID mocks base method. func (m *MockFullNode) ID(arg0 context.Context) (peer.ID, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ID", arg0) @@ -929,13 +929,13 @@ func (m *MockFullNode) ID(arg0 context.Context) (peer.ID, error) { return ret0, ret1 } -// ID indicates an expected call of ID +// ID indicates an expected call of ID. func (mr *MockFullNodeMockRecorder) ID(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockFullNode)(nil).ID), arg0) } -// LogList mocks base method +// LogList mocks base method. func (m *MockFullNode) LogList(arg0 context.Context) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LogList", arg0) @@ -944,13 +944,13 @@ func (m *MockFullNode) LogList(arg0 context.Context) ([]string, error) { return ret0, ret1 } -// LogList indicates an expected call of LogList +// LogList indicates an expected call of LogList. func (mr *MockFullNodeMockRecorder) LogList(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogList", reflect.TypeOf((*MockFullNode)(nil).LogList), arg0) } -// LogSetLevel mocks base method +// LogSetLevel mocks base method. func (m *MockFullNode) LogSetLevel(arg0 context.Context, arg1, arg2 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LogSetLevel", arg0, arg1, arg2) @@ -958,13 +958,13 @@ func (m *MockFullNode) LogSetLevel(arg0 context.Context, arg1, arg2 string) erro return ret0 } -// LogSetLevel indicates an expected call of LogSetLevel +// LogSetLevel indicates an expected call of LogSetLevel. func (mr *MockFullNodeMockRecorder) LogSetLevel(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogSetLevel", reflect.TypeOf((*MockFullNode)(nil).LogSetLevel), arg0, arg1, arg2) } -// MarketAddBalance mocks base method +// MarketAddBalance mocks base method. func (m *MockFullNode) MarketAddBalance(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarketAddBalance", arg0, arg1, arg2, arg3) @@ -973,13 +973,13 @@ func (m *MockFullNode) MarketAddBalance(arg0 context.Context, arg1, arg2 address return ret0, ret1 } -// MarketAddBalance indicates an expected call of MarketAddBalance +// MarketAddBalance indicates an expected call of MarketAddBalance. func (mr *MockFullNodeMockRecorder) MarketAddBalance(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketAddBalance", reflect.TypeOf((*MockFullNode)(nil).MarketAddBalance), arg0, arg1, arg2, arg3) } -// MarketGetReserved mocks base method +// MarketGetReserved mocks base method. func (m *MockFullNode) MarketGetReserved(arg0 context.Context, arg1 address.Address) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarketGetReserved", arg0, arg1) @@ -988,13 +988,13 @@ func (m *MockFullNode) MarketGetReserved(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// MarketGetReserved indicates an expected call of MarketGetReserved +// MarketGetReserved indicates an expected call of MarketGetReserved. func (mr *MockFullNodeMockRecorder) MarketGetReserved(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketGetReserved", reflect.TypeOf((*MockFullNode)(nil).MarketGetReserved), arg0, arg1) } -// MarketReleaseFunds mocks base method +// MarketReleaseFunds mocks base method. func (m *MockFullNode) MarketReleaseFunds(arg0 context.Context, arg1 address.Address, arg2 big.Int) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarketReleaseFunds", arg0, arg1, arg2) @@ -1002,13 +1002,13 @@ func (m *MockFullNode) MarketReleaseFunds(arg0 context.Context, arg1 address.Add return ret0 } -// MarketReleaseFunds indicates an expected call of MarketReleaseFunds +// MarketReleaseFunds indicates an expected call of MarketReleaseFunds. func (mr *MockFullNodeMockRecorder) MarketReleaseFunds(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketReleaseFunds", reflect.TypeOf((*MockFullNode)(nil).MarketReleaseFunds), arg0, arg1, arg2) } -// MarketReserveFunds mocks base method +// MarketReserveFunds mocks base method. func (m *MockFullNode) MarketReserveFunds(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarketReserveFunds", arg0, arg1, arg2, arg3) @@ -1017,13 +1017,13 @@ func (m *MockFullNode) MarketReserveFunds(arg0 context.Context, arg1, arg2 addre return ret0, ret1 } -// MarketReserveFunds indicates an expected call of MarketReserveFunds +// MarketReserveFunds indicates an expected call of MarketReserveFunds. func (mr *MockFullNodeMockRecorder) MarketReserveFunds(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketReserveFunds", reflect.TypeOf((*MockFullNode)(nil).MarketReserveFunds), arg0, arg1, arg2, arg3) } -// MarketWithdraw mocks base method +// MarketWithdraw mocks base method. func (m *MockFullNode) MarketWithdraw(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MarketWithdraw", arg0, arg1, arg2, arg3) @@ -1032,13 +1032,13 @@ func (m *MockFullNode) MarketWithdraw(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MarketWithdraw indicates an expected call of MarketWithdraw +// MarketWithdraw indicates an expected call of MarketWithdraw. func (mr *MockFullNodeMockRecorder) MarketWithdraw(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketWithdraw", reflect.TypeOf((*MockFullNode)(nil).MarketWithdraw), arg0, arg1, arg2, arg3) } -// MinerCreateBlock mocks base method +// MinerCreateBlock mocks base method. func (m *MockFullNode) MinerCreateBlock(arg0 context.Context, arg1 *api.BlockTemplate) (*types.BlockMsg, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MinerCreateBlock", arg0, arg1) @@ -1047,13 +1047,13 @@ func (m *MockFullNode) MinerCreateBlock(arg0 context.Context, arg1 *api.BlockTem return ret0, ret1 } -// MinerCreateBlock indicates an expected call of MinerCreateBlock +// MinerCreateBlock indicates an expected call of MinerCreateBlock. func (mr *MockFullNodeMockRecorder) MinerCreateBlock(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinerCreateBlock", reflect.TypeOf((*MockFullNode)(nil).MinerCreateBlock), arg0, arg1) } -// MinerGetBaseInfo mocks base method +// MinerGetBaseInfo mocks base method. func (m *MockFullNode) MinerGetBaseInfo(arg0 context.Context, arg1 address.Address, arg2 abi.ChainEpoch, arg3 types.TipSetKey) (*api.MiningBaseInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MinerGetBaseInfo", arg0, arg1, arg2, arg3) @@ -1062,13 +1062,13 @@ func (m *MockFullNode) MinerGetBaseInfo(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// MinerGetBaseInfo indicates an expected call of MinerGetBaseInfo +// MinerGetBaseInfo indicates an expected call of MinerGetBaseInfo. func (mr *MockFullNodeMockRecorder) MinerGetBaseInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinerGetBaseInfo", reflect.TypeOf((*MockFullNode)(nil).MinerGetBaseInfo), arg0, arg1, arg2, arg3) } -// MpoolBatchPush mocks base method +// MpoolBatchPush mocks base method. func (m *MockFullNode) MpoolBatchPush(arg0 context.Context, arg1 []*types.SignedMessage) ([]cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolBatchPush", arg0, arg1) @@ -1077,13 +1077,13 @@ func (m *MockFullNode) MpoolBatchPush(arg0 context.Context, arg1 []*types.Signed return ret0, ret1 } -// MpoolBatchPush indicates an expected call of MpoolBatchPush +// MpoolBatchPush indicates an expected call of MpoolBatchPush. func (mr *MockFullNodeMockRecorder) MpoolBatchPush(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPush", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPush), arg0, arg1) } -// MpoolBatchPushMessage mocks base method +// MpoolBatchPushMessage mocks base method. func (m *MockFullNode) MpoolBatchPushMessage(arg0 context.Context, arg1 []*types.Message, arg2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolBatchPushMessage", arg0, arg1, arg2) @@ -1092,13 +1092,13 @@ func (m *MockFullNode) MpoolBatchPushMessage(arg0 context.Context, arg1 []*types return ret0, ret1 } -// MpoolBatchPushMessage indicates an expected call of MpoolBatchPushMessage +// MpoolBatchPushMessage indicates an expected call of MpoolBatchPushMessage. func (mr *MockFullNodeMockRecorder) MpoolBatchPushMessage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPushMessage", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPushMessage), arg0, arg1, arg2) } -// MpoolBatchPushUntrusted mocks base method +// MpoolBatchPushUntrusted mocks base method. func (m *MockFullNode) MpoolBatchPushUntrusted(arg0 context.Context, arg1 []*types.SignedMessage) ([]cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolBatchPushUntrusted", arg0, arg1) @@ -1107,13 +1107,13 @@ func (m *MockFullNode) MpoolBatchPushUntrusted(arg0 context.Context, arg1 []*typ return ret0, ret1 } -// MpoolBatchPushUntrusted indicates an expected call of MpoolBatchPushUntrusted +// MpoolBatchPushUntrusted indicates an expected call of MpoolBatchPushUntrusted. func (mr *MockFullNodeMockRecorder) MpoolBatchPushUntrusted(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPushUntrusted", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPushUntrusted), arg0, arg1) } -// MpoolClear mocks base method +// MpoolClear mocks base method. func (m *MockFullNode) MpoolClear(arg0 context.Context, arg1 bool) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolClear", arg0, arg1) @@ -1121,13 +1121,13 @@ func (m *MockFullNode) MpoolClear(arg0 context.Context, arg1 bool) error { return ret0 } -// MpoolClear indicates an expected call of MpoolClear +// MpoolClear indicates an expected call of MpoolClear. func (mr *MockFullNodeMockRecorder) MpoolClear(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolClear", reflect.TypeOf((*MockFullNode)(nil).MpoolClear), arg0, arg1) } -// MpoolGetConfig mocks base method +// MpoolGetConfig mocks base method. func (m *MockFullNode) MpoolGetConfig(arg0 context.Context) (*types.MpoolConfig, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolGetConfig", arg0) @@ -1136,13 +1136,13 @@ func (m *MockFullNode) MpoolGetConfig(arg0 context.Context) (*types.MpoolConfig, return ret0, ret1 } -// MpoolGetConfig indicates an expected call of MpoolGetConfig +// MpoolGetConfig indicates an expected call of MpoolGetConfig. func (mr *MockFullNodeMockRecorder) MpoolGetConfig(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolGetConfig", reflect.TypeOf((*MockFullNode)(nil).MpoolGetConfig), arg0) } -// MpoolGetNonce mocks base method +// MpoolGetNonce mocks base method. func (m *MockFullNode) MpoolGetNonce(arg0 context.Context, arg1 address.Address) (uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolGetNonce", arg0, arg1) @@ -1151,13 +1151,13 @@ func (m *MockFullNode) MpoolGetNonce(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// MpoolGetNonce indicates an expected call of MpoolGetNonce +// MpoolGetNonce indicates an expected call of MpoolGetNonce. func (mr *MockFullNodeMockRecorder) MpoolGetNonce(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolGetNonce", reflect.TypeOf((*MockFullNode)(nil).MpoolGetNonce), arg0, arg1) } -// MpoolPending mocks base method +// MpoolPending mocks base method. func (m *MockFullNode) MpoolPending(arg0 context.Context, arg1 types.TipSetKey) ([]*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolPending", arg0, arg1) @@ -1166,13 +1166,13 @@ func (m *MockFullNode) MpoolPending(arg0 context.Context, arg1 types.TipSetKey) return ret0, ret1 } -// MpoolPending indicates an expected call of MpoolPending +// MpoolPending indicates an expected call of MpoolPending. func (mr *MockFullNodeMockRecorder) MpoolPending(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPending", reflect.TypeOf((*MockFullNode)(nil).MpoolPending), arg0, arg1) } -// MpoolPush mocks base method +// MpoolPush mocks base method. func (m *MockFullNode) MpoolPush(arg0 context.Context, arg1 *types.SignedMessage) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolPush", arg0, arg1) @@ -1181,13 +1181,13 @@ func (m *MockFullNode) MpoolPush(arg0 context.Context, arg1 *types.SignedMessage return ret0, ret1 } -// MpoolPush indicates an expected call of MpoolPush +// MpoolPush indicates an expected call of MpoolPush. func (mr *MockFullNodeMockRecorder) MpoolPush(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPush", reflect.TypeOf((*MockFullNode)(nil).MpoolPush), arg0, arg1) } -// MpoolPushMessage mocks base method +// MpoolPushMessage mocks base method. func (m *MockFullNode) MpoolPushMessage(arg0 context.Context, arg1 *types.Message, arg2 *api.MessageSendSpec) (*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolPushMessage", arg0, arg1, arg2) @@ -1196,13 +1196,13 @@ func (m *MockFullNode) MpoolPushMessage(arg0 context.Context, arg1 *types.Messag return ret0, ret1 } -// MpoolPushMessage indicates an expected call of MpoolPushMessage +// MpoolPushMessage indicates an expected call of MpoolPushMessage. func (mr *MockFullNodeMockRecorder) MpoolPushMessage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPushMessage", reflect.TypeOf((*MockFullNode)(nil).MpoolPushMessage), arg0, arg1, arg2) } -// MpoolPushUntrusted mocks base method +// MpoolPushUntrusted mocks base method. func (m *MockFullNode) MpoolPushUntrusted(arg0 context.Context, arg1 *types.SignedMessage) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolPushUntrusted", arg0, arg1) @@ -1211,13 +1211,13 @@ func (m *MockFullNode) MpoolPushUntrusted(arg0 context.Context, arg1 *types.Sign return ret0, ret1 } -// MpoolPushUntrusted indicates an expected call of MpoolPushUntrusted +// MpoolPushUntrusted indicates an expected call of MpoolPushUntrusted. func (mr *MockFullNodeMockRecorder) MpoolPushUntrusted(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPushUntrusted", reflect.TypeOf((*MockFullNode)(nil).MpoolPushUntrusted), arg0, arg1) } -// MpoolSelect mocks base method +// MpoolSelect mocks base method. func (m *MockFullNode) MpoolSelect(arg0 context.Context, arg1 types.TipSetKey, arg2 float64) ([]*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolSelect", arg0, arg1, arg2) @@ -1226,13 +1226,13 @@ func (m *MockFullNode) MpoolSelect(arg0 context.Context, arg1 types.TipSetKey, a return ret0, ret1 } -// MpoolSelect indicates an expected call of MpoolSelect +// MpoolSelect indicates an expected call of MpoolSelect. func (mr *MockFullNodeMockRecorder) MpoolSelect(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSelect", reflect.TypeOf((*MockFullNode)(nil).MpoolSelect), arg0, arg1, arg2) } -// MpoolSetConfig mocks base method +// MpoolSetConfig mocks base method. func (m *MockFullNode) MpoolSetConfig(arg0 context.Context, arg1 *types.MpoolConfig) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolSetConfig", arg0, arg1) @@ -1240,13 +1240,13 @@ func (m *MockFullNode) MpoolSetConfig(arg0 context.Context, arg1 *types.MpoolCon return ret0 } -// MpoolSetConfig indicates an expected call of MpoolSetConfig +// MpoolSetConfig indicates an expected call of MpoolSetConfig. func (mr *MockFullNodeMockRecorder) MpoolSetConfig(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSetConfig", reflect.TypeOf((*MockFullNode)(nil).MpoolSetConfig), arg0, arg1) } -// MpoolSub mocks base method +// MpoolSub mocks base method. func (m *MockFullNode) MpoolSub(arg0 context.Context) (<-chan api.MpoolUpdate, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MpoolSub", arg0) @@ -1255,13 +1255,13 @@ func (m *MockFullNode) MpoolSub(arg0 context.Context) (<-chan api.MpoolUpdate, e return ret0, ret1 } -// MpoolSub indicates an expected call of MpoolSub +// MpoolSub indicates an expected call of MpoolSub. func (mr *MockFullNodeMockRecorder) MpoolSub(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSub", reflect.TypeOf((*MockFullNode)(nil).MpoolSub), arg0) } -// MsigAddApprove mocks base method +// MsigAddApprove mocks base method. func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address, arg6 bool) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigAddApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6) @@ -1270,13 +1270,13 @@ func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MsigAddApprove indicates an expected call of MsigAddApprove +// MsigAddApprove indicates an expected call of MsigAddApprove. func (mr *MockFullNodeMockRecorder) MsigAddApprove(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddApprove", reflect.TypeOf((*MockFullNode)(nil).MsigAddApprove), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } -// MsigAddCancel mocks base method +// MsigAddCancel mocks base method. func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4 address.Address, arg5 bool) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigAddCancel", arg0, arg1, arg2, arg3, arg4, arg5) @@ -1285,13 +1285,13 @@ func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Ad return ret0, ret1 } -// MsigAddCancel indicates an expected call of MsigAddCancel +// MsigAddCancel indicates an expected call of MsigAddCancel. func (mr *MockFullNodeMockRecorder) MsigAddCancel(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddCancel", reflect.TypeOf((*MockFullNode)(nil).MsigAddCancel), arg0, arg1, arg2, arg3, arg4, arg5) } -// MsigAddPropose mocks base method +// MsigAddPropose mocks base method. func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigAddPropose", arg0, arg1, arg2, arg3, arg4) @@ -1300,13 +1300,13 @@ func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 add return ret0, ret1 } -// MsigAddPropose indicates an expected call of MsigAddPropose +// MsigAddPropose indicates an expected call of MsigAddPropose. func (mr *MockFullNodeMockRecorder) MsigAddPropose(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddPropose", reflect.TypeOf((*MockFullNode)(nil).MsigAddPropose), arg0, arg1, arg2, arg3, arg4) } -// MsigApprove mocks base method +// MsigApprove mocks base method. func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigApprove", arg0, arg1, arg2, arg3) @@ -1315,13 +1315,13 @@ func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, a return ret0, ret1 } -// MsigApprove indicates an expected call of MsigApprove +// MsigApprove indicates an expected call of MsigApprove. func (mr *MockFullNodeMockRecorder) MsigApprove(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigApprove", reflect.TypeOf((*MockFullNode)(nil).MsigApprove), arg0, arg1, arg2, arg3) } -// MsigApproveTxnHash mocks base method +// MsigApproveTxnHash mocks base method. func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3, arg4 address.Address, arg5 big.Int, arg6 address.Address, arg7 uint64, arg8 []byte) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigApproveTxnHash", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) @@ -1330,13 +1330,13 @@ func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// MsigApproveTxnHash indicates an expected call of MsigApproveTxnHash +// MsigApproveTxnHash indicates an expected call of MsigApproveTxnHash. func (mr *MockFullNodeMockRecorder) MsigApproveTxnHash(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigApproveTxnHash", reflect.TypeOf((*MockFullNode)(nil).MsigApproveTxnHash), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) } -// MsigCancel mocks base method +// MsigCancel mocks base method. func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address, arg4 big.Int, arg5 address.Address, arg6 uint64, arg7 []byte) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigCancel", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) @@ -1345,13 +1345,13 @@ func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, ar return ret0, ret1 } -// MsigCancel indicates an expected call of MsigCancel +// MsigCancel indicates an expected call of MsigCancel. func (mr *MockFullNodeMockRecorder) MsigCancel(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigCancel", reflect.TypeOf((*MockFullNode)(nil).MsigCancel), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) } -// MsigCreate mocks base method +// MsigCreate mocks base method. func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []address.Address, arg3 abi.ChainEpoch, arg4 big.Int, arg5 address.Address, arg6 big.Int) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigCreate", arg0, arg1, arg2, arg3, arg4, arg5, arg6) @@ -1360,13 +1360,13 @@ func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []addr return ret0, ret1 } -// MsigCreate indicates an expected call of MsigCreate +// MsigCreate indicates an expected call of MsigCreate. func (mr *MockFullNodeMockRecorder) MsigCreate(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigCreate", reflect.TypeOf((*MockFullNode)(nil).MsigCreate), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } -// MsigGetAvailableBalance mocks base method +// MsigGetAvailableBalance mocks base method. func (m *MockFullNode) MsigGetAvailableBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigGetAvailableBalance", arg0, arg1, arg2) @@ -1375,13 +1375,13 @@ func (m *MockFullNode) MsigGetAvailableBalance(arg0 context.Context, arg1 addres return ret0, ret1 } -// MsigGetAvailableBalance indicates an expected call of MsigGetAvailableBalance +// MsigGetAvailableBalance indicates an expected call of MsigGetAvailableBalance. func (mr *MockFullNodeMockRecorder) MsigGetAvailableBalance(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetAvailableBalance", reflect.TypeOf((*MockFullNode)(nil).MsigGetAvailableBalance), arg0, arg1, arg2) } -// MsigGetPending mocks base method +// MsigGetPending mocks base method. func (m *MockFullNode) MsigGetPending(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]*api.MsigTransaction, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigGetPending", arg0, arg1, arg2) @@ -1390,13 +1390,13 @@ func (m *MockFullNode) MsigGetPending(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// MsigGetPending indicates an expected call of MsigGetPending +// MsigGetPending indicates an expected call of MsigGetPending. func (mr *MockFullNodeMockRecorder) MsigGetPending(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetPending", reflect.TypeOf((*MockFullNode)(nil).MsigGetPending), arg0, arg1, arg2) } -// MsigGetVested mocks base method +// MsigGetVested mocks base method. func (m *MockFullNode) MsigGetVested(arg0 context.Context, arg1 address.Address, arg2, arg3 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigGetVested", arg0, arg1, arg2, arg3) @@ -1405,13 +1405,13 @@ func (m *MockFullNode) MsigGetVested(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// MsigGetVested indicates an expected call of MsigGetVested +// MsigGetVested indicates an expected call of MsigGetVested. func (mr *MockFullNodeMockRecorder) MsigGetVested(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetVested", reflect.TypeOf((*MockFullNode)(nil).MsigGetVested), arg0, arg1, arg2, arg3) } -// MsigGetVestingSchedule mocks base method +// MsigGetVestingSchedule mocks base method. func (m *MockFullNode) MsigGetVestingSchedule(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MsigVesting, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigGetVestingSchedule", arg0, arg1, arg2) @@ -1420,13 +1420,13 @@ func (m *MockFullNode) MsigGetVestingSchedule(arg0 context.Context, arg1 address return ret0, ret1 } -// MsigGetVestingSchedule indicates an expected call of MsigGetVestingSchedule +// MsigGetVestingSchedule indicates an expected call of MsigGetVestingSchedule. func (mr *MockFullNodeMockRecorder) MsigGetVestingSchedule(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetVestingSchedule", reflect.TypeOf((*MockFullNode)(nil).MsigGetVestingSchedule), arg0, arg1, arg2) } -// MsigPropose mocks base method +// MsigPropose mocks base method. func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int, arg4 address.Address, arg5 uint64, arg6 []byte) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigPropose", arg0, arg1, arg2, arg3, arg4, arg5, arg6) @@ -1435,13 +1435,13 @@ func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Addr return ret0, ret1 } -// MsigPropose indicates an expected call of MsigPropose +// MsigPropose indicates an expected call of MsigPropose. func (mr *MockFullNodeMockRecorder) MsigPropose(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigPropose", reflect.TypeOf((*MockFullNode)(nil).MsigPropose), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } -// MsigRemoveSigner mocks base method +// MsigRemoveSigner mocks base method. func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigRemoveSigner", arg0, arg1, arg2, arg3, arg4) @@ -1450,13 +1450,13 @@ func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 a return ret0, ret1 } -// MsigRemoveSigner indicates an expected call of MsigRemoveSigner +// MsigRemoveSigner indicates an expected call of MsigRemoveSigner. func (mr *MockFullNodeMockRecorder) MsigRemoveSigner(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigRemoveSigner", reflect.TypeOf((*MockFullNode)(nil).MsigRemoveSigner), arg0, arg1, arg2, arg3, arg4) } -// MsigSwapApprove mocks base method +// MsigSwapApprove mocks base method. func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5, arg6 address.Address) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigSwapApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6) @@ -1465,13 +1465,13 @@ func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address. return ret0, ret1 } -// MsigSwapApprove indicates an expected call of MsigSwapApprove +// MsigSwapApprove indicates an expected call of MsigSwapApprove. func (mr *MockFullNodeMockRecorder) MsigSwapApprove(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapApprove", reflect.TypeOf((*MockFullNode)(nil).MsigSwapApprove), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } -// MsigSwapCancel mocks base method +// MsigSwapCancel mocks base method. func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigSwapCancel", arg0, arg1, arg2, arg3, arg4, arg5) @@ -1480,13 +1480,13 @@ func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MsigSwapCancel indicates an expected call of MsigSwapCancel +// MsigSwapCancel indicates an expected call of MsigSwapCancel. func (mr *MockFullNodeMockRecorder) MsigSwapCancel(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapCancel", reflect.TypeOf((*MockFullNode)(nil).MsigSwapCancel), arg0, arg1, arg2, arg3, arg4, arg5) } -// MsigSwapPropose mocks base method +// MsigSwapPropose mocks base method. func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, arg4 address.Address) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigSwapPropose", arg0, arg1, arg2, arg3, arg4) @@ -1495,13 +1495,13 @@ func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, a return ret0, ret1 } -// MsigSwapPropose indicates an expected call of MsigSwapPropose +// MsigSwapPropose indicates an expected call of MsigSwapPropose. func (mr *MockFullNodeMockRecorder) MsigSwapPropose(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapPropose", reflect.TypeOf((*MockFullNode)(nil).MsigSwapPropose), arg0, arg1, arg2, arg3, arg4) } -// NetAddrsListen mocks base method +// NetAddrsListen mocks base method. func (m *MockFullNode) NetAddrsListen(arg0 context.Context) (peer.AddrInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetAddrsListen", arg0) @@ -1510,13 +1510,13 @@ func (m *MockFullNode) NetAddrsListen(arg0 context.Context) (peer.AddrInfo, erro return ret0, ret1 } -// NetAddrsListen indicates an expected call of NetAddrsListen +// NetAddrsListen indicates an expected call of NetAddrsListen. func (mr *MockFullNodeMockRecorder) NetAddrsListen(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAddrsListen", reflect.TypeOf((*MockFullNode)(nil).NetAddrsListen), arg0) } -// NetAgentVersion mocks base method +// NetAgentVersion mocks base method. func (m *MockFullNode) NetAgentVersion(arg0 context.Context, arg1 peer.ID) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetAgentVersion", arg0, arg1) @@ -1525,13 +1525,13 @@ func (m *MockFullNode) NetAgentVersion(arg0 context.Context, arg1 peer.ID) (stri return ret0, ret1 } -// NetAgentVersion indicates an expected call of NetAgentVersion +// NetAgentVersion indicates an expected call of NetAgentVersion. func (mr *MockFullNodeMockRecorder) NetAgentVersion(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAgentVersion", reflect.TypeOf((*MockFullNode)(nil).NetAgentVersion), arg0, arg1) } -// NetAutoNatStatus mocks base method +// NetAutoNatStatus mocks base method. func (m *MockFullNode) NetAutoNatStatus(arg0 context.Context) (api.NatInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetAutoNatStatus", arg0) @@ -1540,13 +1540,13 @@ func (m *MockFullNode) NetAutoNatStatus(arg0 context.Context) (api.NatInfo, erro return ret0, ret1 } -// NetAutoNatStatus indicates an expected call of NetAutoNatStatus +// NetAutoNatStatus indicates an expected call of NetAutoNatStatus. func (mr *MockFullNodeMockRecorder) NetAutoNatStatus(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAutoNatStatus", reflect.TypeOf((*MockFullNode)(nil).NetAutoNatStatus), arg0) } -// NetBandwidthStats mocks base method +// NetBandwidthStats mocks base method. func (m *MockFullNode) NetBandwidthStats(arg0 context.Context) (metrics.Stats, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBandwidthStats", arg0) @@ -1555,13 +1555,13 @@ func (m *MockFullNode) NetBandwidthStats(arg0 context.Context) (metrics.Stats, e return ret0, ret1 } -// NetBandwidthStats indicates an expected call of NetBandwidthStats +// NetBandwidthStats indicates an expected call of NetBandwidthStats. func (mr *MockFullNodeMockRecorder) NetBandwidthStats(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStats", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStats), arg0) } -// NetBandwidthStatsByPeer mocks base method +// NetBandwidthStatsByPeer mocks base method. func (m *MockFullNode) NetBandwidthStatsByPeer(arg0 context.Context) (map[string]metrics.Stats, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBandwidthStatsByPeer", arg0) @@ -1570,13 +1570,13 @@ func (m *MockFullNode) NetBandwidthStatsByPeer(arg0 context.Context) (map[string return ret0, ret1 } -// NetBandwidthStatsByPeer indicates an expected call of NetBandwidthStatsByPeer +// NetBandwidthStatsByPeer indicates an expected call of NetBandwidthStatsByPeer. func (mr *MockFullNodeMockRecorder) NetBandwidthStatsByPeer(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStatsByPeer", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStatsByPeer), arg0) } -// NetBandwidthStatsByProtocol mocks base method +// NetBandwidthStatsByProtocol mocks base method. func (m *MockFullNode) NetBandwidthStatsByProtocol(arg0 context.Context) (map[protocol.ID]metrics.Stats, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBandwidthStatsByProtocol", arg0) @@ -1585,13 +1585,13 @@ func (m *MockFullNode) NetBandwidthStatsByProtocol(arg0 context.Context) (map[pr return ret0, ret1 } -// NetBandwidthStatsByProtocol indicates an expected call of NetBandwidthStatsByProtocol +// NetBandwidthStatsByProtocol indicates an expected call of NetBandwidthStatsByProtocol. func (mr *MockFullNodeMockRecorder) NetBandwidthStatsByProtocol(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStatsByProtocol", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStatsByProtocol), arg0) } -// NetBlockAdd mocks base method +// NetBlockAdd mocks base method. func (m *MockFullNode) NetBlockAdd(arg0 context.Context, arg1 api.NetBlockList) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBlockAdd", arg0, arg1) @@ -1599,13 +1599,13 @@ func (m *MockFullNode) NetBlockAdd(arg0 context.Context, arg1 api.NetBlockList) return ret0 } -// NetBlockAdd indicates an expected call of NetBlockAdd +// NetBlockAdd indicates an expected call of NetBlockAdd. func (mr *MockFullNodeMockRecorder) NetBlockAdd(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockAdd", reflect.TypeOf((*MockFullNode)(nil).NetBlockAdd), arg0, arg1) } -// NetBlockList mocks base method +// NetBlockList mocks base method. func (m *MockFullNode) NetBlockList(arg0 context.Context) (api.NetBlockList, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBlockList", arg0) @@ -1614,13 +1614,13 @@ func (m *MockFullNode) NetBlockList(arg0 context.Context) (api.NetBlockList, err return ret0, ret1 } -// NetBlockList indicates an expected call of NetBlockList +// NetBlockList indicates an expected call of NetBlockList. func (mr *MockFullNodeMockRecorder) NetBlockList(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockList", reflect.TypeOf((*MockFullNode)(nil).NetBlockList), arg0) } -// NetBlockRemove mocks base method +// NetBlockRemove mocks base method. func (m *MockFullNode) NetBlockRemove(arg0 context.Context, arg1 api.NetBlockList) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetBlockRemove", arg0, arg1) @@ -1628,13 +1628,13 @@ func (m *MockFullNode) NetBlockRemove(arg0 context.Context, arg1 api.NetBlockLis return ret0 } -// NetBlockRemove indicates an expected call of NetBlockRemove +// NetBlockRemove indicates an expected call of NetBlockRemove. func (mr *MockFullNodeMockRecorder) NetBlockRemove(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockRemove", reflect.TypeOf((*MockFullNode)(nil).NetBlockRemove), arg0, arg1) } -// NetConnect mocks base method +// NetConnect mocks base method. func (m *MockFullNode) NetConnect(arg0 context.Context, arg1 peer.AddrInfo) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetConnect", arg0, arg1) @@ -1642,13 +1642,13 @@ func (m *MockFullNode) NetConnect(arg0 context.Context, arg1 peer.AddrInfo) erro return ret0 } -// NetConnect indicates an expected call of NetConnect +// NetConnect indicates an expected call of NetConnect. func (mr *MockFullNodeMockRecorder) NetConnect(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetConnect", reflect.TypeOf((*MockFullNode)(nil).NetConnect), arg0, arg1) } -// NetConnectedness mocks base method +// NetConnectedness mocks base method. func (m *MockFullNode) NetConnectedness(arg0 context.Context, arg1 peer.ID) (network0.Connectedness, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetConnectedness", arg0, arg1) @@ -1657,13 +1657,13 @@ func (m *MockFullNode) NetConnectedness(arg0 context.Context, arg1 peer.ID) (net return ret0, ret1 } -// NetConnectedness indicates an expected call of NetConnectedness +// NetConnectedness indicates an expected call of NetConnectedness. func (mr *MockFullNodeMockRecorder) NetConnectedness(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetConnectedness", reflect.TypeOf((*MockFullNode)(nil).NetConnectedness), arg0, arg1) } -// NetDisconnect mocks base method +// NetDisconnect mocks base method. func (m *MockFullNode) NetDisconnect(arg0 context.Context, arg1 peer.ID) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetDisconnect", arg0, arg1) @@ -1671,13 +1671,13 @@ func (m *MockFullNode) NetDisconnect(arg0 context.Context, arg1 peer.ID) error { return ret0 } -// NetDisconnect indicates an expected call of NetDisconnect +// NetDisconnect indicates an expected call of NetDisconnect. func (mr *MockFullNodeMockRecorder) NetDisconnect(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetDisconnect", reflect.TypeOf((*MockFullNode)(nil).NetDisconnect), arg0, arg1) } -// NetFindPeer mocks base method +// NetFindPeer mocks base method. func (m *MockFullNode) NetFindPeer(arg0 context.Context, arg1 peer.ID) (peer.AddrInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetFindPeer", arg0, arg1) @@ -1686,13 +1686,13 @@ func (m *MockFullNode) NetFindPeer(arg0 context.Context, arg1 peer.ID) (peer.Add return ret0, ret1 } -// NetFindPeer indicates an expected call of NetFindPeer +// NetFindPeer indicates an expected call of NetFindPeer. func (mr *MockFullNodeMockRecorder) NetFindPeer(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetFindPeer", reflect.TypeOf((*MockFullNode)(nil).NetFindPeer), arg0, arg1) } -// NetPeerInfo mocks base method +// NetPeerInfo mocks base method. func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetPeerInfo", arg0, arg1) @@ -1701,13 +1701,13 @@ func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.Ext return ret0, ret1 } -// NetPeerInfo indicates an expected call of NetPeerInfo +// NetPeerInfo indicates an expected call of NetPeerInfo. func (mr *MockFullNodeMockRecorder) NetPeerInfo(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeerInfo", reflect.TypeOf((*MockFullNode)(nil).NetPeerInfo), arg0, arg1) } -// NetPeers mocks base method +// NetPeers mocks base method. func (m *MockFullNode) NetPeers(arg0 context.Context) ([]peer.AddrInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetPeers", arg0) @@ -1716,13 +1716,13 @@ func (m *MockFullNode) NetPeers(arg0 context.Context) ([]peer.AddrInfo, error) { return ret0, ret1 } -// NetPeers indicates an expected call of NetPeers +// NetPeers indicates an expected call of NetPeers. func (mr *MockFullNodeMockRecorder) NetPeers(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeers", reflect.TypeOf((*MockFullNode)(nil).NetPeers), arg0) } -// NetPubsubScores mocks base method +// NetPubsubScores mocks base method. func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NetPubsubScores", arg0) @@ -1731,13 +1731,13 @@ func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, return ret0, ret1 } -// NetPubsubScores indicates an expected call of NetPubsubScores +// NetPubsubScores indicates an expected call of NetPubsubScores. func (mr *MockFullNodeMockRecorder) NetPubsubScores(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0) } -// PaychAllocateLane mocks base method +// PaychAllocateLane mocks base method. func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Address) (uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychAllocateLane", arg0, arg1) @@ -1746,13 +1746,13 @@ func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// PaychAllocateLane indicates an expected call of PaychAllocateLane +// PaychAllocateLane indicates an expected call of PaychAllocateLane. func (mr *MockFullNodeMockRecorder) PaychAllocateLane(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAllocateLane", reflect.TypeOf((*MockFullNode)(nil).PaychAllocateLane), arg0, arg1) } -// PaychAvailableFunds mocks base method +// PaychAvailableFunds mocks base method. func (m *MockFullNode) PaychAvailableFunds(arg0 context.Context, arg1 address.Address) (*api.ChannelAvailableFunds, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychAvailableFunds", arg0, arg1) @@ -1761,13 +1761,13 @@ func (m *MockFullNode) PaychAvailableFunds(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// PaychAvailableFunds indicates an expected call of PaychAvailableFunds +// PaychAvailableFunds indicates an expected call of PaychAvailableFunds. func (mr *MockFullNodeMockRecorder) PaychAvailableFunds(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAvailableFunds", reflect.TypeOf((*MockFullNode)(nil).PaychAvailableFunds), arg0, arg1) } -// PaychAvailableFundsByFromTo mocks base method +// PaychAvailableFundsByFromTo mocks base method. func (m *MockFullNode) PaychAvailableFundsByFromTo(arg0 context.Context, arg1, arg2 address.Address) (*api.ChannelAvailableFunds, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychAvailableFundsByFromTo", arg0, arg1, arg2) @@ -1776,13 +1776,13 @@ func (m *MockFullNode) PaychAvailableFundsByFromTo(arg0 context.Context, arg1, a return ret0, ret1 } -// PaychAvailableFundsByFromTo indicates an expected call of PaychAvailableFundsByFromTo +// PaychAvailableFundsByFromTo indicates an expected call of PaychAvailableFundsByFromTo. func (mr *MockFullNodeMockRecorder) PaychAvailableFundsByFromTo(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAvailableFundsByFromTo", reflect.TypeOf((*MockFullNode)(nil).PaychAvailableFundsByFromTo), arg0, arg1, arg2) } -// PaychCollect mocks base method +// PaychCollect mocks base method. func (m *MockFullNode) PaychCollect(arg0 context.Context, arg1 address.Address) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychCollect", arg0, arg1) @@ -1791,13 +1791,13 @@ func (m *MockFullNode) PaychCollect(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// PaychCollect indicates an expected call of PaychCollect +// PaychCollect indicates an expected call of PaychCollect. func (mr *MockFullNodeMockRecorder) PaychCollect(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychCollect", reflect.TypeOf((*MockFullNode)(nil).PaychCollect), arg0, arg1) } -// PaychGet mocks base method +// PaychGet mocks base method. func (m *MockFullNode) PaychGet(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (*api.ChannelInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychGet", arg0, arg1, arg2, arg3) @@ -1806,13 +1806,13 @@ func (m *MockFullNode) PaychGet(arg0 context.Context, arg1, arg2 address.Address return ret0, ret1 } -// PaychGet indicates an expected call of PaychGet +// PaychGet indicates an expected call of PaychGet. func (mr *MockFullNodeMockRecorder) PaychGet(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychGet", reflect.TypeOf((*MockFullNode)(nil).PaychGet), arg0, arg1, arg2, arg3) } -// PaychGetWaitReady mocks base method +// PaychGetWaitReady mocks base method. func (m *MockFullNode) PaychGetWaitReady(arg0 context.Context, arg1 cid.Cid) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychGetWaitReady", arg0, arg1) @@ -1821,13 +1821,13 @@ func (m *MockFullNode) PaychGetWaitReady(arg0 context.Context, arg1 cid.Cid) (ad return ret0, ret1 } -// PaychGetWaitReady indicates an expected call of PaychGetWaitReady +// PaychGetWaitReady indicates an expected call of PaychGetWaitReady. func (mr *MockFullNodeMockRecorder) PaychGetWaitReady(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychGetWaitReady", reflect.TypeOf((*MockFullNode)(nil).PaychGetWaitReady), arg0, arg1) } -// PaychList mocks base method +// PaychList mocks base method. func (m *MockFullNode) PaychList(arg0 context.Context) ([]address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychList", arg0) @@ -1836,13 +1836,13 @@ func (m *MockFullNode) PaychList(arg0 context.Context) ([]address.Address, error return ret0, ret1 } -// PaychList indicates an expected call of PaychList +// PaychList indicates an expected call of PaychList. func (mr *MockFullNodeMockRecorder) PaychList(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychList", reflect.TypeOf((*MockFullNode)(nil).PaychList), arg0) } -// PaychNewPayment mocks base method +// PaychNewPayment mocks base method. func (m *MockFullNode) PaychNewPayment(arg0 context.Context, arg1, arg2 address.Address, arg3 []api.VoucherSpec) (*api.PaymentInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychNewPayment", arg0, arg1, arg2, arg3) @@ -1851,13 +1851,13 @@ func (m *MockFullNode) PaychNewPayment(arg0 context.Context, arg1, arg2 address. return ret0, ret1 } -// PaychNewPayment indicates an expected call of PaychNewPayment +// PaychNewPayment indicates an expected call of PaychNewPayment. func (mr *MockFullNodeMockRecorder) PaychNewPayment(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychNewPayment", reflect.TypeOf((*MockFullNode)(nil).PaychNewPayment), arg0, arg1, arg2, arg3) } -// PaychSettle mocks base method +// PaychSettle mocks base method. func (m *MockFullNode) PaychSettle(arg0 context.Context, arg1 address.Address) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychSettle", arg0, arg1) @@ -1866,13 +1866,13 @@ func (m *MockFullNode) PaychSettle(arg0 context.Context, arg1 address.Address) ( return ret0, ret1 } -// PaychSettle indicates an expected call of PaychSettle +// PaychSettle indicates an expected call of PaychSettle. func (mr *MockFullNodeMockRecorder) PaychSettle(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychSettle", reflect.TypeOf((*MockFullNode)(nil).PaychSettle), arg0, arg1) } -// PaychStatus mocks base method +// PaychStatus mocks base method. func (m *MockFullNode) PaychStatus(arg0 context.Context, arg1 address.Address) (*api.PaychStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychStatus", arg0, arg1) @@ -1881,13 +1881,13 @@ func (m *MockFullNode) PaychStatus(arg0 context.Context, arg1 address.Address) ( return ret0, ret1 } -// PaychStatus indicates an expected call of PaychStatus +// PaychStatus indicates an expected call of PaychStatus. func (mr *MockFullNodeMockRecorder) PaychStatus(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychStatus", reflect.TypeOf((*MockFullNode)(nil).PaychStatus), arg0, arg1) } -// PaychVoucherAdd mocks base method +// PaychVoucherAdd mocks base method. func (m *MockFullNode) PaychVoucherAdd(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3 []byte, arg4 big.Int) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherAdd", arg0, arg1, arg2, arg3, arg4) @@ -1896,13 +1896,13 @@ func (m *MockFullNode) PaychVoucherAdd(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// PaychVoucherAdd indicates an expected call of PaychVoucherAdd +// PaychVoucherAdd indicates an expected call of PaychVoucherAdd. func (mr *MockFullNodeMockRecorder) PaychVoucherAdd(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherAdd", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherAdd), arg0, arg1, arg2, arg3, arg4) } -// PaychVoucherCheckSpendable mocks base method +// PaychVoucherCheckSpendable mocks base method. func (m *MockFullNode) PaychVoucherCheckSpendable(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3, arg4 []byte) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherCheckSpendable", arg0, arg1, arg2, arg3, arg4) @@ -1911,13 +1911,13 @@ func (m *MockFullNode) PaychVoucherCheckSpendable(arg0 context.Context, arg1 add return ret0, ret1 } -// PaychVoucherCheckSpendable indicates an expected call of PaychVoucherCheckSpendable +// PaychVoucherCheckSpendable indicates an expected call of PaychVoucherCheckSpendable. func (mr *MockFullNodeMockRecorder) PaychVoucherCheckSpendable(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCheckSpendable", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCheckSpendable), arg0, arg1, arg2, arg3, arg4) } -// PaychVoucherCheckValid mocks base method +// PaychVoucherCheckValid mocks base method. func (m *MockFullNode) PaychVoucherCheckValid(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherCheckValid", arg0, arg1, arg2) @@ -1925,13 +1925,13 @@ func (m *MockFullNode) PaychVoucherCheckValid(arg0 context.Context, arg1 address return ret0 } -// PaychVoucherCheckValid indicates an expected call of PaychVoucherCheckValid +// PaychVoucherCheckValid indicates an expected call of PaychVoucherCheckValid. func (mr *MockFullNodeMockRecorder) PaychVoucherCheckValid(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCheckValid", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCheckValid), arg0, arg1, arg2) } -// PaychVoucherCreate mocks base method +// PaychVoucherCreate mocks base method. func (m *MockFullNode) PaychVoucherCreate(arg0 context.Context, arg1 address.Address, arg2 big.Int, arg3 uint64) (*api.VoucherCreateResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherCreate", arg0, arg1, arg2, arg3) @@ -1940,13 +1940,13 @@ func (m *MockFullNode) PaychVoucherCreate(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// PaychVoucherCreate indicates an expected call of PaychVoucherCreate +// PaychVoucherCreate indicates an expected call of PaychVoucherCreate. func (mr *MockFullNodeMockRecorder) PaychVoucherCreate(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCreate", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCreate), arg0, arg1, arg2, arg3) } -// PaychVoucherList mocks base method +// PaychVoucherList mocks base method. func (m *MockFullNode) PaychVoucherList(arg0 context.Context, arg1 address.Address) ([]*paych.SignedVoucher, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherList", arg0, arg1) @@ -1955,13 +1955,13 @@ func (m *MockFullNode) PaychVoucherList(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// PaychVoucherList indicates an expected call of PaychVoucherList +// PaychVoucherList indicates an expected call of PaychVoucherList. func (mr *MockFullNodeMockRecorder) PaychVoucherList(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherList", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherList), arg0, arg1) } -// PaychVoucherSubmit mocks base method +// PaychVoucherSubmit mocks base method. func (m *MockFullNode) PaychVoucherSubmit(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3, arg4 []byte) (cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PaychVoucherSubmit", arg0, arg1, arg2, arg3, arg4) @@ -1970,13 +1970,13 @@ func (m *MockFullNode) PaychVoucherSubmit(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// PaychVoucherSubmit indicates an expected call of PaychVoucherSubmit +// PaychVoucherSubmit indicates an expected call of PaychVoucherSubmit. func (mr *MockFullNodeMockRecorder) PaychVoucherSubmit(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherSubmit", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherSubmit), arg0, arg1, arg2, arg3, arg4) } -// Session mocks base method +// Session mocks base method. func (m *MockFullNode) Session(arg0 context.Context) (uuid.UUID, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Session", arg0) @@ -1985,13 +1985,13 @@ func (m *MockFullNode) Session(arg0 context.Context) (uuid.UUID, error) { return ret0, ret1 } -// Session indicates an expected call of Session +// Session indicates an expected call of Session. func (mr *MockFullNodeMockRecorder) Session(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Session", reflect.TypeOf((*MockFullNode)(nil).Session), arg0) } -// Shutdown mocks base method +// Shutdown mocks base method. func (m *MockFullNode) Shutdown(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Shutdown", arg0) @@ -1999,13 +1999,13 @@ func (m *MockFullNode) Shutdown(arg0 context.Context) error { return ret0 } -// Shutdown indicates an expected call of Shutdown +// Shutdown indicates an expected call of Shutdown. func (mr *MockFullNodeMockRecorder) Shutdown(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shutdown", reflect.TypeOf((*MockFullNode)(nil).Shutdown), arg0) } -// StateAccountKey mocks base method +// StateAccountKey mocks base method. func (m *MockFullNode) StateAccountKey(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateAccountKey", arg0, arg1, arg2) @@ -2014,13 +2014,13 @@ func (m *MockFullNode) StateAccountKey(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// StateAccountKey indicates an expected call of StateAccountKey +// StateAccountKey indicates an expected call of StateAccountKey. func (mr *MockFullNodeMockRecorder) StateAccountKey(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateAccountKey", reflect.TypeOf((*MockFullNode)(nil).StateAccountKey), arg0, arg1, arg2) } -// StateAllMinerFaults mocks base method +// StateAllMinerFaults mocks base method. func (m *MockFullNode) StateAllMinerFaults(arg0 context.Context, arg1 abi.ChainEpoch, arg2 types.TipSetKey) ([]*api.Fault, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateAllMinerFaults", arg0, arg1, arg2) @@ -2029,13 +2029,13 @@ func (m *MockFullNode) StateAllMinerFaults(arg0 context.Context, arg1 abi.ChainE return ret0, ret1 } -// StateAllMinerFaults indicates an expected call of StateAllMinerFaults +// StateAllMinerFaults indicates an expected call of StateAllMinerFaults. func (mr *MockFullNodeMockRecorder) StateAllMinerFaults(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateAllMinerFaults", reflect.TypeOf((*MockFullNode)(nil).StateAllMinerFaults), arg0, arg1, arg2) } -// StateCall mocks base method +// StateCall mocks base method. func (m *MockFullNode) StateCall(arg0 context.Context, arg1 *types.Message, arg2 types.TipSetKey) (*api.InvocResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateCall", arg0, arg1, arg2) @@ -2044,13 +2044,13 @@ func (m *MockFullNode) StateCall(arg0 context.Context, arg1 *types.Message, arg2 return ret0, ret1 } -// StateCall indicates an expected call of StateCall +// StateCall indicates an expected call of StateCall. func (mr *MockFullNodeMockRecorder) StateCall(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCall", reflect.TypeOf((*MockFullNode)(nil).StateCall), arg0, arg1, arg2) } -// StateChangedActors mocks base method +// StateChangedActors mocks base method. func (m *MockFullNode) StateChangedActors(arg0 context.Context, arg1, arg2 cid.Cid) (map[string]types.Actor, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateChangedActors", arg0, arg1, arg2) @@ -2059,13 +2059,13 @@ func (m *MockFullNode) StateChangedActors(arg0 context.Context, arg1, arg2 cid.C return ret0, ret1 } -// StateChangedActors indicates an expected call of StateChangedActors +// StateChangedActors indicates an expected call of StateChangedActors. func (mr *MockFullNodeMockRecorder) StateChangedActors(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateChangedActors", reflect.TypeOf((*MockFullNode)(nil).StateChangedActors), arg0, arg1, arg2) } -// StateCirculatingSupply mocks base method +// StateCirculatingSupply mocks base method. func (m *MockFullNode) StateCirculatingSupply(arg0 context.Context, arg1 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateCirculatingSupply", arg0, arg1) @@ -2074,13 +2074,13 @@ func (m *MockFullNode) StateCirculatingSupply(arg0 context.Context, arg1 types.T return ret0, ret1 } -// StateCirculatingSupply indicates an expected call of StateCirculatingSupply +// StateCirculatingSupply indicates an expected call of StateCirculatingSupply. func (mr *MockFullNodeMockRecorder) StateCirculatingSupply(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCirculatingSupply", reflect.TypeOf((*MockFullNode)(nil).StateCirculatingSupply), arg0, arg1) } -// StateCompute mocks base method +// StateCompute mocks base method. func (m *MockFullNode) StateCompute(arg0 context.Context, arg1 abi.ChainEpoch, arg2 []*types.Message, arg3 types.TipSetKey) (*api.ComputeStateOutput, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateCompute", arg0, arg1, arg2, arg3) @@ -2089,13 +2089,13 @@ func (m *MockFullNode) StateCompute(arg0 context.Context, arg1 abi.ChainEpoch, a return ret0, ret1 } -// StateCompute indicates an expected call of StateCompute +// StateCompute indicates an expected call of StateCompute. func (mr *MockFullNodeMockRecorder) StateCompute(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCompute", reflect.TypeOf((*MockFullNode)(nil).StateCompute), arg0, arg1, arg2, arg3) } -// StateDealProviderCollateralBounds mocks base method +// StateDealProviderCollateralBounds mocks base method. func (m *MockFullNode) StateDealProviderCollateralBounds(arg0 context.Context, arg1 abi.PaddedPieceSize, arg2 bool, arg3 types.TipSetKey) (api.DealCollateralBounds, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateDealProviderCollateralBounds", arg0, arg1, arg2, arg3) @@ -2104,13 +2104,13 @@ func (m *MockFullNode) StateDealProviderCollateralBounds(arg0 context.Context, a return ret0, ret1 } -// StateDealProviderCollateralBounds indicates an expected call of StateDealProviderCollateralBounds +// StateDealProviderCollateralBounds indicates an expected call of StateDealProviderCollateralBounds. func (mr *MockFullNodeMockRecorder) StateDealProviderCollateralBounds(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateDealProviderCollateralBounds", reflect.TypeOf((*MockFullNode)(nil).StateDealProviderCollateralBounds), arg0, arg1, arg2, arg3) } -// StateDecodeParams mocks base method +// StateDecodeParams mocks base method. func (m *MockFullNode) StateDecodeParams(arg0 context.Context, arg1 address.Address, arg2 abi.MethodNum, arg3 []byte, arg4 types.TipSetKey) (interface{}, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateDecodeParams", arg0, arg1, arg2, arg3, arg4) @@ -2119,13 +2119,13 @@ func (m *MockFullNode) StateDecodeParams(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// StateDecodeParams indicates an expected call of StateDecodeParams +// StateDecodeParams indicates an expected call of StateDecodeParams. func (mr *MockFullNodeMockRecorder) StateDecodeParams(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateDecodeParams", reflect.TypeOf((*MockFullNode)(nil).StateDecodeParams), arg0, arg1, arg2, arg3, arg4) } -// StateGetActor mocks base method +// StateGetActor mocks base method. func (m *MockFullNode) StateGetActor(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*types.Actor, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateGetActor", arg0, arg1, arg2) @@ -2134,13 +2134,13 @@ func (m *MockFullNode) StateGetActor(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// StateGetActor indicates an expected call of StateGetActor +// StateGetActor indicates an expected call of StateGetActor. func (mr *MockFullNodeMockRecorder) StateGetActor(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetActor", reflect.TypeOf((*MockFullNode)(nil).StateGetActor), arg0, arg1, arg2) } -// StateGetReceipt mocks base method +// StateGetReceipt mocks base method. func (m *MockFullNode) StateGetReceipt(arg0 context.Context, arg1 cid.Cid, arg2 types.TipSetKey) (*types.MessageReceipt, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateGetReceipt", arg0, arg1, arg2) @@ -2149,13 +2149,13 @@ func (m *MockFullNode) StateGetReceipt(arg0 context.Context, arg1 cid.Cid, arg2 return ret0, ret1 } -// StateGetReceipt indicates an expected call of StateGetReceipt +// StateGetReceipt indicates an expected call of StateGetReceipt. func (mr *MockFullNodeMockRecorder) StateGetReceipt(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetReceipt", reflect.TypeOf((*MockFullNode)(nil).StateGetReceipt), arg0, arg1, arg2) } -// StateListActors mocks base method +// StateListActors mocks base method. func (m *MockFullNode) StateListActors(arg0 context.Context, arg1 types.TipSetKey) ([]address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateListActors", arg0, arg1) @@ -2164,13 +2164,13 @@ func (m *MockFullNode) StateListActors(arg0 context.Context, arg1 types.TipSetKe return ret0, ret1 } -// StateListActors indicates an expected call of StateListActors +// StateListActors indicates an expected call of StateListActors. func (mr *MockFullNodeMockRecorder) StateListActors(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListActors", reflect.TypeOf((*MockFullNode)(nil).StateListActors), arg0, arg1) } -// StateListMessages mocks base method +// StateListMessages mocks base method. func (m *MockFullNode) StateListMessages(arg0 context.Context, arg1 *api.MessageMatch, arg2 types.TipSetKey, arg3 abi.ChainEpoch) ([]cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateListMessages", arg0, arg1, arg2, arg3) @@ -2179,13 +2179,13 @@ func (m *MockFullNode) StateListMessages(arg0 context.Context, arg1 *api.Message return ret0, ret1 } -// StateListMessages indicates an expected call of StateListMessages +// StateListMessages indicates an expected call of StateListMessages. func (mr *MockFullNodeMockRecorder) StateListMessages(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListMessages", reflect.TypeOf((*MockFullNode)(nil).StateListMessages), arg0, arg1, arg2, arg3) } -// StateListMiners mocks base method +// StateListMiners mocks base method. func (m *MockFullNode) StateListMiners(arg0 context.Context, arg1 types.TipSetKey) ([]address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateListMiners", arg0, arg1) @@ -2194,13 +2194,13 @@ func (m *MockFullNode) StateListMiners(arg0 context.Context, arg1 types.TipSetKe return ret0, ret1 } -// StateListMiners indicates an expected call of StateListMiners +// StateListMiners indicates an expected call of StateListMiners. func (mr *MockFullNodeMockRecorder) StateListMiners(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListMiners", reflect.TypeOf((*MockFullNode)(nil).StateListMiners), arg0, arg1) } -// StateLookupID mocks base method +// StateLookupID mocks base method. func (m *MockFullNode) StateLookupID(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateLookupID", arg0, arg1, arg2) @@ -2209,13 +2209,13 @@ func (m *MockFullNode) StateLookupID(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// StateLookupID indicates an expected call of StateLookupID +// StateLookupID indicates an expected call of StateLookupID. func (mr *MockFullNodeMockRecorder) StateLookupID(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateLookupID", reflect.TypeOf((*MockFullNode)(nil).StateLookupID), arg0, arg1, arg2) } -// StateMarketBalance mocks base method +// StateMarketBalance mocks base method. func (m *MockFullNode) StateMarketBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MarketBalance, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMarketBalance", arg0, arg1, arg2) @@ -2224,13 +2224,13 @@ func (m *MockFullNode) StateMarketBalance(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// StateMarketBalance indicates an expected call of StateMarketBalance +// StateMarketBalance indicates an expected call of StateMarketBalance. func (mr *MockFullNodeMockRecorder) StateMarketBalance(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketBalance", reflect.TypeOf((*MockFullNode)(nil).StateMarketBalance), arg0, arg1, arg2) } -// StateMarketDeals mocks base method +// StateMarketDeals mocks base method. func (m *MockFullNode) StateMarketDeals(arg0 context.Context, arg1 types.TipSetKey) (map[string]api.MarketDeal, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMarketDeals", arg0, arg1) @@ -2239,13 +2239,13 @@ func (m *MockFullNode) StateMarketDeals(arg0 context.Context, arg1 types.TipSetK return ret0, ret1 } -// StateMarketDeals indicates an expected call of StateMarketDeals +// StateMarketDeals indicates an expected call of StateMarketDeals. func (mr *MockFullNodeMockRecorder) StateMarketDeals(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketDeals", reflect.TypeOf((*MockFullNode)(nil).StateMarketDeals), arg0, arg1) } -// StateMarketParticipants mocks base method +// StateMarketParticipants mocks base method. func (m *MockFullNode) StateMarketParticipants(arg0 context.Context, arg1 types.TipSetKey) (map[string]api.MarketBalance, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMarketParticipants", arg0, arg1) @@ -2254,13 +2254,13 @@ func (m *MockFullNode) StateMarketParticipants(arg0 context.Context, arg1 types. return ret0, ret1 } -// StateMarketParticipants indicates an expected call of StateMarketParticipants +// StateMarketParticipants indicates an expected call of StateMarketParticipants. func (mr *MockFullNodeMockRecorder) StateMarketParticipants(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketParticipants", reflect.TypeOf((*MockFullNode)(nil).StateMarketParticipants), arg0, arg1) } -// StateMarketStorageDeal mocks base method +// StateMarketStorageDeal mocks base method. func (m *MockFullNode) StateMarketStorageDeal(arg0 context.Context, arg1 abi.DealID, arg2 types.TipSetKey) (*api.MarketDeal, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMarketStorageDeal", arg0, arg1, arg2) @@ -2269,13 +2269,13 @@ func (m *MockFullNode) StateMarketStorageDeal(arg0 context.Context, arg1 abi.Dea return ret0, ret1 } -// StateMarketStorageDeal indicates an expected call of StateMarketStorageDeal +// StateMarketStorageDeal indicates an expected call of StateMarketStorageDeal. func (mr *MockFullNodeMockRecorder) StateMarketStorageDeal(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketStorageDeal", reflect.TypeOf((*MockFullNode)(nil).StateMarketStorageDeal), arg0, arg1, arg2) } -// StateMinerActiveSectors mocks base method +// StateMinerActiveSectors mocks base method. func (m *MockFullNode) StateMinerActiveSectors(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerActiveSectors", arg0, arg1, arg2) @@ -2284,13 +2284,13 @@ func (m *MockFullNode) StateMinerActiveSectors(arg0 context.Context, arg1 addres return ret0, ret1 } -// StateMinerActiveSectors indicates an expected call of StateMinerActiveSectors +// StateMinerActiveSectors indicates an expected call of StateMinerActiveSectors. func (mr *MockFullNodeMockRecorder) StateMinerActiveSectors(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerActiveSectors", reflect.TypeOf((*MockFullNode)(nil).StateMinerActiveSectors), arg0, arg1, arg2) } -// StateMinerAvailableBalance mocks base method +// StateMinerAvailableBalance mocks base method. func (m *MockFullNode) StateMinerAvailableBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerAvailableBalance", arg0, arg1, arg2) @@ -2299,13 +2299,13 @@ func (m *MockFullNode) StateMinerAvailableBalance(arg0 context.Context, arg1 add return ret0, ret1 } -// StateMinerAvailableBalance indicates an expected call of StateMinerAvailableBalance +// StateMinerAvailableBalance indicates an expected call of StateMinerAvailableBalance. func (mr *MockFullNodeMockRecorder) StateMinerAvailableBalance(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerAvailableBalance", reflect.TypeOf((*MockFullNode)(nil).StateMinerAvailableBalance), arg0, arg1, arg2) } -// StateMinerDeadlines mocks base method +// StateMinerDeadlines mocks base method. func (m *MockFullNode) StateMinerDeadlines(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]api.Deadline, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerDeadlines", arg0, arg1, arg2) @@ -2314,13 +2314,13 @@ func (m *MockFullNode) StateMinerDeadlines(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// StateMinerDeadlines indicates an expected call of StateMinerDeadlines +// StateMinerDeadlines indicates an expected call of StateMinerDeadlines. func (mr *MockFullNodeMockRecorder) StateMinerDeadlines(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerDeadlines", reflect.TypeOf((*MockFullNode)(nil).StateMinerDeadlines), arg0, arg1, arg2) } -// StateMinerFaults mocks base method +// StateMinerFaults mocks base method. func (m *MockFullNode) StateMinerFaults(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (bitfield.BitField, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerFaults", arg0, arg1, arg2) @@ -2329,13 +2329,13 @@ func (m *MockFullNode) StateMinerFaults(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// StateMinerFaults indicates an expected call of StateMinerFaults +// StateMinerFaults indicates an expected call of StateMinerFaults. func (mr *MockFullNodeMockRecorder) StateMinerFaults(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerFaults", reflect.TypeOf((*MockFullNode)(nil).StateMinerFaults), arg0, arg1, arg2) } -// StateMinerInfo mocks base method +// StateMinerInfo mocks base method. func (m *MockFullNode) StateMinerInfo(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (miner.MinerInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerInfo", arg0, arg1, arg2) @@ -2344,13 +2344,13 @@ func (m *MockFullNode) StateMinerInfo(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// StateMinerInfo indicates an expected call of StateMinerInfo +// StateMinerInfo indicates an expected call of StateMinerInfo. func (mr *MockFullNodeMockRecorder) StateMinerInfo(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInfo", reflect.TypeOf((*MockFullNode)(nil).StateMinerInfo), arg0, arg1, arg2) } -// StateMinerInitialPledgeCollateral mocks base method +// StateMinerInitialPledgeCollateral mocks base method. func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerInitialPledgeCollateral", arg0, arg1, arg2, arg3) @@ -2359,13 +2359,13 @@ func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, a return ret0, ret1 } -// StateMinerInitialPledgeCollateral indicates an expected call of StateMinerInitialPledgeCollateral +// StateMinerInitialPledgeCollateral indicates an expected call of StateMinerInitialPledgeCollateral. func (mr *MockFullNodeMockRecorder) StateMinerInitialPledgeCollateral(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInitialPledgeCollateral", reflect.TypeOf((*MockFullNode)(nil).StateMinerInitialPledgeCollateral), arg0, arg1, arg2, arg3) } -// StateMinerPartitions mocks base method +// StateMinerPartitions mocks base method. func (m *MockFullNode) StateMinerPartitions(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 types.TipSetKey) ([]api.Partition, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerPartitions", arg0, arg1, arg2, arg3) @@ -2374,13 +2374,13 @@ func (m *MockFullNode) StateMinerPartitions(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateMinerPartitions indicates an expected call of StateMinerPartitions +// StateMinerPartitions indicates an expected call of StateMinerPartitions. func (mr *MockFullNodeMockRecorder) StateMinerPartitions(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPartitions", reflect.TypeOf((*MockFullNode)(nil).StateMinerPartitions), arg0, arg1, arg2, arg3) } -// StateMinerPower mocks base method +// StateMinerPower mocks base method. func (m *MockFullNode) StateMinerPower(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*api.MinerPower, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerPower", arg0, arg1, arg2) @@ -2389,13 +2389,13 @@ func (m *MockFullNode) StateMinerPower(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// StateMinerPower indicates an expected call of StateMinerPower +// StateMinerPower indicates an expected call of StateMinerPower. func (mr *MockFullNodeMockRecorder) StateMinerPower(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPower", reflect.TypeOf((*MockFullNode)(nil).StateMinerPower), arg0, arg1, arg2) } -// StateMinerPreCommitDepositForPower mocks base method +// StateMinerPreCommitDepositForPower mocks base method. func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerPreCommitDepositForPower", arg0, arg1, arg2, arg3) @@ -2404,13 +2404,13 @@ func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, return ret0, ret1 } -// StateMinerPreCommitDepositForPower indicates an expected call of StateMinerPreCommitDepositForPower +// StateMinerPreCommitDepositForPower indicates an expected call of StateMinerPreCommitDepositForPower. func (mr *MockFullNodeMockRecorder) StateMinerPreCommitDepositForPower(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPreCommitDepositForPower", reflect.TypeOf((*MockFullNode)(nil).StateMinerPreCommitDepositForPower), arg0, arg1, arg2, arg3) } -// StateMinerProvingDeadline mocks base method +// StateMinerProvingDeadline mocks base method. func (m *MockFullNode) StateMinerProvingDeadline(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*dline.Info, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerProvingDeadline", arg0, arg1, arg2) @@ -2419,13 +2419,13 @@ func (m *MockFullNode) StateMinerProvingDeadline(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateMinerProvingDeadline indicates an expected call of StateMinerProvingDeadline +// StateMinerProvingDeadline indicates an expected call of StateMinerProvingDeadline. func (mr *MockFullNodeMockRecorder) StateMinerProvingDeadline(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerProvingDeadline", reflect.TypeOf((*MockFullNode)(nil).StateMinerProvingDeadline), arg0, arg1, arg2) } -// StateMinerRecoveries mocks base method +// StateMinerRecoveries mocks base method. func (m *MockFullNode) StateMinerRecoveries(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (bitfield.BitField, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerRecoveries", arg0, arg1, arg2) @@ -2434,13 +2434,13 @@ func (m *MockFullNode) StateMinerRecoveries(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateMinerRecoveries indicates an expected call of StateMinerRecoveries +// StateMinerRecoveries indicates an expected call of StateMinerRecoveries. func (mr *MockFullNodeMockRecorder) StateMinerRecoveries(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerRecoveries", reflect.TypeOf((*MockFullNode)(nil).StateMinerRecoveries), arg0, arg1, arg2) } -// StateMinerSectorAllocated mocks base method +// StateMinerSectorAllocated mocks base method. func (m *MockFullNode) StateMinerSectorAllocated(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerSectorAllocated", arg0, arg1, arg2, arg3) @@ -2449,13 +2449,13 @@ func (m *MockFullNode) StateMinerSectorAllocated(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateMinerSectorAllocated indicates an expected call of StateMinerSectorAllocated +// StateMinerSectorAllocated indicates an expected call of StateMinerSectorAllocated. func (mr *MockFullNodeMockRecorder) StateMinerSectorAllocated(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectorAllocated", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectorAllocated), arg0, arg1, arg2, arg3) } -// StateMinerSectorCount mocks base method +// StateMinerSectorCount mocks base method. func (m *MockFullNode) StateMinerSectorCount(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MinerSectors, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerSectorCount", arg0, arg1, arg2) @@ -2464,13 +2464,13 @@ func (m *MockFullNode) StateMinerSectorCount(arg0 context.Context, arg1 address. return ret0, ret1 } -// StateMinerSectorCount indicates an expected call of StateMinerSectorCount +// StateMinerSectorCount indicates an expected call of StateMinerSectorCount. func (mr *MockFullNodeMockRecorder) StateMinerSectorCount(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectorCount", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectorCount), arg0, arg1, arg2) } -// StateMinerSectors mocks base method +// StateMinerSectors mocks base method. func (m *MockFullNode) StateMinerSectors(arg0 context.Context, arg1 address.Address, arg2 *bitfield.BitField, arg3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerSectors", arg0, arg1, arg2, arg3) @@ -2479,13 +2479,13 @@ func (m *MockFullNode) StateMinerSectors(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// StateMinerSectors indicates an expected call of StateMinerSectors +// StateMinerSectors indicates an expected call of StateMinerSectors. func (mr *MockFullNodeMockRecorder) StateMinerSectors(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectors", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectors), arg0, arg1, arg2, arg3) } -// StateNetworkName mocks base method +// StateNetworkName mocks base method. func (m *MockFullNode) StateNetworkName(arg0 context.Context) (dtypes.NetworkName, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateNetworkName", arg0) @@ -2494,13 +2494,13 @@ func (m *MockFullNode) StateNetworkName(arg0 context.Context) (dtypes.NetworkNam return ret0, ret1 } -// StateNetworkName indicates an expected call of StateNetworkName +// StateNetworkName indicates an expected call of StateNetworkName. func (mr *MockFullNodeMockRecorder) StateNetworkName(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateNetworkName", reflect.TypeOf((*MockFullNode)(nil).StateNetworkName), arg0) } -// StateNetworkVersion mocks base method +// StateNetworkVersion mocks base method. func (m *MockFullNode) StateNetworkVersion(arg0 context.Context, arg1 types.TipSetKey) (network.Version, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateNetworkVersion", arg0, arg1) @@ -2509,13 +2509,13 @@ func (m *MockFullNode) StateNetworkVersion(arg0 context.Context, arg1 types.TipS return ret0, ret1 } -// StateNetworkVersion indicates an expected call of StateNetworkVersion +// StateNetworkVersion indicates an expected call of StateNetworkVersion. func (mr *MockFullNodeMockRecorder) StateNetworkVersion(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateNetworkVersion", reflect.TypeOf((*MockFullNode)(nil).StateNetworkVersion), arg0, arg1) } -// StateReadState mocks base method +// StateReadState mocks base method. func (m *MockFullNode) StateReadState(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*api.ActorState, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateReadState", arg0, arg1, arg2) @@ -2524,13 +2524,13 @@ func (m *MockFullNode) StateReadState(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// StateReadState indicates an expected call of StateReadState +// StateReadState indicates an expected call of StateReadState. func (mr *MockFullNodeMockRecorder) StateReadState(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateReadState", reflect.TypeOf((*MockFullNode)(nil).StateReadState), arg0, arg1, arg2) } -// StateReplay mocks base method +// StateReplay mocks base method. func (m *MockFullNode) StateReplay(arg0 context.Context, arg1 types.TipSetKey, arg2 cid.Cid) (*api.InvocResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateReplay", arg0, arg1, arg2) @@ -2539,13 +2539,13 @@ func (m *MockFullNode) StateReplay(arg0 context.Context, arg1 types.TipSetKey, a return ret0, ret1 } -// StateReplay indicates an expected call of StateReplay +// StateReplay indicates an expected call of StateReplay. func (mr *MockFullNodeMockRecorder) StateReplay(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateReplay", reflect.TypeOf((*MockFullNode)(nil).StateReplay), arg0, arg1, arg2) } -// StateSearchMsg mocks base method +// StateSearchMsg mocks base method. func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 cid.Cid) (*api.MsgLookup, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSearchMsg", arg0, arg1) @@ -2554,13 +2554,13 @@ func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 cid.Cid) (*api. return ret0, ret1 } -// StateSearchMsg indicates an expected call of StateSearchMsg +// StateSearchMsg indicates an expected call of StateSearchMsg. func (mr *MockFullNodeMockRecorder) StateSearchMsg(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsg", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsg), arg0, arg1) } -// StateSearchMsgLimited mocks base method +// StateSearchMsgLimited mocks base method. func (m *MockFullNode) StateSearchMsgLimited(arg0 context.Context, arg1 cid.Cid, arg2 abi.ChainEpoch) (*api.MsgLookup, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSearchMsgLimited", arg0, arg1, arg2) @@ -2569,13 +2569,13 @@ func (m *MockFullNode) StateSearchMsgLimited(arg0 context.Context, arg1 cid.Cid, return ret0, ret1 } -// StateSearchMsgLimited indicates an expected call of StateSearchMsgLimited +// StateSearchMsgLimited indicates an expected call of StateSearchMsgLimited. func (mr *MockFullNodeMockRecorder) StateSearchMsgLimited(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsgLimited", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsgLimited), arg0, arg1, arg2) } -// StateSectorExpiration mocks base method +// StateSectorExpiration mocks base method. func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorExpiration, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorExpiration", arg0, arg1, arg2, arg3) @@ -2584,13 +2584,13 @@ func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address. return ret0, ret1 } -// StateSectorExpiration indicates an expected call of StateSectorExpiration +// StateSectorExpiration indicates an expected call of StateSectorExpiration. func (mr *MockFullNodeMockRecorder) StateSectorExpiration(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorExpiration", reflect.TypeOf((*MockFullNode)(nil).StateSectorExpiration), arg0, arg1, arg2, arg3) } -// StateSectorGetInfo mocks base method +// StateSectorGetInfo mocks base method. func (m *MockFullNode) StateSectorGetInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorGetInfo", arg0, arg1, arg2, arg3) @@ -2599,13 +2599,13 @@ func (m *MockFullNode) StateSectorGetInfo(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// StateSectorGetInfo indicates an expected call of StateSectorGetInfo +// StateSectorGetInfo indicates an expected call of StateSectorGetInfo. func (mr *MockFullNodeMockRecorder) StateSectorGetInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorGetInfo", reflect.TypeOf((*MockFullNode)(nil).StateSectorGetInfo), arg0, arg1, arg2, arg3) } -// StateSectorPartition mocks base method +// StateSectorPartition mocks base method. func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorLocation, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorPartition", arg0, arg1, arg2, arg3) @@ -2614,13 +2614,13 @@ func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateSectorPartition indicates an expected call of StateSectorPartition +// StateSectorPartition indicates an expected call of StateSectorPartition. func (mr *MockFullNodeMockRecorder) StateSectorPartition(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorPartition", reflect.TypeOf((*MockFullNode)(nil).StateSectorPartition), arg0, arg1, arg2, arg3) } -// StateSectorPreCommitInfo mocks base method +// StateSectorPreCommitInfo mocks base method. func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorPreCommitInfo", arg0, arg1, arg2, arg3) @@ -2629,13 +2629,13 @@ func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 addre return ret0, ret1 } -// StateSectorPreCommitInfo indicates an expected call of StateSectorPreCommitInfo +// StateSectorPreCommitInfo indicates an expected call of StateSectorPreCommitInfo. func (mr *MockFullNodeMockRecorder) StateSectorPreCommitInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorPreCommitInfo", reflect.TypeOf((*MockFullNode)(nil).StateSectorPreCommitInfo), arg0, arg1, arg2, arg3) } -// StateVMCirculatingSupplyInternal mocks base method +// StateVMCirculatingSupplyInternal mocks base method. func (m *MockFullNode) StateVMCirculatingSupplyInternal(arg0 context.Context, arg1 types.TipSetKey) (api.CirculatingSupply, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateVMCirculatingSupplyInternal", arg0, arg1) @@ -2644,13 +2644,13 @@ func (m *MockFullNode) StateVMCirculatingSupplyInternal(arg0 context.Context, ar return ret0, ret1 } -// StateVMCirculatingSupplyInternal indicates an expected call of StateVMCirculatingSupplyInternal +// StateVMCirculatingSupplyInternal indicates an expected call of StateVMCirculatingSupplyInternal. func (mr *MockFullNodeMockRecorder) StateVMCirculatingSupplyInternal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVMCirculatingSupplyInternal", reflect.TypeOf((*MockFullNode)(nil).StateVMCirculatingSupplyInternal), arg0, arg1) } -// StateVerifiedClientStatus mocks base method +// StateVerifiedClientStatus mocks base method. func (m *MockFullNode) StateVerifiedClientStatus(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateVerifiedClientStatus", arg0, arg1, arg2) @@ -2659,13 +2659,13 @@ func (m *MockFullNode) StateVerifiedClientStatus(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateVerifiedClientStatus indicates an expected call of StateVerifiedClientStatus +// StateVerifiedClientStatus indicates an expected call of StateVerifiedClientStatus. func (mr *MockFullNodeMockRecorder) StateVerifiedClientStatus(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifiedClientStatus", reflect.TypeOf((*MockFullNode)(nil).StateVerifiedClientStatus), arg0, arg1, arg2) } -// StateVerifiedRegistryRootKey mocks base method +// StateVerifiedRegistryRootKey mocks base method. func (m *MockFullNode) StateVerifiedRegistryRootKey(arg0 context.Context, arg1 types.TipSetKey) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateVerifiedRegistryRootKey", arg0, arg1) @@ -2674,13 +2674,13 @@ func (m *MockFullNode) StateVerifiedRegistryRootKey(arg0 context.Context, arg1 t return ret0, ret1 } -// StateVerifiedRegistryRootKey indicates an expected call of StateVerifiedRegistryRootKey +// StateVerifiedRegistryRootKey indicates an expected call of StateVerifiedRegistryRootKey. func (mr *MockFullNodeMockRecorder) StateVerifiedRegistryRootKey(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifiedRegistryRootKey", reflect.TypeOf((*MockFullNode)(nil).StateVerifiedRegistryRootKey), arg0, arg1) } -// StateVerifierStatus mocks base method +// StateVerifierStatus mocks base method. func (m *MockFullNode) StateVerifierStatus(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateVerifierStatus", arg0, arg1, arg2) @@ -2689,13 +2689,13 @@ func (m *MockFullNode) StateVerifierStatus(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// StateVerifierStatus indicates an expected call of StateVerifierStatus +// StateVerifierStatus indicates an expected call of StateVerifierStatus. func (mr *MockFullNodeMockRecorder) StateVerifierStatus(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifierStatus", reflect.TypeOf((*MockFullNode)(nil).StateVerifierStatus), arg0, arg1, arg2) } -// StateWaitMsg mocks base method +// StateWaitMsg mocks base method. func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uint64) (*api.MsgLookup, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateWaitMsg", arg0, arg1, arg2) @@ -2704,13 +2704,13 @@ func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uin return ret0, ret1 } -// StateWaitMsg indicates an expected call of StateWaitMsg +// StateWaitMsg indicates an expected call of StateWaitMsg. func (mr *MockFullNodeMockRecorder) StateWaitMsg(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsg", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsg), arg0, arg1, arg2) } -// StateWaitMsgLimited mocks base method +// StateWaitMsgLimited mocks base method. func (m *MockFullNode) StateWaitMsgLimited(arg0 context.Context, arg1 cid.Cid, arg2 uint64, arg3 abi.ChainEpoch) (*api.MsgLookup, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateWaitMsgLimited", arg0, arg1, arg2, arg3) @@ -2719,13 +2719,13 @@ func (m *MockFullNode) StateWaitMsgLimited(arg0 context.Context, arg1 cid.Cid, a return ret0, ret1 } -// StateWaitMsgLimited indicates an expected call of StateWaitMsgLimited +// StateWaitMsgLimited indicates an expected call of StateWaitMsgLimited. func (mr *MockFullNodeMockRecorder) StateWaitMsgLimited(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsgLimited", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsgLimited), arg0, arg1, arg2, arg3) } -// SyncCheckBad mocks base method +// SyncCheckBad mocks base method. func (m *MockFullNode) SyncCheckBad(arg0 context.Context, arg1 cid.Cid) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncCheckBad", arg0, arg1) @@ -2734,13 +2734,13 @@ func (m *MockFullNode) SyncCheckBad(arg0 context.Context, arg1 cid.Cid) (string, return ret0, ret1 } -// SyncCheckBad indicates an expected call of SyncCheckBad +// SyncCheckBad indicates an expected call of SyncCheckBad. func (mr *MockFullNodeMockRecorder) SyncCheckBad(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncCheckBad", reflect.TypeOf((*MockFullNode)(nil).SyncCheckBad), arg0, arg1) } -// SyncCheckpoint mocks base method +// SyncCheckpoint mocks base method. func (m *MockFullNode) SyncCheckpoint(arg0 context.Context, arg1 types.TipSetKey) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncCheckpoint", arg0, arg1) @@ -2748,13 +2748,13 @@ func (m *MockFullNode) SyncCheckpoint(arg0 context.Context, arg1 types.TipSetKey return ret0 } -// SyncCheckpoint indicates an expected call of SyncCheckpoint +// SyncCheckpoint indicates an expected call of SyncCheckpoint. func (mr *MockFullNodeMockRecorder) SyncCheckpoint(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncCheckpoint", reflect.TypeOf((*MockFullNode)(nil).SyncCheckpoint), arg0, arg1) } -// SyncIncomingBlocks mocks base method +// SyncIncomingBlocks mocks base method. func (m *MockFullNode) SyncIncomingBlocks(arg0 context.Context) (<-chan *types.BlockHeader, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncIncomingBlocks", arg0) @@ -2763,13 +2763,13 @@ func (m *MockFullNode) SyncIncomingBlocks(arg0 context.Context) (<-chan *types.B return ret0, ret1 } -// SyncIncomingBlocks indicates an expected call of SyncIncomingBlocks +// SyncIncomingBlocks indicates an expected call of SyncIncomingBlocks. func (mr *MockFullNodeMockRecorder) SyncIncomingBlocks(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncIncomingBlocks", reflect.TypeOf((*MockFullNode)(nil).SyncIncomingBlocks), arg0) } -// SyncMarkBad mocks base method +// SyncMarkBad mocks base method. func (m *MockFullNode) SyncMarkBad(arg0 context.Context, arg1 cid.Cid) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncMarkBad", arg0, arg1) @@ -2777,13 +2777,13 @@ func (m *MockFullNode) SyncMarkBad(arg0 context.Context, arg1 cid.Cid) error { return ret0 } -// SyncMarkBad indicates an expected call of SyncMarkBad +// SyncMarkBad indicates an expected call of SyncMarkBad. func (mr *MockFullNodeMockRecorder) SyncMarkBad(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncMarkBad", reflect.TypeOf((*MockFullNode)(nil).SyncMarkBad), arg0, arg1) } -// SyncState mocks base method +// SyncState mocks base method. func (m *MockFullNode) SyncState(arg0 context.Context) (*api.SyncState, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncState", arg0) @@ -2792,13 +2792,13 @@ func (m *MockFullNode) SyncState(arg0 context.Context) (*api.SyncState, error) { return ret0, ret1 } -// SyncState indicates an expected call of SyncState +// SyncState indicates an expected call of SyncState. func (mr *MockFullNodeMockRecorder) SyncState(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncState", reflect.TypeOf((*MockFullNode)(nil).SyncState), arg0) } -// SyncSubmitBlock mocks base method +// SyncSubmitBlock mocks base method. func (m *MockFullNode) SyncSubmitBlock(arg0 context.Context, arg1 *types.BlockMsg) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncSubmitBlock", arg0, arg1) @@ -2806,13 +2806,13 @@ func (m *MockFullNode) SyncSubmitBlock(arg0 context.Context, arg1 *types.BlockMs return ret0 } -// SyncSubmitBlock indicates an expected call of SyncSubmitBlock +// SyncSubmitBlock indicates an expected call of SyncSubmitBlock. func (mr *MockFullNodeMockRecorder) SyncSubmitBlock(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncSubmitBlock", reflect.TypeOf((*MockFullNode)(nil).SyncSubmitBlock), arg0, arg1) } -// SyncUnmarkAllBad mocks base method +// SyncUnmarkAllBad mocks base method. func (m *MockFullNode) SyncUnmarkAllBad(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncUnmarkAllBad", arg0) @@ -2820,13 +2820,13 @@ func (m *MockFullNode) SyncUnmarkAllBad(arg0 context.Context) error { return ret0 } -// SyncUnmarkAllBad indicates an expected call of SyncUnmarkAllBad +// SyncUnmarkAllBad indicates an expected call of SyncUnmarkAllBad. func (mr *MockFullNodeMockRecorder) SyncUnmarkAllBad(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncUnmarkAllBad", reflect.TypeOf((*MockFullNode)(nil).SyncUnmarkAllBad), arg0) } -// SyncUnmarkBad mocks base method +// SyncUnmarkBad mocks base method. func (m *MockFullNode) SyncUnmarkBad(arg0 context.Context, arg1 cid.Cid) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncUnmarkBad", arg0, arg1) @@ -2834,13 +2834,13 @@ func (m *MockFullNode) SyncUnmarkBad(arg0 context.Context, arg1 cid.Cid) error { return ret0 } -// SyncUnmarkBad indicates an expected call of SyncUnmarkBad +// SyncUnmarkBad indicates an expected call of SyncUnmarkBad. func (mr *MockFullNodeMockRecorder) SyncUnmarkBad(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncUnmarkBad", reflect.TypeOf((*MockFullNode)(nil).SyncUnmarkBad), arg0, arg1) } -// SyncValidateTipset mocks base method +// SyncValidateTipset mocks base method. func (m *MockFullNode) SyncValidateTipset(arg0 context.Context, arg1 types.TipSetKey) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncValidateTipset", arg0, arg1) @@ -2849,13 +2849,13 @@ func (m *MockFullNode) SyncValidateTipset(arg0 context.Context, arg1 types.TipSe return ret0, ret1 } -// SyncValidateTipset indicates an expected call of SyncValidateTipset +// SyncValidateTipset indicates an expected call of SyncValidateTipset. func (mr *MockFullNodeMockRecorder) SyncValidateTipset(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncValidateTipset", reflect.TypeOf((*MockFullNode)(nil).SyncValidateTipset), arg0, arg1) } -// Version mocks base method +// Version mocks base method. func (m *MockFullNode) Version(arg0 context.Context) (api.APIVersion, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Version", arg0) @@ -2864,13 +2864,13 @@ func (m *MockFullNode) Version(arg0 context.Context) (api.APIVersion, error) { return ret0, ret1 } -// Version indicates an expected call of Version +// Version indicates an expected call of Version. func (mr *MockFullNodeMockRecorder) Version(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockFullNode)(nil).Version), arg0) } -// WalletBalance mocks base method +// WalletBalance mocks base method. func (m *MockFullNode) WalletBalance(arg0 context.Context, arg1 address.Address) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletBalance", arg0, arg1) @@ -2879,13 +2879,13 @@ func (m *MockFullNode) WalletBalance(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// WalletBalance indicates an expected call of WalletBalance +// WalletBalance indicates an expected call of WalletBalance. func (mr *MockFullNodeMockRecorder) WalletBalance(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletBalance", reflect.TypeOf((*MockFullNode)(nil).WalletBalance), arg0, arg1) } -// WalletDefaultAddress mocks base method +// WalletDefaultAddress mocks base method. func (m *MockFullNode) WalletDefaultAddress(arg0 context.Context) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletDefaultAddress", arg0) @@ -2894,13 +2894,13 @@ func (m *MockFullNode) WalletDefaultAddress(arg0 context.Context) (address.Addre return ret0, ret1 } -// WalletDefaultAddress indicates an expected call of WalletDefaultAddress +// WalletDefaultAddress indicates an expected call of WalletDefaultAddress. func (mr *MockFullNodeMockRecorder) WalletDefaultAddress(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletDefaultAddress", reflect.TypeOf((*MockFullNode)(nil).WalletDefaultAddress), arg0) } -// WalletDelete mocks base method +// WalletDelete mocks base method. func (m *MockFullNode) WalletDelete(arg0 context.Context, arg1 address.Address) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletDelete", arg0, arg1) @@ -2908,13 +2908,13 @@ func (m *MockFullNode) WalletDelete(arg0 context.Context, arg1 address.Address) return ret0 } -// WalletDelete indicates an expected call of WalletDelete +// WalletDelete indicates an expected call of WalletDelete. func (mr *MockFullNodeMockRecorder) WalletDelete(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletDelete", reflect.TypeOf((*MockFullNode)(nil).WalletDelete), arg0, arg1) } -// WalletExport mocks base method +// WalletExport mocks base method. func (m *MockFullNode) WalletExport(arg0 context.Context, arg1 address.Address) (*types.KeyInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletExport", arg0, arg1) @@ -2923,13 +2923,13 @@ func (m *MockFullNode) WalletExport(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// WalletExport indicates an expected call of WalletExport +// WalletExport indicates an expected call of WalletExport. func (mr *MockFullNodeMockRecorder) WalletExport(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletExport", reflect.TypeOf((*MockFullNode)(nil).WalletExport), arg0, arg1) } -// WalletHas mocks base method +// WalletHas mocks base method. func (m *MockFullNode) WalletHas(arg0 context.Context, arg1 address.Address) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletHas", arg0, arg1) @@ -2938,13 +2938,13 @@ func (m *MockFullNode) WalletHas(arg0 context.Context, arg1 address.Address) (bo return ret0, ret1 } -// WalletHas indicates an expected call of WalletHas +// WalletHas indicates an expected call of WalletHas. func (mr *MockFullNodeMockRecorder) WalletHas(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletHas", reflect.TypeOf((*MockFullNode)(nil).WalletHas), arg0, arg1) } -// WalletImport mocks base method +// WalletImport mocks base method. func (m *MockFullNode) WalletImport(arg0 context.Context, arg1 *types.KeyInfo) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletImport", arg0, arg1) @@ -2953,13 +2953,13 @@ func (m *MockFullNode) WalletImport(arg0 context.Context, arg1 *types.KeyInfo) ( return ret0, ret1 } -// WalletImport indicates an expected call of WalletImport +// WalletImport indicates an expected call of WalletImport. func (mr *MockFullNodeMockRecorder) WalletImport(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletImport", reflect.TypeOf((*MockFullNode)(nil).WalletImport), arg0, arg1) } -// WalletList mocks base method +// WalletList mocks base method. func (m *MockFullNode) WalletList(arg0 context.Context) ([]address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletList", arg0) @@ -2968,13 +2968,13 @@ func (m *MockFullNode) WalletList(arg0 context.Context) ([]address.Address, erro return ret0, ret1 } -// WalletList indicates an expected call of WalletList +// WalletList indicates an expected call of WalletList. func (mr *MockFullNodeMockRecorder) WalletList(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletList", reflect.TypeOf((*MockFullNode)(nil).WalletList), arg0) } -// WalletNew mocks base method +// WalletNew mocks base method. func (m *MockFullNode) WalletNew(arg0 context.Context, arg1 types.KeyType) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletNew", arg0, arg1) @@ -2983,13 +2983,13 @@ func (m *MockFullNode) WalletNew(arg0 context.Context, arg1 types.KeyType) (addr return ret0, ret1 } -// WalletNew indicates an expected call of WalletNew +// WalletNew indicates an expected call of WalletNew. func (mr *MockFullNodeMockRecorder) WalletNew(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletNew", reflect.TypeOf((*MockFullNode)(nil).WalletNew), arg0, arg1) } -// WalletSetDefault mocks base method +// WalletSetDefault mocks base method. func (m *MockFullNode) WalletSetDefault(arg0 context.Context, arg1 address.Address) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletSetDefault", arg0, arg1) @@ -2997,13 +2997,13 @@ func (m *MockFullNode) WalletSetDefault(arg0 context.Context, arg1 address.Addre return ret0 } -// WalletSetDefault indicates an expected call of WalletSetDefault +// WalletSetDefault indicates an expected call of WalletSetDefault. func (mr *MockFullNodeMockRecorder) WalletSetDefault(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSetDefault", reflect.TypeOf((*MockFullNode)(nil).WalletSetDefault), arg0, arg1) } -// WalletSign mocks base method +// WalletSign mocks base method. func (m *MockFullNode) WalletSign(arg0 context.Context, arg1 address.Address, arg2 []byte) (*crypto.Signature, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletSign", arg0, arg1, arg2) @@ -3012,13 +3012,13 @@ func (m *MockFullNode) WalletSign(arg0 context.Context, arg1 address.Address, ar return ret0, ret1 } -// WalletSign indicates an expected call of WalletSign +// WalletSign indicates an expected call of WalletSign. func (mr *MockFullNodeMockRecorder) WalletSign(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSign", reflect.TypeOf((*MockFullNode)(nil).WalletSign), arg0, arg1, arg2) } -// WalletSignMessage mocks base method +// WalletSignMessage mocks base method. func (m *MockFullNode) WalletSignMessage(arg0 context.Context, arg1 address.Address, arg2 *types.Message) (*types.SignedMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletSignMessage", arg0, arg1, arg2) @@ -3027,13 +3027,13 @@ func (m *MockFullNode) WalletSignMessage(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// WalletSignMessage indicates an expected call of WalletSignMessage +// WalletSignMessage indicates an expected call of WalletSignMessage. func (mr *MockFullNodeMockRecorder) WalletSignMessage(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSignMessage", reflect.TypeOf((*MockFullNode)(nil).WalletSignMessage), arg0, arg1, arg2) } -// WalletValidateAddress mocks base method +// WalletValidateAddress mocks base method. func (m *MockFullNode) WalletValidateAddress(arg0 context.Context, arg1 string) (address.Address, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletValidateAddress", arg0, arg1) @@ -3042,13 +3042,13 @@ func (m *MockFullNode) WalletValidateAddress(arg0 context.Context, arg1 string) return ret0, ret1 } -// WalletValidateAddress indicates an expected call of WalletValidateAddress +// WalletValidateAddress indicates an expected call of WalletValidateAddress. func (mr *MockFullNodeMockRecorder) WalletValidateAddress(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletValidateAddress", reflect.TypeOf((*MockFullNode)(nil).WalletValidateAddress), arg0, arg1) } -// WalletVerify mocks base method +// WalletVerify mocks base method. func (m *MockFullNode) WalletVerify(arg0 context.Context, arg1 address.Address, arg2 []byte, arg3 *crypto.Signature) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WalletVerify", arg0, arg1, arg2, arg3) @@ -3057,7 +3057,7 @@ func (m *MockFullNode) WalletVerify(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// WalletVerify indicates an expected call of WalletVerify +// WalletVerify indicates an expected call of WalletVerify. func (mr *MockFullNodeMockRecorder) WalletVerify(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletVerify", reflect.TypeOf((*MockFullNode)(nil).WalletVerify), arg0, arg1, arg2, arg3) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 42786c08181eac5d8fe084ae59707f7c48acf9e4..4490109e9a86b60056fa644e8a120a5908e8ed69 100644 GIT binary patch delta 22669 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 z%0D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 diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index ad9ccd6c73409d47c68017e2aaae7965b76c57bd..1d8ff7579b9810276be694c1bf01a4af2374c10b 100644 GIT binary patch literal 8088 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 literal 8089 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 diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 13b0c1e156cd46a923264efbeca28a822c9fbafd..3c4fa4f701624af1b7af35092668b932227e41b9 100644 GIT binary patch literal 2497 zcmV;y2|o58iwFP!00000|Li?&bDKKWe?_C`OLK?#J-)5K^>OxgGt(Dua=ZP|WHvG! z+iF1KN+OAy@qgbD!ZsL)f!cQ+hsjJ5gwD~Cbl!DCA6uBR3CDvc ztf+DU5Aa8>0*Nk1L-c-hfh~LwLQ>8`h<3ZtI(6V4FD&eVnsG) zvc`MI8BwqSTi5|<3+gL_;`a7-%CFfZU^aRq(Qn_lxC3#eL}05Ev;=$Ow~)=5f=AUD zn!gtE+ej)d$P^k^U@I;zVPYY_gTCL8F>QQhK5-l{2(IW)u#n$Hd3Sm%T<1iQ6ZA%3 z(h0GlF(j^gac&_Hf{PRMbj_}n02K&^WaEM<5RABu7^#{xO^6;)qdvK2i)(g!dy6eB z1J5I3jt6)>fSI!%MqV>)VV?-%nI#B>UdHkK)aR0hOBUTuEVJKEt!rv!5@YKNdj=lS z`wWl7^Ib3)FV1z-C(1zJLA%vzS@?6{jrG;Lg@s3g^U0rcAMoJq;>N(m zfWHDNz`+A00??b`3$TgOE#c%A)_S)(sol!q*g|{80@uBT+z~sqL@_WONu6-5Jfk- zlMGy?aYwXms;Ep#H#!v20Y+y$s|U0&1bAElaw)sR77m1q2Y9BG zF9*%$H0;u_x!0UTX8zO{T+`Kbwad^PyL{aAh*Th&#HUSP@W=Uorob9g{(m34y>~4= zr?j*14@Sl=I3<0B2r9!>I6-g5oV(jB_!>dB!7gE$v!qp%keX7|xLqps-o~_zgB@W>Ir5*8JWMm;DoWpn|)&B)6Ea zSUZKU&?(Gg&;5B!J8+lMUSC>}3UM8lKwQeEI7XCIB5c`>50?_-Vsv@@9x4-6yK%J} zcVuqdS*xF8#VI2${Rz=tlr-lF;IjFjW&0&z(@NHPbM&Q|uFdm7h|nRJ=M65ama8eT zv|lC@398uIhKZGm3sW)kQ(Ly$vK^acYxlA(+Xb8OlJ-o4WTz%J&jEDLZT2a`wwF9b z7Cp}hZlY5W;r%C>S5^WTT?KdosOB}IEp+0&AhOi=%_aW-J(k&?(Hg!Q_jfxDB zShj)yX3=YP&^_yPvem&Seh*j17bvL}VvxH@T~+XPlQh(h?m=19LvVCoP9CcEL2DoM z*o;m$=a6hf)J&E%Hz7>67iywekd4R`=&su=#}eIM+|Vq7a$@jQr~L-vL&B~g^0*A| zEl=YXR(MmBlzrC-ZpyFw$Zg_=v}fJ@26Q?r6!`BjoIhA`$T>0`32uXwS0JTfu2OQ5 z0L~VWAfQg;>(}l6R0>(Pco;yfqy=FP_mIYo_yj$Kq#fpj0F zGwaX0q}x~HuDk=!|G^*s@`E||{2ya)0`p0?H=*5N-VXxkb?$q{#oi^plB#k&c)9(I zFGCr~U3x)vyjRD2FWIU6J?ETj?a!sncTuOdQ@*%Dw?=N{mq7iJAKIyNn1?1jhv0jr zx$NcnW3?fw4bjmVqMQ?Etov4 z6;5U?EIq6nh6)`~?BKeCO8dW5t}T_Mb%F zog0N!k_}^!xhx38)mlu3!ZDFfEQfn>m*~ z(CKy1YIOmb2aA6>{MtfzYL&M4FOrg3^19}nCA$xv!iqniD7`47L`I_V+tw7uaVHo0 zy`0#~R4-QfJVy+&>g#Kk-vjvnxq=Jkz~h#$bYvcepCOw%jUja^WXzLusGk?8Q|E0UD;XN@G|?B-#B`kmeNK~sIuWPHK1oXlh-%O(B5 z2r4_SS*eHT{jfETy}V8;Z({5AJ=wf&yW4qN+3FoC`{ZO3zY(hb6;Mzm8E6HU$wJR& zX5ygPoU`hI#xA$-Bnp_KE>bfPfQSIZ%vp;>B48{$q4`B-dv&RjejhIuH;exU00960 L(#d+JPI3SMs8`^6 literal 2580 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 diff --git a/node/test/builder.go b/node/test/builder.go index 6b0b9aa96..080feda13 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -521,9 +521,14 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes } fulls[i].Stb = storageBuilder(fulls[i], mn, node.Options( - node.Override(new(sectorstorage.SectorManager), func() (sectorstorage.SectorManager, error) { + node.Override(new(*mock.SectorMgr), func() (*mock.SectorMgr, error) { return mock.NewMockSectorMgr(nil), nil }), + + node.Override(new(sectorstorage.SectorManager), node.From(new(*mock.SectorMgr))), + node.Override(new(sectorstorage.Unsealer), node.From(new(*mock.SectorMgr))), + node.Override(new(sectorstorage.PieceProvider), node.From(new(*mock.SectorMgr))), + node.Override(new(ffiwrapper.Verifier), mock.MockVerifier), node.Override(new(ffiwrapper.Prover), mock.MockProver), node.Unset(new(*sectorstorage.Manager)), @@ -564,9 +569,14 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes opts = node.Options() } storers[i] = CreateTestStorageNode(ctx, t, genms[i].Worker, maddrs[i], pidKeys[i], f, mn, node.Options( - node.Override(new(sectorstorage.SectorManager), func() (sectorstorage.SectorManager, error) { + node.Override(new(*mock.SectorMgr), func() (*mock.SectorMgr, error) { return mock.NewMockSectorMgr(sectors), nil }), + + node.Override(new(sectorstorage.SectorManager), node.From(new(*mock.SectorMgr))), + node.Override(new(sectorstorage.Unsealer), node.From(new(*mock.SectorMgr))), + node.Override(new(sectorstorage.PieceProvider), node.From(new(*mock.SectorMgr))), + node.Override(new(ffiwrapper.Verifier), mock.MockVerifier), node.Override(new(ffiwrapper.Prover), mock.MockProver), node.Unset(new(*sectorstorage.Manager)), From 1a90d3bbb52c57f97d14f5c4e04f5cd976a47595 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 7 Jun 2021 16:12:39 +0530 Subject: [PATCH 60/66] update ffi --- extern/filecoin-ffi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index dc4e4e8dc..8b97bd823 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit dc4e4e8dc9554dedb6f48304f7f0c6328331f9ec +Subproject commit 8b97bd8230b77bd32f4f27e4766a6d8a03b4e801 From ddd9bf610ef041536dd54b8a44af403f621e84d4 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 7 Jun 2021 16:45:52 +0530 Subject: [PATCH 61/66] fix CI --- api/test/deals.go | 2 +- extern/sector-storage/mock/mock.go | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/api/test/deals.go b/api/test/deals.go index 69870beb6..6e49a7ed5 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -441,7 +441,7 @@ func TestOfflineDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, st require.Eventually(t, func() bool { cd, _ := s.client.ClientGetDealInfo(s.ctx, *proposalCid) return cd.State == storagemarket.StorageDealCheckForAcceptance - }, 1*time.Second, 100*time.Millisecond, "actual deal status is %s", storagemarket.DealStates[cd.State]) + }, 30*time.Second, 1*time.Second, "actual deal status is %s", storagemarket.DealStates[cd.State]) // Create a CAR file from the raw file carFileDir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-car") diff --git a/extern/sector-storage/mock/mock.go b/extern/sector-storage/mock/mock.go index 977960c8f..1d8a317f1 100644 --- a/extern/sector-storage/mock/mock.go +++ b/extern/sector-storage/mock/mock.go @@ -6,6 +6,7 @@ import ( "crypto/sha256" "fmt" "io" + "io/ioutil" "math/rand" "sync" @@ -375,13 +376,12 @@ func generateFakePoSt(sectorInfo []proof5.SectorInfo, rpt func(abi.RegisteredSea } } -func (mgr *SectorMgr) ReadPiece(ctx context.Context, w io.Writer, sectorID storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, c cid.Cid) error { +func (mgr *SectorMgr) ReadPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) (io.ReadCloser, bool, error) { if offset != 0 { panic("implme") } - _, err := io.CopyN(w, bytes.NewReader(mgr.pieces[mgr.sectors[sectorID.ID].pieces[0]]), int64(size)) - return err + return ioutil.NopCloser(bytes.NewReader(mgr.pieces[mgr.sectors[sector.ID].pieces[0]][:size])), false, nil } func (mgr *SectorMgr) StageFakeData(mid abi.ActorID, spt abi.RegisteredSealProof) (storage.SectorRef, []abi.PieceInfo, error) { @@ -492,6 +492,10 @@ func (mgr *SectorMgr) ReturnFetch(ctx context.Context, callID storiface.CallID, panic("not supported") } +func (mgr *SectorMgr) SectorsUnsealPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, commd *cid.Cid) error { + return nil +} + func (m mockVerifProver) VerifySeal(svi proof5.SealVerifyInfo) (bool, error) { plen, err := svi.SealProof.ProofSize() if err != nil { From 7124cd5149fd27742e1b6a6865b8eddfb05e9f09 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 7 Jun 2021 19:33:16 +0530 Subject: [PATCH 62/66] fix lotus soup build --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b0f8120f3..f0580bfc8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -331,7 +331,7 @@ jobs: - run: cd extern/filecoin-ffi && make - run: name: "go get lotus@master" - command: cd testplans/lotus-soup && go mod edit -replace=github.com/filecoin-project/lotus=../.. + command: cd testplans/lotus-soup && go mod edit -replace=github.com/filecoin-project/lotus=../.. && go mod tidy - run: name: "build lotus-soup testplan" command: pushd testplans/lotus-soup && go build -tags=testground . From 8625da34794c8770956770d5072c7c96910eedfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 7 Jun 2021 16:57:24 +0200 Subject: [PATCH 63/66] Bump miner/worker api versions --- api/version.go | 4 ++-- node/impl/remoteworker.go | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/api/version.go b/api/version.go index 743170f04..e8011204d 100644 --- a/api/version.go +++ b/api/version.go @@ -57,8 +57,8 @@ var ( FullAPIVersion0 = newVer(1, 3, 0) FullAPIVersion1 = newVer(2, 1, 0) - MinerAPIVersion0 = newVer(1, 0, 1) - WorkerAPIVersion0 = newVer(1, 0, 0) + MinerAPIVersion0 = newVer(1, 1, 0) + WorkerAPIVersion0 = newVer(1, 1, 0) ) //nolint:varcheck,deadcode diff --git a/node/impl/remoteworker.go b/node/impl/remoteworker.go index 8dc7510b4..d27b3baff 100644 --- a/node/impl/remoteworker.go +++ b/node/impl/remoteworker.go @@ -38,6 +38,16 @@ func connectRemoteWorker(ctx context.Context, fa api.Common, url string) (*remot return nil, xerrors.Errorf("creating jsonrpc client: %w", err) } + wver, err := wapi.Version(ctx) + if err != nil { + closer() + return nil, err + } + + if !wver.EqMajorMinor(api.WorkerAPIVersion0) { + return nil, xerrors.Errorf("unsupported worker api version: %s (expected %s)", wver, api.WorkerAPIVersion0) + } + return &remoteWorker{wapi, closer}, nil } From f9acd07987c5d5be49475036012e2de68420be0f Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Mon, 7 Jun 2021 18:51:48 +0200 Subject: [PATCH 64/66] Update libp2p to 0.14.1 This does not resolve the CI issue but prepares us for it after https://github.com/libp2p/go-libp2p/pull/1116 Signed-off-by: Jakub Sztandera --- go.mod | 32 ++++---- go.sum | 153 +++++++++++++++++++++++++------------ node/impl/common/common.go | 2 +- 3 files changed, 120 insertions(+), 67 deletions(-) diff --git a/go.mod b/go.mod index f21b6760a..39af14658 100644 --- a/go.mod +++ b/go.mod @@ -89,7 +89,7 @@ require ( github.com/ipfs/go-ipfs-util v0.0.2 github.com/ipfs/go-ipld-cbor v0.0.5 github.com/ipfs/go-ipld-format v0.2.0 - github.com/ipfs/go-log/v2 v2.1.2 + github.com/ipfs/go-log/v2 v2.1.3 github.com/ipfs/go-merkledag v0.3.2 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 @@ -102,21 +102,21 @@ require ( github.com/lib/pq v1.7.0 github.com/libp2p/go-buffer-pool v0.0.2 github.com/libp2p/go-eventbus v0.2.1 - github.com/libp2p/go-libp2p v0.12.0 + github.com/libp2p/go-libp2p v0.14.1 github.com/libp2p/go-libp2p-connmgr v0.2.4 - github.com/libp2p/go-libp2p-core v0.7.0 + github.com/libp2p/go-libp2p-core v0.8.5 github.com/libp2p/go-libp2p-discovery v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.11.0 - github.com/libp2p/go-libp2p-mplex v0.3.0 - github.com/libp2p/go-libp2p-noise v0.1.2 - github.com/libp2p/go-libp2p-peerstore v0.2.6 + github.com/libp2p/go-libp2p-mplex v0.4.1 + github.com/libp2p/go-libp2p-noise v0.2.0 + github.com/libp2p/go-libp2p-peerstore v0.2.7 github.com/libp2p/go-libp2p-pubsub v0.4.2-0.20210212194758-6c1addf493eb - github.com/libp2p/go-libp2p-quic-transport v0.9.0 + github.com/libp2p/go-libp2p-quic-transport v0.10.0 github.com/libp2p/go-libp2p-record v0.1.3 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 - github.com/libp2p/go-libp2p-swarm v0.3.1 + github.com/libp2p/go-libp2p-swarm v0.5.0 github.com/libp2p/go-libp2p-tls v0.1.3 - github.com/libp2p/go-libp2p-yamux v0.4.1 + github.com/libp2p/go-libp2p-yamux v0.5.4 github.com/libp2p/go-maddr-filter v0.1.0 github.com/mattn/go-colorable v0.1.6 // indirect github.com/mattn/go-isatty v0.0.12 @@ -124,10 +124,9 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-base32 v0.0.3 github.com/multiformats/go-multiaddr v0.3.1 - github.com/multiformats/go-multiaddr-dns v0.2.0 + github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.0.3 github.com/multiformats/go-multihash v0.0.14 - github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333 github.com/opentracing/opentracing-go v1.2.0 github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a @@ -145,18 +144,17 @@ require ( github.com/whyrusleeping/pubsub v0.0.0-20190708150250-92bcb0691325 github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 go.etcd.io/bbolt v1.3.4 - go.opencensus.io v0.22.5 + go.opencensus.io v0.23.0 go.uber.org/dig v1.10.0 // indirect go.uber.org/fx v1.9.0 go.uber.org/multierr v1.6.0 go.uber.org/zap v1.16.0 - golang.org/x/net v0.0.0-20201022231255-08b38378de70 - golang.org/x/sync v0.0.0-20201207232520-09787c993a3a - golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 + golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6 + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c + golang.org/x/sys v0.0.0-20210426080607-c94f62235c83 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 - golang.org/x/tools v0.0.0-20201112185108-eeaa07dd7696 + golang.org/x/tools v0.0.0-20210106214847-113979e3529a golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 - gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 gotest.tools v2.2.0+incompatible honnef.co/go/tools v0.0.1-2020.1.3 // indirect diff --git a/go.sum b/go.sum index 63998058c..a9a57ec6b 100644 --- a/go.sum +++ b/go.sum @@ -107,14 +107,18 @@ github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dm github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= +github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129 h1:gfAMKE626QEuKG3si0pdTRcr/YEbBoxY+3GOH3gWvl4= @@ -186,8 +190,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= -github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f h1:BOaYiTvg8p9vBUXpklC22XSK/mifLF7lG9jtmYYi3Tc= github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e h1:lj77EKYUpYXTd8CD/+QMIf8b6OIOTsfEBSXiAzuEHTU= github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e/go.mod h1:3ZQK6DMPSz/QZ73jlWxBtUhNA8xZx7LzUFSq/OfP8vk= github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= @@ -332,8 +338,9 @@ github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/g github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg= github.com/filecoin-project/test-vectors/schema v0.0.5/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= +github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= +github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -398,8 +405,9 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/status v1.0.3/go.mod h1:SavQ51ycCLnc7dGyJxp8YAmudx8xqiVrRf+6IXRsugc= github.com/gogo/status v1.1.0 h1:+eIkrewn5q6b30y+g/BJINVVdi2xH7je5MPJ3ZPK3JA= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= @@ -430,8 +438,9 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf h1:gFVkHXmVAhEbxZVDln5V9GKrLaluNoFHDbrZwAWZgws= @@ -443,14 +452,16 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= -github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY= github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -691,8 +702,9 @@ github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscw github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= -github.com/ipfs/go-log/v2 v2.1.2 h1:a0dRiL098zY23vay1h3dimx6y94XchEUyt5h0l4VvQU= github.com/ipfs/go-log/v2 v2.1.2/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= +github.com/ipfs/go-log/v2 v2.1.3 h1:1iS3IU7aXRlbgUpN8yTTpJ53NXYjAe37vcI5+5nYrzk= +github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= @@ -793,6 +805,7 @@ github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391 h1:51kHw7l/dUDdOdW github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391/go.mod h1:XXfR6YFCRSrkEXbNlIyDsgXVNJWVUV30m/ebkVy9n6s= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -823,8 +836,9 @@ github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40J github.com/libp2p/go-conn-security-multistream v0.0.1/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= -github.com/libp2p/go-conn-security-multistream v0.2.0 h1:uNiDjS58vrvJTg9jO6bySd1rMKejieG7v45ekqHbZ1M= github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= +github.com/libp2p/go-conn-security-multistream v0.2.1 h1:ft6/POSK7F+vl/2qzegnHDaXFU0iWB4yVTYrioC6Zy0= +github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= github.com/libp2p/go-eventbus v0.0.2/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk= github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc= @@ -847,8 +861,9 @@ github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qD github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM= github.com/libp2p/go-libp2p v0.9.2/go.mod h1:cunHNLDVus66Ct9iXXcjKRLdmHdFdHVe1TAnbubJQqQ= github.com/libp2p/go-libp2p v0.10.0/go.mod h1:yBJNpb+mGJdgrwbKAKrhPU0u3ogyNFTfjJ6bdM+Q/G8= -github.com/libp2p/go-libp2p v0.12.0 h1:+xai9RQnQ9l5elFOKvp5wRyjyWisSwEx+6nU2+onpUA= github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g/nT9PgQM0= +github.com/libp2p/go-libp2p v0.14.1 h1:R0vNY7nkU8IISlDuHd2yk4eNAZsVQ0rCr2bPfWU3sXo= +github.com/libp2p/go-libp2p v0.14.1/go.mod h1:0PQMADQEjCM2l8cSMYDpTgsb8gr6Zq7i4LUgq1mlW2E= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 h1:BM7aaOF7RpmNn9+9g6uTjGJ0cTzWr5j9i9IKeun2M8U= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo= github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= @@ -859,8 +874,9 @@ github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQ github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= github.com/libp2p/go-libp2p-autonat v0.2.3/go.mod h1:2U6bNWCNsAG9LEbwccBDQbjzQ8Krdjge1jLTE9rdoMM= -github.com/libp2p/go-libp2p-autonat v0.4.0 h1:3y8XQbpr+ssX8QfZUHekjHCYK64sj6/4hnf/awD4+Ug= github.com/libp2p/go-libp2p-autonat v0.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= +github.com/libp2p/go-libp2p-autonat v0.4.2 h1:YMp7StMi2dof+baaxkbxaizXjY1RPvU71CXfxExzcUU= +github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6PBL9MlV/xumymRFkKq5A= github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= @@ -907,8 +923,12 @@ github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.7.0 h1:4a0TMjrWNTZlNvcqxZmrMRDi/NQWrhwO2pkTuLSQ/IQ= github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.5 h1:aEgbIcPGsKy6zYcC+5AJivYFedhYa4sW7mIpWpUaLKw= +github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= @@ -943,8 +963,10 @@ github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3 github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw5oadDq7+L/FELo= github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= -github.com/libp2p/go-libp2p-mplex v0.3.0 h1:CZyqqKP0BSGQyPLvpRQougbfXaaaJZdGgzhCpJNuNSk= github.com/libp2p/go-libp2p-mplex v0.3.0/go.mod h1:l9QWxRbbb5/hQMECEb908GbS9Sm2UAR2KFZKUJEynEs= +github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= +github.com/libp2p/go-libp2p-mplex v0.4.1 h1:/pyhkP1nLwjG3OM+VuaNJkQT/Pqq73WzB3aDN3Fx1sc= +github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= github.com/libp2p/go-libp2p-nat v0.0.2/go.mod h1:QrjXQSD5Dj4IJOdEcjHRkWTSomyxRo6HnUkf/TfQpLQ= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz1ChgiN79yKPE= @@ -956,8 +978,8 @@ github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFx github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= github.com/libp2p/go-libp2p-noise v0.1.1/go.mod h1:QDFLdKX7nluB7DEnlVPbz7xlLHdwHFA9HiohJRr3vwM= -github.com/libp2p/go-libp2p-noise v0.1.2 h1:IH9GRihQJTx56obm+GnpdPX4KeVIlvpXrP6xnJ0wxWk= -github.com/libp2p/go-libp2p-noise v0.1.2/go.mod h1:9B10b7ueo7TIxZHHcjcDCo5Hd6kfKT2m77by82SFRfE= +github.com/libp2p/go-libp2p-noise v0.2.0 h1:wmk5nhB9a2w2RxMOyvsoKjizgJOEaJdfAakr0jN8gds= +github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= @@ -972,8 +994,9 @@ github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRj github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= github.com/libp2p/go-libp2p-peerstore v0.2.3/go.mod h1:K8ljLdFn590GMttg/luh4caB/3g0vKuY01psze0upRw= github.com/libp2p/go-libp2p-peerstore v0.2.4/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= -github.com/libp2p/go-libp2p-peerstore v0.2.6 h1:2ACefBX23iMdJU9Ke+dcXt3w86MIryes9v7In4+Qq3U= github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= +github.com/libp2p/go-libp2p-peerstore v0.2.7 h1:83JoLxyR9OYTnNfB5vvFqvMUv/xDNa6NoPHnENhBsGw= +github.com/libp2p/go-libp2p-peerstore v0.2.7/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= @@ -984,8 +1007,8 @@ github.com/libp2p/go-libp2p-pubsub v0.4.2-0.20210212194758-6c1addf493eb h1:HExLc github.com/libp2p/go-libp2p-pubsub v0.4.2-0.20210212194758-6c1addf493eb/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= github.com/libp2p/go-libp2p-quic-transport v0.5.0/go.mod h1:IEcuC5MLxvZ5KuHKjRu+dr3LjCT1Be3rcD/4d8JrX8M= -github.com/libp2p/go-libp2p-quic-transport v0.9.0 h1:WPuq5nV/chmIZIzvrkC2ulSdAQ0P0BDvgvAhZFOZ59E= -github.com/libp2p/go-libp2p-quic-transport v0.9.0/go.mod h1:xyY+IgxL0qsW7Kiutab0+NlxM0/p9yRtrGTYsuMWf70= +github.com/libp2p/go-libp2p-quic-transport v0.10.0 h1:koDCbWD9CCHwcHZL3/WEvP2A+e/o5/W5L3QS/2SPMA0= +github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.1.1/go.mod h1:VRgKajOyMVgP/F0L5g3kH7SVskp17vFi2xheb5uMJtg= @@ -1012,8 +1035,9 @@ github.com/libp2p/go-libp2p-swarm v0.2.4/go.mod h1:/xIpHFPPh3wmSthtxdGbkHZ0OET1h github.com/libp2p/go-libp2p-swarm v0.2.7/go.mod h1:ZSJ0Q+oq/B1JgfPHJAT2HTall+xYRNYp1xs4S2FBWKA= github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM= github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= -github.com/libp2p/go-libp2p-swarm v0.3.1 h1:UTobu+oQHGdXTOGpZ4RefuVqYoJXcT0EBtSR74m2LkI= github.com/libp2p/go-libp2p-swarm v0.3.1/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= +github.com/libp2p/go-libp2p-swarm v0.5.0 h1:HIK0z3Eqoo8ugmN8YqWAhD2RORgR+3iNXYG4U2PFd1E= +github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= @@ -1021,8 +1045,9 @@ github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MB github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= -github.com/libp2p/go-libp2p-testing v0.3.0 h1:ZiBYstPamsi7y6NJZebRudUzsYmVkt998hltyLqf8+g= github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= +github.com/libp2p/go-libp2p-testing v0.4.0 h1:PrwHRi0IGqOwVQWR3xzgigSlhlLfxgfXgkHxr77EghQ= +github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= @@ -1032,8 +1057,9 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.0.1/go.mod h1:NJpUAgQab/8K6K0m github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= -github.com/libp2p/go-libp2p-transport-upgrader v0.3.0 h1:q3ULhsknEQ34eVDhv4YwKS8iet69ffs9+Fir6a7weN4= github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.2 h1:4JsnbfJzgZeRS9AWN7B9dPqn/LY/HoQTlO9gtdJTIYM= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= @@ -1043,8 +1069,9 @@ github.com/libp2p/go-libp2p-yamux v0.2.5/go.mod h1:Zpgj6arbyQrmZ3wxSZxfBmbdnWtbZ github.com/libp2p/go-libp2p-yamux v0.2.7/go.mod h1:X28ENrBMU/nm4I3Nx4sZ4dgjZ6VhLEn0XhIoZ5viCwU= github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= -github.com/libp2p/go-libp2p-yamux v0.4.1 h1:TJxRVPY9SjH7TNrNC80l1OJMBiWhs1qpKmeB+1Ug3xU= -github.com/libp2p/go-libp2p-yamux v0.4.1/go.mod h1:FA/NjRYRVNjqOzpGuGqcruH7jAU2mYIjtKBicVOL3dc= +github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= +github.com/libp2p/go-libp2p-yamux v0.5.4 h1:/UOPtT/6DHPtr3TtKXBHa6g0Le0szYuI33Xc/Xpd7fQ= +github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= @@ -1056,8 +1083,9 @@ github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTW github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= github.com/libp2p/go-mplex v0.1.1/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= -github.com/libp2p/go-mplex v0.2.0 h1:Ov/D+8oBlbRkjBs1R1Iua8hJ8cUfbdiW8EOdZuxcgaI= github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= +github.com/libp2p/go-mplex v0.3.0 h1:U1T+vmCYJaEoDJPV1aq31N56hS+lJgb397GsylNSgrU= +github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= github.com/libp2p/go-msgio v0.0.1/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= @@ -1069,8 +1097,9 @@ github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/ github.com/libp2p/go-nat v0.0.5 h1:qxnwkco8RLKqVh1NmjQ+tJ8p8khNLFxuElYG/TwqW4Q= github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= -github.com/libp2p/go-netroute v0.1.3 h1:1ngWRx61us/EpaKkdqkMjKk/ufr/JlIFYQAxV2XX8Ig= github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.6 h1:ruPJStbYyXVYGQ81uzEDzuvbYRLKRrLvTYd33yomC38= +github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= @@ -1086,8 +1115,9 @@ github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2 github.com/libp2p/go-reuseport-transport v0.0.4 h1:OZGz0RB620QDGpv300n1zaOcKGGAoGVf8h9txtt/1uM= github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-sockaddr v0.1.0 h1:Y4s3/jNoryVRKEBrkJ576F17CPOaMIzUeCsg7dlTDj0= github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-sockaddr v0.1.1 h1:yD80l2ZOdGksnOyHrhxDdTDFrf7Oy+v3FMVArIRgZxQ= +github.com/libp2p/go-sockaddr v0.1.1/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= @@ -1109,8 +1139,9 @@ github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y= github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= github.com/libp2p/go-ws-transport v0.3.0/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= -github.com/libp2p/go-ws-transport v0.3.1 h1:ZX5rWB8nhRRJVaPO6tmkGI/Xx8XNboYX20PW5hXIscw= github.com/libp2p/go-ws-transport v0.3.1/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= +github.com/libp2p/go-ws-transport v0.4.0 h1:9tvtQ9xbws6cA5LvqdE6Ne3vcmGB4f1z9SByggk4s0k= +github.com/libp2p/go-ws-transport v0.4.0/go.mod h1:EcIEKqf/7GDjth6ksuS/6p7R49V4CBY6/E7R/iyhYUA= github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= @@ -1122,12 +1153,14 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux/v2 v2.2.0 h1:RwtpYZ2/wVviZ5+3pjC8qdQ4TKnrak0/E01N1UWoAFU= +github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= github.com/lucas-clemente/quic-go v0.16.0/go.mod h1:I0+fcNTdb9eS1ZcjQZbDVPGchJ86chcIxPALn9lEJqE= -github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys= -github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= +github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= +github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lufia/iostat v1.1.0/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg= @@ -1142,13 +1175,13 @@ github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7 github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI= -github.com/marten-seemann/qpack v0.2.0/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= +github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= github.com/marten-seemann/qtls v0.9.1/go.mod h1:T1MmAdDPyISzxlK6kjRr0pcZFBVd1OZbBb/j3cvzHhk= github.com/marten-seemann/qtls v0.10.0 h1:ECsuYUKalRL240rRD4Ri33ISb7kAQ3qGDlrrl55b2pc= github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= -github.com/marten-seemann/qtls-go1-15 v0.1.0 h1:i/YPXVxz8q9umso/5y474CNcHmTpA+5DH+mFPjx6PZg= -github.com/marten-seemann/qtls-go1-15 v0.1.0/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-15 v0.1.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ= +github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1182,6 +1215,8 @@ github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nr github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= @@ -1228,8 +1263,9 @@ github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/94 github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.1.0/go.mod h1:01k2RAqtoXIuPa3DCavAE9/6jc6nM0H3EgZyfUhN2oY= -github.com/multiformats/go-multiaddr-dns v0.2.0 h1:YWJoIDwLePniH7OU5hBnDZV6SWuvJqJ0YtN6pLeH9zA= github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= +github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= +github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= @@ -1259,8 +1295,10 @@ github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wS github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= -github.com/multiformats/go-multistream v0.2.0 h1:6AuNmQVKUkRnddw2YiDjt5Elit40SFxMJkVnhmETXtU= github.com/multiformats/go-multistream v0.2.0/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-multistream v0.2.2 h1:TCYu1BHTDr1F/Qm75qwYISQdzGcRdC21nFgQW7l7GBo= +github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -1277,8 +1315,6 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy8ALwOebjekYExl9HTT9urdawqC95tA= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= @@ -1296,6 +1332,7 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -1580,6 +1617,7 @@ github.com/xorcare/golden v0.6.0/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/ github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 h1:oWgZJmC1DorFZDpfMfWg7xk29yEOZiXmo/wZl+utTI8= github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/U6FtvQ= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= @@ -1607,8 +1645,8 @@ go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1661,16 +1699,19 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1693,8 +1734,9 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1705,6 +1747,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1740,6 +1783,7 @@ golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1747,8 +1791,11 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201022231255-08b38378de70 h1:Z6x4N9mAi4oF0TbHweCsH618MO6OI6UFgV0FP5n0wBY= golang.org/x/net v0.0.0-20201022231255-08b38378de70/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6 h1:0PC75Fz/kyMGhL0e1QnypqK2kQMqKt9csD1GnMJR+Zk= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1766,8 +1813,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1834,16 +1881,21 @@ golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200812155832-6a926be9bd1d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426080607-c94f62235c83 h1:kHSDPqCtsHZOg0nVylfTo20DDhE9gG4Y0jn7hKQ0QAM= +golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1887,10 +1939,12 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200711155855-7342f9734a7d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201112185108-eeaa07dd7696 h1:Bfazo+enXJET5SbHeh95NtxabJF6fJ9r/jpfRJgd3j4= golang.org/x/tools v0.0.0-20201112185108-eeaa07dd7696/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1958,8 +2012,9 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1975,8 +2030,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= diff --git a/node/impl/common/common.go b/node/impl/common/common.go index 7d99fb42a..f1c57665c 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -156,7 +156,7 @@ func (a *CommonAPI) NetFindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, } func (a *CommonAPI) NetAutoNatStatus(ctx context.Context) (i api.NatInfo, err error) { - autonat := a.RawHost.(*basichost.BasicHost).AutoNat + autonat := a.RawHost.(*basichost.BasicHost).GetAutoNat() if autonat == nil { return api.NatInfo{ From 5ef5680b9816d57420467bb2f5c37695823a6399 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 7 Jun 2021 12:14:01 -0700 Subject: [PATCH 65/66] chore: update to go-libp2p v0.14.2 This should fix test flakes due to a race in the go-libp2p mock network. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 39af14658..e22be541a 100644 --- a/go.mod +++ b/go.mod @@ -102,7 +102,7 @@ require ( github.com/lib/pq v1.7.0 github.com/libp2p/go-buffer-pool v0.0.2 github.com/libp2p/go-eventbus v0.2.1 - github.com/libp2p/go-libp2p v0.14.1 + github.com/libp2p/go-libp2p v0.14.2 github.com/libp2p/go-libp2p-connmgr v0.2.4 github.com/libp2p/go-libp2p-core v0.8.5 github.com/libp2p/go-libp2p-discovery v0.5.0 diff --git a/go.sum b/go.sum index a9a57ec6b..9ad58a702 100644 --- a/go.sum +++ b/go.sum @@ -862,8 +862,8 @@ github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El github.com/libp2p/go-libp2p v0.9.2/go.mod h1:cunHNLDVus66Ct9iXXcjKRLdmHdFdHVe1TAnbubJQqQ= github.com/libp2p/go-libp2p v0.10.0/go.mod h1:yBJNpb+mGJdgrwbKAKrhPU0u3ogyNFTfjJ6bdM+Q/G8= github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g/nT9PgQM0= -github.com/libp2p/go-libp2p v0.14.1 h1:R0vNY7nkU8IISlDuHd2yk4eNAZsVQ0rCr2bPfWU3sXo= -github.com/libp2p/go-libp2p v0.14.1/go.mod h1:0PQMADQEjCM2l8cSMYDpTgsb8gr6Zq7i4LUgq1mlW2E= +github.com/libp2p/go-libp2p v0.14.2 h1:qs0ABtjjNjS+RIXT1uM7sMJEvIc0pq2nKR0VQxFXhHI= +github.com/libp2p/go-libp2p v0.14.2/go.mod h1:0PQMADQEjCM2l8cSMYDpTgsb8gr6Zq7i4LUgq1mlW2E= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 h1:BM7aaOF7RpmNn9+9g6uTjGJ0cTzWr5j9i9IKeun2M8U= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo= github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= From 4aecb839329b94ecac7d77b8db028ea1c9359f59 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 7 Jun 2021 12:17:05 -0700 Subject: [PATCH 66/66] chore: update docs for new libp2p version --- documentation/en/api-v0-methods-miner.md | 12 ++++++------ documentation/en/api-v0-methods.md | 12 ++++++------ documentation/en/api-v1-unstable-methods.md | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index 53d485815..388213666 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -889,8 +889,8 @@ Inputs: `null` Response: ```json { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ``` @@ -1039,8 +1039,8 @@ Inputs: ```json [ { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ] ``` @@ -1090,8 +1090,8 @@ Inputs: Response: ```json { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ``` diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index 7d27a1228..f6da2244c 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -2841,8 +2841,8 @@ Inputs: `null` Response: ```json { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ``` @@ -2991,8 +2991,8 @@ Inputs: ```json [ { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ] ``` @@ -3042,8 +3042,8 @@ Inputs: Response: ```json { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ``` diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 89f62f456..761950829 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -3068,8 +3068,8 @@ Inputs: `null` Response: ```json { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ``` @@ -3218,8 +3218,8 @@ Inputs: ```json [ { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ] ``` @@ -3269,8 +3269,8 @@ Inputs: Response: ```json { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ```