From 7fddbb528dff3aa540ca37b27951e2667ec44e36 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Mon, 5 Apr 2021 13:11:10 +0200 Subject: [PATCH 01/80] Introduce stateless offline dealflow, bypassing the FSM/deallists This is aproposal for an additional flag --manual-stateless-deal and a corresponding API endpoint ClientStatelessDeal. This allows firing off an offline-style deal against a miner without keeping further track of it locally. Not keeping any local state introduces the limitation of requiring free storage deals, as there is nothing to tie the payment channel setup to. Rationale/need for this type of flow is the case of incredibly large sets of data nd deals, where the client and providers have prearranged payment ahead of time, and the client has a separate-from-lotus database of deal inventory. This way the client can use their lotus node merely as a network gateway, without running into any limitations currently present in both lotus as a whole and go-fil-markets in particular. Specific context for this work is filecoin-discover, where the requirement is to onboard ~ 12,000,000 individual deals against a pool of miners with whom the client has prearranged a relationship. --- api/api_full.go | 2 + api/apistruct/struct.go | 5 ++ cli/client.go | 19 ++++- node/impl/client/client.go | 140 ++++++++++++++++++++++++++++++++----- 4 files changed, 145 insertions(+), 21 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index ca3a02c74..3ed28f429 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -289,6 +289,8 @@ type FullNode interface { ClientRemoveImport(ctx context.Context, importID multistore.StoreID) error // ClientStartDeal proposes a deal with a miner. ClientStartDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error) + // ClientStatelessDeal fire-and-forget-proposes an offline deal to a miner without subsequent tracking. + ClientStatelessDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error) // ClientGetDealInfo returns the latest information about a given deal. ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error) // ClientListDeals returns information about the deals made by the local client. diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 34b18cd41..fb08c24ee 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -163,6 +163,7 @@ type FullNodeStruct struct { ClientFindData func(ctx context.Context, root cid.Cid, piece *cid.Cid) ([]api.QueryOffer, error) `perm:"read"` ClientMinerQueryOffer func(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (api.QueryOffer, error) `perm:"read"` ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"` + ClientStatelessDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"write"` ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"` ClientGetDealStatus func(context.Context, uint64) (string, error) `perm:"read"` ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"` @@ -604,6 +605,10 @@ func (c *FullNodeStruct) ClientStartDeal(ctx context.Context, params *api.StartD return c.Internal.ClientStartDeal(ctx, params) } +func (c *FullNodeStruct) ClientStatelessDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) { + return c.Internal.ClientStatelessDeal(ctx, params) +} + func (c *FullNodeStruct) ClientGetDealInfo(ctx context.Context, deal cid.Cid) (*api.DealInfo, error) { return c.Internal.ClientGetDealInfo(ctx, deal) } diff --git a/cli/client.go b/cli/client.go index 98f4b0229..189d34882 100644 --- a/cli/client.go +++ b/cli/client.go @@ -311,6 +311,10 @@ var clientDealCmd = &cli.Command{ Name: "manual-piece-size", Usage: "if manually specifying piece cid, used to specify size (dataCid must be to a car file)", }, + &cli.BoolFlag{ + Name: "manual-stateless-deal", + Usage: "instructs the node to send an offline deal without registering it with the deallist/fsm", + }, &cli.StringFlag{ Name: "from", Usage: "specify address to fund the deal with", @@ -447,7 +451,7 @@ var clientDealCmd = &cli.Command{ isVerified = verifiedDealParam } - proposal, err := api.ClientStartDeal(ctx, &lapi.StartDealParams{ + sdParams := &lapi.StartDealParams{ Data: ref, Wallet: a, Miner: miner, @@ -457,7 +461,18 @@ var clientDealCmd = &cli.Command{ FastRetrieval: cctx.Bool("fast-retrieval"), VerifiedDeal: isVerified, ProviderCollateral: provCol, - }) + } + + var proposal *cid.Cid + if cctx.Bool("manual-stateless-deal") { + if ref.TransferType != storagemarket.TTManual { + return xerrors.New("when manual-stateless-deal is enabled, you must also provide a 'price' of 0 and specify 'manual-piece-cid' and 'manual-piece-size'") + } + proposal, err = api.ClientStatelessDeal(ctx, sdParams) + } else { + proposal, err = api.ClientStartDeal(ctx, sdParams) + } + if err != nil { return err } diff --git a/node/impl/client/client.go b/node/impl/client/client.go index ac526ac60..0576fcbf4 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -31,10 +31,12 @@ import ( "github.com/ipld/go-ipld-prime/traversal/selector/builder" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" + "github.com/multiformats/go-multibase" mh "github.com/multiformats/go-multihash" "go.uber.org/fx" "github.com/filecoin-project/go-address" + cborutil "github.com/filecoin-project/go-cbor-util" "github.com/filecoin-project/go-commp-utils/ffiwrapper" "github.com/filecoin-project/go-commp-utils/writer" datatransfer "github.com/filecoin-project/go-data-transfer" @@ -43,8 +45,10 @@ import ( rm "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/shared" "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/go-fil-markets/storagemarket/network" "github.com/filecoin-project/go-multistore" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/specs-actors/v3/actors/builtin/market" marketevents "github.com/filecoin-project/lotus/markets/loggers" @@ -97,8 +101,23 @@ func (a *API) imgr() *importmgr.Mgr { } func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) { + return a.dealStarter(ctx, params, false) +} + +func (a *API) ClientStatelessDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) { + return a.dealStarter(ctx, params, true) +} + +func (a *API) dealStarter(ctx context.Context, params *api.StartDealParams, isStateless bool) (*cid.Cid, error) { var storeID *multistore.StoreID - if params.Data.TransferType == storagemarket.TTGraphsync { + if isStateless { + if params.Data.TransferType != storagemarket.TTManual { + return nil, xerrors.Errorf("invalid transfer type %s for stateless storage deal", params.Data.TransferType) + } + if !params.EpochPrice.IsZero() { + return nil, xerrors.New("stateless storage deals can only be initiated with storage price of 0") + } + } else if params.Data.TransferType == storagemarket.TTGraphsync { importIDs := a.imgr().List() for _, importID := range importIDs { info, err := a.imgr().Info(importID) @@ -146,8 +165,6 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams) return nil, xerrors.New("data doesn't fit in a sector") } - providerInfo := utils.NewStorageProviderInfo(params.Miner, mi.Worker, mi.SectorSize, *mi.PeerId, mi.Multiaddrs) - dealStart := params.DealStartEpoch if dealStart <= 0 { // unset, or explicitly 'epoch undefined' ts, err := a.ChainHead(ctx) @@ -169,25 +186,110 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams) return nil, xerrors.Errorf("failed to get seal proof type: %w", err) } - result, err := a.SMDealClient.ProposeStorageDeal(ctx, storagemarket.ProposeStorageDealParams{ - Addr: params.Wallet, - Info: &providerInfo, - Data: params.Data, - StartEpoch: dealStart, - EndEpoch: calcDealExpiration(params.MinBlocksDuration, md, dealStart), - Price: params.EpochPrice, - Collateral: params.ProviderCollateral, - Rt: st, - FastRetrieval: params.FastRetrieval, - VerifiedDeal: params.VerifiedDeal, - StoreID: storeID, - }) + // regular flow + if !isStateless { + providerInfo := utils.NewStorageProviderInfo(params.Miner, mi.Worker, mi.SectorSize, *mi.PeerId, mi.Multiaddrs) - if err != nil { - return nil, xerrors.Errorf("failed to start deal: %w", err) + result, err := a.SMDealClient.ProposeStorageDeal(ctx, storagemarket.ProposeStorageDealParams{ + Addr: params.Wallet, + Info: &providerInfo, + Data: params.Data, + StartEpoch: dealStart, + EndEpoch: calcDealExpiration(params.MinBlocksDuration, md, dealStart), + Price: params.EpochPrice, + Collateral: params.ProviderCollateral, + Rt: st, + FastRetrieval: params.FastRetrieval, + VerifiedDeal: params.VerifiedDeal, + StoreID: storeID, + }) + + if err != nil { + return nil, xerrors.Errorf("failed to start deal: %w", err) + } + + return &result.ProposalCid, nil } - return &result.ProposalCid, nil + // + // stateless flow from here to the end + // + + dealProposal := &market.DealProposal{ + PieceCID: *params.Data.PieceCid, + PieceSize: params.Data.PieceSize.Padded(), + Client: walletKey, + Provider: params.Miner, + Label: params.Data.Root.Encode(multibase.MustNewEncoder('u')), + StartEpoch: dealStart, + EndEpoch: calcDealExpiration(params.MinBlocksDuration, md, dealStart), + StoragePricePerEpoch: big.Zero(), + ProviderCollateral: params.ProviderCollateral, + ClientCollateral: big.Zero(), + VerifiedDeal: params.VerifiedDeal, + } + + if dealProposal.ProviderCollateral.IsZero() { + networkCollateral, err := a.StateDealProviderCollateralBounds(ctx, params.Data.PieceSize.Padded(), params.VerifiedDeal, types.EmptyTSK) + if err != nil { + return nil, xerrors.Errorf("failed to determine minimum provider collateral: %w", err) + } + dealProposal.ProviderCollateral = networkCollateral.Min + } + + dealProposalSerialized, err := cborutil.Dump(dealProposal) + if err != nil { + return nil, xerrors.Errorf("failed to serialize deal proposal: %w", err) + } + + dealProposalSig, err := a.WalletSign(ctx, walletKey, dealProposalSerialized) + if err != nil { + return nil, xerrors.Errorf("failed to sign proposal : %w", err) + } + + dealProposalSigned := &market.ClientDealProposal{ + Proposal: *dealProposal, + ClientSignature: *dealProposalSig, + } + dStream, err := network.NewFromLibp2pHost(a.Host, + network.RetryParameters(0, 0, 0, 0), + ).NewDealStream(ctx, *mi.PeerId) + if err != nil { + return nil, xerrors.Errorf("opening dealstream to %s/%s failed: %w", params.Miner, *mi.PeerId, err) + } + + if err = dStream.WriteDealProposal(network.Proposal{ + FastRetrieval: true, + DealProposal: dealProposalSigned, + Piece: &storagemarket.DataRef{ + TransferType: storagemarket.TTManual, + Root: params.Data.Root, + PieceCid: params.Data.PieceCid, + PieceSize: params.Data.PieceSize, + }, + }); err != nil { + return nil, xerrors.Errorf("sending deal proposal failed: %w", err) + } + + resp, _, err := dStream.ReadDealResponse() + if err != nil { + return nil, xerrors.Errorf("reading proposal response failed: %w", err) + } + + dealProposalIpld, err := cborutil.AsIpld(dealProposalSigned) + if err != nil { + return nil, xerrors.Errorf("serializing proposal node failed: %w", err) + } + + if !dealProposalIpld.Cid().Equals(resp.Response.Proposal) { + return nil, xerrors.Errorf("provider returned proposal cid %s but we expected %s", resp.Response.Proposal, dealProposalIpld.Cid()) + } + + if resp.Response.State != storagemarket.StorageDealWaitingForData { + return nil, xerrors.Errorf("provider returned unexpected state %d for proposal %s, with message: %s", resp.Response.State, resp.Response.Proposal, resp.Response.Message) + } + + return &resp.Response.Proposal, nil } func (a *API) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) { From b8dff22a401a549d84ef026a8e02117c8bad8c20 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Mon, 5 Apr 2021 19:15:32 +0200 Subject: [PATCH 02/80] `make gen` --- build/openrpc/full.json.gz | Bin 22798 -> 22899 bytes build/openrpc/miner.json.gz | Bin 7828 -> 7829 bytes build/openrpc/worker.json.gz | Bin 2574 -> 2577 bytes documentation/en/api-methods.md | 34 ++++++++++++++++++++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 297a6411e87e5ee299eef28d9911538e51e12e9a..88ab4a3d32b69b798a84e20e3e315eed496467c6 100644 GIT binary patch literal 22899 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 M;~*6mhJo_`0778xjQ{`u literal 22798 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 SkN+hY_~` diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 07ec95fd47ef22b9fbe2614ac6dbb01c244cde80..85e7821919e28976b0aec0204a4334c50e409f8c 100644 GIT binary patch literal 7829 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 literal 7828 zcmV;F9&6zriwFP!00000|LlEhbK5r7|5w5A|KdqHvZ7mj(M(@Ba+11rT0NH2Jln*x zg-A%kngqBc_JdM2(Yn=g30$##7615L-~oH-?|T z83a1K<~wX7lVZ|7HyQQLEz3i`Z?p^x`KE_mCaL`W_uq5+h0K=31TTE>(}YnE&d~=< zkT+r8(qu0|oWKjW158R7dSLC5{PQJv0p-hfP^blv=TYw^`1XZ-VIE>jj{v`YNf`17 zwA*V0Uw$D^U&!Bo|82Akf9W{Tdo+fI(K1}G3g5ACFw>W6}5EH6QbB%kYrD zv>E?$!SL6*lp1*YeWGdKTp$N>dguWnv2_sVr6(OBD@`r zTkl$$=Q2tZbKN&%?4c2L9L)H4@ThGJ${Cx^v73%ym!#H zr_j6$xiNV6iF$YIFQ1B--Hko^w%(<024=_+Z!{z(6qu*z0rWih$bV<|{##gXN~w(? ziIrR*OIFeJcdf0z=~<|W^wWXD%W)38Opy35{s&dZmKBW*U}*uj3)VCO2b(Ewuj*+b zO`;i2c4MfCzKPr2ee-;#SlV^h%B8c@=|1e7moq<0R&Nz*s%M9{_C@o z{%QaC^maA4pyWY_P`8sULZbyT@5Uaz=df5wfD#mx;xonVYc$8ao5&i|2^)Kq&RW3j zfzP+TBpb~1HR8|vfMfAX@WO%a=M@{snY{Ixhe@G&U+)_43U88=->&Fo4|i+)Tb*lH zqv)kt&6pT15aA}pZ7bAhp9@r4(nPqtDAa+;3W66iKVhI6gWpfB;4A8seag_ZVg_%- z(-H(?5E+{zsjf>;Q9m_BTt>9!gj0`oAhdI;19y&Crh1uQR>#Qg_WH)qFd_LL2B0bW z3p@lZU{mwX;2m@!<5E9PFh~2Rm~9s{c&J8Fcc4Ic>bOgWLIA1&@G$}^eE)nqU1FPI z63p=>nNb1meA+qwT|;6~he*?DRXU~#3ZOjMi4e)RisD&=+ByJEkSIiFdYHzGBWomK zGb}D5Ho}8b68HpXsC(f zRxN39oGAL{k;%#qvasmP6cgw@z9lBLIDZX|DfH3tAm*dy;crzw+H*)gRY00_}2q` z@NICjKwpRqM1x>neZUrwi7Mi&9yxr7Tp+zAA(+g;SIidt{TFie$IZvdzu%mXe)~B7 z_nY&{+kcPGZ+-!Y++&XthlAZc^f0&cfsYtq6!_FZz=dql0+3jutuKT(#-GJH`E`K^ zFrjVp78Aq7zUToaqK}-PMcpr?CjC;v0t(84duT6_5tEjHMs-yBeQDbn*eD*x{F4Y5 zZTm1}v!@7IUm$4vBT9U1A@7gb%*F&=Bj#ar4{h*cI$x;1f^l6b>mJLRx}jxGP^R`@H6 zYE9gwAl>lRZh0%ukiT?X>ah#RV0BJf(NINlOl-AB*b?z{t*B0#?oQ(6K|hOEIWyza zNm?Up0gv;Aj|lSt1U|B7N3zTmlezp*goTM2$O1T`)&`dhU?0q==O7DA9{~h^%G}5n zfM7%|WP%r87uZ|?Oe}1QXch#{(q`D?Z;xDP-XSY$g|qfc5l4dH1246J{-T{+g#Bi` z5@FBTV{iHoG!g87^{vJ6V;}a9*|hK9A;efY1te58*1pQ$rLkF)+@hWpFMBP~n!Y1~yw3C3uCULlV+XIDt!+NvLKn9`K<^GQUQ|o-1mw1&Vb(j8 zvGkEDu;q0RkGj-{cFBZ;k&O{yL8LV!d^#xzJmuxq?$O+(lzq3vVn%5509TUJ-&L^Z3_t3 z$jb`y4JRKQC!ZF$do{-WvZ$%|WCgJ_O~%b4ymfAE0)E>H_%#w5lTd{xD_0vwkeJB6 zfDGPvkodC<=Ft&Q6)}~3T982&lxc^BFE2!zhl`Nc7Ju*S=$@RWi}$>%Dg#qI;%v;j z3c|id+j77h-y^bmet9AInX(1)#0YBJDWmvQ+dB_pEBon#N!3fk==Lu9zft<>{XY-? z{Px$s?$Iy*$K3bF=f3yx*Ei;;hhN^joAiG1-_rLt58j8X```YL%_^sB?CBo!=L%P6 zig1OL)c1&;`*#~alq8V7V)#>ViBAAj}%lUR~Ox6|*nj1TZ3{Y)NP5uUfxGH$SgdESi^qyJ<9|M$M?wcXcr0BH_k%u@m{zdH0Uz0Zrll;0s|NHaL##6~- zx`LsWs1bHmCz&AmHMD9ZzNu!7YFQ^@B1 zWy05+M;4;^N8*cPI99kmhK~*+OniZRXmcD+J-j5QhoFxHNSA}$6nU-mI#u&}xq0zX zmxa8<2dW552PM;|sxu0us07LQ2-=l53uF3)HP_ai>8>KNVXJvP*7v@4*}BSIfY^^e+i!7&7W* zWtZ~;6GVcX`}Ern$oJtKWo`@jgDsFZMv1Di)4~{>qv8XK*A6p_D(M|>ytdOq9L8gD zpQ*fsauJ{DjPYF2dF75>(Rn7#ARoUGH0^wWZ1n z?ACIU>C#+ea_zI(cW|mY{4oZ-mDkPJXw6sK2`RWH-L1;-Y0#j1ejexeU<@yf#tl;yCIlM+b^6sU1Tdp^G z?%M~%pamHmL$=5+5S^5tsbH1$8jGc|SoXtW2|2M62#%Li8~ck&b+6H^B=?8Olw0SW zYxq?pY?i1&DJ$Qt&@GRkSmA0X*2T*mFkjZ>i<3n&iEt$=QFo+QXb#QCu}2v-sls5*vpC1_(WbE4A{&{@E!ItAIb;3oMifp967 zx{xgfUUJ5+;n#`|?xssDU4QUx4NkP~8_!&6z&6rWoflTg7Lq`ldD92(s ztRz>}2|rgo>Ml(!Q|oEuwPusrik5q>*@~*GL*xWpBcDr8O`1IQS1T;>BtfhXTLJ8qjDx6O{*ox)dc2E}C49k&zJj#~jz{B!#4H+X(Ym_Vkr z2Yqpi@@N4u5f)VoxC42yGPEpYMHXcXxUaLGYXMu-#WqpMv-e) z&G^cLl6~xD8aa}TvNg08Tas%)>_PVB&q?;(;wbvP8V2$DhaE(t0ahA7b%#`hjy3Jc zofPiL6*?hnKdUZ|uhHN78BWdK+e6=b+WgFfIJ|h>b2U zG8a>HxNe6V#n!$0l6YX9>L=(&uAkk zkI0k*^Qf9OoW~n#0R1@wx|(xUrL>&G7$DVy?6EA7U1oPQxqJt|GOoJ6OoHVV_Spzq zocF6OiKoeIc;R0r!RE5R13CM9&xJ*GKiY~Z<=-|G75TT?1SKNZh)E+RI}sB_q;YH` zYmTHsuO=cf0*XxHDQ<@rL!pEusbx#Y4RTxnUCh}7Fyu2#=B1KVGE<6Uz06#Mi@nq_ zID;M1-A<>|GQxd}XC*Dg)i&!wn@oRe-HXWO(pVWU7CHw$TuOr7pU1KKVCY<`Yz zUY1LO^>rB}cC3BfE_>Of+{z(L-7sklUp<|*lLarjfp2OdW7vsp)J&elS~g@Y$Y~w1 zuiO~gEHc-i7!|Q%sS@5HCX&0VYDH1MluE3u0K=wsa*}kT;TjEBq~RK@ZLoF?YZal} z0KhPTHvVT5cRP#Fj?j0#%?5@W7;a#=f#E%bVbv|V63IT$`|ytY4KO%HWj6qvY_LJ! z27Md!ZP0fg(O0q7Bw_3t!Hq-l5sgyFJEhd#ECe5Kw>SphfN%rCI|AX|?DB2`&y5}^ zp$Ak~Pls4)Bj_W!0}Z89Rmy0C1f|_rYyYf2`haI7M zoShY+idqNN>GC9c(8w;N`i z#i;Bi#~|5YlV8xN(!Efn4f;0dyN14s`~q%lU@||SQZIe5vkvga3Fu;O0kp1>-1=dY z4Wc%P+Q3B;E)*`Lvu^fVJbH>XED4M6 z5qtaKB9kGD^Vr4Gg8^Suk(C^Z*{8WN?4Wj7q*!9|>8nI1rxuta=8O9aQScV?JwQ_VsGS8%66%?QG9!V4rtd5ySooH1RTryx$r`H(2`bl14ZJis0sWn zxfQv$75^yqR3l3(SyEl@8nIU$-pVB3Td6KJajF`kvT|AceQ;SCVLCKn%60uGoKu28 z>L$VzBU7u*xJI~8o?^wh*$1Wwn9#P71%v{UCLAWdysKt1pYVkT~jlEGpB3t<#6 z56|bwiz3JfdiG;u*gZ@6QC;Y|=0a>BJQ0mrB_~d`NNl3AD?cjXc7+ZVc)?vBGUqym zQ2gYE~TKTC0e2|z>b3~3>mVyy+HgEwKIVkL<_*M(CgP|&Df8qke4dhDHFBT>_F?s?OlFXJO{t`gj z=1$Z+ic|Qt^8D}FwpwP9V&4DU?e$yT-r#nBc0cYp$L7Wn1bbYPiSVH}<=l{t${+fC z3thYl5HPeUU&k6$yGnw`V<7|=dJLOO8+uXbpe8>iHNJ{ldDl&oij3I^=3Wb?>Q=^p zzpv43BZ1`gvsH-$-OrM@ZbOcRHnOhKOjGm%(p$NpSKYbP$H*%&YcKM#bCfw{^>Wg-iF8_t78b{itWE zYv2NQ=TN@fNERgp-7sNvBKu45Vx>^zEvZ`a88w%`FYY~JGFT{zb6*L9Ilf0>z@2;K zmlw|{%C`sSh-covoZx}K{JKE@`}5C6%Mi;kVYwS@-bpz7Q*2)g9=~;|x!^$B?Q{i@$!*hl zWuk)s#tt#ubey$TJ$m;7(h{xykUo zTrZU!X&G-HT#U;TELt9?r9X$Jk++YW-=tIwb z42NBAS5myUIvOFE-m)9r14gJ)EtssbRpZ~WK%1siSHO;S@77x1krhmv&S#HvkWTqE zrYZXYBCbzu>iW-+0i>-I1y^QC4E5(@qjw%5rA_ z7vBuAHo*Tf#RPhfZ;44ogmq|4p^uISv2LzvN06mw@kQvg1p_fa;Sx*`V6+bP0Nb}K zhgpmfsI^RP43*P?4LPRyqG5*y$Wyj@Du*hE>H*}gocNQ#qT0j-kR;R|`C91c789mx z?nk86c7E^+U^1iJ(yuGftLS;Auby2_$65^y(_y#QDR8}O5VQm3an;R_0T+FAt&Q6Yf`N7@RDiP^O-m0#XH|a7lu~V(TNI^QctSf55^rz7hyd(|v zF(7>Iii9ggYX|3lcrx6e!IBBbz2VEv`BHTSS;z;BL9=51R-8iK(KN^pTa&>}w+Cka zl3~03PQ)-ZIW}x3Umb)E29YugJ=7N2Opis=t`W!7oE*=(XQ!vrBQ)!Gjt15VI-2&8 zd2|MkdndEO6uyS1M$7nkeH8`QLfd`NYZ)KlLwIAe_&tK+xY3X=`A^uunBreXxK-s*T#a?~+LDn)VK{a^VtTeI`>^lgHHb&vjnE;KQF6v5c@dx&i~ zfQ^@#ObPBG%fENGw zdL^5)i)zp)s%11O@NbaM&TX5Tn<$ltNb!+p66tv_ZXR7E-HphWpWuIxIMaDmehk^- zMkJ8F_3?qF6ZR0+}}SP;hSH2FRZvRNz$vrwb?3 z&l6yuQVxS4<3h*dSno<4=Q*jZW4#!n9;j$}7nS!z=%Kmx$)1YyJj>a&JIipdQBnLr zYJ0FpnK94P((ZLsS9yi_TQXjJBE}8*hH6mUM%z4Z7|WT^neNL0kTE$vaG} z&7o~YrFgY6b|sX;bnK_&3ZXR_izEbVaAo5OiLUO{&}OGeQjE#NZtuh;Ti~Xp*j`9+qfWJ4*7gQw+rle2eqpsKmRCgeEQQ}~p zz?H}@)Ri>jl?54mZzjV%uKriz%hL@zPb78V9#=a2p4A zrMiNYg71-Muy*@%SfV6g$hPG*Duh}HFv`0i z-%#*X6!pRNcvR#5;btHFcjIK$rFD`gex=iDCx5Q0s~1|9OKi12evB3eB~V5+i_~|b ziLI@=6m&9k5vI6~j>bo`Q|s&u_KuEEk6#}Rx~FGHr?VM6I-8+cXLi~-MhHa-5aE%Q zF)g234Gj_sjFaQeX?F@cN5|c%bu@SlUms1)&gl`HbzaZ9X73oiwpOR86;Ql^{vDTL z1npP%omZUG#ffsSxK6)bl1~sbW7rV^7LOT2qu1$mj=J5WZttdZHth9=os++emhlVq zS@78x)Mv(4)@fIbWJG}EXDmTYR;c%kGY39gN`l?vmf>I$`?a2=v6`Q~F#*%TpV;Dc z#0~mK`0eN5B4++(%&6x;&ej%W=!jtlWu25Lg`~o9jtA;zsxEhw5IJFxZK8EVeI2#4 zj?JQ?p4ti9*n!^3>}7%8QPrtW?|d^vie3U#C31_H3tf6BFnPWSZmv?Cs`qBgzm;AC*xKOUU6jM4a`Zw!wIE#tlT z+h+s5AAbbhe*eU{<+AdYz^T2Gix0^8=p*X`CPD*+KjDM;`QBa1a8Do}Bk|i9cAg3} zPnq1mfTq^*xMAnBG6AE`W~K=SGf|f&Ow3=I(TZ8o8SDF?q<%(Xf{nBygmEs?tRT6u mE`1m0H_Z-2?7GVZmpxY&;wIDEr~e-S0RR7gna(<^fB^szK}uKv diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index cfe344989ae17abed055d93710ffbc919a380d23..64e17f73d76221ed8ce76c8177b93face6942748 100644 GIT binary patch delta 1116 zcmV-i1f%*mYBpP=knMJWhrs(FnoV`<8D|Jo@C-Nx0!5mB?K zxSuF~Z-=x0i91lkd0etv&U0*B#24ry7K!KX{HHBAPgx%@t4M#Pqz+3UE@e}kU`i?x zmTbqP%cyZVzC3;hwV7(1y2hzHP^a$QX#tp1MqK(6qE}K8)lqGdLHn@w58ouJ}aVg-DtG`%du0o@R zu`&wyA*vahm<$i=CLuLPWx7aBTS)>l>5WxbS%rSSRrr%l1SNkJdkWUkMnuhIMbrst z@_kYh;(}~Nh@h)(0+3~MJ8??$7%B+NGnIB5oev4SgvkFgBDh?zTUg;k%~JkTqrVw1 z?<2Q~8}gp_^c&FWtW-8&i!uJ5YsE>ys^Um+8>GAhDUFO(QjZjIzMcdDby{D)ZuYJ+ zjpb{JA=D;Y5axey59ziMpP>7YH6#tag{Htj=(iD7bm!=P1}v&~#eCBrl8OjbZO2)j z`o-hS%wh6LiKUcMFu0SQPMd-4uvDTTH-7=7)-KJMt|&mEy!A~`1tJbi*29(L3j1=4 z*gxkA&Y1%b;Zl3<=CK;FOp@8(y4)U5!f)F%w$Wv80<0nZ46vSBHqU6s4mVKtJH5BN z*+cn!wt_YRV-qkQXu#MllamE@e~5+@EE`+`afjUVsLBe_(`u5Stmge0*(B~on73pg zWqf8gR2^a~dIy;r{piGR7)Y8eGXCqeE{4>RHN466P}cKBx}V0Y+za^H2d^?Kz6W@K zw@?wE^;okRsx_0c^AI8IX&5d0MUxU*Os3Ge15D8gO-k}=)$jihFeGN~VD$#0r44UM zs}(0429LO{4JMh)yW^k42GYBi&g^vFBfV2K?#Wy5{2%<`Z$FrG&;K#@CNQ7$`V-m< z=BGgb{q9}gINaN8ucE13bzbd#Ca0ka)phJnfRL+S$n+mI+R>NRoQC8yGx&{pMY_ iHV*E&Koyh02|5&Q2QL=ai~j`x0RR60!d2b@djJ6UNggZ! delta 1116 zcmV-i1f%m*u#+ zEM$fh6>e5e{fZMtP16Bk2O3PPG{UgOGGnsVL0b_znbarJOS)GR9Q zCyL+O;p~6n4%BcSm+Y4F92*z$1-ghu;<-EjX$#I%)(6ZgQYn9_!xD%~*%T+3l1hXn z+wtf!YFv&lkKaLUrW&WNaq14#se9Kc0CUQSOMgQ2N-CmyinwZ0Xjy(i*t8Z%ulK%0 z>jtIwLX-9ZrPrjaUIM4W)P9*vB&c$88)jQ-PE5^oPy=ucz#S^U_45JloK1K|Skol= z`HJ;50$p=; zaq*zvwRFMdJ@MlY7a&30X}Qq_!_il1{`wI9r48<)qK2u4jQX0jsc zgf#g+sR?mGwjxB(RW||1vbmi&rFje$1m>AayN%9=gk3`9e;E;6F4!%s@S$cY|Eba6 zjFxD8TXf|N$aDyc_`IA2eKfI6+OUpISK zna1+9#1LweEeL;exQBGxh)>Xc$QqJ{-a=DgAoSaaD!OxYKLZxkyJEiS4@pIYs~CFek0;@`?HSwXvNt0E)_w+9Pc55gv}1=GDEpn> z+uiJ;d_G%2n}D$i7!NdHJSmfu1$KXihI9*-4K9JWL+*K0WrgTzHAzrb^Ztx%689p^ zTQZO`KC>ID4zU%zgG`NnbmBJ*B+V8X|MglIL+Z#H-eh_x>-i$xPvceY1$^y;SD6*x z13bW6sEE&ctl13Jnn~Gth!FNPjF$bPNeL|`Q|R0Qrs#wwC3&^#_kRc&5;I`;dV|r@ zhPR~EiW3flN8Hv1lT7B_@lRp{>D^0bb~^8o-l-b*{z`1I43W!Ok0P z*GB^Cr(0IUTgkYr1wS>BD#cVXchUgXUMSf<0M^0hOqx7G1N9Bmzd)#yNe90(N(gTph4?)>?m2p<76+9fPVUPdZi(H)Ga@}nH$(^hOLo_5Jr?d;?Z%LFG`BuPEn4Gf;Xe)Fzd i8wdAWpxzXd!wEVQO?aYj@xK570RR6dg{F=HdjJ52nIfeC diff --git a/documentation/en/api-methods.md b/documentation/en/api-methods.md index 2830be0bd..f6ee521f8 100644 --- a/documentation/en/api-methods.md +++ b/documentation/en/api-methods.md @@ -57,6 +57,7 @@ * [ClientRetrieveTryRestartInsufficientFunds](#ClientRetrieveTryRestartInsufficientFunds) * [ClientRetrieveWithEvents](#ClientRetrieveWithEvents) * [ClientStartDeal](#ClientStartDeal) + * [ClientStatelessDeal](#ClientStatelessDeal) * [Create](#Create) * [CreateBackup](#CreateBackup) * [Gas](#Gas) @@ -1501,6 +1502,39 @@ Inputs: Response: `null` +### ClientStatelessDeal +ClientStatelessDeal fire-and-forget-proposes an offline deal to a miner without subsequent tracking. + + +Perms: write + +Inputs: +```json +[ + { + "Data": { + "TransferType": "string value", + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceCid": null, + "PieceSize": 1024, + "RawBlockSize": 42 + }, + "Wallet": "f01234", + "Miner": "f01234", + "EpochPrice": "0", + "MinBlocksDuration": 42, + "ProviderCollateral": "0", + "DealStartEpoch": 10101, + "FastRetrieval": true, + "VerifiedDeal": true + } +] +``` + +Response: `null` + ## Create From 7d8ee0d65a4707b93e11db13d330d3102d41c636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 13 Apr 2021 12:27:46 +0200 Subject: [PATCH 03/80] Lotus v1.7.0-rc1 --- CHANGELOG.md | 67 +++++++++++++++++++++++++++++++++++ build/openrpc/full.json.gz | Bin 22803 -> 22804 bytes build/openrpc/miner.json.gz | Bin 7828 -> 7828 bytes build/openrpc/worker.json.gz | Bin 2574 -> 2574 bytes build/version.go | 2 +- 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4fca397d..49ce31bcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,72 @@ # Lotus changelog +# 1.7.0-rc1 / 2021-04-13 + +This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. + +## Highlights + +- OpenRPC Support (https://github.com/filecoin-project/lotus/pull/5843) +- Take latency into account when making interactive deals (https://github.com/filecoin-project/lotus/pull/5876) +- Update go-commp-utils for >10x faster client commp calculation (https://github.com/filecoin-project/lotus/pull/5892) +- add `lotus client cancel-retrieval` cmd to lotus CLI (https://github.com/filecoin-project/lotus/pull/5871) +- add `inspect-deal` command to `lotus client` (https://github.com/filecoin-project/lotus/pull/5833) +- Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917) +- go-fil-markets v1.1.9 -> v1.2.5 + - For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md +- rust-fil-proofs v5.4.1 -> v6.1.0 + - For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md + +## Changes +- storagefsm: Apply global events even in broken states (https://github.com/filecoin-project/lotus/pull/5962) +- Default the AlwaysKeepUnsealedCopy flag to true (https://github.com/filecoin-project/lotus/pull/5743) +- splitstore: compact hotstore prior to garbage collection (https://github.com/filecoin-project/lotus/pull/5778) +- ipfs-force bootstrapper update (https://github.com/filecoin-project/lotus/pull/5799) +- better logging when unsealing fails (https://github.com/filecoin-project/lotus/pull/5851) +- perf: add cache for gas permium estimation (https://github.com/filecoin-project/lotus/pull/5709) +- backupds: Compact log on restart (https://github.com/filecoin-project/lotus/pull/5875) +- backupds: Improve truncated log handling (https://github.com/filecoin-project/lotus/pull/5891) +- State CLI improvements (State CLI improvements) +- API proxy struct codegen (https://github.com/filecoin-project/lotus/pull/5854) +- move DI stuff for paychmgr into modules (https://github.com/filecoin-project/lotus/pull/5791) +- Implement Event observer and Settings for 3rd party dep injection (https://github.com/filecoin-project/lotus/pull/5693) +- Export developer and network commands for consumption by derivatives of Lotus (https://github.com/filecoin-project/lotus/pull/5864) +- mock sealer: Simulate randomness sideeffects (https://github.com/filecoin-project/lotus/pull/5805) +- localstorage: Demote reservation stat error to debug (https://github.com/filecoin-project/lotus/pull/5976) +- shed command to unpack miner info dumps (https://github.com/filecoin-project/lotus/pull/5800) +- Add two utils to Lotus-shed (https://github.com/filecoin-project/lotus/pull/5867) +- add shed election estimate command (https://github.com/filecoin-project/lotus/pull/5092) +- Add --actor flag in lotus-shed sectors terminate (https://github.com/filecoin-project/lotus/pull/5819) +- Move lotus mpool clear to lotus-shed (https://github.com/filecoin-project/lotus/pull/5900) +- Centralize everything on ipfs/go-log/v2 (https://github.com/filecoin-project/lotus/pull/5974) +- expose NextID from nice market actor interface (https://github.com/filecoin-project/lotus/pull/5850) +- add available options for perm on error (https://github.com/filecoin-project/lotus/pull/5814) +- API docs clarification: Document StateSearchMsg replaced message behavior (https://github.com/filecoin-project/lotus/pull/5838) +- api: Document StateReplay replaced message behavior (https://github.com/filecoin-project/lotus/pull/5840) +- add godocs to miner objects (https://github.com/filecoin-project/lotus/pull/2184) +- Add description to the client deal CLI command (https://github.com/filecoin-project/lotus/pull/5999) +- lint: don't skip builtin (https://github.com/filecoin-project/lotus/pull/5881) +- use deal duration from actors (https://github.com/filecoin-project/lotus/pull/5270) +- remote calc winningpost proof (https://github.com/filecoin-project/lotus/pull/5884) +- packer: other network images (https://github.com/filecoin-project/lotus/pull/5930) +- Convert the chainstore lock to RW (https://github.com/filecoin-project/lotus/pull/5971) +- Remove CachedBlockstore (https://github.com/filecoin-project/lotus/pull/5972) +- remove messagepool CapGasFee duplicate code (https://github.com/filecoin-project/lotus/pull/5992) + +## Fixes +- return buffers after canceling badger operation (https://github.com/filecoin-project/lotus/pull/5796) +- avoid holding a lock while calling the View callback (https://github.com/filecoin-project/lotus/pull/5792) +- storagefsm: Trigger input processing when below limits (https://github.com/filecoin-project/lotus/pull/5801) +- After importing a previously deleted key, be able to delete it again (https://github.com/filecoin-project/lotus/pull/4653) +- fix StateManager.Replay on reward actor (https://github.com/filecoin-project/lotus/pull/5804) +- make sure atomic 64bit fields are 64bit aligned (https://github.com/filecoin-project/lotus/pull/5794) +- Import secp sigs in paych tests (https://github.com/filecoin-project/lotus/pull/5879) +- fix ci build-macos (https://github.com/filecoin-project/lotus/pull/5934) +- Fix creation of remainder account when it's not a multisig (https://github.com/filecoin-project/lotus/pull/5807) +- Fix fallback chainstore (https://github.com/filecoin-project/lotus/pull/6003) +- fix 4857: show help for set-addrs (https://github.com/filecoin-project/lotus/pull/5943) +- fix health report (https://github.com/filecoin-project/lotus/pull/6011) + # 1.6.0 / 2021-04-05 This is a mandatory release of Lotus that upgrades the network to version 11, which implements [FIP-0014](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0014.md). The network will upgrade at height 665280, which is 2021-04-12T22:00:00Z. diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 3af032baba190eb94427b32e9ca001de22222994..6a0558f208e1f52e27dbe433c0f5544b65a0287b 100644 GIT binary patch literal 22804 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 delta 22 ecmbPYJH>WFJCoD*jh)PL9Q8BLS*>nhWB>qZ#t5VU diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index cfe344989ae17abed055d93710ffbc919a380d23..59cdb4164c83448432169fee99b7989bf99b9654 100644 GIT binary patch delta 2472 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 diff --git a/build/version.go b/build/version.go index 5baa4743a..788f1b10f 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.7.0-dev" +const BuildVersion = "1.7.0-rc1" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit From 95e0c3df1d42538b6975b629ce1c2a8bdf5ef7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 27 Apr 2021 09:34:12 +0200 Subject: [PATCH 04/80] 1.9.0-rc1 --- CHANGELOG.md | 2 +- build/openrpc/full.json.gz | Bin 22804 -> 22804 bytes build/openrpc/miner.json.gz | Bin 7828 -> 7828 bytes build/openrpc/worker.json.gz | Bin 2574 -> 2573 bytes build/version.go | 2 +- chain/actors/policy/policy.go | 6 +++--- 6 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40d088195..8801205ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Lotus changelog -# 1.7.0-rc1 / 2021-04-13 +# 1.9.0-rc1 / 2021-04-27 This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 6a0558f208e1f52e27dbe433c0f5544b65a0287b..2b96388a44b45106a92762669c2a4689244c0499 100644 GIT binary patch literal 22804 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 delta 21 dcmbPYJH>WFGvnlqEgW(j^OB>^u5Mst003PD2mt^9 diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 59cdb4164c83448432169fee99b7989bf99b9654..55f416dce7b787d966c340dce403c6d0289ea369 100644 GIT binary patch delta 101 zcmV-r0Gj`f6pa*+eF4|8em4nNJ?-@0*2cm87N|D`xyNsWs{aHOR7H`B>2ihY$plW4 zG+&P58ffft`&OcWDe59M0|AH#K+LSuNF)Nr!quH$6up<4QF#-d=v(|R00960^hH&g H0eb)d%tSBK delta 102 zcmV-s0Ga=d6pj>-eF4+4em4nOef{QLw>A#$w?Mrq$US}|RQ)HQpel+~OqVNEPbP4Z zr1^3b*Fa;J+qV)0Oi>r983;f`0AgmHMj{a~7Ow96qUgQUjLMtvMBn0n0RRC1|Ka8& ITmgFk01wtJi~s-t diff --git a/build/version.go b/build/version.go index 788f1b10f..1e9bcba98 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.7.0-rc1" +const BuildVersion = "1.9.0-rc1" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index 01c4b14d2..f210b8d94 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -30,9 +30,9 @@ import ( ) const ( - ChainFinality = miner4.ChainFinality - SealRandomnessLookback = ChainFinality - PaychSettleDelay = paych4.SettleDelay + ChainFinality = miner4.ChainFinality + SealRandomnessLookback = ChainFinality + PaychSettleDelay = paych4.SettleDelay MaxPreCommitRandomnessLookback = builtin4.EpochsInDay + SealRandomnessLookback ) From 7c37618b507a5e0635fe531fabdbf837b2d74db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 30 Apr 2021 14:30:12 +0200 Subject: [PATCH 05/80] Update ffi to proofs v7 --- extern/filecoin-ffi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index d82899449..3db17a0a0 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit d82899449741ce190e950a3582ebe33806f018a9 +Subproject commit 3db17a0a0f24ce6a04e946f86bf18b0e1d8c0007 From 8227085c370dce98b47d6e73214c2891741f0860 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 30 Apr 2021 13:58:16 -0400 Subject: [PATCH 06/80] Lotus version 1.9.0-rc2 --- CHANGELOG.md | 4 ++-- build/openrpc/full.json.gz | Bin 22804 -> 22804 bytes build/openrpc/miner.json.gz | Bin 7828 -> 7828 bytes build/openrpc/worker.json.gz | Bin 2573 -> 2573 bytes build/version.go | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8801205ed..b502a1447 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Lotus changelog -# 1.9.0-rc1 / 2021-04-27 +# 1.9.0-rc2 / 2021-04-27 This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. @@ -14,7 +14,7 @@ This is an optional Lotus release that introduces various improvements to the se - Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917) - go-fil-markets v1.1.9 -> v1.2.5 - For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md -- rust-fil-proofs v5.4.1 -> v6.1.0 +- rust-fil-proofs v5.4.1 -> v7 - For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md ## Changes diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 2b96388a44b45106a92762669c2a4689244c0499..6cc950d730897d8c52ba5121c06489f43d23b890 100644 GIT binary patch delta 23 ecmbQTiE+v%#tB`FWgEL2BRDdIBDs`mSQr3r9S6Js delta 23 fcmbQTiE+v%#tB`FVH>*}BRCf1{|r^CVPOCOcHapc diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index c9e6fdc7515db488d024c3f7517d6c5e80484112..90dd7ddf7934b879a7b3ff5b6965af721245da9c 100644 GIT binary patch delta 21 dcmbPYJH>WF2V?cdPG&idwZA;iu5Mst003Y;2!j9s delta 21 dcmbPYJH>WF2jlLIoy>9^cQ-Hny}E&s0RU!N2{r%# diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 55f416dce7b787d966c340dce403c6d0289ea369..cd1e2683ac9a9c34cb00bda9242b14892b7336f3 100644 GIT binary patch delta 2470 zcmV;X30d}y6pa*+fq%P;7Z&zF&A21+;QJ$H#M6|2QWtDaS?j&yj40TEE$o1_1@)C_ z;pXOM%CFcYU^aRs(I4NqxCL>kL}05Uv?P1wcaY7Qf(O+an%@@kPmokxkSVk-!B$*c zz{Em+7k$4bW7_)4eBwA@8n~oC!9soy6+P+4ZJiNCj?gRpk$+Bz4Xq(@-SaaGfe>6A zp~owBr39!zFeF>&Oo3p;Z6#RMtZ7Dchq~#bE4H{|H#axf!ZPqYBIbC2R~?u!>u%%~ z!xr|5AfB0mKrd|%79I)CCx6X-z=OAoYYP*{3E3jstt-jERl4nnw{;Vh z%jsH$GB&{2j3@1YR%YCJWBwiI{8;|OwX8%W%#Wo+ccXRi$ium5@Z{9O9%YG7QDr0J z3o9}9{eQDmwM|d9Olyh(t}|}u%=8DUX2BQ<@VElxQg(|i90(T=@JuOR4%+Q$Sfyoi zuRV!i{@52>^VN2>$Iu?TeBAbkR3O^Kr~1DPQLSx$wWj1qI!zBYEo!fenHr@7D%u6zC`N=rT0RU_5r2Wq^w>7r^3{JnM@?8a&sGI zTWU^B&2&%$a1Fp6D!}#g0q&elctu##B>DM@^)&)ra}!KOt?eXvk;l&y`kSg$Mu-2+ zrHZ@Kjx@R>ZlKNR1xOwUJCa=RMzgu3Hh*#Ppx?E0!R0;i;|~`gLELG%(FMcNS84wG z5dNhN?xLcGuQ+>L3V7t|FV>i=(5PXoi~@d$YQ`oe!^65sNX=21E>hE0lE6%QV-;3b z;cdQE_{8tv(s%|HjYEQRJNc{{o^P6m#_ioJeBB4P_xU8J8jrN`NDmWxPC5naXn!N3 zX0jscgf#g+sR?mGwjxB(RW||1vbmi&rFje$1m>AayN%9=gk3`9e;E;6F4!%s@S$cY z|Eba6jFxD8TXf|N$aDyc_`IA2eKfI6+O zUpISKna1+9#1LweEeLbChjiPBPk+#T$QqJ{-a=DgAoSaaD!OxYKLZxkyJEiS4@pIY zs~CFek0;@`?HSwXvNr+Neg;@iEq|M5v}1=G zDEpn>+uiJ;d_G%2n}D$i7!NdHJSkYhxBwT3gs)5jslEYojrw=5(r3GG@|Am~O#6_p zY?kR8jB7CNMPOXPg4_j!J2$IBn$Ym6}^K@jed0EHw+}r78(EbS{Fm=$Qs^cdMNAp zBHd5pRqh3R?SogD72g9qz+0$@&w8xc4Aq)R*?EW%_B4!^{h~<;Eq^9c=-dIO=!7OE zd9~{Ie+U>7GxvIf(b9&uq}7TO4uePB)&`SI=H2m6Vgu>jOJ{aE?~&fA8u#Qac>WLm z@V6h#x##~FdlQ&Xdi@FQ1@qG&fPVL`ZyfGzwpYg>swDP!s(%(cdBX zwgrp-E4MC-;$?l?Zh!Udn7TCbCcgygm)y~Ali1uh9oh#MG%ID#&n;{4sKKKH#iL%q z&KqslM*`}nTUNwd$+)ZqKQ)mm#Z)qP(g4<8DA_&$*1_jYnmj@S^$pa&K&UU+T$2LE zI??BfxLyFdLgo4~Xo`m>4Babz+6Pq6m9^&w>BXIO>KE>AQT6VZT@ekqFGQ_ENlC=rdPH&4~U%C6b^NWz#F>kvUT277#%bxJMFf z&K!vpN7|&4DSuI*KPVz^k(O5{aJRVQ?Dt%5+idAd2z}AAmvPJ9J5G3xxT@r*sf(iz zLD_VZ0%Y1M)`G1?5MiRD+-;-D%ZIjkyXQ-l$kzpl@4tw=Ju~L3qBJHb3ndYVt8JPL zyD@j)JSmmwHg_+P8UD)Oh1BpvJuZ0 zC7uQG+Va&@z2GIL%a7SS;(yP+|7*k2<6=`Jmux*>Mwd0v@m0|2^Z=Q=OMW>*+rW5c zmNwTfle}4qycVFP)DIrR4TC;WdQwKI+(qk;jmeIek%l-e2+zzO$U2u%Bq;0NmzQ?| z#Z%uLmVdj5{uS__>kJpmIgJaEu>jtKg%`HD&l z5j5lu*yz>$jM_6qnM3subst{fDr)Pe$3C%d!GDQ+QK2hNn1cxVq-)KHoVC(|vz;Ra z%{PZMD^tzNRN5shNM1%NUC|wksPdy6;?q`aDV}!8R_*NM4$A~5StLn4+YJn!o_6|g zYvbU43)Gu}+~YSw)qesCs-j56bh$$HWCABinlDFj4K#MSeJfGG6m^lBfdE7VAZFHS kBp(t1W8vz~FN)qv&8WNyPxLMR7XSeN|5@eR=mC2G0BbbJ#sB~S delta 2470 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 diff --git a/build/version.go b/build/version.go index 1e9bcba98..f0b09661b 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.9.0-rc1" +const BuildVersion = "1.9.0-rc2" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit From ba63b93026b95d758542fab9b5cdda2cafae6ab9 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 30 Apr 2021 14:34:03 -0400 Subject: [PATCH 07/80] Fix 1.9.0-rc2 date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b502a1447..95bc25dbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Lotus changelog -# 1.9.0-rc2 / 2021-04-27 +# 1.9.0-rc2 / 2021-04-30 This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. From f6360c34dd97366692435a4765f222150779bc35 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Wed, 28 Apr 2021 19:24:09 -0400 Subject: [PATCH 08/80] Add verifreg utils to CLI --- cli/cmd.go | 1 + cli/verifreg.go | 276 ++++++++++++++++++++++++++++++++++ cmd/lotus-shed/verifreg.go | 30 ++-- documentation/en/cli-lotus.md | 99 +++++++++++- 4 files changed, 391 insertions(+), 15 deletions(-) create mode 100644 cli/verifreg.go diff --git a/cli/cmd.go b/cli/cmd.go index 6ecd236f4..70cd79e44 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -71,6 +71,7 @@ var Commands = []*cli.Command{ WithCategory("basic", walletCmd), WithCategory("basic", clientCmd), WithCategory("basic", multisigCmd), + WithCategory("basic", verifRegCmd), WithCategory("basic", paychCmd), WithCategory("developer", AuthCmd), WithCategory("developer", MpoolCmd), diff --git a/cli/verifreg.go b/cli/verifreg.go new file mode 100644 index 000000000..70d03df26 --- /dev/null +++ b/cli/verifreg.go @@ -0,0 +1,276 @@ +package cli + +import ( + "context" + "fmt" + + verifreg4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/verifreg" + + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/api/v0api" + + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/blockstore" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" + "github.com/filecoin-project/lotus/chain/types" + cbor "github.com/ipfs/go-ipld-cbor" +) + +var verifRegCmd = &cli.Command{ + Name: "verifreg", + Usage: "Interact with the verified registry actor", + Flags: []cli.Flag{}, + Subcommands: []*cli.Command{ + verifRegVerifyClientCmd, + verifRegListVerifiersCmd, + verifRegListClientsCmd, + verifRegCheckClientCmd, + verifRegCheckVerifierCmd, + }, +} + +var verifRegVerifyClientCmd = &cli.Command{ + Name: "verify-client", + Usage: "give allowance to the specified verified client address", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "from", + Usage: "specify your verifier address to send the message from", + Required: true, + }, + }, + Action: func(cctx *cli.Context) error { + froms := cctx.String("from") + if froms == "" { + return fmt.Errorf("must specify from address with --from") + } + + fromk, err := address.NewFromString(froms) + if err != nil { + return err + } + + if cctx.Args().Len() != 2 { + return fmt.Errorf("must specify two arguments: address and allowance") + } + + target, err := address.NewFromString(cctx.Args().Get(0)) + if err != nil { + return err + } + + allowance, err := types.BigFromString(cctx.Args().Get(1)) + if err != nil { + return err + } + + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + found, dcap, err := checkVerifier(ctx, api, fromk) + if err != nil { + return err + } + + if !found { + return xerrors.New("sender address must be a verifier") + } + + if dcap.Cmp(allowance.Int) < 0 { + return xerrors.Errorf("cannot allot more allowance than verifier data cap: %s < %s", dcap, allowance) + } + + // TODO: This should be abstracted over actor versions + params, err := actors.SerializeParams(&verifreg4.AddVerifiedClientParams{Address: target, Allowance: allowance}) + if err != nil { + return err + } + + msg := &types.Message{ + To: verifreg.Address, + From: fromk, + Method: verifreg.Methods.AddVerifiedClient, + Params: params, + } + + smsg, err := api.MpoolPushMessage(ctx, msg, nil) + if err != nil { + return err + } + + fmt.Printf("message sent, now waiting on cid: %s\n", smsg.Cid()) + + mwait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) + if err != nil { + return err + } + + if mwait.Receipt.ExitCode != 0 { + return fmt.Errorf("failed to add verified client: %d", mwait.Receipt.ExitCode) + } + + return nil + }, +} + +var verifRegListVerifiersCmd = &cli.Command{ + Name: "list-verifiers", + Usage: "list all verifiers", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + act, err := api.StateGetActor(ctx, verifreg.Address, types.EmptyTSK) + if err != nil { + return err + } + + apibs := blockstore.NewAPIBlockstore(api) + store := adt.WrapStore(ctx, cbor.NewCborStore(apibs)) + + st, err := verifreg.Load(store, act) + if err != nil { + return err + } + return st.ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error { + _, err := fmt.Printf("%s: %s\n", addr, dcap) + return err + }) + }, +} + +var verifRegListClientsCmd = &cli.Command{ + Name: "list-clients", + Usage: "list all verified clients", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + act, err := api.StateGetActor(ctx, verifreg.Address, types.EmptyTSK) + if err != nil { + return err + } + + apibs := blockstore.NewAPIBlockstore(api) + store := adt.WrapStore(ctx, cbor.NewCborStore(apibs)) + + st, err := verifreg.Load(store, act) + if err != nil { + return err + } + return st.ForEachClient(func(addr address.Address, dcap abi.StoragePower) error { + _, err := fmt.Printf("%s: %s\n", addr, dcap) + return err + }) + }, +} + +var verifRegCheckClientCmd = &cli.Command{ + Name: "check-client", + Usage: "check verified client remaining bytes", + Action: func(cctx *cli.Context) error { + if !cctx.Args().Present() { + return fmt.Errorf("must specify client address to check") + } + + caddr, err := address.NewFromString(cctx.Args().First()) + if err != nil { + return err + } + + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + dcap, err := api.StateVerifiedClientStatus(ctx, caddr, types.EmptyTSK) + if err != nil { + return err + } + if dcap == nil { + return xerrors.Errorf("client %s is not a verified client", err) + } + + fmt.Println(*dcap) + + return nil + }, +} + +var verifRegCheckVerifierCmd = &cli.Command{ + Name: "check-verifier", + Usage: "check verifiers remaining bytes", + Action: func(cctx *cli.Context) error { + if !cctx.Args().Present() { + return fmt.Errorf("must specify verifier address to check") + } + + vaddr, err := address.NewFromString(cctx.Args().First()) + if err != nil { + return err + } + + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + found, dcap, err := checkVerifier(ctx, api, vaddr) + if err != nil { + return err + } + if !found { + return fmt.Errorf("not found") + } + + fmt.Println(dcap) + + return nil + }, +} + +func checkVerifier(ctx context.Context, api v0api.FullNode, vaddr address.Address) (bool, abi.StoragePower, error) { + vid, err := api.StateLookupID(ctx, vaddr, types.EmptyTSK) + if err != nil { + return false, big.Zero(), err + } + + act, err := api.StateGetActor(ctx, verifreg.Address, types.EmptyTSK) + if err != nil { + return false, big.Zero(), err + } + + apibs := blockstore.NewAPIBlockstore(api) + store := adt.WrapStore(ctx, cbor.NewCborStore(apibs)) + + st, err := verifreg.Load(store, act) + if err != nil { + return false, big.Zero(), err + } + + return st.VerifierDataCap(vid) +} diff --git a/cmd/lotus-shed/verifreg.go b/cmd/lotus-shed/verifreg.go index 426827ad2..988de5d53 100644 --- a/cmd/lotus-shed/verifreg.go +++ b/cmd/lotus-shed/verifreg.go @@ -102,8 +102,9 @@ var verifRegAddVerifierCmd = &cli.Command{ } var verifRegVerifyClientCmd = &cli.Command{ - Name: "verify-client", - Usage: "make a given account a verified client", + Name: "verify-client", + Usage: "make a given account a verified client", + Hidden: true, Flags: []cli.Flag{ &cli.StringFlag{ Name: "from", @@ -111,6 +112,7 @@ var verifRegVerifyClientCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { + fmt.Println("DEPRECATED: This behavior is being moved to `lotus verifreg`") froms := cctx.String("from") if froms == "" { return fmt.Errorf("must specify from address with --from") @@ -175,9 +177,11 @@ var verifRegVerifyClientCmd = &cli.Command{ } var verifRegListVerifiersCmd = &cli.Command{ - Name: "list-verifiers", - Usage: "list all verifiers", + Name: "list-verifiers", + Usage: "list all verifiers", + Hidden: true, Action: func(cctx *cli.Context) error { + fmt.Println("DEPRECATED: This behavior is being moved to `lotus verifreg`") api, closer, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err @@ -205,9 +209,11 @@ var verifRegListVerifiersCmd = &cli.Command{ } var verifRegListClientsCmd = &cli.Command{ - Name: "list-clients", - Usage: "list all verified clients", + Name: "list-clients", + Usage: "list all verified clients", + Hidden: true, Action: func(cctx *cli.Context) error { + fmt.Println("DEPRECATED: This behavior is being moved to `lotus verifreg`") api, closer, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err @@ -235,9 +241,11 @@ var verifRegListClientsCmd = &cli.Command{ } var verifRegCheckClientCmd = &cli.Command{ - Name: "check-client", - Usage: "check verified client remaining bytes", + Name: "check-client", + Usage: "check verified client remaining bytes", + Hidden: true, Action: func(cctx *cli.Context) error { + fmt.Println("DEPRECATED: This behavior is being moved to `lotus verifreg`") if !cctx.Args().Present() { return fmt.Errorf("must specify client address to check") } @@ -269,9 +277,11 @@ var verifRegCheckClientCmd = &cli.Command{ } var verifRegCheckVerifierCmd = &cli.Command{ - Name: "check-verifier", - Usage: "check verifiers remaining bytes", + Name: "check-verifier", + Usage: "check verifiers remaining bytes", + Hidden: true, Action: func(cctx *cli.Context) error { + fmt.Println("DEPRECATED: This behavior is being moved to `lotus verifreg`") if !cctx.Args().Present() { return fmt.Errorf("must specify verifier address to check") } diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index ebd3300f0..82c8dfad3 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -15,11 +15,12 @@ COMMANDS: version Print version help, h Shows a list of commands or help for one command BASIC: - send Send funds between accounts - wallet Manage wallet - client Make deals, store data, retrieve data - msig Interact with a multisig wallet - paych Manage payment channels + send Send funds between accounts + wallet Manage wallet + client Make deals, store data, retrieve data + msig Interact with a multisig wallet + verifreg Interact with the verified registry actor + paych Manage payment channels DEVELOPER: auth Manage RPC permissions mpool Manage message pool @@ -1029,6 +1030,94 @@ OPTIONS: ``` +## lotus verifreg +``` +NAME: + lotus verifreg - Interact with the verified registry actor + +USAGE: + lotus verifreg command [command options] [arguments...] + +COMMANDS: + verify-client give allowance to the specified verified client address + list-verifiers list all verifiers + list-clients list all verified clients + check-client check verified client remaining bytes + check-verifier check verifiers remaining bytes + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus verifreg verify-client +``` +NAME: + lotus verifreg verify-client - give allowance to the specified verified client address + +USAGE: + lotus verifreg verify-client [command options] [arguments...] + +OPTIONS: + --from value specify your verifier address to send the message from + --help, -h show help (default: false) + +``` + +### lotus verifreg list-verifiers +``` +NAME: + lotus verifreg list-verifiers - list all verifiers + +USAGE: + lotus verifreg list-verifiers [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus verifreg list-clients +``` +NAME: + lotus verifreg list-clients - list all verified clients + +USAGE: + lotus verifreg list-clients [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus verifreg check-client +``` +NAME: + lotus verifreg check-client - check verified client remaining bytes + +USAGE: + lotus verifreg check-client [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus verifreg check-verifier +``` +NAME: + lotus verifreg check-verifier - check verifiers remaining bytes + +USAGE: + lotus verifreg check-verifier [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + ## lotus paych ``` NAME: From 323bb02ca5a87356d7fdc89ad829333751495c8e Mon Sep 17 00:00:00 2001 From: Travis Person Date: Tue, 4 May 2021 20:14:32 +0000 Subject: [PATCH 09/80] Update to new proofs with gpu support enabled in release binaries --- extern/filecoin-ffi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 3db17a0a0..9f60ca8af 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 3db17a0a0f24ce6a04e946f86bf18b0e1d8c0007 +Subproject commit 9f60ca8af53b393e994614ae6814f5f9579fbbd9 From 14f6d170b27a262a93a310ec99a6e20cf05e9b95 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Tue, 4 May 2021 18:18:26 +0200 Subject: [PATCH 10/80] Add a mining-heartbeat INFO line at every epoch --- chain/gen/gen.go | 9 +++++++++ miner/miner.go | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index d06c755fa..a6bf1b2b1 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -3,6 +3,7 @@ package gen import ( "bytes" "context" + "encoding/base64" "fmt" "io" "io/ioutil" @@ -610,6 +611,8 @@ func (wpp *wppProvider) ComputeProof(context.Context, []proof2.SectorInfo, abi.P return ValidWpostForTesting, nil } +var b64 = base64.URLEncoding.WithPadding(base64.NoPadding) + func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch, miner address.Address, brand types.BeaconEntry, mbi *api.MiningBaseInfo, a MiningCheckAPI) (*types.ElectionProof, error) { @@ -631,6 +634,12 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch, ep := &types.ElectionProof{VRFProof: vrfout} j := ep.ComputeWinCount(mbi.MinerPower, mbi.NetworkPower) ep.WinCount = j + + log.Infow("completed winAttemptVRF", + "VRFb64", b64.EncodeToString(vrfout), + "winCount", j, + ) + if j < 1 { return nil, nil } diff --git a/miner/miner.go b/miner/miner.go index eb7dd95f5..1e6ff2792 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -11,6 +11,7 @@ import ( proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/gen/slashfilter" "github.com/filecoin-project/go-address" @@ -423,8 +424,37 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, return nil, xerrors.Errorf("failed to get mining base info: %w", err) } if mbi == nil { + log.Warnf("mineOne: unexpectedly nil MiningBaseInfo for round %d, off tipset %d/%s", round, base.TipSet.Height(), base.TipSet.Key().String()) return nil, nil } + + // always write out a log from this point out + var winner *types.ElectionProof + lookBack := make(chan int64) + + // figure this out in the background, instead of slowing down the main loop + go func() { + lb := int64(-1) + if netVer, err := m.api.StateNetworkVersion(ctx, base.TipSet.Key()); err == nil { + lb = int64(policy.GetWinningPoStSectorSetLookback(netVer)) + } + lookBack <- lb + }() + + defer func() { + + log.Infow( + "completed mineOne", + "forRound", int64(round), + "baseEpoch", int64(base.TipSet.Height()), + "lookbackEpochs", <-lookBack, + "networkPowerAtLookback", mbi.NetworkPower.String(), + "minerPowerAtLookback", mbi.MinerPower.String(), + "isEligible", mbi.EligibleForMining, + "isWinner", (winner != nil), + ) + }() + if !mbi.EligibleForMining { // slashed or just have no power yet return nil, nil @@ -451,7 +481,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, return nil, xerrors.Errorf("scratching ticket failed: %w", err) } - winner, err := gen.IsRoundWinner(ctx, base.TipSet, round, m.address, rbase, mbi, m.api) + winner, err = gen.IsRoundWinner(ctx, base.TipSet, round, m.address, rbase, mbi, m.api) if err != nil { return nil, xerrors.Errorf("failed to check if we win next round: %w", err) } @@ -503,7 +533,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, for i, header := range base.TipSet.Blocks() { parentMiners[i] = header.Miner } - log.Infow("mined new block", "cid", b.Cid(), "height", b.Header.Height, "miner", b.Header.Miner, "parents", parentMiners, "took", dur) + log.Infow("mined new block", "cid", b.Cid(), "height", int64(b.Header.Height), "miner", b.Header.Miner, "parents", parentMiners, "parentTipset", base.TipSet.Key().String(), "took", dur) if dur > time.Second*time.Duration(build.BlockDelaySecs) { log.Warnw("CAUTION: block production took longer than the block delay. Your computer may not be fast enough to keep up", "tMinerBaseInfo ", tMBI.Sub(start), From 3b0fc01e820f4d55d1b54dc73e12927d56172b49 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Wed, 5 May 2021 20:39:16 +0200 Subject: [PATCH 11/80] Log more ComputeVRF() inputs as per Why's request --- chain/gen/gen.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index a6bf1b2b1..b4e04424c 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -636,7 +636,10 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch, ep.WinCount = j log.Infow("completed winAttemptVRF", - "VRFb64", b64.EncodeToString(vrfout), + "beaconRound", brand.Round, + "beaconDataB64", b64.EncodeToString(brand.Data), + "electionRandB64", b64.EncodeToString(electionRand), + "vrfB64", b64.EncodeToString(vrfout), "winCount", j, ) From 26841aa09430b3d6d8be013e890ce31f913fef9f Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Wed, 5 May 2021 22:54:01 +0200 Subject: [PATCH 12/80] mining lookback is effectively a constant - make it so --- chain/actors/policy/policy.go | 1 + miner/miner.go | 14 +------------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index f210b8d94..07f489b11 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -187,6 +187,7 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { return 10 } + // NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well return ChainFinality } diff --git a/miner/miner.go b/miner/miner.go index 1e6ff2792..2ad0f638e 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -430,24 +430,12 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, // always write out a log from this point out var winner *types.ElectionProof - lookBack := make(chan int64) - - // figure this out in the background, instead of slowing down the main loop - go func() { - lb := int64(-1) - if netVer, err := m.api.StateNetworkVersion(ctx, base.TipSet.Key()); err == nil { - lb = int64(policy.GetWinningPoStSectorSetLookback(netVer)) - } - lookBack <- lb - }() - defer func() { - log.Infow( "completed mineOne", "forRound", int64(round), "baseEpoch", int64(base.TipSet.Height()), - "lookbackEpochs", <-lookBack, + "lookbackEpochs", int64(policy.ChainFinality), // hardcoded as it is unlikely to change again: https://github.com/filecoin-project/lotus/blob/v1.8.0/chain/actors/policy/policy.go#L180-L186 "networkPowerAtLookback", mbi.NetworkPower.String(), "minerPowerAtLookback", mbi.MinerPower.String(), "isEligible", mbi.EligibleForMining, From 5b1fab8ffa3c1c3ddfb70f82df45cdad83f57ae8 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Fri, 23 Apr 2021 15:32:50 +0200 Subject: [PATCH 13/80] feat: markets v1.3 --- go.mod | 6 +++--- go.sum | 16 ++++++++++------ node/modules/client.go | 17 ++++++----------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index 9d5accbf1..059df7cc6 100644 --- a/go.mod +++ b/go.mod @@ -32,9 +32,9 @@ require ( github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 - github.com/filecoin-project/go-data-transfer v1.4.3 + github.com/filecoin-project/go-data-transfer v1.1.1-0.20210428151930-29bfef7e037e github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a - github.com/filecoin-project/go-fil-markets v1.2.5 + github.com/filecoin-project/go-fil-markets v1.3.0-rc1.0.20210428152617-25f4f7791e17 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 @@ -74,7 +74,7 @@ require ( github.com/ipfs/go-ds-pebble v0.0.2-0.20200921225637-ce220f8ac459 github.com/ipfs/go-filestore v1.0.0 github.com/ipfs/go-fs-lock v0.0.6 - github.com/ipfs/go-graphsync v0.6.0 + github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17 github.com/ipfs/go-ipfs-blockstore v1.0.3 github.com/ipfs/go-ipfs-chunker v0.0.5 github.com/ipfs/go-ipfs-ds-help v1.0.0 diff --git a/go.sum b/go.sum index 54c5da743..33addbfb4 100644 --- a/go.sum +++ b/go.sum @@ -96,6 +96,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bep/debounce v1.2.0 h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo= +github.com/bep/debounce v1.2.0/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/briandowns/spinner v1.11.1/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= @@ -265,16 +267,16 @@ github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7/ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= -github.com/filecoin-project/go-data-transfer v1.4.3 h1:ECEw69NOfmEZ7XN1NSBvj3KTbbH2mIczQs+Z2w4bD7c= -github.com/filecoin-project/go-data-transfer v1.4.3/go.mod h1:n8kbDQXWrY1c4UgfMa9KERxNCWbOTDwdNhf2MpN9dpo= +github.com/filecoin-project/go-data-transfer v1.1.1-0.20210428151930-29bfef7e037e h1:8sGyac9gEAPRUifBYQfEdNqPUS6S0p4Eh+D1ATDgmIw= +github.com/filecoin-project/go-data-transfer v1.1.1-0.20210428151930-29bfef7e037e/go.mod h1:E3WW4mCEYwU2y65swPEajSZoFWFmfXt7uwGduoACZQc= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.2.5 h1:bQgtXbwxKyPxSEQoUI5EaTHJ0qfzyd5NosspuADCm6Y= -github.com/filecoin-project/go-fil-markets v1.2.5/go.mod h1:7JIqNBmFvOyBzk/EiPYnweVdQnWhshixb5B9b1653Ag= +github.com/filecoin-project/go-fil-markets v1.3.0-rc1.0.20210428152617-25f4f7791e17 h1:32eSVd/b6+Y0I+bx3OHAE5x3QggdK7Te4Ysv5rFUtSI= +github.com/filecoin-project/go-fil-markets v1.3.0-rc1.0.20210428152617-25f4f7791e17/go.mod h1:bYo+LdtoDRs1KLtogTHty1ioFFJDjf6mEVmYPT6dW/A= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= @@ -597,8 +599,10 @@ github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28 github.com/ipfs/go-graphsync v0.1.0/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE= github.com/ipfs/go-graphsync v0.4.2/go.mod h1:/VmbZTUdUMTbNkgzAiCEucIIAU3BkLE2cZrDCVUhyi0= github.com/ipfs/go-graphsync v0.4.3/go.mod h1:mPOwDYv128gf8gxPFgXnz4fNrSYPsWyqisJ7ych+XDY= -github.com/ipfs/go-graphsync v0.6.0 h1:x6UvDUGA7wjaKNqx5Vbo7FGT8aJ5ryYA0dMQ5jN3dF0= -github.com/ipfs/go-graphsync v0.6.0/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= +github.com/ipfs/go-graphsync v0.6.1 h1:i9wN7YkBXWwIsUjVQeuaDxFB59yWZrG1xL564Nz7aGE= +github.com/ipfs/go-graphsync v0.6.1/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= +github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17 h1:rOoF88dVuDGbIx7idSdimN7JvXriyOIT96WD3eX9sHA= +github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17/go.mod h1:5WyaeigpNdpiYQuW2vwpuecOoEfB4h747ZGEOKmAGTg= github.com/ipfs/go-hamt-ipld v0.1.1/go.mod h1:1EZCr2v0jlCnhpa+aZ0JZYp8Tt2w16+JJOAVz17YcDk= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= diff --git a/node/modules/client.go b/node/modules/client.go index c5dbff9bd..150eea75b 100644 --- a/node/modules/client.go +++ b/node/modules/client.go @@ -134,23 +134,18 @@ func NewClientGraphsyncDataTransfer(lc fx.Lifecycle, h host.Host, gs dtypes.Grap // data-transfer push / pull channel restart configuration: dtRestartConfig := dtimpl.ChannelRestartConfig(channelmonitor.Config{ - // For now only monitor push channels (for storage deals) - MonitorPushChannels: true, - // TODO: Enable pull channel monitoring (for retrievals) when the - // following issue has been fixed: - // https://github.com/filecoin-project/go-data-transfer/issues/172 - MonitorPullChannels: false, // Wait up to 30s for the other side to respond to an Open channel message AcceptTimeout: 30 * time.Second, - // Send a restart message if the data rate falls below 1024 bytes / minute - Interval: time.Minute, - MinBytesTransferred: 1024, - // Perform check 10 times / minute - ChecksPerInterval: 10, + // When an error occurs, wait a little while until all related errors + // have fired before sending a restart message + RestartDebounce: 10 * time.Second, // After sending a restart, wait for at least 1 minute before sending another RestartBackoff: time.Minute, // After trying to restart 3 times, give up and fail the transfer MaxConsecutiveRestarts: 3, + // After sending a restart message, the time to wait for the peer to + // respond with an ack of the restart + RestartAckTimeout: 30 * time.Second, // Wait up to 30s for the other side to send a Complete message once all // data has been sent / received CompleteTimeout: 30 * time.Second, From c17a340f2e6d78407236939827c3d03f40d64a89 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Fri, 30 Apr 2021 11:40:22 +0200 Subject: [PATCH 14/80] feat: deals end to end test with restarts --- .../baseline-docker-1-1-with-restarts.toml | 59 +++++++++++++++ .../_compositions/baseline-docker-1-1.toml | 2 +- testplans/lotus-soup/deals_e2e.go | 74 +++++++++++++++++-- testplans/lotus-soup/go.mod | 5 +- testplans/lotus-soup/go.sum | 21 +++--- testplans/lotus-soup/manifest.toml | 3 + testplans/lotus-soup/testkit/net.go | 5 ++ 7 files changed, 149 insertions(+), 20 deletions(-) create mode 100644 testplans/lotus-soup/_compositions/baseline-docker-1-1-with-restarts.toml diff --git a/testplans/lotus-soup/_compositions/baseline-docker-1-1-with-restarts.toml b/testplans/lotus-soup/_compositions/baseline-docker-1-1-with-restarts.toml new file mode 100644 index 000000000..28865a03b --- /dev/null +++ b/testplans/lotus-soup/_compositions/baseline-docker-1-1-with-restarts.toml @@ -0,0 +1,59 @@ +[metadata] + name = "lotus-soup" + author = "" + +[global] + plan = "lotus-soup" + case = "deals-e2e" + total_instances = 3 + builder = "docker:go" + runner = "local:docker" + +[global.build] + selectors = ["testground"] + +[global.run_config] + exposed_ports = { pprof = "6060", node_rpc = "1234", miner_rpc = "2345" } + +[global.build_config] + enable_go_build_cache = true + +[global.run.test_params] + clients = "1" + miners = "1" + genesis_timestamp_offset = "0" + balance = "20000000" # These balances will work for maximum 100 nodes, as TotalFilecoin is 2B + sectors = "3" + random_beacon_type = "mock" + mining_mode = "natural" + bandwidth = "4MB" + + +[[groups]] + id = "bootstrapper" + [groups.instances] + count = 1 + percentage = 0.0 + [groups.run] + [groups.run.test_params] + role = "bootstrapper" + +[[groups]] + id = "miners" + [groups.instances] + count = 1 + percentage = 0.0 + [groups.run] + [groups.run.test_params] + role = "miner" + +[[groups]] + id = "clients" + [groups.instances] + count = 1 + percentage = 0.0 + [groups.run] + [groups.run.test_params] + role = "client" + # Bounce the connection during push and pull requests + bounce_conn_data_transfers = "true" diff --git a/testplans/lotus-soup/_compositions/baseline-docker-1-1.toml b/testplans/lotus-soup/_compositions/baseline-docker-1-1.toml index 9012be69c..25a31f9ec 100644 --- a/testplans/lotus-soup/_compositions/baseline-docker-1-1.toml +++ b/testplans/lotus-soup/_compositions/baseline-docker-1-1.toml @@ -23,7 +23,7 @@ miners = "1" genesis_timestamp_offset = "0" balance = "20000000" # These balances will work for maximum 100 nodes, as TotalFilecoin is 2B - sectors = "10" + sectors = "3" random_beacon_type = "mock" mining_mode = "natural" diff --git a/testplans/lotus-soup/deals_e2e.go b/testplans/lotus-soup/deals_e2e.go index 42d969762..6737bdae2 100644 --- a/testplans/lotus-soup/deals_e2e.go +++ b/testplans/lotus-soup/deals_e2e.go @@ -4,19 +4,19 @@ import ( "context" "fmt" "io/ioutil" + mbig "math/big" "math/rand" "os" "time" - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/lotus/api" + "github.com/libp2p/go-libp2p-core/peer" "github.com/testground/sdk-go/sync" - mbig "math/big" - + "github.com/filecoin-project/go-address" + datatransfer "github.com/filecoin-project/go-data-transfer" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/testplans/lotus-soup/testkit" ) @@ -39,6 +39,8 @@ import ( // Then we create a genesis block that allocates some funds to each node and collects // the presealed sectors. func dealsE2E(t *testkit.TestEnvironment) error { + t.RecordMessage("running node with role '%s'", t.Role) + // Dispatch/forward non-client roles to defaults. if t.Role != "client" { return testkit.HandleDefaultRole(t) @@ -79,7 +81,7 @@ func dealsE2E(t *testkit.TestEnvironment) error { time.Sleep(time.Duration(t.GlobalSeq) * 5 * time.Second) - // generate 1600 bytes of random data + // generate 5000000 bytes of random data data := make([]byte, 5000000) rand.New(rand.NewSource(time.Now().UnixNano())).Read(data) @@ -100,6 +102,15 @@ func dealsE2E(t *testkit.TestEnvironment) error { } t.RecordMessage("file cid: %s", fcid) + // Check if we should bounce the connection during data transfers + if t.BooleanParam("bounce_conn_data_transfers") { + t.RecordMessage("Will bounce connection during push and pull data-transfers") + err = bounceConnInTransfers(ctx, t, client, minerAddr.MinerNetAddrs.ID) + if err != nil { + return err + } + } + // start deal t1 := time.Now() deal := testkit.StartDeal(ctx, minerAddr.MinerActorAddr, client, fcid.Root, fastRetrieval) @@ -133,6 +144,55 @@ func dealsE2E(t *testkit.TestEnvironment) error { return nil } +func bounceConnInTransfers(ctx context.Context, t *testkit.TestEnvironment, client api.FullNode, minerPeerID peer.ID) error { + storageConnBroken := false + retrievalConnBroken := false + upds, err := client.ClientDataTransferUpdates(ctx) + if err != nil { + return err + } + + go func() { + for upd := range upds { + dir := "push" + if !upd.IsSender { + dir = "pull" + } + + t.RecordMessage("%s data transfer status: %s, transferred: %d", dir, datatransfer.Statuses[upd.Status], upd.Transferred) + + // Bounce the connection after the first block is sent for the storage deal + if upd.IsSender && upd.Transferred > 0 && !storageConnBroken { + storageConnBroken = true + bounceConnection(ctx, t, client, minerPeerID) + } + + // Bounce the connection after the first block is received for the retrieval deal + if !upd.IsSender && upd.Transferred > 0 && !retrievalConnBroken { + retrievalConnBroken = true + bounceConnection(ctx, t, client, minerPeerID) + } + } + }() + + return nil +} + +func bounceConnection(ctx context.Context, t *testkit.TestEnvironment, client api.FullNode, minerPeerID peer.ID) { + t.RecordMessage("disconnecting peer %s", minerPeerID) + client.NetBlockAdd(ctx, api.NetBlockList{ + Peers: []peer.ID{minerPeerID}, + }) + + go func() { + time.Sleep(3 * time.Second) + t.RecordMessage("reconnecting to peer %s", minerPeerID) + client.NetBlockRemove(ctx, api.NetBlockList{ + Peers: []peer.ID{minerPeerID}, + }) + }() +} + // filToAttoFil converts a fractional filecoin value into AttoFIL, rounding if necessary func filToAttoFil(f float64) big.Int { a := mbig.NewFloat(f) diff --git a/testplans/lotus-soup/go.mod b/testplans/lotus-soup/go.mod index 872c17735..154e8564b 100644 --- a/testplans/lotus-soup/go.mod +++ b/testplans/lotus-soup/go.mod @@ -8,11 +8,12 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/drand/drand v1.2.1 github.com/filecoin-project/go-address v0.0.5 - github.com/filecoin-project/go-fil-markets v1.2.5 + github.com/filecoin-project/go-data-transfer v1.1.1-0.20210428151930-29bfef7e037e + github.com/filecoin-project/go-fil-markets v1.3.0-rc1.0.20210428152617-25f4f7791e17 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-state-types v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/lotus v1.8.1-0.20210428122447-4688da51781a + github.com/filecoin-project/lotus v1.6.1-0.20210429092235-20782ecae36f github.com/filecoin-project/specs-actors v0.9.13 github.com/google/uuid v1.1.2 github.com/gorilla/mux v1.7.4 diff --git a/testplans/lotus-soup/go.sum b/testplans/lotus-soup/go.sum index 929e2a612..41c2501f6 100644 --- a/testplans/lotus-soup/go.sum +++ b/testplans/lotus-soup/go.sum @@ -101,6 +101,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bep/debounce v1.2.0 h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo= +github.com/bep/debounce v1.2.0/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= @@ -273,16 +275,16 @@ github.com/filecoin-project/go-commp-utils v0.1.0/go.mod h1:6s95K91mCyHY51RPWECZ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= -github.com/filecoin-project/go-data-transfer v1.4.3 h1:ECEw69NOfmEZ7XN1NSBvj3KTbbH2mIczQs+Z2w4bD7c= -github.com/filecoin-project/go-data-transfer v1.4.3/go.mod h1:n8kbDQXWrY1c4UgfMa9KERxNCWbOTDwdNhf2MpN9dpo= +github.com/filecoin-project/go-data-transfer v1.1.1-0.20210428151930-29bfef7e037e h1:8sGyac9gEAPRUifBYQfEdNqPUS6S0p4Eh+D1ATDgmIw= +github.com/filecoin-project/go-data-transfer v1.1.1-0.20210428151930-29bfef7e037e/go.mod h1:E3WW4mCEYwU2y65swPEajSZoFWFmfXt7uwGduoACZQc= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.2.5 h1:bQgtXbwxKyPxSEQoUI5EaTHJ0qfzyd5NosspuADCm6Y= -github.com/filecoin-project/go-fil-markets v1.2.5/go.mod h1:7JIqNBmFvOyBzk/EiPYnweVdQnWhshixb5B9b1653Ag= +github.com/filecoin-project/go-fil-markets v1.3.0-rc1.0.20210428152617-25f4f7791e17 h1:32eSVd/b6+Y0I+bx3OHAE5x3QggdK7Te4Ysv5rFUtSI= +github.com/filecoin-project/go-fil-markets v1.3.0-rc1.0.20210428152617-25f4f7791e17/go.mod h1:bYo+LdtoDRs1KLtogTHty1ioFFJDjf6mEVmYPT6dW/A= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= @@ -310,8 +312,8 @@ github.com/filecoin-project/go-statestore v0.1.1 h1:ufMFq00VqnT2CAuDpcGnwLnCX1I/ github.com/filecoin-project/go-statestore v0.1.1/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= -github.com/filecoin-project/lotus v1.8.1-0.20210428122447-4688da51781a h1:8M4BZHB+R3psW72CGarBdyc5OvbFBRRlebzw8u5EWsg= -github.com/filecoin-project/lotus v1.8.1-0.20210428122447-4688da51781a/go.mod h1:4YC/8rizrrp2wKOYvHQEjCxZbziXi68BhrzvI+FCye0= +github.com/filecoin-project/lotus v1.6.1-0.20210429092235-20782ecae36f h1:e85TP82iW8oMUCt/hdbpAExiIQrez8LHJay0bDi4ITQ= +github.com/filecoin-project/lotus v1.6.1-0.20210429092235-20782ecae36f/go.mod h1:Sp9hSZZXileBDMt8rQMYTy2/c+0cywaYvetKtuWALk0= github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.12/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= github.com/filecoin-project/specs-actors v0.9.13 h1:rUEOQouefi9fuVY/2HOroROJlZbOzWYXXeIh41KF2M4= @@ -322,8 +324,6 @@ github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb/go.mod h1:LljnY2Mn2homxZsmokJZCpRuhOPxfXhvcek5gWkmqAc= github.com/filecoin-project/specs-actors/v3 v3.1.0 h1:s4qiPw8pgypqBGAy853u/zdZJ7K9cTZdM1rTiSonHrg= github.com/filecoin-project/specs-actors/v3 v3.1.0/go.mod h1:mpynccOLlIRy0QnR008BwYBwT9fen+sPR13MA1VmMww= -github.com/filecoin-project/specs-actors/v4 v4.0.0 h1:vMALksY5G3J5rj3q9rbcyB+f4Tk1xrLqSgdB3jOok4s= -github.com/filecoin-project/specs-actors/v4 v4.0.0/go.mod h1:TkHXf/l7Wyw4ZejyXIPS2rK8bBO0rdwhTZyQQgaglng= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= @@ -620,8 +620,9 @@ github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28 github.com/ipfs/go-graphsync v0.1.0/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE= github.com/ipfs/go-graphsync v0.4.2/go.mod h1:/VmbZTUdUMTbNkgzAiCEucIIAU3BkLE2cZrDCVUhyi0= github.com/ipfs/go-graphsync v0.4.3/go.mod h1:mPOwDYv128gf8gxPFgXnz4fNrSYPsWyqisJ7ych+XDY= -github.com/ipfs/go-graphsync v0.6.0 h1:x6UvDUGA7wjaKNqx5Vbo7FGT8aJ5ryYA0dMQ5jN3dF0= -github.com/ipfs/go-graphsync v0.6.0/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= +github.com/ipfs/go-graphsync v0.6.1/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= +github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17 h1:rOoF88dVuDGbIx7idSdimN7JvXriyOIT96WD3eX9sHA= +github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17/go.mod h1:5WyaeigpNdpiYQuW2vwpuecOoEfB4h747ZGEOKmAGTg= github.com/ipfs/go-hamt-ipld v0.1.1/go.mod h1:1EZCr2v0jlCnhpa+aZ0JZYp8Tt2w16+JJOAVz17YcDk= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= diff --git a/testplans/lotus-soup/manifest.toml b/testplans/lotus-soup/manifest.toml index f33acffb7..fc58fbd5b 100644 --- a/testplans/lotus-soup/manifest.toml +++ b/testplans/lotus-soup/manifest.toml @@ -58,6 +58,9 @@ instances = { min = 1, max = 100, default = 5 } # Fast retrieval fast_retrieval = { type = "bool", default = false } + # Bounce connection during push and pull data transfers + bounce_conn_data_transfers = { type = "bool", default = false } + [[testcases]] name = "drand-halting" diff --git a/testplans/lotus-soup/testkit/net.go b/testplans/lotus-soup/testkit/net.go index 018813830..d2dbc2ae6 100644 --- a/testplans/lotus-soup/testkit/net.go +++ b/testplans/lotus-soup/testkit/net.go @@ -74,6 +74,11 @@ func ApplyNetworkParameters(t *TestEnvironment) { t.D().RecordPoint("duplicate_packet_correlation", float64(ls.DuplicateCorr)) } + if t.IsParamSet("bandwidth") { + ls.Bandwidth = t.SizeParam("bandwidth") + t.D().RecordPoint("bandwidth_bytes", float64(ls.Bandwidth)) + } + t.NetClient.MustConfigureNetwork(ctx, &network.Config{ Network: "default", Enable: true, From 312ad4abdce6cc477ee835e96ee3a1fd207f22ae Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Thu, 6 May 2021 09:49:35 +0200 Subject: [PATCH 15/80] feat: update to markets v1.3.0 --- go.mod | 6 +++--- go.sum | 10 ++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 059df7cc6..a06f3db15 100644 --- a/go.mod +++ b/go.mod @@ -32,9 +32,9 @@ require ( github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 - github.com/filecoin-project/go-data-transfer v1.1.1-0.20210428151930-29bfef7e037e + github.com/filecoin-project/go-data-transfer v1.5.0 github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a - github.com/filecoin-project/go-fil-markets v1.3.0-rc1.0.20210428152617-25f4f7791e17 + github.com/filecoin-project/go-fil-markets v1.3.0 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 @@ -74,7 +74,7 @@ require ( github.com/ipfs/go-ds-pebble v0.0.2-0.20200921225637-ce220f8ac459 github.com/ipfs/go-filestore v1.0.0 github.com/ipfs/go-fs-lock v0.0.6 - github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17 + github.com/ipfs/go-graphsync v0.6.1 github.com/ipfs/go-ipfs-blockstore v1.0.3 github.com/ipfs/go-ipfs-chunker v0.0.5 github.com/ipfs/go-ipfs-ds-help v1.0.0 diff --git a/go.sum b/go.sum index 33addbfb4..9e6d4a714 100644 --- a/go.sum +++ b/go.sum @@ -267,16 +267,16 @@ github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7/ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= -github.com/filecoin-project/go-data-transfer v1.1.1-0.20210428151930-29bfef7e037e h1:8sGyac9gEAPRUifBYQfEdNqPUS6S0p4Eh+D1ATDgmIw= -github.com/filecoin-project/go-data-transfer v1.1.1-0.20210428151930-29bfef7e037e/go.mod h1:E3WW4mCEYwU2y65swPEajSZoFWFmfXt7uwGduoACZQc= +github.com/filecoin-project/go-data-transfer v1.5.0 h1:eXmcq7boRl/S3plV0/h4qdxkM6EgFIXF9y3UdOL0VXE= +github.com/filecoin-project/go-data-transfer v1.5.0/go.mod h1:E3WW4mCEYwU2y65swPEajSZoFWFmfXt7uwGduoACZQc= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.3.0-rc1.0.20210428152617-25f4f7791e17 h1:32eSVd/b6+Y0I+bx3OHAE5x3QggdK7Te4Ysv5rFUtSI= -github.com/filecoin-project/go-fil-markets v1.3.0-rc1.0.20210428152617-25f4f7791e17/go.mod h1:bYo+LdtoDRs1KLtogTHty1ioFFJDjf6mEVmYPT6dW/A= +github.com/filecoin-project/go-fil-markets v1.3.0 h1:yYWHO5x87i+5UlqBwlMVk4oN2GPNfQ0WG6LdORArL/o= +github.com/filecoin-project/go-fil-markets v1.3.0/go.mod h1:v8QjFAGf5h2wKH3saYjGOu3pOFUoVQ1Uhow4gIcUR3I= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= @@ -601,8 +601,6 @@ github.com/ipfs/go-graphsync v0.4.2/go.mod h1:/VmbZTUdUMTbNkgzAiCEucIIAU3BkLE2cZ github.com/ipfs/go-graphsync v0.4.3/go.mod h1:mPOwDYv128gf8gxPFgXnz4fNrSYPsWyqisJ7ych+XDY= github.com/ipfs/go-graphsync v0.6.1 h1:i9wN7YkBXWwIsUjVQeuaDxFB59yWZrG1xL564Nz7aGE= github.com/ipfs/go-graphsync v0.6.1/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= -github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17 h1:rOoF88dVuDGbIx7idSdimN7JvXriyOIT96WD3eX9sHA= -github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17/go.mod h1:5WyaeigpNdpiYQuW2vwpuecOoEfB4h747ZGEOKmAGTg= github.com/ipfs/go-hamt-ipld v0.1.1/go.mod h1:1EZCr2v0jlCnhpa+aZ0JZYp8Tt2w16+JJOAVz17YcDk= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= From b1d046ce16b881b556a7bc91967f1f1f3a7e8968 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Thu, 6 May 2021 17:31:15 -0400 Subject: [PATCH 16/80] Update to proof v7.0.1 --- extern/filecoin-ffi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 9f60ca8af..dc4e4e8dc 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 9f60ca8af53b393e994614ae6814f5f9579fbbd9 +Subproject commit dc4e4e8dc9554dedb6f48304f7f0c6328331f9ec From 026cd103c2db979bc69af31fb56d6763dde87ba6 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Thu, 6 May 2021 15:36:11 -0700 Subject: [PATCH 17/80] add snapcraft --- Makefile | 4 ++++ snap/snapcraft.yaml | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 snap/snapcraft.yaml diff --git a/Makefile b/Makefile index 1ccce11ed..430efe72f 100644 --- a/Makefile +++ b/Makefile @@ -371,6 +371,10 @@ gen: type-gen method-gen docsgen api-gen @echo ">>> IF YOU'VE MODIFIED THE CLI, REMEMBER TO ALSO MAKE docsgen-cli" .PHONY: gen +snap: lotus lotus-miner lotus-worker + snapcraft + # snapcraft upload ./lotus_*.snap + # separate from gen because it needs binaries docsgen-cli: lotus lotus-miner lotus-worker python ./scripts/generate-lotus-cli.py diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 000000000..69522e5d3 --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,27 @@ +name: lotus +base: core20 +version: '1.8.0' +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 + +parts: + libs: + plugin: dump + source: ./ + organize: + 'lotus' : bin/ + 'lotus-*' : bin/ + stage-packages: + - ocl-icd-libopencl1 + - libhwloc15 +apps: + lotus: + command: bin/lotus + lotus-miner: + command: bin/lotus-miner + lotus-worker: + command: bin/lotus-worker From 838369229c4e2117b2bdc1a2d651f2b18bc7aeaf Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Thu, 6 May 2021 16:28:27 -0700 Subject: [PATCH 18/80] downgrade to core18 --- snap/snapcraft.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 69522e5d3..7cdc1746d 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: lotus -base: core20 +base: core18 version: '1.8.0' summary: filecoin daemon/client description: | @@ -17,7 +17,8 @@ parts: 'lotus-*' : bin/ stage-packages: - ocl-icd-libopencl1 - - libhwloc15 + - libhwloc1 + - libgcc1 apps: lotus: command: bin/lotus From 0398e556d4b00050c816c8d1b1ccde5f15a2392e Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Fri, 7 May 2021 11:09:06 -0400 Subject: [PATCH 19/80] Bump the version --- build/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/version.go b/build/version.go index f0b09661b..32ee57b4c 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.9.0-rc2" +const BuildVersion = "1.9.0-rc3" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit From 6f71eab8cee0b32832a3643e7918b6c7d66573fd Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Tue, 11 May 2021 04:26:04 +0200 Subject: [PATCH 20/80] Adjust lp2p retry params --- node/impl/client/client.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 5423f7f79..fa87446c9 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + "time" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -254,7 +255,9 @@ func (a *API) dealStarter(ctx context.Context, params *api.StartDealParams, isSt ClientSignature: *dealProposalSig, } dStream, err := network.NewFromLibp2pHost(a.Host, - network.RetryParameters(0, 0, 0, 0), + // params duplicated from .../node/modules/client.go + // https://github.com/filecoin-project/lotus/pull/5961#discussion_r629768011 + network.RetryParameters(time.Second, 5*time.Minute, 15, 5), ).NewDealStream(ctx, *mi.PeerId) if err != nil { return nil, xerrors.Errorf("opening dealstream to %s/%s failed: %w", params.Miner, *mi.PeerId, err) From f7fbaef361bf59aa3baaa70d3e84bd04cfa47000 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 4 May 2021 21:16:18 -0700 Subject: [PATCH 21/80] chore: update go-libp2p From 0.12.0 to 0.14.0. Headline for lotus: faster yamux. --- documentation/en/api-v0-methods-miner.md | 12 +- documentation/en/api-v0-methods.md | 12 +- documentation/en/api-v1-unstable-methods.md | 12 +- go.mod | 32 ++-- go.sum | 153 +++++++++++++------- node/impl/common/common.go | 2 +- 6 files changed, 138 insertions(+), 85 deletions(-) diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index ea5ca75f8..1f6cc98e9 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -885,8 +885,8 @@ Inputs: `null` Response: ```json { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ``` @@ -1035,8 +1035,8 @@ Inputs: ```json [ { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ] ``` @@ -1086,8 +1086,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 3c5356a56..2ce222878 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -2747,8 +2747,8 @@ Inputs: `null` Response: ```json { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ``` @@ -2897,8 +2897,8 @@ Inputs: ```json [ { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ] ``` @@ -2948,8 +2948,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 83c2d6d41..60c369948 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -2974,8 +2974,8 @@ Inputs: `null` Response: ```json { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ``` @@ -3124,8 +3124,8 @@ Inputs: ```json [ { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ] ``` @@ -3175,8 +3175,8 @@ Inputs: Response: ```json { - "Addrs": null, - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Addrs": [] } ``` diff --git a/go.mod b/go.mod index 384cac442..52d5cfbb4 100644 --- a/go.mod +++ b/go.mod @@ -88,7 +88,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 @@ -101,21 +101,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.0 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.3 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 @@ -123,10 +123,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 @@ -144,18 +143,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 ef3ac9678..29e62646e 100644 --- a/go.sum +++ b/go.sum @@ -105,14 +105,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= @@ -185,8 +189,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= @@ -321,8 +327,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= @@ -387,8 +394,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= @@ -418,8 +426,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= @@ -431,14 +440,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= @@ -679,8 +690,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= @@ -782,6 +794,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= @@ -812,8 +825,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= @@ -836,8 +850,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.0 h1:mYab0qShfAojYN/QTOtxPyQoK9knUHbUncwst4+wBcA= +github.com/libp2p/go-libp2p v0.14.0/go.mod h1:dsQrWLAoIn+GkHPN/U+yypizkHiB9tnv79Os+kSgQ4Q= 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= @@ -848,8 +863,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= @@ -896,8 +912,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= @@ -932,8 +952,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= @@ -945,8 +967,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= @@ -961,8 +983,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= @@ -973,8 +996,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= @@ -1001,8 +1024,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= @@ -1010,8 +1034,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= @@ -1021,8 +1046,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= @@ -1032,8 +1058,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.3 h1:x2bK2BWktdMdTrciiDmgTMIxYNBdkxewQFEjHDl7VgU= +github.com/libp2p/go-libp2p-yamux v0.5.3/go.mod h1:Vy3TMonBAfTMXHWopsMc8iX/XGRYrRlpUaMzaeuHV/s= 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= @@ -1045,8 +1072,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= @@ -1058,8 +1086,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= @@ -1075,8 +1104,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= @@ -1098,8 +1128,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= @@ -1111,12 +1142,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.1.1 h1:3RkXAnDmaXJPckF/QbDnNbA6lZXMgycNTVMMTQ2YlAI= +github.com/libp2p/go-yamux/v2 v2.1.1/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= @@ -1131,13 +1164,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= @@ -1171,6 +1204,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= @@ -1217,8 +1252,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= @@ -1248,8 +1284,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= @@ -1266,8 +1304,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= @@ -1285,6 +1321,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= @@ -1569,6 +1606,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= @@ -1597,8 +1635,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= @@ -1651,16 +1689,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= @@ -1683,8 +1724,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= @@ -1695,6 +1737,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= @@ -1730,6 +1773,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= @@ -1737,8 +1781,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= @@ -1756,8 +1803,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= @@ -1824,16 +1871,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= @@ -1877,10 +1929,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= @@ -1948,8 +2002,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= @@ -1965,8 +2020,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 0019187a4f67dec7694350329cdb972eafda7ddf Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Tue, 11 May 2021 04:44:07 +0200 Subject: [PATCH 22/80] Forgotten pre-API zero-price check --- cli/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/client.go b/cli/client.go index 2bea31cd6..84e077943 100644 --- a/cli/client.go +++ b/cli/client.go @@ -479,7 +479,7 @@ The minimum value is 518400 (6 months).`, var proposal *cid.Cid if cctx.Bool("manual-stateless-deal") { - if ref.TransferType != storagemarket.TTManual { + if ref.TransferType != storagemarket.TTManual || price.Int64() != 0 { return xerrors.New("when manual-stateless-deal is enabled, you must also provide a 'price' of 0 and specify 'manual-piece-cid' and 'manual-piece-size'") } proposal, err = api.ClientStatelessDeal(ctx, sdParams) From e07438417cbb8eb93098a0e97ae40f3c6dbd5825 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Tue, 11 May 2021 13:19:26 +0200 Subject: [PATCH 23/80] consider storiface.PathStorage when calculating storage requirements --- extern/sector-storage/stores/index.go | 10 +++++++++- extern/sector-storage/storiface/filetype.go | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/extern/sector-storage/stores/index.go b/extern/sector-storage/stores/index.go index 4acc2ecdb..b4fe61a32 100644 --- a/extern/sector-storage/stores/index.go +++ b/extern/sector-storage/stores/index.go @@ -3,6 +3,7 @@ package stores import ( "context" "errors" + "math" "net/url" gopath "path" "sort" @@ -383,7 +384,14 @@ func (i *Index) StorageBestAlloc(ctx context.Context, allocate storiface.SectorF var candidates []storageEntry - spaceReq, err := allocate.SealSpaceUse(ssize) + var err error + spaceReq := uint64(math.MaxUint64) + switch pathType { + case storiface.PathSealing: + spaceReq, err = allocate.SealSpaceUse(ssize) + case storiface.PathStorage: + spaceReq, err = allocate.StoreSpaceUse(ssize) + } if err != nil { return nil, xerrors.Errorf("estimating required space: %w", err) } diff --git a/extern/sector-storage/storiface/filetype.go b/extern/sector-storage/storiface/filetype.go index 3f7c7455e..2e0999022 100644 --- a/extern/sector-storage/storiface/filetype.go +++ b/extern/sector-storage/storiface/filetype.go @@ -73,6 +73,24 @@ func (t SectorFileType) SealSpaceUse(ssize abi.SectorSize) (uint64, error) { return need, nil } +func (t SectorFileType) StoreSpaceUse(ssize abi.SectorSize) (uint64, error) { + var need uint64 + for _, pathType := range PathTypes { + if !t.Has(pathType) { + continue + } + + oh, ok := FsOverheadFinalized[pathType] + if !ok { + return 0, xerrors.Errorf("no finalized overhead info for %s", pathType) + } + + need += uint64(oh) * uint64(ssize) / FSOverheadDen + } + + return need, nil +} + func (t SectorFileType) All() [FileTypes]bool { var out [FileTypes]bool From eb13c74dcea174284caa15b52be457f90ba54888 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Tue, 11 May 2021 18:14:01 +0200 Subject: [PATCH 24/80] panic on unknown pathType --- extern/sector-storage/stores/index.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/extern/sector-storage/stores/index.go b/extern/sector-storage/stores/index.go index b4fe61a32..a84adf016 100644 --- a/extern/sector-storage/stores/index.go +++ b/extern/sector-storage/stores/index.go @@ -3,7 +3,7 @@ package stores import ( "context" "errors" - "math" + "fmt" "net/url" gopath "path" "sort" @@ -385,12 +385,14 @@ func (i *Index) StorageBestAlloc(ctx context.Context, allocate storiface.SectorF var candidates []storageEntry var err error - spaceReq := uint64(math.MaxUint64) + var spaceReq uint64 switch pathType { case storiface.PathSealing: spaceReq, err = allocate.SealSpaceUse(ssize) case storiface.PathStorage: spaceReq, err = allocate.StoreSpaceUse(ssize) + default: + panic(fmt.Sprintf("unexpected pathType: %s", pathType)) } if err != nil { return nil, xerrors.Errorf("estimating required space: %w", err) From 60dca635f4eb3037576c1e0d3352530836df3902 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Wed, 12 May 2021 09:55:52 -0700 Subject: [PATCH 25/80] Update RELEASE_ISSUE_TEMPLATE.md Update RELEASE_ISSUE_TEMPLATE.md to account for binaries and improving along the way. --- documentation/misc/RELEASE_ISSUE_TEMPLATE.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md index df5e8d1c5..4d44e4b39 100644 --- a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md +++ b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md @@ -20,6 +20,8 @@ We're happy to announce Lotus X.Y.Z... ## ✅ Release Checklist +**Note for whomever is owning the release:** please capture notes as comments in this issue for anything you noticed that could be improved for future releases. There is a *Post Release* step below for incorporating changes back into the [RELEASE_ISSUE_TEMPLATE](https://github.com/filecoin-project/lotus/blob/master/documentation/misc/RELEASE_ISSUE_TEMPLATE.md), and this is easier done by collecting notes from along the way rather than just thinking about it at the end. + First steps: - [ ] Fork a new branch (`release/vX.Y.Z`) from `master` and make any further release related changes to this branch. If any "non-trivial" changes get added to the release, uncheck all the checkboxes and return to this stage. @@ -40,6 +42,9 @@ Testing an RC: - [ ] Testground tests - [ ] **Stage 1 - Internal Testing** + - Binaries + - [ ] Ensure the RC release has downloadable binaries + - [ ] Validate the binary is able to run on at least one platform - Upgrade our testnet infra - [ ] 1 bootstrap node - [ ] 1 miner @@ -100,7 +105,8 @@ Testing an RC: - [ ] **Post-Release** - [ ] Merge the `releases` branch back into `master`, ignoring the changes to `version.go` (keep the `-dev` version from master). - - [ ] Create an issue using this release issue template for the _next_ release. + - [ ] Update [RELEASE_ISSUE_TEMPLATE.md](https://github.com/filecoin-project/lotus/blob/master/documentation/misc/RELEASE_ISSUE_TEMPLATE.md) with any improvements determined from this latest release iteration. + - [ ] Create an issue using [RELEASE_ISSUE_TEMPLATE.md](https://github.com/filecoin-project/lotus/blob/master/documentation/misc/RELEASE_ISSUE_TEMPLATE.md) for the _next_ release. ## ❤️ Contributors From df7631df778217330b6c877f5d54528eb7ce96cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 13 May 2021 13:07:42 +0100 Subject: [PATCH 26/80] docs: rename some wdpost methods; add docs. --- storage/wdpost_run.go | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index cec86a09b..15525e001 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -233,8 +233,25 @@ func (s *WindowPoStScheduler) checkSectors(ctx context.Context, check bitfield.B return sbf, nil } -func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uint64, partitions []api.Partition, tsk types.TipSetKey) ([]miner.RecoveryDeclaration, *types.SignedMessage, error) { - ctx, span := trace.StartSpan(ctx, "storage.checkNextRecoveries") +// declareRecoveries identifies sectors that were previously marked as faulty +// for our miner, but are now recovered (i.e. are now provable again) and +// still not reported as such. +// +// It then reports the recovery on chain via a `DeclareFaultsRecovered` +// message to our miner actor. +// +// This is always invoked ahead of time, before the deadline for the evaluated +// sectors arrives. That way, recoveries are declared in preparation for those +// sectors to be proven. +// +// If a declaration is made, it awaits for build.MessageConfidence confirmations +// on chain before returning. +// +// TODO: the waiting should happen in the background. Right now this +// is blocking/delaying the actual generation and submission of WindowPoSts in +// this deadline! +func (s *WindowPoStScheduler) declareRecoveries(ctx context.Context, dlIdx uint64, partitions []api.Partition, tsk types.TipSetKey) ([]miner.RecoveryDeclaration, *types.SignedMessage, error) { + ctx, span := trace.StartSpan(ctx, "storage.declareRecoveries") defer span.End() faulty := uint64(0) @@ -325,8 +342,21 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uin return recoveries, sm, nil } -func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64, partitions []api.Partition, tsk types.TipSetKey) ([]miner.FaultDeclaration, *types.SignedMessage, error) { - ctx, span := trace.StartSpan(ctx, "storage.checkNextFaults") +// declareFaults identifies the sectors on the specified proving deadline that +// are faulty, and reports the faults on chain via the `DeclareFaults` message +// to our miner actor. +// +// This is always invoked ahead of time, before the deadline for the evaluated +// sectors arrives. That way, faults are declared before a penalty is accrued. +// +// If a declaration is made, it awaits for build.MessageConfidence confirmations +// on chain before returning. +// +// TODO: the waiting should happen in the background. Right now this +// is blocking/delaying the actual generation and submission of WindowPoSts in +// this deadline! +func (s *WindowPoStScheduler) declareFaults(ctx context.Context, dlIdx uint64, partitions []api.Partition, tsk types.TipSetKey) ([]miner.FaultDeclaration, *types.SignedMessage, error) { + ctx, span := trace.StartSpan(ctx, "storage.declareFaults") defer span.End() bad := uint64(0) @@ -443,7 +473,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty } ) - if recoveries, sigmsg, err = s.checkNextRecoveries(context.TODO(), declDeadline, partitions, ts.Key()); err != nil { + if recoveries, sigmsg, err = s.declareRecoveries(context.TODO(), declDeadline, partitions, ts.Key()); err != nil { // TODO: This is potentially quite bad, but not even trying to post when this fails is objectively worse log.Errorf("checking sector recoveries: %v", err) } @@ -462,7 +492,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty return // FORK: declaring faults after ignition upgrade makes no sense } - if faults, sigmsg, err = s.checkNextFaults(context.TODO(), declDeadline, partitions, ts.Key()); err != nil { + if faults, sigmsg, err = s.declareFaults(context.TODO(), declDeadline, partitions, ts.Key()); err != nil { // TODO: This is also potentially really bad, but we try to post anyways log.Errorf("checking sector faults: %v", err) } From 5daacc0f07b2b8548eb5ce602eb94725d492aa7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 13 May 2021 13:08:52 +0100 Subject: [PATCH 27/80] docs: add docs to chain store methods. --- chain/store/store.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/chain/store/store.go b/chain/store/store.go index 1e78ce73d..7caddbd5c 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -853,6 +853,14 @@ func (cs *ChainStore) NearestCommonAncestor(a, b *types.TipSet) (*types.TipSet, return cs.LoadTipSet(l[len(l)-1].Parents()) } +// ReorgOps takes two tipsets (which can be at different heights), and walks +// their corresponding chains backwards one step at a time until we find +// a common ancestor. It then returns the respective chain segments that fork +// from the identified ancestor, in reverse order, where the first element of +// each slice is the supplied tipset, and the last element is the common +// ancenstor. +// +// If an error happens along the way, we return the error with nil slices. func (cs *ChainStore) ReorgOps(a, b *types.TipSet) ([]*types.TipSet, []*types.TipSet, error) { return ReorgOps(cs.LoadTipSet, a, b) } @@ -1235,6 +1243,9 @@ func (cs *ChainStore) ReadMsgMetaCids(mmc cid.Cid) ([]cid.Cid, []cid.Cid, error) return blscids, secpkcids, nil } +// GetPath returns returns the sequence of atomic head change operations that +// need to be applied in order to switch the head of the chain from the `from` +// tipset to the `to` tipset. func (cs *ChainStore) GetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*api.HeadChange, error) { fts, err := cs.LoadTipSet(from) if err != nil { From 1d6941b0eb0c326fcf228d18f5797a8731749a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 13 May 2021 14:33:35 +0100 Subject: [PATCH 28/80] rename storage/{sealing=>miner_sealing}.go --- storage/{sealing.go => miner_sealing.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename storage/{sealing.go => miner_sealing.go} (100%) diff --git a/storage/sealing.go b/storage/miner_sealing.go similarity index 100% rename from storage/sealing.go rename to storage/miner_sealing.go From c7d50fe195b69338de65e55d7ec5a18aed35f4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 13 May 2021 14:36:16 +0100 Subject: [PATCH 29/80] rename {storageMinerApi=>fullNodeFilteredAPI}; add docs. --- storage/adapter_storage_miner.go | 4 ++-- storage/miner.go | 8 +++++--- storage/wdpost_changehandler.go | 1 + storage/wdpost_run_test.go | 4 ++-- storage/wdpost_sched.go | 8 ++++---- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index fea02651a..502b9adb0 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -31,10 +31,10 @@ import ( var _ sealing.SealingAPI = new(SealingAPIAdapter) type SealingAPIAdapter struct { - delegate storageMinerApi + delegate fullNodeFilteredAPI } -func NewSealingAPIAdapter(api storageMinerApi) SealingAPIAdapter { +func NewSealingAPIAdapter(api fullNodeFilteredAPI) SealingAPIAdapter { return SealingAPIAdapter{delegate: api} } diff --git a/storage/miner.go b/storage/miner.go index 9a24cbe9d..96184724b 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -42,7 +42,7 @@ import ( var log = logging.Logger("storageminer") type Miner struct { - api storageMinerApi + api fullNodeFilteredAPI feeCfg config.MinerFeeConfig h host.Host sealer sectorstorage.SectorManager @@ -70,7 +70,9 @@ type SealingStateEvt struct { Error string } -type storageMinerApi interface { +// fullNodeFilteredAPI is the subset of the full node API the Miner needs from +// a Lotus full node. +type fullNodeFilteredAPI interface { // Call a read only method on actors (no interaction with the chain required) StateCall(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) StateMinerSectors(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) @@ -116,7 +118,7 @@ type storageMinerApi interface { WalletHas(context.Context, address.Address) (bool, error) } -func NewMiner(api storageMinerApi, maddr address.Address, h host.Host, ds datastore.Batching, sealer sectorstorage.SectorManager, sc sealing.SectorIDCounter, verif ffiwrapper.Verifier, gsd dtypes.GetSealingConfigFunc, feeCfg config.MinerFeeConfig, journal journal.Journal, as *AddressSelector) (*Miner, error) { +func NewMiner(api fullNodeFilteredAPI, maddr address.Address, h host.Host, ds datastore.Batching, sealer sectorstorage.SectorManager, sc sealing.SectorIDCounter, verif ffiwrapper.Verifier, gsd dtypes.GetSealingConfigFunc, feeCfg config.MinerFeeConfig, journal journal.Journal, as *AddressSelector) (*Miner, error) { m := &Miner{ api: api, feeCfg: feeCfg, diff --git a/storage/wdpost_changehandler.go b/storage/wdpost_changehandler.go index 188d7e93a..081cfecaf 100644 --- a/storage/wdpost_changehandler.go +++ b/storage/wdpost_changehandler.go @@ -25,6 +25,7 @@ type changeHandlerAPI interface { StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) startGeneratePoST(ctx context.Context, ts *types.TipSet, deadline *dline.Info, onComplete CompleteGeneratePoSTCb) context.CancelFunc startSubmitPoST(ctx context.Context, ts *types.TipSet, deadline *dline.Info, posts []miner.SubmitWindowedPoStParams, onComplete CompleteSubmitPoSTCb) context.CancelFunc + onAbort(ts *types.TipSet, deadline *dline.Info) failPost(err error, ts *types.TipSet, deadline *dline.Info) } diff --git a/storage/wdpost_run_test.go b/storage/wdpost_run_test.go index 6a55bad1f..584369dff 100644 --- a/storage/wdpost_run_test.go +++ b/storage/wdpost_run_test.go @@ -35,7 +35,7 @@ import ( type mockStorageMinerAPI struct { partitions []api.Partition pushedMessages chan *types.Message - storageMinerApi + fullNodeFilteredAPI } func newMockStorageMinerAPI() *mockStorageMinerAPI { @@ -389,4 +389,4 @@ func (m *mockStorageMinerAPI) WalletHas(ctx context.Context, address address.Add return true, nil } -var _ storageMinerApi = &mockStorageMinerAPI{} +var _ fullNodeFilteredAPI = &mockStorageMinerAPI{} diff --git a/storage/wdpost_sched.go b/storage/wdpost_sched.go index 8c24a5516..0ebd491ec 100644 --- a/storage/wdpost_sched.go +++ b/storage/wdpost_sched.go @@ -24,7 +24,7 @@ import ( ) type WindowPoStScheduler struct { - api storageMinerApi + api fullNodeFilteredAPI feeCfg config.MinerFeeConfig addrSel *AddressSelector prover storage.Prover @@ -43,7 +43,7 @@ type WindowPoStScheduler struct { // failLk sync.Mutex } -func NewWindowedPoStScheduler(api storageMinerApi, fc config.MinerFeeConfig, as *AddressSelector, sb storage.Prover, verif ffiwrapper.Verifier, ft sectorstorage.FaultTracker, j journal.Journal, actor address.Address) (*WindowPoStScheduler, error) { +func NewWindowedPoStScheduler(api fullNodeFilteredAPI, fc config.MinerFeeConfig, as *AddressSelector, sb storage.Prover, verif ffiwrapper.Verifier, ft sectorstorage.FaultTracker, j journal.Journal, actor address.Address) (*WindowPoStScheduler, error) { mi, err := api.StateMinerInfo(context.TODO(), actor, types.EmptyTSK) if err != nil { return nil, xerrors.Errorf("getting sector size: %w", err) @@ -71,13 +71,13 @@ func NewWindowedPoStScheduler(api storageMinerApi, fc config.MinerFeeConfig, as } type changeHandlerAPIImpl struct { - storageMinerApi + fullNodeFilteredAPI *WindowPoStScheduler } func (s *WindowPoStScheduler) Run(ctx context.Context) { // Initialize change handler - chImpl := &changeHandlerAPIImpl{storageMinerApi: s.api, WindowPoStScheduler: s} + chImpl := &changeHandlerAPIImpl{fullNodeFilteredAPI: s.api, WindowPoStScheduler: s} s.ch = newChangeHandler(chImpl, s.actor) defer s.ch.shutdown() s.ch.start() From 1f651b84cecece97b1631b439ec7c2eff1e8c736 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Wed, 12 May 2021 14:31:34 -0400 Subject: [PATCH 30/80] chore(ci): Enable build on RC tags --- .circleci/config.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 40e2bb2b1..16ed7049b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -747,7 +747,7 @@ workflows: filters: tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - test-conformance: test-suite-name: conformance packages: "./conformance" @@ -768,28 +768,28 @@ workflows: filters: tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-ntwk-calibration: requires: - test-short filters: tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-ntwk-butterfly: requires: - test-short filters: tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-ntwk-nerpa: requires: - test-short filters: tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-lotus-soup - build-macos: requires: @@ -800,7 +800,7 @@ workflows: - /.*/ tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - publish: requires: - build-all @@ -811,7 +811,7 @@ workflows: - /.*/ tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-and-push-image: dockerfile: Dockerfile.lotus path: . @@ -826,7 +826,7 @@ workflows: - /.*/ tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - publish-packer-calibrationnet: requires: - build-ntwk-calibration @@ -836,7 +836,7 @@ workflows: - /.*/ tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - publish-packer-butterflynet: requires: - build-ntwk-butterfly @@ -846,7 +846,7 @@ workflows: - /.*/ tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - publish-packer-nerpanet: requires: - build-ntwk-nerpa @@ -856,4 +856,4 @@ workflows: - /.*/ tags: only: - - /^v\d+\.\d+\.\d+$/ + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ From 624f5969b30e298d9b369121e227c3727be46568 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 13 May 2021 19:58:15 +0200 Subject: [PATCH 31/80] fix: wait-api should use GetAPI to acquire binary specific API Fixes #6244 Signed-off-by: Jakub Sztandera --- cli/wait.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/wait.go b/cli/wait.go index 98fc9c0d8..ea897d5ad 100644 --- a/cli/wait.go +++ b/cli/wait.go @@ -12,7 +12,7 @@ var WaitApiCmd = &cli.Command{ Usage: "Wait for lotus api to come online", Action: func(cctx *cli.Context) error { for i := 0; i < 30; i++ { - api, closer, err := GetFullNodeAPI(cctx) + api, closer, err := GetAPI(cctx) if err != nil { fmt.Printf("Not online yet... (%s)\n", err) time.Sleep(time.Second) From efb078947a0f11ee9107af318650e2d6b95471f9 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Thu, 13 May 2021 15:50:10 -0400 Subject: [PATCH 32/80] Upgrade nerpa to actor v4 around May 27th 1600 ET --- build/params_nerpanet.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/params_nerpanet.go b/build/params_nerpanet.go index fb6cfc47a..4587e81f8 100644 --- a/build/params_nerpanet.go +++ b/build/params_nerpanet.go @@ -40,8 +40,8 @@ const UpgradeClausHeight = 250 const UpgradeOrangeHeight = 300 const UpgradeActorsV3Height = 600 -const UpgradeNorwegianHeight = 999999 -const UpgradeActorsV4Height = 99999999 +const UpgradeNorwegianHeight = 201000 +const UpgradeActorsV4Height = 203000 func init() { // Minimum block production power is set to 4 TiB From 1c4ddcd409e3c5e470365d294b8dedbade213eb6 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Thu, 13 May 2021 17:48:55 -0400 Subject: [PATCH 33/80] Pull the nerpa upgrade pr and update the version to rc4 --- build/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/version.go b/build/version.go index 32ee57b4c..1a34ce44c 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.9.0-rc3" +const BuildVersion = "1.9.0-rc4" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit From 3535c2dba8d644891654fd927bd01dbd5619a026 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Thu, 13 May 2021 18:02:54 -0400 Subject: [PATCH 34/80] docsgen --- build/openrpc/full.json.gz | Bin 22804 -> 22803 bytes build/openrpc/miner.json.gz | Bin 7828 -> 7828 bytes build/openrpc/worker.json.gz | Bin 2573 -> 2573 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 6cc950d730897d8c52ba5121c06489f43d23b890..76ecd2cf0b85a43012db16f27ba534bf06a38db4 100644 GIT binary patch delta 30 mcmbQTiE;8K#tB`Fc^kWrF*2^$9L%&cjN`{k$*oE?EDQk1Xbdv| delta 31 ncmbQdiE+v%#tB`FWgEMXF*3b5wK<4sXBbC@P$ZX94GRMR)4B_H diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 90dd7ddf7934b879a7b3ff5b6965af721245da9c..be9927b97e5c83515ecba007f3e9896b94a597d3 100644 GIT binary patch delta 21 dcmbPYJH>WF2P6B&PG&g{-;9Y1RyQy*002|A2RHx# delta 21 dcmbPYJH>WF2V?cdPG&idwZA;iu5Mst003Y;2!j9s diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index cd1e2683ac9a9c34cb00bda9242b14892b7336f3..eaacf94c9b4f4326decd9c707a768ebced6b8eea 100644 GIT binary patch delta 21 ccmeAb=@psK#Mr;Fxrvj5dC4(e#%cxz08;G+q5uE@ delta 21 ccmeAb=@psK#Mr&Dxrvh_^6BjtjMWSb09)}0B>(^b From 2191517786795d321d6d52d7d682a0b5b9139eeb Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Thu, 13 May 2021 18:09:31 -0400 Subject: [PATCH 35/80] update change log --- CHANGELOG.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95bc25dbf..5ab80f806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,75 @@ # Lotus changelog +# 1.9.0-rc4 / 2021-05-13 + +This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. + +## Highlights + +- OpenRPC Support (https://github.com/filecoin-project/lotus/pull/5843) +- Take latency into account when making interactive deals (https://github.com/filecoin-project/lotus/pull/5876) +- Update go-commp-utils for >10x faster client commp calculation (https://github.com/filecoin-project/lotus/pull/5892) +- add `lotus client cancel-retrieval` cmd to lotus CLI (https://github.com/filecoin-project/lotus/pull/5871) +- add `inspect-deal` command to `lotus client` (https://github.com/filecoin-project/lotus/pull/5833) +- Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917) +- go-fil-markets v1.1.9 -> v1.2.5 + - For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md +- rust-fil-proofs v5.4.1 -> v7.0.1 + - For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md + +## Changes +- storagefsm: Apply global events even in broken states (https://github.com/filecoin-project/lotus/pull/5962) +- Default the AlwaysKeepUnsealedCopy flag to true (https://github.com/filecoin-project/lotus/pull/5743) +- splitstore: compact hotstore prior to garbage collection (https://github.com/filecoin-project/lotus/pull/5778) +- ipfs-force bootstrapper update (https://github.com/filecoin-project/lotus/pull/5799) +- better logging when unsealing fails (https://github.com/filecoin-project/lotus/pull/5851) +- perf: add cache for gas permium estimation (https://github.com/filecoin-project/lotus/pull/5709) +- backupds: Compact log on restart (https://github.com/filecoin-project/lotus/pull/5875) +- backupds: Improve truncated log handling (https://github.com/filecoin-project/lotus/pull/5891) +- State CLI improvements (State CLI improvements) +- API proxy struct codegen (https://github.com/filecoin-project/lotus/pull/5854) +- move DI stuff for paychmgr into modules (https://github.com/filecoin-project/lotus/pull/5791) +- Implement Event observer and Settings for 3rd party dep injection (https://github.com/filecoin-project/lotus/pull/5693) +- Export developer and network commands for consumption by derivatives of Lotus (https://github.com/filecoin-project/lotus/pull/5864) +- mock sealer: Simulate randomness sideeffects (https://github.com/filecoin-project/lotus/pull/5805) +- localstorage: Demote reservation stat error to debug (https://github.com/filecoin-project/lotus/pull/5976) +- shed command to unpack miner info dumps (https://github.com/filecoin-project/lotus/pull/5800) +- Add two utils to Lotus-shed (https://github.com/filecoin-project/lotus/pull/5867) +- add shed election estimate command (https://github.com/filecoin-project/lotus/pull/5092) +- Add --actor flag in lotus-shed sectors terminate (https://github.com/filecoin-project/lotus/pull/5819) +- Move lotus mpool clear to lotus-shed (https://github.com/filecoin-project/lotus/pull/5900) +- Centralize everything on ipfs/go-log/v2 (https://github.com/filecoin-project/lotus/pull/5974) +- expose NextID from nice market actor interface (https://github.com/filecoin-project/lotus/pull/5850) +- add available options for perm on error (https://github.com/filecoin-project/lotus/pull/5814) +- API docs clarification: Document StateSearchMsg replaced message behavior (https://github.com/filecoin-project/lotus/pull/5838) +- api: Document StateReplay replaced message behavior (https://github.com/filecoin-project/lotus/pull/5840) +- add godocs to miner objects (https://github.com/filecoin-project/lotus/pull/2184) +- Add description to the client deal CLI command (https://github.com/filecoin-project/lotus/pull/5999) +- lint: don't skip builtin (https://github.com/filecoin-project/lotus/pull/5881) +- use deal duration from actors (https://github.com/filecoin-project/lotus/pull/5270) +- remote calc winningpost proof (https://github.com/filecoin-project/lotus/pull/5884) +- packer: other network images (https://github.com/filecoin-project/lotus/pull/5930) +- Convert the chainstore lock to RW (https://github.com/filecoin-project/lotus/pull/5971) +- Remove CachedBlockstore (https://github.com/filecoin-project/lotus/pull/5972) +- remove messagepool CapGasFee duplicate code (https://github.com/filecoin-project/lotus/pull/5992) +- Add a mining-heartbeat INFO line at every epoch (https://github.com/filecoin-project/lotus/pull/6183) +- chore(ci): Enable build on RC tags (https://github.com/filecoin-project/lotus/pull/6245) +- Upgrade nerpa to actor v4 and bump the version to rc4 (https://github.com/filecoin-project/lotus/pull/6249) +## Fixes +- return buffers after canceling badger operation (https://github.com/filecoin-project/lotus/pull/5796) +- avoid holding a lock while calling the View callback (https://github.com/filecoin-project/lotus/pull/5792) +- storagefsm: Trigger input processing when below limits (https://github.com/filecoin-project/lotus/pull/5801) +- After importing a previously deleted key, be able to delete it again (https://github.com/filecoin-project/lotus/pull/4653) +- fix StateManager.Replay on reward actor (https://github.com/filecoin-project/lotus/pull/5804) +- make sure atomic 64bit fields are 64bit aligned (https://github.com/filecoin-project/lotus/pull/5794) +- Import secp sigs in paych tests (https://github.com/filecoin-project/lotus/pull/5879) +- fix ci build-macos (https://github.com/filecoin-project/lotus/pull/5934) +- Fix creation of remainder account when it's not a multisig (https://github.com/filecoin-project/lotus/pull/5807) +- Fix fallback chainstore (https://github.com/filecoin-project/lotus/pull/6003) +- fix 4857: show help for set-addrs (https://github.com/filecoin-project/lotus/pull/5943) +- fix health report (https://github.com/filecoin-project/lotus/pull/6011) + + # 1.9.0-rc2 / 2021-04-30 This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. From 2d7f4b1c6121872a78a063f664f338151059e082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Fri, 14 May 2021 19:45:47 +0100 Subject: [PATCH 36/80] docs: add godocs to storage module. --- extern/storage-sealing/precommit_policy.go | 5 ++++- storage/miner.go | 23 +++++++++++++++++++++- storage/wdpost_changehandler.go | 2 +- storage/wdpost_run.go | 13 +++++++++++- storage/wdpost_sched.go | 20 ++++++++++++++++--- 5 files changed, 56 insertions(+), 7 deletions(-) diff --git a/extern/storage-sealing/precommit_policy.go b/extern/storage-sealing/precommit_policy.go index 0b774b56f..a6add5693 100644 --- a/extern/storage-sealing/precommit_policy.go +++ b/extern/storage-sealing/precommit_policy.go @@ -40,7 +40,10 @@ type BasicPreCommitPolicy struct { duration abi.ChainEpoch } -// NewBasicPreCommitPolicy produces a BasicPreCommitPolicy +// NewBasicPreCommitPolicy produces a BasicPreCommitPolicy. +// +// The provided duration is used as the default sector expiry when the sector +// contains no deals. The proving boundary is used to adjust/align the sector's expiration. func NewBasicPreCommitPolicy(api Chain, duration abi.ChainEpoch, provingBoundary abi.ChainEpoch) BasicPreCommitPolicy { return BasicPreCommitPolicy{ api: api, diff --git a/storage/miner.go b/storage/miner.go index 96184724b..dc8fb019a 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -41,6 +41,14 @@ import ( var log = logging.Logger("storageminer") +// Miner is the central miner entrypoint object inside Lotus. It is +// instantiated in the node builder, along with the WindowPoStScheduler. +// +// This object is the owner of the sealing pipeline. Most of the actual logic +// lives in the storage-sealing module (sealing.Sealing), and the Miner object +// exposes it to the rest of the system by proxying calls. +// +// Miner#Run starts the sealing FSM. type Miner struct { api fullNodeFilteredAPI feeCfg config.MinerFeeConfig @@ -118,7 +126,18 @@ type fullNodeFilteredAPI interface { WalletHas(context.Context, address.Address) (bool, error) } -func NewMiner(api fullNodeFilteredAPI, maddr address.Address, h host.Host, ds datastore.Batching, sealer sectorstorage.SectorManager, sc sealing.SectorIDCounter, verif ffiwrapper.Verifier, gsd dtypes.GetSealingConfigFunc, feeCfg config.MinerFeeConfig, journal journal.Journal, as *AddressSelector) (*Miner, error) { +// NewMiner creates a new Miner object. +func NewMiner(api fullNodeFilteredAPI, + maddr address.Address, + h host.Host, + ds datastore.Batching, + sealer sectorstorage.SectorManager, + sc sealing.SectorIDCounter, + verif ffiwrapper.Verifier, + gsd dtypes.GetSealingConfigFunc, + feeCfg config.MinerFeeConfig, + journal journal.Journal, + as *AddressSelector) (*Miner, error) { m := &Miner{ api: api, feeCfg: feeCfg, @@ -138,6 +157,7 @@ func NewMiner(api fullNodeFilteredAPI, maddr address.Address, h host.Host, ds da return m, nil } +// Run starts the sealing FSM in the background, running preliminary checks first. func (m *Miner) Run(ctx context.Context) error { if err := m.runPreflightChecks(ctx); err != nil { return xerrors.Errorf("miner preflight checks failed: %w", err) @@ -186,6 +206,7 @@ func (m *Miner) Stop(ctx context.Context) error { return m.sealing.Stop(ctx) } +// runPreflightChecks verifies that preconditions to run the miner are satisfied. func (m *Miner) runPreflightChecks(ctx context.Context) error { mi, err := m.api.StateMinerInfo(ctx, m.maddr, types.EmptyTSK) if err != nil { diff --git a/storage/wdpost_changehandler.go b/storage/wdpost_changehandler.go index 081cfecaf..8bcd7164e 100644 --- a/storage/wdpost_changehandler.go +++ b/storage/wdpost_changehandler.go @@ -23,9 +23,9 @@ type CompleteSubmitPoSTCb func(err error) type changeHandlerAPI interface { StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) + startGeneratePoST(ctx context.Context, ts *types.TipSet, deadline *dline.Info, onComplete CompleteGeneratePoSTCb) context.CancelFunc startSubmitPoST(ctx context.Context, ts *types.TipSet, deadline *dline.Info, posts []miner.SubmitWindowedPoStParams, onComplete CompleteSubmitPoSTCb) context.CancelFunc - onAbort(ts *types.TipSet, deadline *dline.Info) failPost(err error, ts *types.TipSet, deadline *dline.Info) } diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 15525e001..25bacc6c1 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -31,6 +31,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +// failPost records a failure in the journal. func (s *WindowPoStScheduler) failPost(err error, ts *types.TipSet, deadline *dline.Info) { s.journal.RecordEvent(s.evtTypes[evtTypeWdPoStScheduler], func() interface{} { c := evtCommon{Error: err} @@ -440,6 +441,12 @@ func (s *WindowPoStScheduler) declareFaults(ctx context.Context, dlIdx uint64, p return faults, sm, nil } +// runPost runs a full cycle of the PoSt process: +// +// 1. performs recovery declarations for the next deadline. +// 2. performs fault declarations for the next deadline. +// 3. computes and submits proofs, batching partitions and making sure they +// don't exceed message capacity. func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *types.TipSet) ([]miner.SubmitWindowedPoStParams, error) { ctx, span := trace.StartSpan(ctx, "storage.runPost") defer span.End() @@ -848,7 +855,9 @@ func (s *WindowPoStScheduler) setSender(ctx context.Context, msg *types.Message, } *msg = *gm - // estimate + // calculate a more frugal estimation; premium is estimated to guarantee + // inclusion within 5 tipsets, and fee cap is estimated for inclusion + // within 4 tipsets. minGasFeeMsg := *msg minGasFeeMsg.GasPremium, err = s.api.GasEstimateGasPremium(ctx, 5, msg.From, msg.GasLimit, types.EmptyTSK) @@ -863,6 +872,8 @@ func (s *WindowPoStScheduler) setSender(ctx context.Context, msg *types.Message, minGasFeeMsg.GasFeeCap = msg.GasFeeCap } + // goodFunds = funds needed for optimal inclusion probability. + // minFunds = funds needed for more speculative inclusion probability. goodFunds := big.Add(msg.RequiredFunds(), msg.Value) minFunds := big.Min(big.Add(minGasFeeMsg.RequiredFunds(), minGasFeeMsg.Value), goodFunds) diff --git a/storage/wdpost_sched.go b/storage/wdpost_sched.go index 0ebd491ec..d69f9c591 100644 --- a/storage/wdpost_sched.go +++ b/storage/wdpost_sched.go @@ -23,6 +23,12 @@ import ( "go.opencensus.io/trace" ) +// WindowPoStScheduler is the coordinator for WindowPoSt submissions, fault +// declaration, and recovery declarations. It watches the chain for reverts and +// applies, and schedules/run those processes as partition deadlines arrive. +// +// WindowPoStScheduler watches the chain though the changeHandler, which in turn +// turn calls the scheduler when the time arrives to do work. type WindowPoStScheduler struct { api fullNodeFilteredAPI feeCfg config.MinerFeeConfig @@ -43,7 +49,15 @@ type WindowPoStScheduler struct { // failLk sync.Mutex } -func NewWindowedPoStScheduler(api fullNodeFilteredAPI, fc config.MinerFeeConfig, as *AddressSelector, sb storage.Prover, verif ffiwrapper.Verifier, ft sectorstorage.FaultTracker, j journal.Journal, actor address.Address) (*WindowPoStScheduler, error) { +// NewWindowedPoStScheduler creates a new WindowPoStScheduler scheduler. +func NewWindowedPoStScheduler(api fullNodeFilteredAPI, + cfg config.MinerFeeConfig, + as *AddressSelector, + sp storage.Prover, + verif ffiwrapper.Verifier, + ft sectorstorage.FaultTracker, + j journal.Journal, + actor address.Address) (*WindowPoStScheduler, error) { mi, err := api.StateMinerInfo(context.TODO(), actor, types.EmptyTSK) if err != nil { return nil, xerrors.Errorf("getting sector size: %w", err) @@ -51,9 +65,9 @@ func NewWindowedPoStScheduler(api fullNodeFilteredAPI, fc config.MinerFeeConfig, return &WindowPoStScheduler{ api: api, - feeCfg: fc, + feeCfg: cfg, addrSel: as, - prover: sb, + prover: sp, verifier: verif, faultTracker: ft, proofType: mi.WindowPoStProofType, From 0187aa6d9c5d98414e16fc1b81b0e49aac34c6cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Fri, 14 May 2021 19:46:41 +0100 Subject: [PATCH 37/80] imports reorder. --- storage/miner.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/miner.go b/storage/miner.go index dc8fb019a..4381263d1 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -5,10 +5,6 @@ import ( "errors" "time" - "github.com/filecoin-project/go-state-types/network" - - "github.com/filecoin-project/go-state-types/dline" - "github.com/filecoin-project/go-bitfield" "github.com/ipfs/go-cid" @@ -20,9 +16,13 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/go-state-types/network" + + "github.com/filecoin-project/specs-storage/storage" + sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" - "github.com/filecoin-project/specs-storage/storage" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/v1api" From 89dfb0ba19b2e75edfafd7bc54738cdcbd951451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Fri, 14 May 2021 19:47:50 +0100 Subject: [PATCH 38/80] minor refactor, renames, docs in Miner#Run. --- storage/miner.go | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/storage/miner.go b/storage/miner.go index 4381263d1..6eb1789dc 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -174,17 +174,37 @@ func (m *Miner) Run(ctx context.Context) error { MaxTerminateGasFee: abi.TokenAmount(m.feeCfg.MaxTerminateGasFee), } - evts := events.NewEvents(ctx, m.api) - adaptedAPI := NewSealingAPIAdapter(m.api) - // TODO: Maybe we update this policy after actor upgrades? - pcp := sealing.NewBasicPreCommitPolicy(adaptedAPI, policy.GetMaxSectorExpirationExtension()-(md.WPoStProvingPeriod*2), md.PeriodStart%md.WPoStProvingPeriod) + var ( + // consumer of chain head changes. + evts = events.NewEvents(ctx, m.api) + evtsAdapter = NewEventsAdapter(evts) - as := func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { - return m.addrSel.AddressFor(ctx, m.api, mi, use, goodFunds, minFunds) - } + // Create a shim to glue the API required by the sealing component + // with the API that Lotus is capable of providing. + // The shim translates between "tipset tokens" and tipset keys, and + // provides extra methods. + adaptedAPI = NewSealingAPIAdapter(m.api) - m.sealing = sealing.New(adaptedAPI, fc, NewEventsAdapter(evts), m.maddr, m.ds, m.sealer, m.sc, m.verif, &pcp, sealing.GetSealingConfigFunc(m.getSealConfig), m.handleSealingNotifications, as) + // Instantiate a precommit policy. + defaultDuration = policy.GetMaxSectorExpirationExtension() - (md.WPoStProvingPeriod * 2) + provingBoundary = md.PeriodStart % md.WPoStProvingPeriod + // TODO: Maybe we update this policy after actor upgrades? + pcp = sealing.NewBasicPreCommitPolicy(adaptedAPI, defaultDuration, provingBoundary) + + // address selector. + as = func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { + return m.addrSel.AddressFor(ctx, m.api, mi, use, goodFunds, minFunds) + } + + // sealing configuration. + cfg = sealing.GetSealingConfigFunc(m.getSealConfig) + ) + + // Instantiate the sealing FSM. + m.sealing = sealing.New(adaptedAPI, fc, evtsAdapter, m.maddr, m.ds, m.sealer, m.sc, m.verif, &pcp, cfg, m.handleSealingNotifications, as) + + // Run the sealing FSM. go m.sealing.Run(ctx) //nolint:errcheck // logged intside the function return nil From 0f4270126f056f06c087297ff758caa2ccce4894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Fri, 14 May 2021 19:48:38 +0100 Subject: [PATCH 39/80] rename {submitPost=>submitPoStMessage}. --- storage/wdpost_run.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 25bacc6c1..35fdd0566 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -168,7 +168,7 @@ func (s *WindowPoStScheduler) runSubmitPoST( commRand, err := s.api.ChainGetRandomnessFromTickets(ctx, ts.Key(), crypto.DomainSeparationTag_PoStChainCommit, commEpoch, nil) if err != nil { err = xerrors.Errorf("failed to get chain randomness from tickets for windowPost (ts=%d; deadline=%d): %w", ts.Height(), commEpoch, err) - log.Errorf("submitPost failed: %+v", err) + log.Errorf("submitPoStMessage failed: %+v", err) return err } @@ -181,7 +181,7 @@ func (s *WindowPoStScheduler) runSubmitPoST( post.ChainCommitRand = commRand // Submit PoST - sm, submitErr := s.submitPost(ctx, post) + sm, submitErr := s.submitPoStMessage(ctx, post) if submitErr != nil { log.Errorf("submit window post failed: %+v", submitErr) } else { @@ -792,7 +792,10 @@ func (s *WindowPoStScheduler) sectorsForProof(ctx context.Context, goodSectors, return proofSectors, nil } -func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.SubmitWindowedPoStParams) (*types.SignedMessage, error) { +// submitPoStMessage builds a SubmitWindowedPoSt message and submits it to +// the mpool. It doesn't synchronously block on confirmations, but it does +// monitor in the background simply for the purposes of logging. +func (s *WindowPoStScheduler) submitPoStMessage(ctx context.Context, proof *miner.SubmitWindowedPoStParams) (*types.SignedMessage, error) { ctx, span := trace.StartSpan(ctx, "storage.commitPost") defer span.End() From 28efa9357c85713b1ba63f508d8cc76688260647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Fri, 14 May 2021 19:49:05 +0100 Subject: [PATCH 40/80] rename {setSender=>prepareMessage}. --- storage/wdpost_run.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 35fdd0566..edb59a64f 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -320,7 +320,7 @@ func (s *WindowPoStScheduler) declareRecoveries(ctx context.Context, dlIdx uint6 Value: types.NewInt(0), } spec := &api.MessageSendSpec{MaxFee: abi.TokenAmount(s.feeCfg.MaxWindowPoStGasFee)} - if err := s.setSender(ctx, msg, spec); err != nil { + if err := s.prepareMessage(ctx, msg, spec); err != nil { return recoveries, nil, err } @@ -418,7 +418,7 @@ func (s *WindowPoStScheduler) declareFaults(ctx context.Context, dlIdx uint64, p Value: types.NewInt(0), // TODO: Is there a fee? } spec := &api.MessageSendSpec{MaxFee: abi.TokenAmount(s.feeCfg.MaxWindowPoStGasFee)} - if err := s.setSender(ctx, msg, spec); err != nil { + if err := s.prepareMessage(ctx, msg, spec); err != nil { return faults, nil, err } @@ -813,13 +813,11 @@ func (s *WindowPoStScheduler) submitPoStMessage(ctx context.Context, proof *mine Value: types.NewInt(0), } spec := &api.MessageSendSpec{MaxFee: abi.TokenAmount(s.feeCfg.MaxWindowPoStGasFee)} - if err := s.setSender(ctx, msg, spec); err != nil { + if err := s.prepareMessage(ctx, msg, spec); err != nil { return nil, err } - // TODO: consider maybe caring about the output sm, err := s.api.MpoolPushMessage(ctx, msg, spec) - if err != nil { return nil, xerrors.Errorf("pushing message to mpool: %w", err) } @@ -843,14 +841,20 @@ func (s *WindowPoStScheduler) submitPoStMessage(ctx context.Context, proof *mine return sm, nil } -func (s *WindowPoStScheduler) setSender(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) error { +// prepareMessage prepares a message before sending it, setting: +// +// * the sender (from the AddressSelector, falling back to the worker address if none set) +// * the right gas parameters +func (s *WindowPoStScheduler) prepareMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) error { mi, err := s.api.StateMinerInfo(ctx, s.actor, types.EmptyTSK) if err != nil { return xerrors.Errorf("error getting miner info: %w", err) } - // use the worker as a fallback + // set the worker as a fallback msg.From = mi.Worker + // (optimal) initial estimation with some overestimation that guarantees + // block inclusion within the next 20 tipsets. gm, err := s.api.GasEstimateMessageGas(ctx, msg, spec, types.EmptyTSK) if err != nil { log.Errorw("estimating gas", "error", err) From 99122129499ce823737f8c92066fc13d165dfd9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Fri, 14 May 2021 20:08:15 +0100 Subject: [PATCH 41/80] minor refactor to anonymize interface. --- storage/wdpost_sched.go | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/storage/wdpost_sched.go b/storage/wdpost_sched.go index d69f9c591..88357c5b3 100644 --- a/storage/wdpost_sched.go +++ b/storage/wdpost_sched.go @@ -84,21 +84,24 @@ func NewWindowedPoStScheduler(api fullNodeFilteredAPI, }, nil } -type changeHandlerAPIImpl struct { - fullNodeFilteredAPI - *WindowPoStScheduler -} - func (s *WindowPoStScheduler) Run(ctx context.Context) { - // Initialize change handler - chImpl := &changeHandlerAPIImpl{fullNodeFilteredAPI: s.api, WindowPoStScheduler: s} - s.ch = newChangeHandler(chImpl, s.actor) + // Initialize change handler. + + // callbacks is a union of the fullNodeFilteredAPI and ourselves. + callbacks := struct { + fullNodeFilteredAPI + *WindowPoStScheduler + }{s.api, s} + + s.ch = newChangeHandler(callbacks, s.actor) defer s.ch.shutdown() s.ch.start() - var notifs <-chan []*api.HeadChange - var err error - var gotCur bool + var ( + notifs <-chan []*api.HeadChange + err error + gotCur bool + ) // not fine to panic after this point for { From 6c8c732104b84035d7920c866e45144607afd40a Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Fri, 14 May 2021 00:22:00 -0400 Subject: [PATCH 42/80] fix(ci): Use recent ubuntu LTS release; Update release params --- .circleci/config.yml | 2 +- scripts/publish-release.sh | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 16ed7049b..11e8ac506 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,7 +11,7 @@ executors: resource_class: 2xlarge ubuntu: docker: - - image: ubuntu:19.10 + - image: ubuntu:20.04 commands: install-deps: diff --git a/scripts/publish-release.sh b/scripts/publish-release.sh index 103de1f0f..e77a6a949 100755 --- a/scripts/publish-release.sh +++ b/scripts/publish-release.sh @@ -32,6 +32,7 @@ if [ "${RELEASE_ID}" = "null" ]; then RELEASE_DATA="{ \"tag_name\": \"${CIRCLE_TAG}\", \"target_commitish\": \"${CIRCLE_SHA1}\", + \"discussion_category_name\": \"announcement\", \"name\": \"${CIRCLE_TAG}\", \"body\": \"\", \"prerelease\": false @@ -51,8 +52,9 @@ else fi RELEASE_UPLOAD_URL=`echo "${RELEASE_RESPONSE}" | jq -r '.upload_url' | cut -d'{' -f1` +echo "Preparing to send artifacts to ${RELEASE_UPLOAD_URL}" -bundles=( +artifacts=( "lotus_${CIRCLE_TAG}_linux-amd64.tar.gz" "lotus_${CIRCLE_TAG}_linux-amd64.tar.gz.cid" "lotus_${CIRCLE_TAG}_linux-amd64.tar.gz.sha512" @@ -60,9 +62,10 @@ bundles=( "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz.cid" "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz.sha512" ) -for RELEASE_FILE in "${bundles[@]}" + +for RELEASE_FILE in "${artifacts[@]}" do - echo "Uploading release bundle: ${RELEASE_FILE}" + echo "Uploading ${RELEASE_FILE}..." curl \ --request POST \ --header "Authorization: token ${GITHUB_TOKEN}" \ @@ -70,7 +73,7 @@ do --data-binary "@${RELEASE_FILE}" \ "$RELEASE_UPLOAD_URL?name=$(basename "${RELEASE_FILE}")" - echo "Release bundle uploaded: ${RELEASE_FILE}" + echo "Uploaded ${RELEASE_FILE}" done popd From 7b95649cab7f97da5b1be2ddb9b0079c9f3f5fa8 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Fri, 14 May 2021 22:22:30 -0400 Subject: [PATCH 43/80] bump the version to v1.9.0-rc5 --- build/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/version.go b/build/version.go index 1a34ce44c..f05ac6269 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.9.0-rc4" +const BuildVersion = "1.9.0-rc5" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit From a4b1dd0f884c072fc39cbe4198537189046ad286 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Fri, 14 May 2021 22:26:11 -0400 Subject: [PATCH 44/80] docsgen --- build/openrpc/full.json.gz | Bin 22803 -> 22804 bytes build/openrpc/miner.json.gz | Bin 7828 -> 7829 bytes build/openrpc/worker.json.gz | Bin 2573 -> 2574 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 76ecd2cf0b85a43012db16f27ba534bf06a38db4..c1a124fa42fc50a8fcb8ccc848af23a9a1d253e3 100644 GIT binary patch delta 22689 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 delta 22727 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 diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index be9927b97e5c83515ecba007f3e9896b94a597d3..ef8ed4a6ae2367e4f55e5e3174f555743ef46798 100644 GIT binary patch delta 7760 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

l<} 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 Wn@n$?{(k@f0RR7@QW^xSfB^t$jsJuI delta 7759 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 VCez!e{~rJV|Nl*Bk)W%90RUeGCw%|_ diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index eaacf94c9b4f4326decd9c707a768ebced6b8eea..d784af49f16980a29570510e0538af6e476a5f59 100644 GIT binary patch delta 2471 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 delta 2470 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 From c77f8fb382c424497acff91984e3b8632fb88a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Fri, 14 May 2021 21:00:13 +0100 Subject: [PATCH 45/80] adopt clearer method names; fix typo. --- chain/store/store.go | 2 +- storage/wdpost_changehandler.go | 2 +- storage/wdpost_changehandler_test.go | 2 +- storage/wdpost_run.go | 16 ++++++++-------- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/chain/store/store.go b/chain/store/store.go index 7caddbd5c..7318a1007 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -1243,7 +1243,7 @@ func (cs *ChainStore) ReadMsgMetaCids(mmc cid.Cid) ([]cid.Cid, []cid.Cid, error) return blscids, secpkcids, nil } -// GetPath returns returns the sequence of atomic head change operations that +// GetPath returns the sequence of atomic head change operations that // need to be applied in order to switch the head of the chain from the `from` // tipset to the `to` tipset. func (cs *ChainStore) GetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*api.HeadChange, error) { diff --git a/storage/wdpost_changehandler.go b/storage/wdpost_changehandler.go index 8bcd7164e..8b519aedd 100644 --- a/storage/wdpost_changehandler.go +++ b/storage/wdpost_changehandler.go @@ -27,7 +27,7 @@ type changeHandlerAPI interface { startGeneratePoST(ctx context.Context, ts *types.TipSet, deadline *dline.Info, onComplete CompleteGeneratePoSTCb) context.CancelFunc startSubmitPoST(ctx context.Context, ts *types.TipSet, deadline *dline.Info, posts []miner.SubmitWindowedPoStParams, onComplete CompleteSubmitPoSTCb) context.CancelFunc onAbort(ts *types.TipSet, deadline *dline.Info) - failPost(err error, ts *types.TipSet, deadline *dline.Info) + recordPoStFailure(err error, ts *types.TipSet, deadline *dline.Info) } type changeHandler struct { diff --git a/storage/wdpost_changehandler_test.go b/storage/wdpost_changehandler_test.go index bae4f40fd..a2283cb7c 100644 --- a/storage/wdpost_changehandler_test.go +++ b/storage/wdpost_changehandler_test.go @@ -191,7 +191,7 @@ func (m *mockAPI) wasAbortCalled() bool { return m.abortCalled } -func (m *mockAPI) failPost(err error, ts *types.TipSet, deadline *dline.Info) { +func (m *mockAPI) recordPoStFailure(err error, ts *types.TipSet, deadline *dline.Info) { } func (m *mockAPI) setChangeHandler(ch *changeHandler) { diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index edb59a64f..b4c702197 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -31,8 +31,8 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -// failPost records a failure in the journal. -func (s *WindowPoStScheduler) failPost(err error, ts *types.TipSet, deadline *dline.Info) { +// recordPoStFailure records a failure in the journal. +func (s *WindowPoStScheduler) recordPoStFailure(err error, ts *types.TipSet, deadline *dline.Info) { s.journal.RecordEvent(s.evtTypes[evtTypeWdPoStScheduler], func() interface{} { c := evtCommon{Error: err} if ts != nil { @@ -100,9 +100,9 @@ func (s *WindowPoStScheduler) runGeneratePoST( ctx, span := trace.StartSpan(ctx, "WindowPoStScheduler.generatePoST") defer span.End() - posts, err := s.runPost(ctx, *deadline, ts) + posts, err := s.runPoStCycle(ctx, *deadline, ts) if err != nil { - log.Errorf("runPost failed: %+v", err) + log.Errorf("runPoStCycle failed: %+v", err) return nil, err } @@ -441,18 +441,18 @@ func (s *WindowPoStScheduler) declareFaults(ctx context.Context, dlIdx uint64, p return faults, sm, nil } -// runPost runs a full cycle of the PoSt process: +// runPoStCycle runs a full cycle of the PoSt process: // // 1. performs recovery declarations for the next deadline. // 2. performs fault declarations for the next deadline. // 3. computes and submits proofs, batching partitions and making sure they // don't exceed message capacity. -func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *types.TipSet) ([]miner.SubmitWindowedPoStParams, error) { - ctx, span := trace.StartSpan(ctx, "storage.runPost") +func (s *WindowPoStScheduler) runPoStCycle(ctx context.Context, di dline.Info, ts *types.TipSet) ([]miner.SubmitWindowedPoStParams, error) { + ctx, span := trace.StartSpan(ctx, "storage.runPoStCycle") defer span.End() go func() { - // TODO: extract from runPost, run on fault cutoff boundaries + // TODO: extract from runPoStCycle, run on fault cutoff boundaries // check faults / recoveries for the *next* deadline. It's already too // late to declare them for this deadline From 50360e68aeb486ca62374f8652c0de4b6e7613bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Fri, 14 May 2021 21:04:35 +0100 Subject: [PATCH 46/80] rename {changeHandlerAPI=>wdPoStCommands} + add docs. --- storage/wdpost_changehandler.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/storage/wdpost_changehandler.go b/storage/wdpost_changehandler.go index 8b519aedd..7b80f2744 100644 --- a/storage/wdpost_changehandler.go +++ b/storage/wdpost_changehandler.go @@ -21,7 +21,9 @@ const ( type CompleteGeneratePoSTCb func(posts []miner.SubmitWindowedPoStParams, err error) type CompleteSubmitPoSTCb func(err error) -type changeHandlerAPI interface { +// wdPoStCommands is the subset of the WindowPoStScheduler + full node APIs used +// by the changeHandler to execute actions and query state. +type wdPoStCommands interface { StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) startGeneratePoST(ctx context.Context, ts *types.TipSet, deadline *dline.Info, onComplete CompleteGeneratePoSTCb) context.CancelFunc @@ -31,13 +33,13 @@ type changeHandlerAPI interface { } type changeHandler struct { - api changeHandlerAPI + api wdPoStCommands actor address.Address proveHdlr *proveHandler submitHdlr *submitHandler } -func newChangeHandler(api changeHandlerAPI, actor address.Address) *changeHandler { +func newChangeHandler(api wdPoStCommands, actor address.Address) *changeHandler { posts := newPostsCache() p := newProver(api, posts) s := newSubmitter(api, posts) @@ -147,7 +149,7 @@ type postResult struct { // proveHandler generates proofs type proveHandler struct { - api changeHandlerAPI + api wdPoStCommands posts *postsCache postResults chan *postResult @@ -164,7 +166,7 @@ type proveHandler struct { } func newProver( - api changeHandlerAPI, + api wdPoStCommands, posts *postsCache, ) *proveHandler { ctx, cancel := context.WithCancel(context.Background()) @@ -249,7 +251,7 @@ func (p *proveHandler) processPostResult(res *postResult) { di := res.currPost.di if res.err != nil { // Proving failed so inform the API - p.api.failPost(res.err, res.ts, di) + p.api.recordPoStFailure(res.err, res.ts, di) log.Warnf("Aborted window post Proving (Deadline: %+v)", di) p.api.onAbort(res.ts, di) @@ -296,7 +298,7 @@ type postInfo struct { // submitHandler submits proofs on-chain type submitHandler struct { - api changeHandlerAPI + api wdPoStCommands posts *postsCache submitResults chan *submitResult @@ -320,7 +322,7 @@ type submitHandler struct { } func newSubmitter( - api changeHandlerAPI, + api wdPoStCommands, posts *postsCache, ) *submitHandler { ctx, cancel := context.WithCancel(context.Background()) @@ -489,7 +491,7 @@ func (s *submitHandler) submitIfReady(ctx context.Context, advance *types.TipSet func (s *submitHandler) processSubmitResult(res *submitResult) { if res.err != nil { // Submit failed so inform the API and go back to the start state - s.api.failPost(res.err, res.pw.ts, res.pw.di) + s.api.recordPoStFailure(res.err, res.pw.ts, res.pw.di) log.Warnf("Aborted window post Submitting (Deadline: %+v)", res.pw.di) s.api.onAbort(res.pw.ts, res.pw.di) From 71bd00559467afb3dfc767001d336dacf227a80a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 13 Apr 2021 12:27:46 +0200 Subject: [PATCH 47/80] wip --- CHANGELOG.md | 287 ++++++++++++++++++++++++++++++++------------ extern/filecoin-ffi | 2 +- 2 files changed, 213 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55534ff05..811b691c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,147 @@ # Lotus changelog -# 1.8.0 / 2021-04-27 +# 1.9.0-rc4 / 2021-05-13 + +This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. + +## Highlights + +- OpenRPC Support (https://github.com/filecoin-project/lotus/pull/5843) +- Take latency into account when making interactive deals (https://github.com/filecoin-project/lotus/pull/5876) +- Update go-commp-utils for >10x faster client commp calculation (https://github.com/filecoin-project/lotus/pull/5892) +- add `lotus client cancel-retrieval` cmd to lotus CLI (https://github.com/filecoin-project/lotus/pull/5871) +- add `inspect-deal` command to `lotus client` (https://github.com/filecoin-project/lotus/pull/5833) +- Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917) +- go-fil-markets v1.1.9 -> v1.2.5 + - For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md +- rust-fil-proofs v5.4.1 -> v7.0.1 + - For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md + +## Changes +- storagefsm: Apply global events even in broken states (https://github.com/filecoin-project/lotus/pull/5962) +- Default the AlwaysKeepUnsealedCopy flag to true (https://github.com/filecoin-project/lotus/pull/5743) +- splitstore: compact hotstore prior to garbage collection (https://github.com/filecoin-project/lotus/pull/5778) +- ipfs-force bootstrapper update (https://github.com/filecoin-project/lotus/pull/5799) +- better logging when unsealing fails (https://github.com/filecoin-project/lotus/pull/5851) +- perf: add cache for gas permium estimation (https://github.com/filecoin-project/lotus/pull/5709) +- backupds: Compact log on restart (https://github.com/filecoin-project/lotus/pull/5875) +- backupds: Improve truncated log handling (https://github.com/filecoin-project/lotus/pull/5891) +- State CLI improvements (State CLI improvements) +- API proxy struct codegen (https://github.com/filecoin-project/lotus/pull/5854) +- move DI stuff for paychmgr into modules (https://github.com/filecoin-project/lotus/pull/5791) +- Implement Event observer and Settings for 3rd party dep injection (https://github.com/filecoin-project/lotus/pull/5693) +- Export developer and network commands for consumption by derivatives of Lotus (https://github.com/filecoin-project/lotus/pull/5864) +- mock sealer: Simulate randomness sideeffects (https://github.com/filecoin-project/lotus/pull/5805) +- localstorage: Demote reservation stat error to debug (https://github.com/filecoin-project/lotus/pull/5976) +- shed command to unpack miner info dumps (https://github.com/filecoin-project/lotus/pull/5800) +- Add two utils to Lotus-shed (https://github.com/filecoin-project/lotus/pull/5867) +- add shed election estimate command (https://github.com/filecoin-project/lotus/pull/5092) +- Add --actor flag in lotus-shed sectors terminate (https://github.com/filecoin-project/lotus/pull/5819) +- Move lotus mpool clear to lotus-shed (https://github.com/filecoin-project/lotus/pull/5900) +- Centralize everything on ipfs/go-log/v2 (https://github.com/filecoin-project/lotus/pull/5974) +- expose NextID from nice market actor interface (https://github.com/filecoin-project/lotus/pull/5850) +- add available options for perm on error (https://github.com/filecoin-project/lotus/pull/5814) +- API docs clarification: Document StateSearchMsg replaced message behavior (https://github.com/filecoin-project/lotus/pull/5838) +- api: Document StateReplay replaced message behavior (https://github.com/filecoin-project/lotus/pull/5840) +- add godocs to miner objects (https://github.com/filecoin-project/lotus/pull/2184) +- Add description to the client deal CLI command (https://github.com/filecoin-project/lotus/pull/5999) +- lint: don't skip builtin (https://github.com/filecoin-project/lotus/pull/5881) +- use deal duration from actors (https://github.com/filecoin-project/lotus/pull/5270) +- remote calc winningpost proof (https://github.com/filecoin-project/lotus/pull/5884) +- packer: other network images (https://github.com/filecoin-project/lotus/pull/5930) +- Convert the chainstore lock to RW (https://github.com/filecoin-project/lotus/pull/5971) +- Remove CachedBlockstore (https://github.com/filecoin-project/lotus/pull/5972) +- remove messagepool CapGasFee duplicate code (https://github.com/filecoin-project/lotus/pull/5992) +- Add a mining-heartbeat INFO line at every epoch (https://github.com/filecoin-project/lotus/pull/6183) +- chore(ci): Enable build on RC tags (https://github.com/filecoin-project/lotus/pull/6245) +- Upgrade nerpa to actor v4 and bump the version to rc4 (https://github.com/filecoin-project/lotus/pull/6249) +## Fixes +- return buffers after canceling badger operation (https://github.com/filecoin-project/lotus/pull/5796) +- avoid holding a lock while calling the View callback (https://github.com/filecoin-project/lotus/pull/5792) +- storagefsm: Trigger input processing when below limits (https://github.com/filecoin-project/lotus/pull/5801) +- After importing a previously deleted key, be able to delete it again (https://github.com/filecoin-project/lotus/pull/4653) +- fix StateManager.Replay on reward actor (https://github.com/filecoin-project/lotus/pull/5804) +- make sure atomic 64bit fields are 64bit aligned (https://github.com/filecoin-project/lotus/pull/5794) +- Import secp sigs in paych tests (https://github.com/filecoin-project/lotus/pull/5879) +- fix ci build-macos (https://github.com/filecoin-project/lotus/pull/5934) +- Fix creation of remainder account when it's not a multisig (https://github.com/filecoin-project/lotus/pull/5807) +- Fix fallback chainstore (https://github.com/filecoin-project/lotus/pull/6003) +- fix 4857: show help for set-addrs (https://github.com/filecoin-project/lotus/pull/5943) +- fix health report (https://github.com/filecoin-project/lotus/pull/6011) + + +# 1.9.0-rc2 / 2021-04-30 + +This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. + +## Highlights + +- OpenRPC Support (https://github.com/filecoin-project/lotus/pull/5843) +- Take latency into account when making interactive deals (https://github.com/filecoin-project/lotus/pull/5876) +- Update go-commp-utils for >10x faster client commp calculation (https://github.com/filecoin-project/lotus/pull/5892) +- add `lotus client cancel-retrieval` cmd to lotus CLI (https://github.com/filecoin-project/lotus/pull/5871) +- add `inspect-deal` command to `lotus client` (https://github.com/filecoin-project/lotus/pull/5833) +- Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917) +- go-fil-markets v1.1.9 -> v1.2.5 + - For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md +- rust-fil-proofs v5.4.1 -> v7 + - For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md + +## Changes +- storagefsm: Apply global events even in broken states (https://github.com/filecoin-project/lotus/pull/5962) +- Default the AlwaysKeepUnsealedCopy flag to true (https://github.com/filecoin-project/lotus/pull/5743) +- splitstore: compact hotstore prior to garbage collection (https://github.com/filecoin-project/lotus/pull/5778) +- ipfs-force bootstrapper update (https://github.com/filecoin-project/lotus/pull/5799) +- better logging when unsealing fails (https://github.com/filecoin-project/lotus/pull/5851) +- perf: add cache for gas permium estimation (https://github.com/filecoin-project/lotus/pull/5709) +- backupds: Compact log on restart (https://github.com/filecoin-project/lotus/pull/5875) +- backupds: Improve truncated log handling (https://github.com/filecoin-project/lotus/pull/5891) +- State CLI improvements (State CLI improvements) +- API proxy struct codegen (https://github.com/filecoin-project/lotus/pull/5854) +- move DI stuff for paychmgr into modules (https://github.com/filecoin-project/lotus/pull/5791) +- Implement Event observer and Settings for 3rd party dep injection (https://github.com/filecoin-project/lotus/pull/5693) +- Export developer and network commands for consumption by derivatives of Lotus (https://github.com/filecoin-project/lotus/pull/5864) +- mock sealer: Simulate randomness sideeffects (https://github.com/filecoin-project/lotus/pull/5805) +- localstorage: Demote reservation stat error to debug (https://github.com/filecoin-project/lotus/pull/5976) +- shed command to unpack miner info dumps (https://github.com/filecoin-project/lotus/pull/5800) +- Add two utils to Lotus-shed (https://github.com/filecoin-project/lotus/pull/5867) +- add shed election estimate command (https://github.com/filecoin-project/lotus/pull/5092) +- Add --actor flag in lotus-shed sectors terminate (https://github.com/filecoin-project/lotus/pull/5819) +- Move lotus mpool clear to lotus-shed (https://github.com/filecoin-project/lotus/pull/5900) +- Centralize everything on ipfs/go-log/v2 (https://github.com/filecoin-project/lotus/pull/5974) +- expose NextID from nice market actor interface (https://github.com/filecoin-project/lotus/pull/5850) +- add available options for perm on error (https://github.com/filecoin-project/lotus/pull/5814) +- API docs clarification: Document StateSearchMsg replaced message behavior (https://github.com/filecoin-project/lotus/pull/5838) +- api: Document StateReplay replaced message behavior (https://github.com/filecoin-project/lotus/pull/5840) +- add godocs to miner objects (https://github.com/filecoin-project/lotus/pull/2184) +- Add description to the client deal CLI command (https://github.com/filecoin-project/lotus/pull/5999) +- lint: don't skip builtin (https://github.com/filecoin-project/lotus/pull/5881) +- use deal duration from actors (https://github.com/filecoin-project/lotus/pull/5270) +- remote calc winningpost proof (https://github.com/filecoin-project/lotus/pull/5884) +- packer: other network images (https://github.com/filecoin-project/lotus/pull/5930) +- Convert the chainstore lock to RW (https://github.com/filecoin-project/lotus/pull/5971) +- Remove CachedBlockstore (https://github.com/filecoin-project/lotus/pull/5972) +- remove messagepool CapGasFee duplicate code (https://github.com/filecoin-project/lotus/pull/5992) + +## Fixes +- return buffers after canceling badger operation (https://github.com/filecoin-project/lotus/pull/5796) +- avoid holding a lock while calling the View callback (https://github.com/filecoin-project/lotus/pull/5792) +- storagefsm: Trigger input processing when below limits (https://github.com/filecoin-project/lotus/pull/5801) +- After importing a previously deleted key, be able to delete it again (https://github.com/filecoin-project/lotus/pull/4653) +- fix StateManager.Replay on reward actor (https://github.com/filecoin-project/lotus/pull/5804) +- make sure atomic 64bit fields are 64bit aligned (https://github.com/filecoin-project/lotus/pull/5794) +- Import secp sigs in paych tests (https://github.com/filecoin-project/lotus/pull/5879) +- fix ci build-macos (https://github.com/filecoin-project/lotus/pull/5934) +- Fix creation of remainder account when it's not a multisig (https://github.com/filecoin-project/lotus/pull/5807) +- Fix fallback chainstore (https://github.com/filecoin-project/lotus/pull/6003) +- fix 4857: show help for set-addrs (https://github.com/filecoin-project/lotus/pull/5943) +- fix health report (https://github.com/filecoin-project/lotus/pull/6011) + +# 1.8.0 / 2021-04-05 This is a mandatory release of Lotus that upgrades the network to version 12, which introduces various performance improvements to the cron processing of the power actor. The network will upgrade at height 712320, which is 2021-04-29T06:00:00Z. -## Changes +## Changes - v4 specs-actors integration, nv12 migration (https://github.com/filecoin-project/lotus/pull/6116) @@ -20,7 +157,7 @@ This release also expands the `lotus-miner sectors extend` CLI, with a new optio - The `expiration-cutoff` flag can be passed to skip sectors whose expiration is past a certain point from the current head. It defaults to infinity (no cutoff), but if, say, 28800 was specified, then only sectors expiring in the next 10 days would be extended (2880 epochs in 1 day). -## Changes +## Changes - Util for miners to extend all v1 sectors (https://github.com/filecoin-project/lotus/pull/5924) - Upgrade the butterfly network (https://github.com/filecoin-project/lotus/pull/5929) @@ -31,7 +168,7 @@ This release also expands the `lotus-miner sectors extend` CLI, with a new optio This is a patch release of Lotus that introduces small fixes to the Storage FSM. -## Changes +## Changes - storagefsm: Fix double unlock with ready WaitDeals sectors (https://github.com/filecoin-project/lotus/pull/5783) - backupds: Allow larger values in write log (https://github.com/filecoin-project/lotus/pull/5776) @@ -47,7 +184,7 @@ This is an hotfix release of Lotus that fixes a critical bug introduced in v1.5. # 1.5.1 / 2021-03-10 -This is an optional release of Lotus that introduces an important fix to the WindowPoSt computation process. The change is to wait for some confidence before drawing beacon randomness for the proof. Without this, invalid proofs might be generated as the result of a null tipset. +This is an optional release of Lotus that introduces an important fix to the WindowPoSt computation process. The change is to wait for some confidence before drawing beacon randomness for the proof. Without this, invalid proofs might be generated as the result of a null tipset. ## Splitstore @@ -140,7 +277,7 @@ FIP-0010 introduces the ability to dispute bad Window PoSts. Node operators are ## Changes - [#5341](https://github.com/filecoin-project/lotus/pull/5341) Add a `LOTUS_DISABLE_V3_ACTOR_MIGRATION` envvar - - Setting this envvar to 1 disables the v3 actor migration, should only be used in the event of a failed migration + - Setting this envvar to 1 disables the v3 actor migration, should only be used in the event of a failed migration # 1.4.2 / 2021-02-17 @@ -148,14 +285,14 @@ This is a large, and highly recommended, optional release with new features and - [FIP-0007 h/amt-v3](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0007.md) which improves the performance of the Filecoin HAMT and AMT. - [FIP-0010 off-chain Window PoSt Verification](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0010.md) which reduces the gas consumption of `SubmitWindowedPoSt` messages significantly by optimistically accepting Window PoSt proofs without verification, and allowing them to be disputed later by off-chain verifiers. - + Note that this release does NOT set an upgrade epoch for v3 actors to take effect. That will be done in the upcoming 1.5.0 release. - - ## New Features - - - [#5341](https://github.com/filecoin-project/lotus/pull/5341) Added sector termination API and CLI - - Run `lotus-miner sectors terminate` -- [#5342](https://github.com/filecoin-project/lotus/pull/5342) Added CLI for using a multisig wallet as miner's owner address + +## New Features + +- [#5341](https://github.com/filecoin-project/lotus/pull/5341) Added sector termination API and CLI + - Run `lotus-miner sectors terminate` +- [#5342](https://github.com/filecoin-project/lotus/pull/5342) Added CLI for using a multisig wallet as miner's owner address - See how to set it up [here](https://github.com/filecoin-project/lotus/pull/5342#issue-554009129) - [#5363](https://github.com/filecoin-project/lotus/pull/5363), [#5418](https://github.com/filecoin-project/lotus/pull/), [#5476](https://github.com/filecoin-project/lotus/pull/5476), [#5459](https://github.com/filecoin-project/lotus/pull/5459) Integrated [spec-actor v3](https://github.com/filecoin-pro5418ject/specs-actors/releases/tag/v3.0.0) - [#5472](https://github.com/filecoin-project/lotus/pull/5472) Generate actor v3 methods for pond @@ -166,7 +303,7 @@ Note that this release does NOT set an upgrade epoch for v3 actors to take effec - [#5411](https://github.com/filecoin-project/lotus/pull/5411) Handle batch `PublishStorageDeals` message in sealing recovery - [#5505](https://github.com/filecoin-project/lotus/pull/5505) Exclude expired deals from batching in `PublishStorageDeals` messages - Added `PublishMsgPeriod` and `MaxDealsPerPublishMsg` to miner `Dealmaking` [configuration](https://docs.filecoin.io/mine/lotus/miner-configuration/#dealmaking-section). See how they work [here](https://docs.filecoin.io/mine/lotus/miner-configuration/#publishing-several-deals-in-one-message). - - [#5538](https://github.com/filecoin-project/lotus/pull/5538), [#5549](https://github.com/filecoin-project/lotus/pull/5549) Added a command to list pending deals and force publish messages. + - [#5538](https://github.com/filecoin-project/lotus/pull/5538), [#5549](https://github.com/filecoin-project/lotus/pull/5549) Added a command to list pending deals and force publish messages. - Run `lotus-miner market pending-publish` - [#5428](https://github.com/filecoin-project/lotus/pull/5428) Moved waiting for `PublishStorageDeals` messages' receipt from markets to lotus - [#5510](https://github.com/filecoin-project/lotus/pull/5510) Added `nerpanet` build option @@ -176,32 +313,32 @@ Note that this release does NOT set an upgrade epoch for v3 actors to take effec - [#5219](https://github.com/filecoin-project/lotus/pull/5219) Added interactive mode for lotus-wallet - [5529](https://github.com/filecoin-project/lotus/pull/5529) Added support for minder nodes in `lotus-shed rpc` util - ## Bug Fixes - - - [#5210](https://github.com/filecoin-project/lotus/pull/5210) Miner should not dial client on restart - - [#5403](https://github.com/filecoin-project/lotus/pull/5403) When estimating GasLimit only apply prior messages up to the nonce - - [#5410](https://github.com/filecoin-project/lotus/pull/510) Fix the calibnet build option - - [#5492](https://github.com/filecoin-project/lotus/pull/5492) Fixed `has` for ipfsbstore for non-existing blocks - - [#5361](https://github.com/filecoin-project/lotus/pull/5361) Fixed retrieval hangs when using `IpfsOnlineMode=true` - - [#5493](https://github.com/filecoin-project/lotus/pull/5493) Fixed retrieval failure when price-per-byte is zero - - [#5506](https://github.com/filecoin-project/lotus/pull/5506) Fixed contexts in the storage adpater - - [#5515](https://github.com/filecoin-project/lotus/pull/5515) Properly wire up `StateReadState` on gateway API - - [#5582](https://github.com/filecoin-project/lotus/pull/5582) Fixed error logging format strings - - [#5614](https://github.com/filecoin-project/lotus/pull/5614) Fixed websocket reconnecting handling +## Bug Fixes + +- [#5210](https://github.com/filecoin-project/lotus/pull/5210) Miner should not dial client on restart +- [#5403](https://github.com/filecoin-project/lotus/pull/5403) When estimating GasLimit only apply prior messages up to the nonce +- [#5410](https://github.com/filecoin-project/lotus/pull/510) Fix the calibnet build option +- [#5492](https://github.com/filecoin-project/lotus/pull/5492) Fixed `has` for ipfsbstore for non-existing blocks +- [#5361](https://github.com/filecoin-project/lotus/pull/5361) Fixed retrieval hangs when using `IpfsOnlineMode=true` +- [#5493](https://github.com/filecoin-project/lotus/pull/5493) Fixed retrieval failure when price-per-byte is zero +- [#5506](https://github.com/filecoin-project/lotus/pull/5506) Fixed contexts in the storage adpater +- [#5515](https://github.com/filecoin-project/lotus/pull/5515) Properly wire up `StateReadState` on gateway API +- [#5582](https://github.com/filecoin-project/lotus/pull/5582) Fixed error logging format strings +- [#5614](https://github.com/filecoin-project/lotus/pull/5614) Fixed websocket reconnecting handling - ## Improvements - - - [#5389](https://github.com/filecoin-project/lotus/pull/5389) Show verified indicator for `./lotus-miner storage-deals list` +## Improvements + +- [#5389](https://github.com/filecoin-project/lotus/pull/5389) Show verified indicator for `./lotus-miner storage-deals list` - [#5229](https://github.com/filecoin-project/lotus/pull/5220) Show power for verified deals in `./lotus-miner setocr list` - [#5407](https://github.com/filecoin-project/lotus/pull/5407) Added explicit check of the miner address protocol - - [#5399](https://github.com/filecoin-project/lotus/pull/5399) watchdog: increase heapprof capture threshold to 90% - - [#5398](https://github.com/filecoin-project/lotus/pull/5398) storageadapter: Look at precommits on-chain since deal publish msg - - [#5470](https://github.com/filecoin-project/lotus/pull/5470) Added `--no-timing` option for `./lotus state compute-state --html` +- [#5399](https://github.com/filecoin-project/lotus/pull/5399) watchdog: increase heapprof capture threshold to 90% +- [#5398](https://github.com/filecoin-project/lotus/pull/5398) storageadapter: Look at precommits on-chain since deal publish msg +- [#5470](https://github.com/filecoin-project/lotus/pull/5470) Added `--no-timing` option for `./lotus state compute-state --html` - [#5417](https://github.com/filecoin-project/lotus/pull/5417) Storage Manager: Always unseal full sectors - [#5393](https://github.com/filecoin-project/lotus/pull/5393) Switched to [filecoin-ffi bls api ](https://github.com/filecoin-project/filecoin-ffi/pull/159)for bls signatures -- [#5380](https://github.com/filecoin-project/lotus/pull/5210) Refactor deals API tests -- [#5397](https://github.com/filecoin-project/lotus/pull/5397) Fixed a flake in the sync manager edge case test +- [#5380](https://github.com/filecoin-project/lotus/pull/5210) Refactor deals API tests +- [#5397](https://github.com/filecoin-project/lotus/pull/5397) Fixed a flake in the sync manager edge case test - [#5406](https://github.com/filecoin-project/lotus/pull/5406) Added a test to ensure a correct window post cannot be disputed - [#5294](https://github.com/filecoin-project/lotus/pull/5394) Added jobs to build Lotus docker image and push it to AWS ECR - [#5387](https://github.com/filecoin-project/lotus/pull/5387) Added network info(mainnet|calibnet) in version @@ -210,7 +347,7 @@ Note that this release does NOT set an upgrade epoch for v3 actors to take effec - [#5047](https://github.com/filecoin-project/lotus/pull/5047) Improved the UX for `./lotus-shed bitfield enc` - [#5282](https://github.com/filecoin-project/lotus/pull/5282) Snake a context through the chian blockstore creation - [#5350](https://github.com/filecoin-project/lotus/pull/5350) Avoid using `mp.cfg` directrly to prevent race condition -- [#5449](https://github.com/filecoin-project/lotus/pull/5449) Documented the block-header better +- [#5449](https://github.com/filecoin-project/lotus/pull/5449) Documented the block-header better - [#5404](https://github.com/filecoin-project/lotus/pull/5404) Added retrying proofs if an incorrect one is generated - [#4545](https://github.com/filecoin-project/lotus/pull/4545) Made state tipset usage consistent in the API - [#5540](https://github.com/filecoin-project/lotus/pull/5540) Removed unnecessary database reads in validation check @@ -227,14 +364,14 @@ Note that this release does NOT set an upgrade epoch for v3 actors to take effec - [#5592](https://github.com/filecoin-project/lotus/pull/5592) Verify FFI version before building ## Dependency Updates - - [#5296](https://github.com/filecoin-project/lotus/pull/5396) Upgraded to [raulk/go-watchdog@v1.0.1](https://github.com/raulk/go-watchdog/releases/tag/v1.0.1) - - [#5450](https://github.com/filecoin-project/lotus/pull/5450) Dependency updates - - [#5425](https://github.com/filecoin-project/lotus/pull/5425) Fixed stale imports in testplans/lotus-soup - - [#5535](https://github.com/filecoin-project/lotus/pull/5535) Updated to [go-fil-markets@v1.1.7](https://github.com/filecoin-project/go-fil-markets/releases/tag/v1.1.7) - - [#5616](https://github.com/filecoin-project/lotus/pull/5600) Updated to [filecoin-ffi@b6e0b35fb49ed0fe](https://github.com/filecoin-project/filecoin-ffi/releases/tag/b6e0b35fb49ed0fe) - - [#5599](https://github.com/filecoin-project/lotus/pull/5599) Updated to [go-bitfield@v0.2.4](https://github.com/filecoin-project/go-bitfield/releases/tag/v0.2.4) - - [#5614](https://github.com/filecoin-project/lotus/pull/5614), , [#5621](https://github.com/filecoin-project/lotus/pull/5621) Updated to [go-jsonrpc@v0.1.3](https://github.com/filecoin-project/go-jsonrpc/releases/tag/v0.1.3) - - [#5459](https://github.com/filecoin-project/lotus/pull/5459) Updated to [spec-actors@v3.0.1](https://github.com/filecoin-project/specs-actors/releases/tag/v3.0.1) +- [#5296](https://github.com/filecoin-project/lotus/pull/5396) Upgraded to [raulk/go-watchdog@v1.0.1](https://github.com/raulk/go-watchdog/releases/tag/v1.0.1) +- [#5450](https://github.com/filecoin-project/lotus/pull/5450) Dependency updates +- [#5425](https://github.com/filecoin-project/lotus/pull/5425) Fixed stale imports in testplans/lotus-soup +- [#5535](https://github.com/filecoin-project/lotus/pull/5535) Updated to [go-fil-markets@v1.1.7](https://github.com/filecoin-project/go-fil-markets/releases/tag/v1.1.7) +- [#5616](https://github.com/filecoin-project/lotus/pull/5600) Updated to [filecoin-ffi@b6e0b35fb49ed0fe](https://github.com/filecoin-project/filecoin-ffi/releases/tag/b6e0b35fb49ed0fe) +- [#5599](https://github.com/filecoin-project/lotus/pull/5599) Updated to [go-bitfield@v0.2.4](https://github.com/filecoin-project/go-bitfield/releases/tag/v0.2.4) +- [#5614](https://github.com/filecoin-project/lotus/pull/5614), , [#5621](https://github.com/filecoin-project/lotus/pull/5621) Updated to [go-jsonrpc@v0.1.3](https://github.com/filecoin-project/go-jsonrpc/releases/tag/v0.1.3) +- [#5459](https://github.com/filecoin-project/lotus/pull/5459) Updated to [spec-actors@v3.0.1](https://github.com/filecoin-project/specs-actors/releases/tag/v3.0.1) ## Network Version v10 Upgrade @@ -242,7 +379,7 @@ Note that this release does NOT set an upgrade epoch for v3 actors to take effec - [#5603](https://github.com/filecoin-project/lotus/pull/5603) Set nerpanet's upgrade epochs up to v3 actors - [#5471](https://github.com/filecoin-project/lotus/pull/5471), [#5456](https://github.com/filecoin-project/lotus/pull/5456) Set calibration net actor v3 migration epochs for testing - [#5434](https://github.com/filecoin-project/lotus/pull/5434) Implemented pre-migration framework -- [#5476](https://github.com/filecoin-project/lotus/pull/5477) Tune migration +- [#5476](https://github.com/filecoin-project/lotus/pull/5477) Tune migration # 1.4.1 / 2021-01-20 @@ -441,9 +578,9 @@ This is an optional Lotus release that introduces various improvements to the mi - Error out deals that are not activated by proposed deal start epoch (https://github.com/filecoin-project/lotus/pull/5061) # 1.2.1 / 2020-11-20 - + This is a very small release of Lotus that fixes an issue users are experiencing when importing snapshots. There is no need to upgrade unless you experience an issue with creating a new datastore directory in the Lotus repo. - + ## Changes - fix blockstore directory not created automatically (https://github.com/filecoin-project/lotus/pull/4922) @@ -463,7 +600,7 @@ The changes that break consensus are: - Correction of the VM circulating supply calculation (https://github.com/filecoin-project/lotus/pull/4862) - Retuning gas costs (https://github.com/filecoin-project/lotus/pull/4830) - Avoid sending messages to the zero BLS address (https://github.com/filecoin-project/lotus/pull/4888) - + ## Other Changes - delayed pubsub subscribe for messages topic (https://github.com/filecoin-project/lotus/pull/3646) @@ -620,7 +757,7 @@ This is an optional release of Lotus that upgrades Lotus dependencies, and inclu This is a patch release of Lotus that builds on the fixes involving worker keys that was introduced in v1.1.1. Miners and node operators should update to this release as soon as possible in order to ensure their blocks are propagated and validated. -## Changes +## Changes - Handle worker key changes correctly in runtime (https://github.com/filecoin-project/lotus/pull/4579) @@ -863,7 +1000,7 @@ This consensus-breaking release of Lotus upgrades the actors version to v2.0.0. - Fix pond (https://github.com/filecoin-project/lotus/pull/4203) - allow manual setting of noncefix fee cap (https://github.com/filecoin-project/lotus/pull/4205) - implement command to get execution traces of any message (https://github.com/filecoin-project/lotus/pull/4200) -- conformance: minor driver refactors (https://github.com/filecoin-project/lotus/pull/4211) +- conformance: minor driver refactors (https://github.com/filecoin-project/lotus/pull/4211) - lotus-pcr: ignore all other messages (https://github.com/filecoin-project/lotus/pull/4218) - lotus-pcr: zero refund (https://github.com/filecoin-project/lotus/pull/4229) @@ -890,7 +1027,7 @@ We are grateful for every contribution! This optional release of Lotus introduces a new version of markets which switches to CBOR-map encodings, and allows datastore migrations. The release also introduces several improvements to the mining process, a few performance optimizations, and a battery of UX additions and enhancements. -## Changes +## Changes #### Dependencies @@ -961,7 +1098,7 @@ This consensus-breaking release of Lotus introduces an upgrade to the network. T This release also updates go-fil-markets to fix an incompatibility issue between v0.7.2 and earlier versions. -## Changes +## Changes #### Dependencies @@ -1050,7 +1187,7 @@ This optional release of Lotus introduces some critical fixes to the window PoSt ## Changes -#### Some notable improvements: +#### Some notable improvements: - Correctly construct params for `SubmitWindowedPoSt` messages (https://github.com/filecoin-project/lotus/pull/3909) - Skip sectors correctly for Window PoSt (https://github.com/filecoin-project/lotus/pull/3839) @@ -1086,7 +1223,7 @@ This consensus-breaking release of Lotus is designed to test a network upgrade o - Drand upgrade (https://github.com/filecoin-project/lotus/pull/3670) - Multisig API additions (https://github.com/filecoin-project/lotus/pull/3590) -#### Storage Miner +#### Storage Miner - Increase the number of times precommit2 is attempted before moving back to precommit1 (https://github.com/filecoin-project/lotus/pull/3720) @@ -1129,7 +1266,7 @@ This release introduces some critical fixes to message selection and gas estimat ## Changes -#### Messagepool +#### Messagepool - Warn when optimal selection fails to pack a block and we fall back to random selection (https://github.com/filecoin-project/lotus/pull/3708) - Add basic command for printing gas performance of messages in the mpool (https://github.com/filecoin-project/lotus/pull/3701) @@ -1199,7 +1336,7 @@ This release also introduces many improvements to Lotus! Among them are a new ve - Add additional info about gas premium (https://github.com/filecoin-project/lotus/pull/3578) - Fix GasPremium capping logic (https://github.com/filecoin-project/lotus/pull/3552) -#### Payment channels +#### Payment channels - Get available funds by address or by from/to (https://github.com/filecoin-project/lotus/pull/3547) - Create `lotus paych status` command (https://github.com/filecoin-project/lotus/pull/3523) @@ -1249,7 +1386,7 @@ This patch includes a crucial fix to the message pool selection logic, strongly This patch includes a hotfix to the `GasEstimateFeeCap` method, capping the estimated fee to a reasonable level by default. -## Changes +## Changes - Added target height to sync wait (https://github.com/filecoin-project/lotus/pull/3502) - Disable codecov annotations (https://github.com/filecoin-project/lotus/pull/3514) @@ -1279,7 +1416,7 @@ This patch includes some bugfixes to the sector sealing process, and updates go- # 0.5.7 / 2020-08-31 -This patch release includes some bugfixes and enhancements to the sector lifecycle and message pool logic. +This patch release includes some bugfixes and enhancements to the sector lifecycle and message pool logic. ## Changes @@ -1299,7 +1436,7 @@ Hotfix release that fixes a panic in the sealing scheduler (https://github.com/f # 0.5.5 This patch release introduces a large number of improvements to the sealing process. -It also updates go-fil-markets to +It also updates go-fil-markets to [version 0.5.8](https://github.com/filecoin-project/go-fil-markets/releases/tag/v0.5.8), and go-libp2p-pubsub to [v0.3.5](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.3.5). @@ -1312,16 +1449,16 @@ and go-libp2p-pubsub to [v0.3.5](https://github.com/libp2p/go-libp2p-pubsub/rele - The following improvements were introduced in https://github.com/filecoin-project/lotus/pull/3350. - - Allow `lotus-miner sectors remove` to remove a sector in any state. - - Create a separate state in the storage FSM dedicated to submitting the Commit message. - - Recovery for when the Deal IDs of deals in a sector get changed in a reorg. - - Auto-retry sending Precommit and Commit messages if they run out of gas - - Auto-retry sector remove tasks when they fail - - Compact worker windows, and allow their tasks to be executed in any order + - Allow `lotus-miner sectors remove` to remove a sector in any state. + - Create a separate state in the storage FSM dedicated to submitting the Commit message. + - Recovery for when the Deal IDs of deals in a sector get changed in a reorg. + - Auto-retry sending Precommit and Commit messages if they run out of gas + - Auto-retry sector remove tasks when they fail + - Compact worker windows, and allow their tasks to be executed in any order - Don't simply skip PoSt for bad sectors (https://github.com/filecoin-project/lotus/pull/3323) -#### Message Pool +#### Message Pool - Spam Protection: Track required funds for pending messages (https://github.com/filecoin-project/lotus/pull/3313) @@ -1346,7 +1483,7 @@ A patch release, containing a few nice bugfixes and improvements: # 0.5.3 -Yet another hotfix release. +Yet another hotfix release. A lesson for readers, having people who have been awake for 12+ hours review your hotfix PR is not a good idea. Find someone who has enough slept recently enough to give you good code review, otherwise you'll end up quickly bumping @@ -1365,9 +1502,9 @@ This is a hotfix release. # 0.5.1 / 2020-08-24 -The Space Race release! +The Space Race release! This release contains the genesis car file and bootstrap peers for the space -race network. +race network. Additionally, we included two small fixes to genesis creation: - Randomize ticket value in genesis generation @@ -1385,9 +1522,9 @@ Among the highlights included in this release are: - Gas changes: We implemented EIP-1559 and introduced real gas values. - Deal-making: We now support "Committed Capacity" sectors, "fast-retrieval" deals, -and the packing of multiple deals into a single sector. + and the packing of multiple deals into a single sector. - Renamed features: We renamed some of the binaries, environment variables, and default -paths associated with a Lotus node. + paths associated with a Lotus node. ### Gas changes @@ -1395,19 +1532,19 @@ We made some significant changes to the mechanics of gas in this release. #### Network fee -We implemented something similar to +We implemented something similar to [Ethereum's EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md). The `Message` structure had three changes: - The `GasPrice` field has been removed - A new `GasFeeCap` field has been added, which controls the maximum cost -the sender incurs for the message + the sender incurs for the message - A new `GasPremium` field has been added, which controls the reward a miner -earns for including the message + earns for including the message -A sender will never be charged more than `GasFeeCap * GasLimit`. +A sender will never be charged more than `GasFeeCap * GasLimit`. A miner will typically earn `GasPremium * GasLimit` as a reward. -The `Blockheader` structure has one new field, called `ParentBaseFee`. +The `Blockheader` structure has one new field, called `ParentBaseFee`. Informally speaking,the `ParentBaseFee` is increased when blocks are densely packed with messages, and decreased otherwise. diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 3db17a0a0..dc4e4e8dc 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 3db17a0a0f24ce6a04e946f86bf18b0e1d8c0007 +Subproject commit dc4e4e8dc9554dedb6f48304f7f0c6328331f9ec From 96c34012318f86501ece4a3084c45aa7dff4dc05 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Mon, 17 May 2021 13:55:05 -0400 Subject: [PATCH 48/80] bump the version to v1.9.0 --- CHANGELOG.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ build/version.go | 2 +- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ab80f806..7c0cc71d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,75 @@ # Lotus changelog +# 1.9.0 / 2021-05-17 + +This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. + +## Highlights + +- OpenRPC Support (https://github.com/filecoin-project/lotus/pull/5843) +- Take latency into account when making interactive deals (https://github.com/filecoin-project/lotus/pull/5876) +- Update go-commp-utils for >10x faster client commp calculation (https://github.com/filecoin-project/lotus/pull/5892) +- add `lotus client cancel-retrieval` cmd to lotus CLI (https://github.com/filecoin-project/lotus/pull/5871) +- add `inspect-deal` command to `lotus client` (https://github.com/filecoin-project/lotus/pull/5833) +- Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917) +- go-fil-markets v1.1.9 -> v1.2.5 + - For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md +- rust-fil-proofs v5.4.1 -> v7.0.1 + - For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md + +## Changes +- storagefsm: Apply global events even in broken states (https://github.com/filecoin-project/lotus/pull/5962) +- Default the AlwaysKeepUnsealedCopy flag to true (https://github.com/filecoin-project/lotus/pull/5743) +- splitstore: compact hotstore prior to garbage collection (https://github.com/filecoin-project/lotus/pull/5778) +- ipfs-force bootstrapper update (https://github.com/filecoin-project/lotus/pull/5799) +- better logging when unsealing fails (https://github.com/filecoin-project/lotus/pull/5851) +- perf: add cache for gas permium estimation (https://github.com/filecoin-project/lotus/pull/5709) +- backupds: Compact log on restart (https://github.com/filecoin-project/lotus/pull/5875) +- backupds: Improve truncated log handling (https://github.com/filecoin-project/lotus/pull/5891) +- State CLI improvements (State CLI improvements) +- API proxy struct codegen (https://github.com/filecoin-project/lotus/pull/5854) +- move DI stuff for paychmgr into modules (https://github.com/filecoin-project/lotus/pull/5791) +- Implement Event observer and Settings for 3rd party dep injection (https://github.com/filecoin-project/lotus/pull/5693) +- Export developer and network commands for consumption by derivatives of Lotus (https://github.com/filecoin-project/lotus/pull/5864) +- mock sealer: Simulate randomness sideeffects (https://github.com/filecoin-project/lotus/pull/5805) +- localstorage: Demote reservation stat error to debug (https://github.com/filecoin-project/lotus/pull/5976) +- shed command to unpack miner info dumps (https://github.com/filecoin-project/lotus/pull/5800) +- Add two utils to Lotus-shed (https://github.com/filecoin-project/lotus/pull/5867) +- add shed election estimate command (https://github.com/filecoin-project/lotus/pull/5092) +- Add --actor flag in lotus-shed sectors terminate (https://github.com/filecoin-project/lotus/pull/5819) +- Move lotus mpool clear to lotus-shed (https://github.com/filecoin-project/lotus/pull/5900) +- Centralize everything on ipfs/go-log/v2 (https://github.com/filecoin-project/lotus/pull/5974) +- expose NextID from nice market actor interface (https://github.com/filecoin-project/lotus/pull/5850) +- add available options for perm on error (https://github.com/filecoin-project/lotus/pull/5814) +- API docs clarification: Document StateSearchMsg replaced message behavior (https://github.com/filecoin-project/lotus/pull/5838) +- api: Document StateReplay replaced message behavior (https://github.com/filecoin-project/lotus/pull/5840) +- add godocs to miner objects (https://github.com/filecoin-project/lotus/pull/2184) +- Add description to the client deal CLI command (https://github.com/filecoin-project/lotus/pull/5999) +- lint: don't skip builtin (https://github.com/filecoin-project/lotus/pull/5881) +- use deal duration from actors (https://github.com/filecoin-project/lotus/pull/5270) +- remote calc winningpost proof (https://github.com/filecoin-project/lotus/pull/5884) +- packer: other network images (https://github.com/filecoin-project/lotus/pull/5930) +- Convert the chainstore lock to RW (https://github.com/filecoin-project/lotus/pull/5971) +- Remove CachedBlockstore (https://github.com/filecoin-project/lotus/pull/5972) +- remove messagepool CapGasFee duplicate code (https://github.com/filecoin-project/lotus/pull/5992) +- Add a mining-heartbeat INFO line at every epoch (https://github.com/filecoin-project/lotus/pull/6183) +- chore(ci): Enable build on RC tags (https://github.com/filecoin-project/lotus/pull/6245) +- Upgrade nerpa to actor v4 and bump the version to rc4 (https://github.com/filecoin-project/lotus/pull/6249) +## Fixes +- return buffers after canceling badger operation (https://github.com/filecoin-project/lotus/pull/5796) +- avoid holding a lock while calling the View callback (https://github.com/filecoin-project/lotus/pull/5792) +- storagefsm: Trigger input processing when below limits (https://github.com/filecoin-project/lotus/pull/5801) +- After importing a previously deleted key, be able to delete it again (https://github.com/filecoin-project/lotus/pull/4653) +- fix StateManager.Replay on reward actor (https://github.com/filecoin-project/lotus/pull/5804) +- make sure atomic 64bit fields are 64bit aligned (https://github.com/filecoin-project/lotus/pull/5794) +- Import secp sigs in paych tests (https://github.com/filecoin-project/lotus/pull/5879) +- fix ci build-macos (https://github.com/filecoin-project/lotus/pull/5934) +- Fix creation of remainder account when it's not a multisig (https://github.com/filecoin-project/lotus/pull/5807) +- Fix fallback chainstore (https://github.com/filecoin-project/lotus/pull/6003) +- fix 4857: show help for set-addrs (https://github.com/filecoin-project/lotus/pull/5943) +- fix health report (https://github.com/filecoin-project/lotus/pull/6011) +- fix(ci): Use recent ubuntu LTS release; Update release params ((https://github.com/filecoin-project/lotus/pull/6011)) + # 1.9.0-rc4 / 2021-05-13 This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. diff --git a/build/version.go b/build/version.go index f05ac6269..c712bfbef 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.9.0-rc5" +const BuildVersion = "1.9.0" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit From 1cade911f6d63380b845bd057f66b728b5b2b9fd Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Mon, 17 May 2021 14:08:36 -0400 Subject: [PATCH 49/80] docsgen --- build/openrpc/full.json.gz | Bin 22804 -> 22800 bytes build/openrpc/miner.json.gz | Bin 7829 -> 7825 bytes build/openrpc/worker.json.gz | Bin 2574 -> 2570 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index c1a124fa42fc50a8fcb8ccc848af23a9a1d253e3..7b63de10fcf67b4935512da641d665e5ba2a99b2 100644 GIT binary patch literal 22800 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

NR4hLP#m5Il0;6V$oilJdR~mF~ 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 diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index ef8ed4a6ae2367e4f55e5e3174f555743ef46798..1f57cdeb4ac81d032981e769186f5089698df6b1 100644 GIT binary patch delta 7759 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 VWP1Db{{sL3|Nqg^j%TNU0RVv;J-+|| delta 7763 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 diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index d784af49f16980a29570510e0538af6e476a5f59..b059e2f81f4fab1d823e2c75aede9faa1011d471 100644 GIT binary patch delta 2469 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 delta 2473 zcmV;a30C%s6pj>-e}5bc`!!xz*aJ1=j>LoSkC+ipQ~pU^usLO|_l`57U<0nrn#`8`zhq#w6+Miene++YjK!1IWh;{jfEV8*Pw zkyi{`*e8N`W(oqKr*S+#_PM0tltqtI)9jyQ<~1`jslN3Gdj=lSuNfYQ=euB9JU`P# zpC|)?2Pd6Q$A7|~18=N9y<1p#Bsib^HTMAz-Y%{!OdKaMt_j*%ghy`5)rgE$nQ&#DCcL&r;PkJ=rp?DF(RCxScc8AE=rIVK)*xLpCD^ORPzkbfCcRJd6=^(#&oHBASE9f%y9=F7pK zpzK*iDF|t*d5tS$Y07o~+9?R##?`|SQM0JHpD2EBhqM2QJ5a-UT(Vovb8KA17w94u ziRbS8r!6>7SsyT~NTs9>OCT;~Q=DK*DiM}!$D_-raXG#`eh0OgYMi>psXI`o?p>z< z%zr5(F8vA7E2)U;DdMV0p=J36VbfY5z25s0ts9iy3r*SwlwOmvdI_8gQ~PByk)X=W zZJ2GTIWaZUK@Gq)0C%VW*UtyIb2i}>VNH|d=PTCN2z1R&Fcr17ljKDnKTqgys!|yp z{x_E@?n*n-=#IF7Hlr6Hc_8daa={zT=6{mf#KnVt*U|--_r#AsTz~{|r{zW$3`bw3 z`RhaYmo~VIiW~SgJk*mL0W3ED@hOsgV_#vtpo0tp_>n0&JM`gN5O|JFV%hwV^s7XZzHPc&e8o0SXA$d`KCW4 z6%nf1j3 ztcNSf753#8v474LoHGX=!lm}y&0{rUnIyBnb-6vBgx|JjY@^HG1X%kSV1GTeY@X4M z9d4lPcY1GkvxoBeYz1us#wK7q(17uzU{sbY|d8q$RMxD@3nQ5$_x zGZ0%l7?|X;q{c7=4l*_R(TU$MkThFl{MTz;45=e)c$4X& ztmlh#KaE$p7x1+YUS(E%5AXnQp&~x(v1T(=YbIsqAwt;GFk1GDCVwTgm`tH_2biK0 znv~?#s^9-1U`Wi|>kURr8{U#uD^55J9&uY6Ofs2w$3KY;q<1f!+3CDTdZ%jKleggc zKlsDnelX{r|6}Y;U_R;fC$tyLPlEvZ-MhYVxVPC}MN_%zyxRLrPD2&SZ8}3u^w&gx zhv3^5EdH1r z3K;7|pDW^e0q6>q>&Kue9-1(8uk>jjP(4@Ho*%F`@YKN5p?|_t!M>P!=b^T95Ngv2 zsE_m(){b6TXdEaMAB|$swwuIxCoQ-RmEoP9%~_`xch;$2xVuHwyI*!iSmb_M-Cub4;XNReAW1Wn)` zNw7I{BvKq{lYdI4M1lUGh`dEwUY)?*;*PW5bGdD^r7I!yMay2sEqm`c;W^@}lAoq7 zjy?os(@hGHX{%TZwiZEziH>r&jV3Q2+UD(^FI6I67bL#_BJ%dkn6HY`n4m0_L?EuV zX)^4_+xZr!_cbTZ6tIX5`S8duhFl@fN%`~HH2H0&$!7( zJYSS}7Q}1IS5x(ZmzXX;X7h;uJ^TKz4NH%UO_5x(^?Vs!)lhUh3|>=Xf>5!G25Ffo*KaZu5`K+vYcu zyZa#B){r_#=A$UwgZnK|Zwhjc-w0Lz2`H$FA{Eo+3e}SdoFr+!9K|)z*yZ-EL;+LOMQR2D5D|cw nSt6&ANCb?9t2@6adM`Dj@+LgdxA Date: Mon, 17 May 2021 16:23:17 -0400 Subject: [PATCH 50/80] docsgen --- build/openrpc/full.json.gz | Bin 22483 -> 22479 bytes build/openrpc/miner.json.gz | Bin 7848 -> 7844 bytes build/openrpc/worker.json.gz | Bin 2577 -> 2574 bytes build/version.go | 1 - 4 files changed, 1 deletion(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index df2b87f1330c334cb1a830105c124265d0b69486..0c0a08621b64c753e5765b8369c1e8ed921b4843 100644 GIT binary patch literal 22479 zcmbTdV~l7`7jE0OZQHhO+qP}nHg)#GZBpPQBf z%&mGpYnz@<^s4N#4Fr_S|0ywTiRO|FJB>W8+LAXc?CrP zy0>>Akr~C!%fKyepW0S$b%lo@iz-Gpo1b_1zjr`}GTysdKfiDBhLP7VBS7{Tg;rkx zy<>X7@8hB@HZEU%_Vh%A3Jkw~K5vQLB*Ph>=a}R4aE1l%BHtb83fGWl73)769dJEk zpxRKa!9RBSpx6=c5}Jb<$)0q_y6&Byu0k`y`lk0Ptnmd=>d!boK9lsKAVhE!hgRdt z10oI#s#y|1zP^%voF)B#zhCuwM-RtA#20t$YS&OKHE<#s{{(u43Up&MNbuq$TK}=I zPy-3fImF_^(^Gm^YsEE=qd>NR0)hpgfFeE_#e4Gw9T*f0u#-UeBiPqPjiM|Fl;YM~ z41Bi+!ZEO#0pfwsM|%D2O&E74LT`#QZi^|S9~Oh${C47MxH%BJ0EfETQit#m&K?Fi zlaG!i4~CH1=c5#lxDQd(1i5t}i4l-9F!J$l#QVwH>Da$|1D%ZWf9rwxkB|WMwo(^j zknAx4!9%~BL;%D6ekH_u;6QL9K2jbND`Y8~CTGn~%0A!jU`ChkZf@^fy~5S^{o9;g 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 diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 04d82b39a9604730726072bbfec48f749f9947ce..49e8306c3fdce35f5f874ef031a87caff3b2b049 100644 GIT binary patch delta 2533 zcmV-7k>u`kld8FZnC$VnSQXz?e?L`Y=nIPHMZm{$w_F2|Gp#37#rKc zcA=LLPiNX9bdHXs^Q|NCgt-q)_%8`h_|f{o?F-hHRX=PgKtlm5l=(?L0zypWvzFPGk>ID1GcaO(iYTL2Kx5) zcEYdOIAAt1GE5p<9CqFnSw{vIy3)T$Uj0-aX}`~x&m8qaS3A! z`CatwhKy+I3-gKNfI)CYe}IMj9xD2#ALBYFiX5Of`Xe0^8(L??buZ2>1VV6efS#_| zwGyBL!H{fSFn$T+(pKqOViS>>p*;HM26QvGoUg3Lep043EU~T`(9g&UMpA%0S@3 zQK!?f@Tb5V=}&Lx79I-D$A8Xzz=PBIjfIKhgk%wSD1W#QLQ#!pOk4>T_7hDD%oPA4 zB9=VJ3?UX)Apwie^CgMv`_AJQKKc%}!s$s>K=5sW;bv}O0e=NlfP)801fVy=7hn^m zTf)iBt>tcYGrLv5v8DEm1+IHzVX7cvip&hsW0|!=R3d^_Ci!gvbEEfm(ME(Iv+A?# zWk#+z$A3EWNUY0Ir`x~DnOVhY^b18xD~fVbRV*o*fKn9Q=uR?lmBt;>wyL6XDP8GM zMh6(3@vI)u!i+n=n?Hv+e=YvtT3RAv=BHAuyH-1R))st=0l41n!|>k&z2dMPDI; z%5fDA(3=tG?m7#;M38T=D_G_{Y1JfTrW7@hEyD|8Br*mHXx z(+1q7tk;(nq*7dmB@mag2~H3tl?Yol~h z`U9f9sA$epz*X}gWqI-G7+poe-g2FwZMoRxejmVQD{)#}ZVzwG9(1 zH5aC4=BKf2jb+<2%hvClf;XJbB(;f)2mP+48?GLRAAh(63F2NejBYp^et(hX zfA7QpX-zw?DB4TPo)(-PIrsAw;wm6Dgq4xJ_fgMSw`6Eo)di_FDlghx0ult& zX?^*!-k-`K%NGv=sFk!J%;6r=xDg+thmbTR4ZMXWz(DA2h&sA6^e_b$^?$o&z8Mcm zMTDwWK$a(W@jNqYnEa;1IY}wQx0S-B^`>l3WT7DOehH*jwPg%f6pK*a`YNab5yv2_ zkxBC0d{OH4&zXV?=D=fkfSy|fRwHal68lRJ(c?wxz4IoP+Ra$%xx?^`bZoH@ zvft^QZl@OV<&<MpNvQBNcdUd64joir3f%+*wwAdG)K9Q1fj5$4SqXP)ny3^}$!tkusdhrTcEM8ZeU_xj95gn*vGK3S#-A2c z&ZI12op^HzTrcEYn&bLWXNra<@Z2du+68l-%WE&sqBnM_u}k}Am);f>z0|wcw3!P{ z>uxfApm(rxg-FUmqd=kfiW7@!Y7+OBG{-trhA(b5ca~nwou%VWVd;vh_w4Huu*l&W zaqh0E>PjJbrm`#UhCCwfBvMmY@H3GJ%y;btU$>Lf2QhzO9oesWbG9ke`p`Q*Dmv3L z9@sm_39tTEW%)F8aiAe6o2=vf46b7K-&n8^CNs)C0-AgwXp@g_zCKng$ZG#dD`w~`|2A#=zSFkD@TuKxSo3FCvs;ji(R*U- zZ4J&efE#~h%ot_Em#=~^dj-MRVo$0*zY@dc2V@@czhyW6MuyN&^L1fb5_>*#E_$HD z>!8!=0WvR({B-!WhVaZPt?yqZC9~jl%{dEpA3TK>e?C!qQHH6EMC-S;DUAJ2E*$p@ zVlPv@Sm(uv1Z3U!>+)WScU)@37!$pZ|46G00960kQ?7uN_qeQUUTDA delta 2536 zcmVdN;hl z7QP1|DQ6)>yWMCVJ8+NZ7WP0*xg&A^+Y@HQ)1ZG)7i>;h&FdMy*=(n$2+<~}KBCypFT7bRrTgc{2!J}#n%)b`$+ej)d$OIZ!U@I;z zVQeA4gTCF65p8^7K5-l{2(IW4u#n$HdEfMwxXy_pN9c|INXNv6#(=o)#kqw*2riD$ z(>1$R0#qOvl7Ed0ra&;_He#e|(ljA@K#lt7n$54-?d>hLunatph#BtV)c|JBdKh`l zu!Vghh-a1{5PBI$vtyr28ZKG%bz+(Qc4}QyE0Y*of3TQ)1dONr9P;fr}bLIo?pUrP9OdKa9i+{L7!F>>lYCL1&O0cjWYg%9~ z0T2UR%^*3JSt~>(B4}-r-xe@8dT$qPL%Da>Qf z-FZw~aF^0vUs{j~aUGUGT*@XmMwC<{Y}t+vmlES*bb0(9Dic+^akU$FXl~rwvm7f< z8FA?ki1wnSIZptW&HpUgFA1Aevd-(HFMrH*ZJzf+g!aKauW?zmTuq6k{X8B^P{r0Z zOsrH~n2MR7+OpM_?Z7NsuXUPj*)G_am$YXZBs(>+eh#2}Zn94iww>fDvgmn6a1))1 z2=BkSRLh~X>x}M+8)*G`36clGj#w7F;dCacO2$wL%PXJE^M*zHX9++R@!Bi@Fbv?#szT)jnwLgC3gE>Es-e z4T+k{lIA9a$@W4`Gz+p3nF8H)lYiw{pxcQXnnh4f44&$=+dzCk*cC(`m*Ks|Y24fj zztkjUe`^Fc<=1`SHgQARv%dWbbTTaz_-`?s-&b+y<{TLg1-C)UE0EGKS1Gwj0A~wG z5KyP_<;!M&DupatJPe>#(tIG=+4l?6n|LM@0$5$ zJR}tns$2nCmfS7pnOej6HwDf~3K_ng6fSKxWd|Y)If?g6AeE{umvDKp2<45hf+`Tp z7-T&%iJzM6;Z%V=VSqMh&j}!hc2MH0Mm<3Wz)4 zo<~)hd!Cn%7-Ttr&oCu%FT>m<11Xo+Y(tqLwxait>d}iX>4q_*sd({E)`l2RM^^A3 zlT%qw4e4=eKXNY&);{==Y4$z9JGZ%l_@d{UPDZV%l${3!;Yfq%OfOoLP-8NME*xNr zj%l2eS4Vn(Lx>Ptxqp)lN=qx=f?8{tV(35NrdF6_JnM{p5F1GMK|0gZS(kKA)u=1) z!1KTJ$G`kw#y$W0$Q#3K-0h8NH<+CU0rWceJ>z0;6JJSHxf;COe#V!f4CFSwpgP{G z=dPFams=tBY36D%v>t>jqN!kvmHDnV2{TT)x9y^yYbuv7=1C8;w9wT-WB{428Y zXE~KK35!@I-dq7!3prQjxO&u?prH;t_ezlV!JKFE+RL-(wOy+1(xKUd>G)$TQI z=R(t_n@k_*9ZRfTp|a2@P-uC@iA6Ovv3pCJV;w5P7dPuWORwh6(n%|~bVXHr_H_lA z=WvZUcQ;gZC6GK**|qG3JRAA zooN{l?49F;SAWa0d=ff8&=8bOHgSFmS3di1Em#PX8O0s}jlU4I%||z1A1mf$wf`jY z?%XJ>l57}*%w<6!uGV5Q9L79Q^DH|iaqgZKQ}h*oo3?r1YT9A=)a=x(`7^B9$w|iO zJu&vS0%sb)t$#A+5@pSouYxbTIlOvV_YH$UNeIOK<#*456Rqo5Hj>_H5={ z^gzegL95jTWL_5e>F{d<;i*;H+`mXlX2I*4a~AC0e+n!9e4_NC3=Au) zIO*lYUZ#4n%8L;($g1zxWxW#d+|P7n9)_PFn>vjFb$=>k%#(Ad?+eta^FnXoy~Ot$ z4)!Ox4y-^SU7#PSx6M0~Sw)bdUy#;>8VI?$H%76NJratgo8Ma04c#ibcwBj zE|gw?F&7>6 zn=l6v^nX$Jni4r}BpGKrmjUV@?Whl$>VqcZ3!da;CL>uc=?6wo*>TNMJv{G+t#It* zJ;}U@t=e~F^SbSB=d7~T+gJ9<$tHd!RQ)HQph_~(5-yX4p3Tg}L9;n$*#nJSZr@21 yFhyOYrXT Date: Mon, 17 May 2021 17:37:18 -0400 Subject: [PATCH 51/80] bump the master version to v1.11.0-dev --- build/openrpc/full.json.gz | Bin 22479 -> 23308 bytes build/openrpc/miner.json.gz | Bin 7844 -> 7846 bytes build/openrpc/worker.json.gz | Bin 2574 -> 2579 bytes build/version.go | 2 +- scripts/publish-release.sh | 4 ---- 5 files changed, 1 insertion(+), 5 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 0c0a08621b64c753e5765b8369c1e8ed921b4843..4d9fb5284d1c6ed52d84f50d11610f338e15b4bf 100644 GIT binary patch literal 23308 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%0A!jU`ChkZf@^fy~5S^{o9;g z%etTZ$M1UaUvHS-kJ{ghaZbZsb?MmP#fVS@NTSb5%2#j0oB3U^soieKH<52f0u=E@ z_a$S#0^)YpjKP_fE<3MCFCCGGY5s2$E>v%WtgPMNujFca>@UE)I-T7pbEn6rWlod4 zkC20n9&#fbcm)t-G62vJz2}c^4k)kA?s^2m-S6ksM5~6A`tjQFV-HL*nVHK~0i#@f za6s%Yu6`YXCu+FyTEii`vR`(f4mP9T-SLr+lhUtJrUk{*X9OUGJI_0D>tf|Ay>J(v zgIZjK-*zz?SC0~qO1xT>Y$E+{()l2GiXcJ}0p7cLgRDU+@X>JT&hwMt6Me^KD3w3P z_BjSlX%{UYYZ+XHE-jrG~5x5qpr9cOI@BvTvh?9i0g-3;qq6nkOK7tuP zD#qpT4PE+t?&cb^8Sh6T6!OQMDMvGg0txbbKADDgP~Xle9+vpUGd>`S;v1GR9`Cgf zfxovuRdpNpU7YXGUjXd49sIkPw+FPjjp~ML4Um5N?S5enDYHZTVaS9t;96V4O{nv3 zh8S(^_3SIH^K}@V1v`uC^H1Zyvo7K9k;DJ7*+s+gmx0 zaZN7a1AHS+?%^7Nr`iuBCy7q~+G&=ZQMM2qYrfgv3{&J7A;298rcdi5Dmd3D-LL(D8|whzqi7JLaXpc_rohnZqRdLInJR3}wt=iX)r0=|gAs%m-z8^k> zpQwF$K4}OK-SBcfI6d4;26S=qv;WpF(Bmu!YyT5pxbDZ%#0dntjDedj7xT&B!t)LQ(JQ2eSvbs1QH>qvOHf?wn2u!|N$T-(03^z^d zfJVxbjvSVInjm0<)+yEPmtbd_Z9-U_Az3wepT}1)f0EqYs58TyG+pXAuN8@G<4Z^P zRsnY@8y7v|C1FxN1-AOo&Q6u}-dxNI%&#S4uvG+EQ|A%+@Lq8zS%k;I!7qJyA$=wx zA+CW&3uNZv*K4nHz`1mgf7t+gFCOyqR%XV`T-SW`ShpX%8Vd_+R2bQbVfNPEyGu%^ zBre4x*;*DGK}?-a``+olH(bBq!U*AusVSmuxMqZ7H{v-iQg2mn-Om^9@MM1a*~rwf zk0Za5+JgDor1t5Y_Wo^3F~&8&1h;Yc=X)A<=1NHF9AGp9vr5VMQc=OmZ4F$`Rlpg06Sej z5TA@HCvR-&`DlMaEJbPldqy6$cw3F4mV2ko?s^#{%v#>g#k1W ziYahF8;22^9@K4u(uAnLe=dnQNFE_0It8gFT)6PFQ6M0D5by>!&TmAb@2O0s;HTT! zNeXal7nzW4NZaneZ$RmnUmjimH+%hX_}cz-jX|y+gFaw>xD77;^!c;5zbSrTdfgmr z)F0pqKZenEkfGA>m;vdECx>o?k}Um9)Uh8?N0`KK*bqY|k*8upIf58!FPPr(5+Xzi zPhTlAiFuYzCKE$=Nqi$zYCB$+^@~*WgTH@)fBsibsU%2D;_7;Q^f#La?bEyBe&>f& z^!M}OcoLmn|EKoc;s@2-9PEJ|4ZP}6&7a$Ze_`0m$>x2t5ch+ogv_Fdb?Tl!0qeNYx@XD6=6 z+TI7Y+uv_1R+B=zNw(D@dcGD0T1ByXV6(GCwLH*AP3kQwxFu?7R9>HLr~lAVgaS3J8krhJ7*;jVF|y3dy>6j zopn{>Mz{sfq#lIggah^buXY~T_OrFN1mMeQqbz9N>hw411K zd0%gPSvPeK521O&tP7%@Nx|wY^<~`gXd;nXyauP;>8L`Y=47qan#bDqJo&~>GNFTu zq%3%fz2~eHG~J}gwNer%MQ%nh=2KyVCfrqRpwwam;DZ4d+!qm!qY_2UaP zLB!67d)lua8w#WIz#^cVdRU=!eofNBHA=)KZb4cL0=DACVb zGMV6VNTHJ_=c(@vqwHVZ?pl&~p_VNA1bmX4TyfF!_^kyN1FH6y5tJj`bKyFH9V|7{ zD8eC43$dSeKXWq@I>?hrj_@HPRc(bQC!XU-qJ4eLFW?-w_hVCbqyj$RI}RPcuD6On z4!H8X1^5M8DG6PC0@jvB-vVCWcUBkX6qqBqHY;VpJm7ogY0Ra?u?a^eH1|~&%o$FW z30Ag?3=&xX_~XP4F#F<7Zy`pG@+$ko_yC*4yh}v2zDSQ+tXt{$6zWVw9o6-Ur5t=l z(51|xw6WRA!7nuc<^X5N5NiT@ub%-fi1L8IL+Y3XoZ505>ti6cu_;`Yh`9`+3qJF? z-1K4BW1B=U51NK6*=ErbZhU2BKgGu%?~CwLbNlcGJYYrx059d z+YU=P7mNO*EnuZ0UQjorCjUBlk+GF{jagXcAlHdDalGt+hTb6dH#en5x@5L4k}hYS zBPWmX56KdZ$;X1wlJ+exW$yeYSFWN!Kol^J2e=Irr>%c;^!KSbmE!aajY>9YAFO)& z8k#4^-GP9jil_gxu$%>x3T)1V`fPRi{Q4#?v|ZoQ)g<8 zN5#{pZSG@wJML2O9s;xvqTxh1DopLQZa%1r`?)Vo9fR#k(#UAI6dEjGA?x!i8WscE zlrqFJe6BmIofv#$ZekgpWQ(>ODyj2y;eN9$i?5&0-#2^I>GB=}%eNx4@|!7F<4d_M zwyDyMg8ta)!RlR%&zGOt&0fFH+1}dy!QY6x?-{)Kp0C%Q*Xx(TpZWI_@SnKu-nLl2 zJe}Vcexo&A{LQ16PiLAOIe52*`gXlC{~6tRW(34QYaARPx>`AG64d~e@RGvfc@S}R zf)$g^!$Gt+3%8VaAE|Qnut*9cmmw1Wgc<1fhG78bJH#T1S$oTjvX94GnENg*GucaW zcVD)PrLhZx@oH|;z5c+BKDt*jc%vRv4Wz~3L*a3U_4-HVJ@lh9Qd+f;?BreoM`MbN zu-uW?`U_NN@!F=oVRyEN8Ol5`m`^PykImb1=Bx->?d%gl(}OKL>3Jmts;OBjdmFnR zTIgTX{GTI{ztbB*o0KmVJPt2ys&1`=mDdRsf!y!~WU`NMEI}c|5{~7<+3}dRD+g1@ zgj4xJJ9#uoR!fgKh!>Sk^xFw43)>_4d!jq|clwMXi?f4-B5oSg>~lE1K|+sLa?T}z z`;xjD@5vv6Wf}7G0M!Sfeto!$^yigM}&_X_C5 z%62*BG82h&0TUjMAwe^PZnlM53cH_+RV{BE+dByEW*#dX}ZFgE^9%hVe7v6T{RDt|-Icdtac$Lan$ zm4iU{M9CM@s|ijx(LBC5YnusTvvls<{xN^YdiR?d*I@K2LpXoJ>}cCD ztZK|UM;npq__Xr2ZrtUL5HRN{B$c@DOmTmUM@-|Q5R8r_OX;}$>rUkO`~^T*_3T`D6M?ExC&A4 zo?d3B3Y^KkifUcQw7t*NETe0_UG@ay=bX8A!4CKI(!S>#VI(mpR80(1ETf5nMCIO`ooDW*uSOB2G?7+Kw9}7p zjBi(jGCX4R_k?5lXuO%icJFk?yQYejtSIj`2feA#OWokwzi{yF`wH>Q<=siXk(MIk zfOg(lmdH9$31T-^2xQ9C9_ha?;E4{j!H|(1H!KtKZK6_1m#+%}wt_yb(01X0)LbI$ z;al~LtA672dJ$sh34T}Qi*h*K2iQhHe1=~oThM5bWfogNfcCrrRhCW5QF$s~lcAPH zJD*9jMSEB0=LgYSd>L28ZQR5x_P>cA*Z7GzSYT?OpvXT%Ws;z1|Ltg+**k9BK zn&NTfhS#L=8?4P_NlC7dvfP4=l0uE7xpO7OuPzmof5l2wwQDT~eJK0uo2qyo^SR!r zjTz(=yE*3U>Df9ookobbLDEIurM~yqMBMfitX*;uk!7AS9Ve#Zog!OZO_HX|kdn^H zL&hX{;!o$4X$_9N&iRI_`=5y_O=0Oyi{}_U@{Xb}X2}_|#Uj6<)?@R=l+PfU0B9aa z)9Bb|*b+f9C$^JQ&ad}K*T2^(0rg5rXl7Q+MR(n4yd4SGaWX-gtkj@pEx>9g2?sa) zwnmN1XDaSs$ZoLE?YAd_ONh9nO%~yrp0)i<^4~CLo_<~LCswMp{T`22u!jo}V(-p3 zbhlp}(mcI==e4xK_HZ!h97xg>bjpC|Wvc1rc$;do>hsu!ga$}ZaUjBpez#WBZCcDV zD^v3QnzdN8{-r-st0p&+uUuCtY3}bh?+E8ERtDO3`QjM&}VvD1FHL6A5!iu&cPMa6YK7+6y# z54NHSUxhmb0Y^_+@fx+3bVi%B9q_Ie#-;aVIR0->8Zlz0;UN_IBFeVsQJ9u^c0F2#bSYAikWGM}s4jp&xq%C2E~MdtKM<|NqI z3VtD;>eRN;LdW)%JUA+{@jmAV=$Q+Vq#bp8w* zOpVOh`j~F2d}i)eNmTheEeuiNtryuzmoLt1uTqy*Co?BsTWQCqEfq2S*<9LTP-z>Z zJE}M>r%+D0ml{BwNTi|yuqphj2%Z<<;wkR|U>}&365T~r9uI@7bHf;P=l@duapiKh zMHJ;l#c86Gu~7y?6}(Q0QWd=UAst6ac|Ls~&fnhe?%>^?oS)sFo%haP?(NREfB?PZ z2*u%K{lkboL4b(h1Rf4^WQBGA4>AtGXlW{OWz4_^&7GJ)B6#pXocg=mkV;I9>SF-s zZFkFs}3Ex9y6n}lpehjJry#M@0*~I zQv$!>bLS_S{}tn0>~&>UaF5kdC3+B3@^NArMT7tk4sASXJ#_$SFx`X#S%H|L;}*f06fu5J<4#+29%12GJ(op#$-VGM|^Lw=4D!XK^;W@NI4G`16U! zK+Vu}UvKw7>t>g0f!X)6t!D9-yZf2d%4`_y6upJ@b*H9xw&Rr9=6S<2-_Le-fcz37 zHbPXmQrKFxis{P$#)!3i&|>E=@F2oAP`Hi^OCKe>lXAzmabf zgxbW7U8C2y?NkL#2~_$S_@@Hjj|g2@qR%$+)>JAPD%7s7E6!psDrrcj{UVIV1WM~l z=Z%mc(of?~LM6ylxeDzQLdP^fja^0f_t%JLmn#np21o<^hepu(c`#fTmFF3r7E-1Ab!#;ApEy+3X ztB8ma47M0bvIs9A+Inm6RFz_Q9Yp4)Cht^0dZ*f-L%PH@LNJHZ^l zaPzDw@yWOoGlF$-3DzZJwOFM)k*!Nuu>xmnzC4DEs1dNpTRbB|q0OF-D1fN_D58>O zB>r`oABV&1a+B>((CUZmMe-+@AOV~%(WfRQl~|1pVw$@V7@vqe=Mi(?`qIWoai7%NWeHiGOW6Qk8MWCmWlJ+G(ggdff%PsB^mxF4yNRht}#QS}Ku( z&(i;2EK*@R>g;t5{DPsH#-CSQ$Jlc7xzfvv*B%&M=4?OS*>q6E2gqicM{V}7X-@;-;f!3onVRILB1&?k-i63D6mx1N z`hCPsnAgC7?|?rEH*|7=R_*j2KLo?7+G6oan;&zwkzRM8~*$x~D%k z^^<9kDC^0ac=JY_rb7vXS0P>ER3v?}C7!c*rX7hc-&FO#q&^CMv!T%Q52wxpgXxVM zC5*YHf?NM4&E8a?rmvHZ5DC04z_@-}c-T*+Dji*QX_wO zC~^En!b>ywF+dB`Y25!IViily%fcXjB+69syXq^j;rFT5E4>&(pyN8JOaWyCh(*eW zHIqWQHaAUDoO6^WYx%__?X@cI$)P_XX6d`PJ;0dJ=`}G*c`LG+jZGR_Zdu1zQ)SpX%#sb$fmL?)42%Vn}iw^M`b*Mw^g=Ycp2C zl9y9m0WlMVKE&v!Q@0B9yRoDGDADrq?|eH~?XY$as*P1Zirhf(`nh*u+d-02^ped; zF7=YJDov$zoG-Z0qohcyuHGu;3}I;bj-}U^%Z`MIgn9#fXnP;5M@R3Pnz`<{vd^DE ziqF~ch#-5B@PF0jD}IZfN8=$&2tI07Vc-{ZC?h`geLyAVA053qNEws(W7GGFA1&$y zb1CHv?~iTFw%ou?%(hLeHfIcOa(s)Vx!grrMb%;7{7cPsmtp*ZRnu|dhC{w8Dn?&r z^dc1kUe|Tqjd>MdQ#woAiK0>pTU13Waks|usYv0f3s&g};}2%Z`&puaxEwAgtz_p? zYB-;P_mPTo2Uz#(42N)5JjfLXnKvkAfBQ=#TxgwHbgIIPXgW^aiv2H|Z7DwiZBprt zQLW8FWBkJ={C~HAekA2;?yuXs-oamZ%wKNO807($xqbCZ*Tl-C9vqN>No{jcFV$5p zD{cdtjPy22coR5K)#(KC-~1wkzg=07%~Pk~3AX8CSjX%d+en^7PT^$r8yzNME9Ndm zGucvhXWj_lF>sQcEF%{=rQ6gqRy7hqTxJ!ysQ4M-8x9VOW|oQF<`|wdIYeweH8WM? zXJxZBIlBolTDbeAUF+-O%O^8*EcJ>}IbtEAA~LT&{La*z zv5_NlPs^RSzB6x1a}!+vm-zxO6qz&n$f$?DQEQ!4<`f0RL3M>x(h;7?AIUal%}PSI zy=Zy7uD?7xC+}==Js+hQstE@L8ALOrcf>3mNLsF`)xuwwGo{z@2VZp-fDV}z#yu=ClCk}VQ`3Z zq(IOSX#ijW=_p0^`V3iEHQbG4D73RHG$N+P=`N}T54&(6`h)hbUI>H&&Iae((%F1t=q0Ln^-OKne z-?r;ja`Y|Fy2o?JOk!&CeBSMCsNqlzcUu%n2ffxS4`d%yE45y4g-46=Ku)!5OXK1+ z`9k{Pgd@oo7LC?f%{OyRDg&;VgRI6>FlCZ^o+P60>?>+8mgx-XC=jF%DAp^SCPE!H zC8lLcdo_&WrT050vSQjfB%1Q$~vnOD*FfQQCw zyJG(AS(?|Vm4}L|Y7lffMaDfRNTt^oZLav5+6V;W7=YurAKHUeBQ~{dsiX|(Z zX7LF=OkCvxnaN|ZTIM$Ux&IKG1v0(Lv!LsXIcElrDcv{IpN*t?KR#Z;spDL12F5%> z{u8;e%LFOQq>O+Br__nCKgWa872*T^SRG>}G^WDLj8!g^N?^*}Ai@HkIDlCV8mDRu z_zsf$Xx>B_74r{^iL}ERbJWl1aR#>SDXql{Vr(z>5IjgpI5ku~JtKluKpjizFv^f@ zh_>2VkJAlMVLUh>kq&&Hkj#(j(S)BA`PTSZot$w4jwtRVIJFNplU6r8ymi?ZAG{bx z>YlRt{A1cLr9?XdN?x5Mw4gz5rtdiRHy)3n9*@%ADbh4e*ZohVg6qmt)5ps-F_*lK$>ieFF@Q~ zH1C6)w=4;`vtJNkAjw{OTZU;Cd0JxHL0>Dq%*SeKJIfMbF~C!OES?w@E~8H1gS0>d z0p|}O90|YKF=u6O?ND1RgSeqcmnpL*Jm7bFX7z$#Pw*3_ zV`djK(a5=qgO+PB`l(j}F7!IU*S0N6tUXXg7)qy-iA%|9@pF>wSP#T+nz;ubIy-9!8Q;lC%O zRoU%$s^b?EvNvpsxsI@p=^5-2WlVYbi)FG>ZQ)6$*Y~Hqo1V*iqwjb_>St+@yu03j zT*WRi()$gI=U@?;z8x_QSs z59Av-&6QVT-#h50M?5TSa*u7MA4}`?8%)3Nmg{5Wjm|xTLjKfI75eNR*fdG}#**XA zWa(I1KM-bVWiN0xdKBF1TMiwX%d6l^&&?DAQKfteZa zK2P*Aj-=9;bSOQgleY|Mgi;`NFN0$KHsHh&?-`@LwNDuWb_Po9YKZM89Rx@ch{Qk- zW}|vmIK5HLz7&Ypv`rbsRqz2+e3bT=9e;s^N1LEeKKF)85ks4jQ_FRCQxUHE>#ZZM zt0-TFYuJkBcis~=$Cjo#4=-F4YIuB|ayLU-4&9>~YBmmsjcf3k zgm$YOqyP5Bd@6fR(5*2ccmr7jy7n_A`q^oe&0`Snhum3+Tgjdv&RprRvYKIR% zXrTAV+_U6!8+u2Li$CT8-0K6BM>#?@%elKX^*ZI*&v;xrudfE)tJMQO&Rb`UxJ=Yl zf65s64`+ulh!n~X{^!;ja*5()%Pftrte-AygjvUCj&r7g0$H^7?E4&hB>JgWhs?dZBH52b} zx|M0{aFf_yF63s~QGelLs;VfMY~cN_Y0qVV!5ey z>S~;N!;Ag%h_(^`7@1idugho7mg^gp#s`2IJDg-bcbglG9>@_JAae)7b-VwMCsbv| zs8x2%^|vd)cT_*h5AMQxU!sU(BL8-b$C*PolY{BKc4JfPL2Y8*=OEgPy6RMV?eDT+ z-p_!dIf{oHZnuUOIn<~CiRJ@5aJCAj3|Nx1Lpyn!Vs3^` z_@QC%Q`AyzMZZA_V`lFeILU_j4qesZ$wu9h()fIGq))tLRz!kyDn`_v)>)Qx{9;BW zKhBRVsrRmv7Q)QjDYCGXmj${mF-emR3*0JVC)d2E0xj2kN1_Tn$tt=fZ1xncXuFHL zqQ#}XeuQQ477@(op?*rJfDhks;YTG%o4qb$-3)^Py-}B5V#z7D=$I9^=#o=<$bwsT z&M}=oYFQ(rN}$ZS&o@C?MN#=?);-=%KP%xoEEsxT&YJzVk7k01Z&l|HD{=0S6Fqvq z8lha$HNW_*9*RL;Ijv2}gw)Bw020Ico8U=etqXTKM}z52eMchfYsOtxXI!F< z0m*0gBV+Us0=Qthjd1%6uI|I8Q$$>Gl}(j6O3kDmO|U`WlF zDk}u{lcXiG3|lv`8SHV)k{rbeN8Gqe2c6LgC)^qA^P8?j9gbG$)0We8Yn_i-P_(*J z&m@gsuR!(!bNvjs=j_7YqhG2*2cu|qo)*8L|79*^{-_^@~+HJh=dn@b7U87Cy1Njb2 zyQI4pHymB>L+i8e$HTI7VBNR{Qp4(NtXn1DC!UTWb`coJQ9vU# zU~8R11ieOJy^u&w2$O@hp{SkA>7b;mbOj&X!tT&n{7VIuOdcfkH!DL0@|n33G_?xa zj=zu;D*DSF!<0+T0n|Pq)d*Ern&E2tXVNc-9HYd41uN;}&RHL?baozywFp$!kwokF z0a)>J&c-P)iTmqB47E7{L!~sUE;WcL8Hg!gRf}3$BwNo}FrP43;m8DhE-)z1= zTJF+tpYrpGoO-4OHWr*tN@A|V>1+`<#Q3-fy)h~sC-OgI;z(=AefbyKvpmh5|I|wk z1HLD>)z5BbQMXF+JG@7Fotr!D*d{m(bpWJ`rY2traHYw{cupL^t4q&u^88vtuTjuU z15Y<6dK7<8C=_s`EPoflq+$MGLmA{TbeTN?e^Gng?7F^a(y3?&YnAi3kncnf^7p|M zxIfm<&)++SIEKEX|D`fdfLMn?vMhKW91uxQ$JYQYCXh@RY)5l4N4HER)cG0S86tj^ zotoJElpwl*8`$fzaCVpCOC*IN?Z79lxiu&WRAt^Mi!}JhSChy_=1R@=$xf55h%MJN zp2OCguRmmc&^sYg| zcb~<+=BU^~hh``knJZ#liFQj2u2GEzH28Zknc+5k`eHGGUOr@y^0U3{xyo*(lVy@T8~{KIiJ$(+FyP5A4babG_GfZwdlaC}8kNNB-FHuh z=nJvS+C75XAdTQQgdB6XI&gmf6df@%s~$6$5>zVkjS|Js&MR;gyh{!|;5NCRFa&5b zK>&E#FeP#bzUQCl{(<^YMKV-5%+Ik$jsp;76x9GSxVNbC^7)RiBN1YPpov*yz3&${ zMx`zFsq2aTkD3C$eGga_VIzTbrazH#8LrX4tU8|&qe)Jc?RYvCZ#D9?BU-?$iJSa& zFkX-jk}@!l(-m7|>d|5*{!4Fe_`!Ax=q8Ei6`7}4`llS81jiAuz)cyuFF`b*hWtZ& zc>?>D;ZOrClJ>4Wti(20Oi09$BdQMmftVrp!Zc-dD;_xV;yEaY&*5JaME-~%0U;p^ zM27otVps8=bXJmY4c-L-qHK4BB5nSJd@90;J6}=?u($Cx6Cs->^tze+d|lURHlVfE zBLdI3(7RYpOu9<5_TY1y^p3qTZ)msKSN4IG)ccMRzq@|l9 zjV&ke>RgadW!Lcw$*XY6nL;CL7qq%RCX`6KO)>+9d%_yUAqth{JFY1@3XUM)pxAMd zF94`gA9=Hd3*U=G*&?l8i%HM2t#CT~(v`h;Z`VhHpYY6JRrR11V%LCL^GZLezjM-% zkgdqChFs0c1Eg>W(p_l3tnT?To-S^n&luAA!`Q?2mL!Vk0i;M->)=}|mZ7h7%+^1z z^sR*N6VXq@+v`m4X|Cfql1geGZV9#R)}RI5y2P}o_aawqV_bB_Z7f40Piek2l@hGO z9p7q#cip64uC0yEPJ3!{nsb$toa@}+Ts10Hk2fs<1+*x2#VDoCbmcAR^q0rp$Moo~JBAwv0*H+G{`mKiiV?UHTMZ&NYwP z*4QaS^GDT7szQsa(1gzESlWS5BEHiF?GNYo=`Bc)LK!Y~Trl#$|=GO#wL zeHt8xK<;Ou9HxeFVdJ0M8^JliqkQmid|_hVas-FksGSSF!g68iuOuj6#-$y1QFS4g zj@DF~s2aj9DeQf3n@+?3UqrZ}PWP-3!Oq;?X*O-}q zFm7XZ%QQ}y6bDle?*D5nX$iI1F!`W+5m|@80NETmr%oT$1A&$MnrITFgl!3e2N~%! zs~UDof?P->dXWrErbjfa(XQelTU=20>Mp*XCa{7hM5Zf#d{wRk7n|~59uQQzj9k|R z_0KF$Y`v5P6ulKx;a=5FOelUe(zMraf+d@PwMG2j3w5 zDL?QCPu0q(&OT7qYl@fhjHsu$4ha;;vVV}U7#34@8He0AN*r6P>hGFdRK4>R;3thsL)szp+Q}L*Q2WC5T|PN;IpQK3!18Y4~t+N zupr_W<=kZ+B4UYIBk5=H9Rh_Ges4g?N(*zPq0Y7SQ>9%`Dz)+ECxy511}>Cl`9Pj` zDcU(Ed@EO9%&DS@e zVQ&a+VYQ@96cgFo@Gv$x9*i<|*O6rm@7Iy7&yOl@$-WZAcXRu`_e#HG7P@nPH?F5QX_RdXvxXLoOLYdLa$CyY51 z_?GPpp0J|QrCrH{f4Ld?SSf{qQ`FnDYA{oU0|HVxdfto-_xf3f#1l}U3wEM&Ad$Hj zEeW`K-BIj)>&rP`jPP)PO7tv8a9&5>>6%N<^8Aw5*QaY2_zz>M!uSWZzaf1%rJI)` z8t~2Vf0##Vl01H{6>2xURQm!-O)jDdwMetgvzWb73spacx8%kP-Z*H98kB@LT$icg zHncE2fKQvXESvWT)2QEclvd^sVXA;FQO=f!J8AB^_3v z!laMFY$eaVSs)(BCEqLJgFB~FYd)jBF@Tp+o~iWk^Hn{b+>ofFiMOn59CxseWr~K| zQ`*z9?kUrc=5n%iZS)jz$cL9}b9k|j4bW>z_sLy#%h$K&LM=tM$ThhZUdyA};zRDf zbc|z*w5wfv2I&OrUDpKJK+YJEt={tMQTW%e!d^40)?|;mj9s<0SDdfaIhXi>`pqyn zZFMcQKPSh0Onl2U$X9qXEDP?q909%I=(F$A*W9$JmsHl+d$mSZE)QEI3aUzz43m_j z35AQk%m~ep^UkrO{+SDuZ--S4dK2d1RW^m_2$ryL0{HnWY_Z?Dnb0Ju;9aG>=Z<@$ zV=ibUtZftne8xiQ$W==v zzIi(T@}*g;Irdai`NbN2w8O?lKmPAPufaoHV*zP})c;*d0%#DodM~i8*W4&miC-JT z8I#v0QB8JIiW1g>vz$hiNMcqa3^>x;uI_V`@W6nUY(XvZ`g1|NLHUS*etK^p)K(F4 z+&0Q&Wcy^FU~vF3Dri0$2GeIm;VLkcAh1_^jqFJBTQ^#De%E55>OST`B?Trwxpo2*%dO8ar;Wu>yUwsptmx{K1KFHyleZEalzsuNg@QvuI;*t-kb;jb071$v+x z9uVsvo3`VJg^d+RYRgn})yH?%DZp!$USl-3n~Wwp?jm?YYw2E2MN~hicVdIa6It>i z)88u!E!V3y6V%tMa#OM`o!ty;8F~#R9QI7Cv@--Sb>QF}LwJabCf!rUypJk@B^D0*s!=i2J0i z+#cG{PL|aZcm~bXt3ZCbNywQ@ zcQu=2TOJN|woh>d;v37{5AzN_w`8r~pb9LuW-PS6L&|t!RvN2wyo;CK^+Kj-K^|&! zLb}+uDNaAqb<9xL=$@2jOh4{0&`ZZu#gI4cujdio?=6)s5`5@Qk;ypeGJI)>jk=jH zx*w}?GoCWMd-d?!7qiegI>3W#9Y$n0z~5IdgPHV%-9pz-z7HUY(GL%ctUSm;f58&& z7XdnAY)U_Q^cVr%o6ghW3eR>O+tn7$jk}L11s=VUs%}rAtjedBVilPcErx}|nl8iB zIl&U`6vIqS8F9=1_bKgTYC6kMU&=i4aVyQ^wA4FX=8%0Oi(!dO5K-?!5w=63eS``V zi48$y$I_^$92%iTw+Vc+X^ntNTcg&BrM#sh5sG@nZqeTTx&3Mw6`{aP))!xl01yB;6tHNOYtLb<5!h=#!_{;WN*&NZP2Ftu;V;YSV;f#FBZKF1AQ z^X{@N?{EEm4~ASp_FOSb>jJ`5R_>9Y$TauP6chTT!-u*_=J9KpRpM5bs6o|4+u56~ z#E@9;7pdx{}~NUHo$cd4cueU%JTlJ>^Qs zR@%qt3rl_#;HwmI)lE%xm4T>y;?$QM&`F_;6BA3AMzE8To6tJFMN=NYrIKi)y6y5Q zZ3ws&sFGYga;41^R9-N7?~)pR@w=-+lWx4?B>Y7=?_#uv@A7jPg-pjiX3#7mZ>qjP8 zxzYM#>~(9w!Ky&^Zro>*EitU5Iq#UgZQuJ>yoeMRT8_`KBKH0jBuEW_XcNWa=J3lh zaCfOU(fNJ|e4yK@-h+pyg*m%1lC+9k1&h21^{9*jvH|7Hy+@w}c zJTM%JyCiTE2UGu$7tx(j7_o<=3U8xuVs4^(f}bW{U)x??mlpZaG`vjPX{NA^__rOU%~NTVUeOO|sW>?_K5I~KBs<@p;~fhmd_0wr zfM}Tftqb2{n|c7I$4gT783H@*~8qC~L3QSu;vSryGkEZJEcAd7;#y=mQ!AD_o*+w$K> zcxZYjsD{a?iG{S7hY<((OM(ea6VqJ$aILjJLV8BvP80D(N}KEQRCa+f%r&l(<(M-r#Z_Afv29}OZpbhxo~=I# zhAfYrFWJI)!;NB0(jzqnYs=edLqvs~c+3|}Z7$uKPGr&08%YKxFn_EIOJWIXipSLb zaL({i>VFNT%}pD75E`J7f8h%nRbB=}uO=igQ~BFMP|G7}OFYa-zF!xD5cRa+VMK|E}9Q z&cTil}E z%GFdgwHLDemU)M+q`s)Q^7I4#VnO?nD;d&pzp>qw&v*o8O>H-_Rk5}2WD#hQ!4wXn z_9l%w=rY1=YQBnUK&|E_1IBmxyYkRCpeb|12*>l7|W8pMx7( zw?!9poRRAv)i3b=F3=pJJ_QR>(|p#`yQb5}H$9*;Fom^kbLrFOH$YzKvdYEWNi_?A zs_dp}e8pyjVT|bGW;F`ebKmqFq?@kE>!~1*QM1Zx7cnFQCxt)v7Ih>ss-l=;T1+Wa zQsy!GVv$tSpySI$^q`<*=2lc(&%8p944&k?%G z;Zky*)u*0v@J;=I4Dbt&w1JkE`mr+4rSGY)gGQ3?aiMoghNX~1+!;hwI{)jj6K+%~ zf9d7Vl3%SXR$9CDZN-&or_H66TwwjDw#BJ_8KD?aHkD-=!pWTP)>?8Ri=VaH=D?M0 z-{_qUBM8%LQW1*;pBR?qc6QpCuQfI=tgmY+LOX9F~k7;s*FCT zhh)ZsYH}Pk`6CZ$MH=bLm@n3EYcfNBR9q_6On}`PUc0uw6uU6F9hM#D2pZJSv~@j& zm*1jFsPM(4#-O1hV*Uq#&SdT*`bN!y1Eq_#mIY9?jTT*7!=4E8*!3Tmj(m!}xM-qy zX)jHbAPwV>Dk-jsJ{hF^-`tSNa;^AjJ#j#Cg0Q3rSzaey0#TtKSbyRxk0)jU`XQM+ z;3GKN#nB=qAD1+;7d!_q9Gq+kQJ4_XQ?Y-Yfu$OqFDVyci{D@rI(WQ?hT#i%+{o`M zfaB7R=rCVS{*ot|+j)@+o(9G%&1@OOiKHPlO&iGchW4Dw7is0SKNOJ*3jYwmdc9to zoL7ceX>M5kbmUrh!2%=K=X>}`N4$Y46Busp(Vrraf~fv`{6yFYN6} z!O2}K=XRbiA}{k8lotw2w3@ycx{KXu3w+ed;4WhfcAMTFF^KZ2LmFdhcFklu>|~XW zQgQH{LeCQ)U|>bTXt&{<@ad6q8rwG%oZn~zxDL?&cfJiPZNRsL+m_AvF1-5dU4s@z3IFEB+c~vRx0|iX9psr2B2M-4+F1p3u~)s7=Eim$nC)axVH z=xy3Kd|Oyp^}Iy)r#tfUjjc2ivsUO-k-)D%=1h0-Etk5^bCFCpf^+-I9-5H5S4ANF zy6vrNCR}O9;m-TzFJu;fiW?=(1M)H~3yjqxE{a8f)0wZGK}Qd-7d_iOKY+dlyvqTHY37z zESh)>0uCc`6aSy3Gj;hFiH(d`GZhB|Qp^6%7y+^_SNy?nwpx(kKW!#%lnE=raz4Kl zj#<&KBA@8MyR-I;=MCq7-i+?lEW*T+`D{oxtWo`Wd@BFgzwvWtD&jP~ymm%dMM3UN zfNifEa;y`yh$!t33D?a;QkTLu`--IYUp!oM;6a3x(|0!+yJjVCWZlK8V)CCxtE&-a zp$pawt@vD7`kl|P;G5_uO^l?8^2PvyHf=2owoa}aGf-LiPp^@ z2`B0oHavU3e5R=%JQqILS^_h>Sa!#cj-DWg|9&UfH97kQ$B74f8(xF??H>9H7tUe9 ziKiq%|0HUHT<72n#clrt2;Y-#Tp0JiC9~{HO2*k7gC+HpJPv=WZX*iC@WPj%dYH|C;K3iAV*}Q{%LJ6!vI#le+?2V+EN1Klv4SlsQDw52dTR6yT>7!yZENM|-R`rQ zK0@V^yV(_AjKuQ7>2h}es%TCM4x)vHeEIYA3-N0AQ`)r%are!4xs;0Vy4^f%V*fbB zy}$O@rqailqe}4C#?NJt4W_aUk3xAiBx$|=H1`Ri`0je z);T6!6~Y|j5#miaOX>Mb^482iDm9(a~ ztu^lT$MQfN60v4r84va`jc`Z#!UtI2nm zYvNceK&)`^{$Y~rpp(cVB{Uu+TqPa(lcz9jKzyKK&T0n#(ZjP-?{fwA0&ibz0VfT% z%WC;wU-!tv9L9l|BCn#15&dQ?(n!vi3uE}^BBAk%7H-tKAHs1_z_Z}}U`7ONjVY1{ zwa2vm?ANGaHl0kIJ14W03shPaF=SqIjIoUhQ$Ti$HqZXVU@zgOMN8G9c|_U%vhTF@ zwzIH>Ej`=Ut_v*l{d+q+QLYb|q3W8jz`4{C_(C8bdkFe?v43y7(~}?+E+AMyPD^on zv0|+u>gk^zRdj{F!mS(g>iq_B3b}kxdH+{<=^D*8;_2i32HY%ywkCx-m-F|C?UgyU zgH;}SKY2PP6Mmj6J#JJtO8fKfQ7s`Y(x#94r8@PKbRyA`(gYy@3GPfWDPc0&-+U9p zo@Ywecqduk6|gvkXcTxMseKJSQ*pbj)5=G(Lvg2vntAj)!e9*7)*2FD6J|^d)xF>I zWz}fn6&%DRFC~!5Lb^N!Kv|7L$m9Wz3UA}#FUfRuNtu&y2{XOrZI!=&p&W#9=56P> z7K{r^?n!`&VC&S2v|2hdB`{m}GiywqBY`7%kp5Wwv-VeUXun7slS@26?(1;AQ-S2C zBxx3%h44Hj_%Ey&gnwtU6F?F^NAg%^cRXkfr%@4@fxP@f`+SPyBO}yZeqSk;^NOsI z8?>3_l!U^|;-t#3^uPysHMK?oa1jATQOm6c55?AAyId@}>IV_W<(nCyFb4 zPHI7Wg0C`(g)yI~V7fiY5P2jo3s&QkdSU5)KHq}AHoBi>H4u)?Xf;NP{rW$k5P%Co+sfdd1U6qzcE5WS~G2 z_2FHJl7sG+T}+QSxxK2WKZnn)Rua&sti-ADP@d7MkOz%bdxX#lS)P2jqOs^lW{dEk zF!_>VG&e8v)tAn&G~GRUo<&E`^OQ;v8DO&?m74`Z#7Jv$fBDO`Q-v~57Wn^wci_Msh*@&7zCB5-i#EAO5vglpCHRxP%#l^w~FV{cm!o zS{P3fg1Jl3w^Mx@$9;czh(SFw0>woMvGZrAk$LCl?BqZ0fg1o$KT5~{-tWDp%J~J8h&MeDA zzHhV)3;CvpT_(x={rBH<`i0Dv!~`#V@Y94*56;mCOprHW-qK_*L7cz~w*yQ{7EddP%~KM}Q_GM=>z^dLXk1vP!%ndBJWW42gMfrlK*5U?@1Gg`*d zvyG9lV9fPLuU^eXk+w;lSF?a2j$DuOe!a3ebG@3{bo$DHK11Fs=;BwdM;{*lnj_Ml z)BktXJ3i?dPfxAQY;{h_49_bwmn4(TVu>O}7%U>X6@NC{`~lYA=Cjy0W9*@G>NuG3 zv3t}uMr3K*EhF>c4e}gJAVX`K1@ki<%^k0q;U`n%TF-}EfhMEdE# zuw>ZTfPWs*6LFIvDMI!@6TEOjsHQeXQYl_>edRowuXoi!mj4jbOal8AksxtL$ z;wz@du>M*xgwXIIOJ|C_6q(<|V}N}CK~y9*?Eawt`t+nf>>m$rSAz>mK6BX_X3Ng` z0-1MXkKS`2EG0P!3QD<|;`TL~W8Obxjp>AqJ%37PE#UUR=UZQr4W{@S@#lTO(f1{I z;XwEEYX0RE-uleLBv+BIca3+2H_6FwSLU*ZyEVow&#tRc^ir*6OpF$Ka3kWj73#3h zIZ7;P6kJ~9YQ1Cy!Hb!nFi?iU@26Jq6?Mu!W$0EhgE!)70Rk~>jLnf$(1oX{pPC{r zBY#?R!l}nP5L!0n5qpDJrh2)#td3dR?e&e3VM6jh3_w%#7kCI-z^3M%!8_5Yp@Zij%(_;m+Q^#F06e3RvWRDS00sH6M=@Q!vlVEZ$$&3nA=kv{h?-~+| zIz$>vtI{zQkb~jLPJ|G?Rrt;t)Yg%2f`3FII@1F)UL0BH5--EzVrB>fmlh%n&v3kI z$o{qeQQ%Vt0ZkXOMGHV;iMGBF-WY!t>*Uu3BEW>U&09S?QOKOFec087$92D;lbQz>JBl_BpmhTwE(ilcu|qxOdRc{AJ3_ICGNL zIkteu8Nx?|`2YeR*|Q^AW{SyNekj7ilnP`498qh7O9rqHX4G?#1*VSxfMC%1kTcC*yL}ITxi}QD{6)F^h*&Ig5U!$wSfMjom@qK{bsxp z;mg@$Z~6~35$u2Ut;O+UANG&gwC~>`$Ndj|_^-Qsq>lTasWU^5v;JU)`^(4UXa266>u?&4u3L$`za8|hGb9<%uP{W#4KG%dnj}`b}fn<$6Y@#vpqMF584Q(^Q!WoI5S&1MM z1{o^IhF8#MA6<(BT#+%#l((W^#)kevyL@_tKfp5G$)=Eq6gX_Xv8j1~XIDb`6e$(t zM;4+6-e(cr68NtS!gb`&H5GLh=nu$@Oc_}RCNaZJQJ)E7TUtiTqpb3{WbSCbkEKC> z>j~Q5FNg1kGw4q@1(?#jP)~?yGu`?*c#V3)zX!v=!_KByR-6-RT_VgOTqg%-lW$n~ zfLM4_OeMt%^&_y(nq)P9_HFR@V41hO$#0A?Lfy-sxuk1kVr2sjBOeYU_cYzPdKX)B z2-nEO3i1sL9}Wxmb9}iP!+2TL)ElCL(3mF2W)a>xn>O*gZN={z(Y)#n2MRY;E*G9d zVj}wjGI--b;?FX;Mn^JL#8iT5K?Ye+rX3c(ybwtlE<#>g{N2}o(KZ{J&fj9Lstio= zi1RP+DhT@;?TG<%e2>WL`Q?RRWXcxE6C|L0#3H1KzDMkT%)hIEO_D(NlHX6k(F%?z*`DAziLBK#|1NJKaIJx@EdS+nG4)~c z%j@j)=OsnD2R3;pI>u^|KK|?jCb9H}Zl~XC86V(7`k6c)B0SKhW!zu~`3yQPFVXFE zTgKZ57xPX9KPTwFzfof}=smRzJ_abi+&4p>{m^R}B3*D=Wc-`hoj)gU7AE;+f&TYj z|1zEm9)J}LwLp!qt2$`_$*-YRBk@f&Yn00u5ffQBMMTbwPRC-itW$iA!-{n*Ge;!O zI0YtHvR0|x)h(m&;UpVVKAtnMA1kxV2~z2z8~xUcZE zpi#Km2Ayku>2F;;ECZ?EQC(?vEx7BA7p zf89R#DOv8V6oie7YpM40le|`qe4^eR@+67ca#10OCW!R~R(a4?DeT6bh7W%lW8SMsYLR=X)%CBgc-3=%su zzHYa?=*n#A_@r(Ow1%&q&c4Zl7u~2ff3=V?>clouCQm&r8jlv_v<|RWZrp6vj4NnF z)jf$)7raAEWM`FChoXKVU07Q4g-z|`xaLN+HL5L7wKX8yfNTJ=syjRb9j=-;Yc01Q8r(-vHBa8qoHzCSNgAm zbXrQvsGMFYl{5Azoz;0k?0&-evRsnRlukatjb5WB?gc${#@!K_I$1hSG>4C)qATVVJj)i4@mWV-f9=O3(?fiI z0v7&4zCz5z!IZ$E9s(AEwhyLg#(!W2#1)!;s6QG`-*Zk^M4}{%e1P8FJL-LO=N`1m z1*5VEsZ5^LS(9=`a$TfM(pz_x*1NeizB_F$n5)3rsymV8)LkQo-dAC1NuX9%j!14Y z+gAm}_q#_Dw*v!X=20hFe+?e@2L|`d!s+sS#h* z;gL)>dnDz>B~DdCMpkZ#zYlInBSnWIMXDP`1J2_t62wKTNKuSTt>)nx;aowA73UTn zm?B_8+eQ`;Do0vtn1HvA%N_ysz$b{AxQt20di^hiQNTPrpCc~{2qWm(kBtrYg9*;Y zFhS%dRFIm8My(bFIQCfGbak5-^3#T!0z&eD<=% zYm+YoE*W(o!(8|tBc~0sgtOL2)Q=@msv9fUc=4UR^vj)Co<&G;;kD-FO$v%yG9?NF z>^R86kRh9!cEs{y(u05_vtDEXBGgYpppX?@coPX)`wNj-e`h}6%mDCgRUL|ehmQ!W z9DV*tb&b?dKlq)Q!SLL2=*( zG6jK+eFo?ZxWSt+3b7JFpKHG<5`xCfNUkagdSHPL48*ar2qr&6#(i#uZ>UOb&Dxvv zomig0VO_%3lXDe2e}1xRPjz2lj4v+9L^#M*SvI7j@_9brMy@3BEFVVZ5!SMCTaiuvs@M_0s*PBh8PYlMc z(%>o!K@ut7wymNdA#w65@F;ZXR7E)XK_apWuIxI0boCehk^-Mx=4R_uZ_Op?Zp9@@PS4gl-yif}pPuxG{o`Q`!$==mn`S9Zqc+$^Ri{0h#mN~- zIVDY(Dp{dFo>6gNnMSHRf4+h_xIm^2Jro@HR{`=9gmV0d;5^=B5_kgTQ(9pVnu1U(qnJ`z)L5N0t;c4v9!HEM`wq^}2il+*IV+19Fi zu0mk)s9OWlMpSBsSxt0}H@{Qcxq;ONR(A@k4W?c7d#an00yubwe~DEc(^gdS*B)c{ zB`J)>emaB@+K;iIL9nt`G<1;Y>P}6|23mA(6?z`fvJoMlWrSs)3{SO?Z-}a76n$>7 zm9d9qf3xZ|fs|@`aPtyuCUX_gfV_ULJ^vECC>`<+8raEo8~b9ZXJLazq_tThKA33k zb4DEHr9Se5mp@rxe^r0eCec8QZzBzPflONyY&IS-P|Hry%-$)si>k`%h_se8D@|>& zyL8PK9rd=dpL9pp?;Q9R(Z2GAoPe>b=KZOX{!(Hm5m8s(0;)R@xF`W|lcW{M64Vtj z7$|4C9*T|(F`x!x-Rmy;l)6rX43x3Hevbr9!tu?i?3x)T^Ezbp+wXdps>;Z#J zdb#yv=(dcEV+9I=yK0Me*w-cnxMB)$b1!Hu7`r*R8KlRT##UZmC%Bo&$Jcay0@^=( zTyuRdL$lN2e~@7AKwMYl&1F)SZ@kB<-fKW&+YaoDDW$r>&{dZjU$*gO8((&%vw{qP z?~yjJuL!BSQ|=S>?vQs*3E=`z1|Sm@Ds4Mor=+&M5+wmcwk>V8sk6#}Ry2I0>;cNzvPG@M=nGHL~2%#vEAv{Mirq@%8 zn?YiLadO-lcBim&bljaihvE(N@3`YV&(w2Ysr&w|gs zpguFUvh2EQBqPcrKVt!EvO>KFi#hP&QWESQw+si9*st|ui`D$>jnS75@Wj@lBW}AaDI_J%e^5L$mr`}}p~S`sgRF|W5%qQS%{nNH zihBAcY-0xsC$pD13P)9^K85qm5IJ@UG?kDo;wp6MnSn4OXS{gyu?cNs)H@jrPfkud z$ESlqi@%zDg|0E`_J+g3X{S3J4m;xUDl*gS4o(Kc{_$YgGS0^zePeVyXc_OtU!M*5 ze}4QCbo>1iDa{X%9-VuBYw_-VqZ2j}PmCdivGZ)viZAWqOmYnGFHoXx z9rt?1(^G3RTb)xf!}H3_CCOy7SfWS~28)Pph0Qj9fPeM3`7HL$7<=fPIu2%h>>jm^ z5n0-H%gB6qgFFWl$k5vJ3+%(Gjeh@1koOMS_7s|TA?pS2K2h&({pC|0XS=aS-`2bI z&A<#f;*ExQgwpX8J%FAEANlX>-hT_rO)0ezB(aj~W63I-{;sw4H$4kAk$yTbEa`VP zV95lDe}ChDP@4fnb7n&S4Vo))wun&D(CV@vc+-0uFXs!V;G_=@Q< ztiM(aA+&kO(wQPJMdmm07+@bj5EY3HyFci^K0WCV`^UrE)!>4X&s=tf*|KxKK<3@p zqxT#LOG!?Gf>Lg#xP6W0nD-A^V>)4DkJ4ESxPLwH`PP?YgDJj7{COX6^nD3lIMDsP zntwTkw?6YQ$yMa*UE^KhO>*+vmAUNUZjEuvv+HUUy;Q3i6QhM5+=#esg*xnWjuJ~6 z1(z4OS}$2a@M7jC43uH;`>7RtMV+!w8M;->;Ei}%fItizV{;@Gbm1xLr>2O@h}N8N z>VL5ggqBTt#NHs5sa|d_t7F!7dwpYMn2`Jr1JD%x1s;MHu&H@x@D93=aj73Cn4|qu z%$f@tJUFvxaIAoK>bOgWLgXod>@fl=VE=qOU1FPI5=`zTnNfl2e7-sGT|;6~he%^- zRXU~uaxgsEi4elK3g20S+B))0kSIiFdVgTXizDk?;$>J|%nV`R(n5sc8ID&C*`HTk ziQ)GHv$VcRvrM^&Nk5Z_Xxf{~Dj&{0tDe#~vjP zN4b0GVQ$$2A2Glv@Tr4<3)!LtAV{%9TVDuoj6aKY^6LT-U_#sGEhdJEebEC5@}KwgOZcRO{lYY|;%=?S`p_iugdr9Mz0cDVnu1 zRD)69g`G|nE>2>GK9YOn32VDvmdd7E6I&^XH>|Z2);j6v80vp)g|V`z*2Go{(hXDX zhN-%ntn^FAr5?M043=l16%Bt?V8+B&`y5*$F0K`%Nz>g)+&k!J{xW4|oHsKNMkMN(Hh2j;OW4B?H(8GwM0W0@FtT!5=bju>~MFrxr57 zi?0i8E&wJLHbrm>0%vJ6Z1T59E;R3u6}7^7`lSd9LGXc>T0no%POg8VeluQ)@a62W zH~j~i2=>4F*5dfF5BtY#+V}5}uT)&&q=aubr)5KHq+T-W_7Rn3kRiNNq)*#52 zs3{Vrbk}$8xxG?+sA0`2pKHRP#|nI~K(fXjHqjV)QO#nlhPIht;f%!3tVECrgA5g9 z!z<{skFLc5uE-c=%3IMdV?%$TT|Pa+!(XO5>1_&$NP)xF8=HTccXlO|PmxkVeqw$DZrHGg?d6vo9Wii!E4kT{yiN2eZ47`73YLnmk4tR*U7=zsBSorcn zBxSe=d2R7`Uq{<)XgYt3xvDZS#UswYysIGWYqTc@%<(-UtLK*&f{`g(AWw{-wrwhk zPqn>s7q+r}J(yIzq=|0tqW>$UpWgrT@XxP*{`(&N{C~`Se}8=Ddmn#!V}5%0`OUjY z?`QuleSh=deYm>+_5awcbaKU>Zt4E$uF<7)1Q|V=^ohRo#+^=Mf&)&517Q#8@io-uVs9I z59w#}c!=;of18$ZgB|2E=(xN@x6^GIZy#LDI~Dw#p#T0xjnSa@)H3)Op!{;*40-lL zuVsjI!IANAVt4+Wyjhs!mj(LYfBnmNDtG`^Fw_Dy!mjG10VKbMR*l3r)vQr2Uqnn~ z;S>=$GddlM&9YAMH4ZD*vCJHiIO7zUV98pgc2~EI48n(#Y)tuh#=t)8DznZBQvm~D zP_MHk3qt_{%V(2n49FfNEmd__N1!&s?^KU&OH<2KaT=MZ*`&6j)_%DBLbFm05CH{4 z3aFi`lV%Q@1a_hORFeY_Hh)&-Lv?l8*hbbIN!?veHev*_e!aS4(4vB(`gyuzQWUjM&W83bgucOzjg7@ z3?$W+X4itd&MdhOT8g=oBvkG$cRuh8ny7saZ9B;963ehFkJs&kpMR3&-bz8(xVV;T zKR?N9)yOC6-62nss4XXJeXN?&Fp2i6DC9zJ2s1h-^8ZH}{|f(a6ci%qLPTzr#tL`7 zv^ntMQWESQw+si9*spa*W>RLK&UPig`eC)3vQ-kSugf5@L*wgq%ZskemX1&A#z1TM z>gnv8EO^n4YEugtqkm3pBW3c`)1vWcK~C!cd*#N>X3e;QMpWICD0RU*#6)&hS#>Dt z7t)2LHDB1&PL6ACR9mCk@>E*`vJJ=vAgj8=Ge9m(ppE~j;#p@A+7axox7pxtgTD>_ zHu$?w_^Y~rRzlbZdLP~dUjck$RCa^B$p#zPZD6;7-3E5|34eA~mkUe$x<;^axILm# z2y&;C+SS7B@pkj$><#)h=({8I-OX0)Cb--v04)Wuak=#x*$Dbb?iNGo%#$K&AVFz2 z_IJ9`#s+V+z+Py927((177*O;bT+QkJuo3Gkf{f)}eP&ukA{ntS{EhS}CPOp^88GDq@ z>e4p7M%y&nW*@bU;POV%G>Yah6-{sBvhGBjL4@jYZ&rj#svA_NlauI8qj?(5vxk}o zHLgyhfeu{*^*63?C!o5jx3eNtN&`tGI>(k@qxxwapMOUE?4|lyal0m$M2nEM9q%%! zm0m%{TQy#6S6cit?BpPoM$a~SR!7fnOe6@-o2{5j7NfG81cGFPP4YmaL-#_5Hn7{k zZUDOjMe+bQFEE*(O{teYVOa-p;{2skifH~u#+|tNq@z$Vu4Bm;d{j1KDfwa$l}a(vGicT5M_j91I6sK));nBJ1mkfDx2x6 zWM)GxFh|T6w*;c#E#O@eC$&M~i>iQ8Ay}1}Hmw0}qnE*Y>W^2z@&z>w!)0-3;QN{-A0#H0n}3Bo2MU&s^zixMPnJC^O-gq7Mr zG|3$TNGw3;iXeYx@L9;A>W*JIb(7k? z1_edsEx>UTLQ7254dltKq9*XS36hZ1zaXi%XoU zhK#J-5`Q1ul17RSMT%56iUyp=StN*yR*|9@nOe=mHNv@q6f4dxJTOJTgtm<=AXJXD z)-VBY9hW@<>VZ!XGjSP{jP?3o2%~^`cs@s76c9$xvmYB9?gtZ`jbVbwO{gF>5sg|! zCVx&fPhO(3D_<$$T7^y%c){HoGUr-_Q2Z2H0_sg&{*WH|>b! z$D{`VM`pdq07R&tgg_xHxbP+twDuPwvwzNfz?lKy*{V7e0S_M$Ryq3olj<6&pMLN= zGlT6dp+FY8@p4~9Qgz+n8Y_!ehdsuj6DN=aEuJcHuE3uFoc8~Y5<8E}I) zVH9E|fyzV7E4sQ){C*Pr=R(Fm$2eg% zwSO{7UhlrGYuHQNSf{+O{jhEo?RQnPViqX^0jjf%7#jh9fb2HwF&TN~S zRkTS&B>%`T3GuuaH;*n7YGq}zPw+oToPxY6KZa~^Bholue7?=nOF0g9x`W^0T;$}S zx8{;`x8jl{r)O)O?+^N~Pfz;8{_(JeVWbbOO|z7yQ5$Tds?(m$;^d5^oRX$Xm8{So z&!{-8OrxHE>W;5q4la;sLk|T9{#Ahd1fd*1A~=sXnFO9d`IJ@|1bGrVKE`@i;sDP{ zZ5`yr5cSYR%bzH{9YGJqwU5M99E4fSlHFOJd5s$48R_f69_6(BaJIGTo~sa;JnGhf zv=Nn>VOA4e zO(3P39^AYHo5@@SG$5~^YtO#~FG`2Jg9dhT-NwFH>RH&J5ov9fhz};3`5 z;N?$$7FgBav`I7&ULe!f1e=XV4AinyG_!Y#?V_r(IwGwl%}P^S>@HoiMMu4@ z>?hsP^*aZ?MYN~9Atzw$s(F8^q`#EdNkr6@w}9#n1TIPd+$3oQvIKQS%y?x%24A_5 zEsPxTQSB=_5EfNlRul2UT}2MPt0xLmEzlf)^kZis<|e%IgM?R}&oG(*^i{v7ys}8b z#5HoM$9_i8W|cCa<8<^E)`DNMima}OY->&J>_Xvvam#Z-X6>u$9(%wblU{B;8M-Ya z<5+=$;I7)D9rm?J0j`(=+}sOV3&w5^ZU*V`rLmRQ*9mSW^6@oYpMdrcAJ<&p%h2q9 zbT}lKI}q1Zd2^YR8v0_;CrME>?=a5 z?v(pPy*uQcQ$n}^lmW;Dg-YAb*D0xOuS7|}kZsG0M+mhLV3c=3zMP9!o48PE6xg$1L)z!;?C(9+a+8;kgYkd+LqnddNJJH0})>3jhnYpx* zUq?sBquJ0pJ%zoa423@}cP zJHzf2c8-p_Q|oB(8ooZ7nw{YhoONE$x@PYfy|z|Im*r5rf&LvAUIgt|_nlXNoW;d4 zZm+l&zh0705Hn-c5kVA>86%_D>2;2}-J@>rrgJ*#^+uhOKaH00Gxb^U*%#Dj##WYH zSB+#udE{p-KuuPt_h2yxK3qzI-Q$+wU=sVao@}w2pS>~q(gB{>T6Dw>`se2D=ink{ z{$|Xm=RnTZ7G&s%VFzU$Pbh_dq{JDD2j)`tRW~0>Y@9I2s;C=LUq|1pgR-cor*FbG zcA#)FdzqtfRCVf8INuDBW0ycv3E3j9LYJNy2qSXFi$@=u&^AWBlfm%h4~8w{eEiWjM#qDe@m~CY_1S>$#~(qr z-#;;KxsbdiaB8mv;sbI%`pEi#iBLV^Pxv5yzIT^0q!Y-+x%h32I!`$&r%3W%KvU~5 z+OYFkseDmqGxPj{nW#$zCg!imXvM7PjP-p`Qa`0I!A4q9z&ICaR*>9Sm!gaFn`Q?h gcHQM_%HC>;q4D%|`}F?}0{{U3|JXGgCf$7j00McUxBvhE diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 49e8306c3fdce35f5f874ef031a87caff3b2b049..d0a18b43acd268400f6888f7f34900d5f665319e 100644 GIT binary patch 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_ literal 2574 zcmV+p3i0(HiwFP!00000|Lh%IbJ{xguV}O{%^e2_kld8FZnC$VnSQXz?e?L`Y=nIP zHMZm{$w_F2|Gp#37#rKccA=LLPiNX9bdHXs^Q|NCgt-q)_%8`h_|f{o?F-hHRX=PgKtlm5l=(?L0zypWvzFP zGo)Yxwy*=z7SvY;`u6sA!mrslU^aRq(QjY5xC3#eL}04}v;ceKcaY7Qf=AUlGyhu1 zKSEM*K_<|;0$Xu$31bWSUG(jSjA-i%^NHhtL2yNXfQ9@XD*C1$<2omb9H2M)BOMbP zT4%&{FU~ClLU3__p03%o5}*RXkZfHr1%eT`l^|7s3eLxW&V0aw)A@~siQ|N15qBuK4?-)~*7C!n8w!-O2RY34}5u-ILA8kNUY0Ir`x~DnOVhY^b18xD~fVbRV*o*fKn9Q=uR?l zmBt;>wyL6XDP8GMMh6(3@vI)u!i+n=n?Hv+e=YvtT3RAv=BHAuyH-1R))st=0l41(z3bN9!F;W&=*|O)poVF&>p#b)b@x}Alk&IZC~)m+5aZMS`+?{553-LSI;Ty zEc}a+kqb^mUm=3ZaTN~Gn-S;kIt#u;kZ-UnSmr!w)g)x56g94wO1-xUZKmOXuoun% zZ#(%6@CPV+T5J-&7WLPv4=<&dap)Z9-rzq7+-|HvJv;Vv%7E$1sX zPT?zb3X9ltdmhsU+@-A7mldQ^T!$qPm$C^?5G9oeTQ=jvWyH7~T^_%O+C(*OT;s;= zn;ZA`w7`l}MqK&>qP?hS&Qriu^FNFBOTs3#tn=#V3p3rA=baFtT`JxwQ=wD>WCUX6C1{Y>j2xGt1WRoa9@!3pVBz?U@G2Pfe_z1L&UX>{EnoD|w1M zdY%#7RHrh+`)@8)Jd}2w(LHektv@e8@<7-T%YrwY&Lp*oiwFI#r5mmuh#!Br1PS6^ zGmLIH8-9`IfA7QpX-zw?DB4TPo)(-PIrsAw;wm6Dgq4xJ_fgMSw`6Eo)di_FDla6xJ}%U_PlSu0-a1t1^ych=XX^cdId*@L&0s3@(QFh%vDJ) zQo#8F5(Ly~efhH9pUNQ17Y_rdm9!wt;U3bs5g((6kTfI>yoDyfKh;f=f(z!rV|aj`TLe}kY)KOPOApcGMfhd4Uu(VdCYIXGSn9dM z@Qie9u@JJ~>78z;7V_nkbT+YJ6C3VZY}hY2pST1Uh=eap0;yg|xdQ#G&)&1cH#y0j zlA>M6Nj8V?jd5#?+g=;DMpNf|_`* ziT7TzQ~P_t$^O!x%bM@9PHne(b){~N+{n*?`YAuO+vG5JO?Y;}_snwH%k#$?L(~|e zy)#4wWi?u%4+Yduuq=T$l4Ds3cWRob6j8}+Nn@#YLb`UrQtf?~q{$pKHomd(ugJ!q z7F5opEMlE_a|v88abDM8u=bDqmc60peO z8gcHfsp?80d8V=}?uI-f?j%xESnxBE2+Viw1z)$&C$5m168#sINP<$7O|F?oW=N4c zKm?890ZFhqb0kt6X(dV~M1lUGh`d9ZQJuiuU>(`7d2_ZY)cVjnJ}NrXG9K7F#|f|g zR%Q7#ba9{|D4VR~{0y#Q_TN~r5GFIqJp!71A!w72ZoWQNEXZpAN#xzRQCJn(FacS} zf}?IsG=Ljr z%ot_Em#=~^dj-MRVo$0*zY@dc2V@@czhyW6MuyN&^L1fb5_>*#E_$HD>!8!=0WvR( z{B-!WhVaZPt?yqZC9~jl%{dEpA3TK>e?C!qQHH6EMC-S;DUAJ2E*$p@VlPv@Sm(uv z1Z3U!>+)WSca_N+i5Tc97Q zxAi-dTSbt@bw(W|^zagx(o>P(jt@u(QzV&8!ikD@~7n=l6v^ilVk5;<+9 z8D}$>0h%A}Xbzg1gC^q(9v5ULBU!HK2S!l&aZRiqp7+C+IJWYhWYNTy?OU>Wy`x_D zw6@jTRrV>!CVnMU{U@NHDl$+Em&-!WW@eJ0`J5B?KqHsicM=6mQ5UHx2tY&tV&<$x kA`vhap3wXxv%R`h$;k>>>>>> master \"name\": \"${CIRCLE_TAG}\", \"body\": \"\", \"prerelease\": ${PRERELEASE} From 9837fe27d75f3da656a6fc0805c80ec6a94f0d5f Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 18 May 2021 19:14:15 -0400 Subject: [PATCH 52/80] Delete CODEOWNERS --- .github/CODEOWNERS | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 9da543c97..000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,16 +0,0 @@ -## filecoin-project/lotus CODEOWNERS -## Refer to https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners. -## -## These users or groups will be automatically assigned as reviewers every time -## a PR is submitted that modifies code in the specified locations. -## -## The Lotus repo configuration requires that at least ONE codeowner approves -## the PR before merging. - -### Global owners. -* @magik6k @arajasek - -### Conformance testing. -conformance/ @ZenGround0 -extern/test-vectors @ZenGround0 -cmd/tvx @ZenGround0 From fc7ea8dfa318fb9b32217c87d6e27ca27a9f9b4d Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 13 May 2021 21:27:58 -0400 Subject: [PATCH 53/80] Useful tool --- cmd/lotus-shed/miner-types.go | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/cmd/lotus-shed/miner-types.go b/cmd/lotus-shed/miner-types.go index bee478195..19a30c4b9 100644 --- a/cmd/lotus-shed/miner-types.go +++ b/cmd/lotus-shed/miner-types.go @@ -4,10 +4,14 @@ import ( "context" "fmt" "io" + "math/big" + + big2 "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -84,6 +88,21 @@ var minerTypesCmd = &cli.Command{ } typeMap := make(map[abi.RegisteredPoStProof]int64) + pa, err := tree.GetActor(power.Address) + if err != nil { + return err + } + + ps, err := power.Load(store, pa) + if err != nil { + return err + } + + dc := 0 + dz := power.Claim{ + RawBytePower: abi.NewStoragePower(0), + QualityAdjPower: abi.NewStoragePower(0), + } err = tree.ForEach(func(addr address.Address, act *types.Actor) error { if act.Code == builtin4.StorageMinerActorCodeID { @@ -97,8 +116,17 @@ var minerTypesCmd = &cli.Command{ return err } - if mi.WindowPoStProofType < abi.RegisteredPoStProof_StackedDrgWindow32GiBV1 { - fmt.Println(addr) + if mi.WindowPoStProofType == abi.RegisteredPoStProof_StackedDrgWindow64GiBV1 { + mp, f, err := ps.MinerPower(addr) + if err != nil { + return err + } + + if f && mp.RawBytePower.Cmp(big.NewInt(10<<40)) >= 0 && mp.RawBytePower.Cmp(big.NewInt(20<<40)) < 0 { + dc = dc + 1 + dz.RawBytePower = big2.Add(dz.RawBytePower, mp.RawBytePower) + dz.QualityAdjPower = big2.Add(dz.QualityAdjPower, mp.QualityAdjPower) + } } c, f := typeMap[mi.WindowPoStProofType] @@ -118,6 +146,9 @@ var minerTypesCmd = &cli.Command{ fmt.Println("Type:", k, " Count: ", v) } + fmt.Println("Mismatched power (raw, QA): ", dz.RawBytePower, " ", dz.QualityAdjPower) + fmt.Println("Mismatched 64 GiB miner count: ", dc) + return nil }, } From 88c6642330260ba2624b4edeb1e5f5e98c90020f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Wed, 19 May 2021 12:22:07 +0100 Subject: [PATCH 54/80] restructure gateway. Move the gateway implementation to the `gateway` top-level package. cmd/lotus-gateway now contains only the entrypoint. This separation is important for the testing refactors. --- cmd/lotus-gateway/api.go | 426 ------------------ cmd/lotus-gateway/endtoend_test.go | 3 +- cmd/lotus-gateway/main.go | 9 +- gateway/node.go | 419 +++++++++++++++++ .../api_test.go => gateway/node_test.go | 15 +- 5 files changed, 439 insertions(+), 433 deletions(-) delete mode 100644 cmd/lotus-gateway/api.go create mode 100644 gateway/node.go rename cmd/lotus-gateway/api_test.go => gateway/node_test.go (95%) diff --git a/cmd/lotus-gateway/api.go b/cmd/lotus-gateway/api.go deleted file mode 100644 index 003625a84..000000000 --- a/cmd/lotus-gateway/api.go +++ /dev/null @@ -1,426 +0,0 @@ -package main - -import ( - "context" - "fmt" - "time" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-bitfield" - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/go-state-types/crypto" - "github.com/filecoin-project/go-state-types/dline" - "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors/builtin/miner" - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/sigs" - _ "github.com/filecoin-project/lotus/lib/sigs/bls" - _ "github.com/filecoin-project/lotus/lib/sigs/secp" - "github.com/filecoin-project/lotus/node/impl/full" - "github.com/ipfs/go-cid" -) - -const ( - LookbackCap = time.Hour * 24 - StateWaitLookbackLimit = abi.ChainEpoch(20) -) - -var ( - ErrLookbackTooLong = fmt.Errorf("lookbacks of more than %s are disallowed", LookbackCap) -) - -// gatewayDepsAPI defines the API methods that the GatewayAPI depends on -// (to make it easy to mock for tests) -type gatewayDepsAPI interface { - Version(context.Context) (api.APIVersion, error) - ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) - ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) - ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) - ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) - ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) - ChainHasObj(context.Context, cid.Cid) (bool, error) - ChainHead(ctx context.Context) (*types.TipSet, error) - ChainNotify(context.Context) (<-chan []*api.HeadChange, error) - ChainReadObj(context.Context, cid.Cid) ([]byte, error) - GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) - MpoolPushUntrusted(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) - MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) - MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) - MsigGetPending(ctx context.Context, addr address.Address, ts types.TipSetKey) ([]*api.MsigTransaction, error) - StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) - StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) - StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) - StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) - StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) - StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) - StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) - StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error) - StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) - StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) - StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) - StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) - StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) - StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) - StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) - StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]api.Deadline, error) - StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) - StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) - StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error) - StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) - StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) - StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error) - WalletBalance(context.Context, address.Address) (types.BigInt, error) //perm:read -} - -var _ gatewayDepsAPI = *new(api.FullNode) // gateway depends on latest - -type GatewayAPI struct { - api gatewayDepsAPI - lookbackCap time.Duration - stateWaitLookbackLimit abi.ChainEpoch -} - -// NewGatewayAPI creates a new GatewayAPI with the default lookback cap -func NewGatewayAPI(api gatewayDepsAPI) *GatewayAPI { - return newGatewayAPI(api, LookbackCap, StateWaitLookbackLimit) -} - -// used by the tests -func newGatewayAPI(api gatewayDepsAPI, lookbackCap time.Duration, stateWaitLookbackLimit abi.ChainEpoch) *GatewayAPI { - return &GatewayAPI{api: api, lookbackCap: lookbackCap, stateWaitLookbackLimit: stateWaitLookbackLimit} -} - -func (a *GatewayAPI) checkTipsetKey(ctx context.Context, tsk types.TipSetKey) error { - if tsk.IsEmpty() { - return nil - } - - ts, err := a.api.ChainGetTipSet(ctx, tsk) - if err != nil { - return err - } - - return a.checkTipset(ts) -} - -func (a *GatewayAPI) checkTipset(ts *types.TipSet) error { - at := time.Unix(int64(ts.Blocks()[0].Timestamp), 0) - if err := a.checkTimestamp(at); err != nil { - return fmt.Errorf("bad tipset: %w", err) - } - return nil -} - -func (a *GatewayAPI) checkTipsetHeight(ts *types.TipSet, h abi.ChainEpoch) error { - tsBlock := ts.Blocks()[0] - heightDelta := time.Duration(uint64(tsBlock.Height-h)*build.BlockDelaySecs) * time.Second - timeAtHeight := time.Unix(int64(tsBlock.Timestamp), 0).Add(-heightDelta) - - if err := a.checkTimestamp(timeAtHeight); err != nil { - return fmt.Errorf("bad tipset height: %w", err) - } - return nil -} - -func (a *GatewayAPI) checkTimestamp(at time.Time) error { - if time.Since(at) > a.lookbackCap { - return ErrLookbackTooLong - } - - return nil -} - -func (a *GatewayAPI) Version(ctx context.Context) (api.APIVersion, error) { - return a.api.Version(ctx) -} - -func (a *GatewayAPI) ChainGetBlockMessages(ctx context.Context, c cid.Cid) (*api.BlockMessages, error) { - return a.api.ChainGetBlockMessages(ctx, c) -} - -func (a *GatewayAPI) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) { - return a.api.ChainHasObj(ctx, c) -} - -func (a *GatewayAPI) ChainHead(ctx context.Context) (*types.TipSet, error) { - // TODO: cache and invalidate cache when timestamp is up (or have internal ChainNotify) - - return a.api.ChainHead(ctx) -} - -func (a *GatewayAPI) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) { - return a.api.ChainGetMessage(ctx, mc) -} - -func (a *GatewayAPI) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) { - return a.api.ChainGetTipSet(ctx, tsk) -} - -func (a *GatewayAPI) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) { - var ts *types.TipSet - if tsk.IsEmpty() { - head, err := a.api.ChainHead(ctx) - if err != nil { - return nil, err - } - ts = head - } else { - gts, err := a.api.ChainGetTipSet(ctx, tsk) - if err != nil { - return nil, err - } - ts = gts - } - - // Check if the tipset key refers to a tipset that's too far in the past - if err := a.checkTipset(ts); err != nil { - return nil, err - } - - // Check if the height is too far in the past - if err := a.checkTipsetHeight(ts, h); err != nil { - return nil, err - } - - return a.api.ChainGetTipSetByHeight(ctx, h, tsk) -} - -func (a *GatewayAPI) ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) { - return a.api.ChainGetNode(ctx, p) -} - -func (a *GatewayAPI) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, error) { - return a.api.ChainNotify(ctx) -} - -func (a *GatewayAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { - return a.api.ChainReadObj(ctx, c) -} - -func (a *GatewayAPI) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - - return a.api.GasEstimateMessageGas(ctx, msg, spec, tsk) -} - -func (a *GatewayAPI) MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) { - // TODO: additional anti-spam checks - return a.api.MpoolPushUntrusted(ctx, sm) -} - -func (a *GatewayAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return types.NewInt(0), err - } - - return a.api.MsigGetAvailableBalance(ctx, addr, tsk) -} - -func (a *GatewayAPI) MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) { - if err := a.checkTipsetKey(ctx, start); err != nil { - return types.NewInt(0), err - } - if err := a.checkTipsetKey(ctx, end); err != nil { - return types.NewInt(0), err - } - - return a.api.MsigGetVested(ctx, addr, start, end) -} - -func (a *GatewayAPI) MsigGetPending(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.MsigTransaction, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - - return a.api.MsigGetPending(ctx, addr, tsk) -} - -func (a *GatewayAPI) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return address.Undef, err - } - - return a.api.StateAccountKey(ctx, addr, tsk) -} - -func (a *GatewayAPI) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return api.DealCollateralBounds{}, err - } - - return a.api.StateDealProviderCollateralBounds(ctx, size, verified, tsk) -} - -func (a *GatewayAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - - return a.api.StateGetActor(ctx, actor, tsk) -} - -func (a *GatewayAPI) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - - return a.api.StateListMiners(ctx, tsk) -} - -func (a *GatewayAPI) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return address.Undef, err - } - - return a.api.StateLookupID(ctx, addr, tsk) -} - -func (a *GatewayAPI) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return api.MarketBalance{}, err - } - - return a.api.StateMarketBalance(ctx, addr, tsk) -} - -func (a *GatewayAPI) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - - return a.api.StateMarketStorageDeal(ctx, dealId, tsk) -} - -func (a *GatewayAPI) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return network.VersionMax, err - } - - return a.api.StateNetworkVersion(ctx, tsk) -} - -func (a *GatewayAPI) StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { - if limit == api.LookbackNoLimit { - limit = a.stateWaitLookbackLimit - } - if a.stateWaitLookbackLimit != api.LookbackNoLimit && limit > a.stateWaitLookbackLimit { - limit = a.stateWaitLookbackLimit - } - if err := a.checkTipsetKey(ctx, from); err != nil { - return nil, err - } - - return a.api.StateSearchMsg(ctx, from, msg, limit, allowReplaced) -} - -func (a *GatewayAPI) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { - if limit == api.LookbackNoLimit { - limit = a.stateWaitLookbackLimit - } - if a.stateWaitLookbackLimit != api.LookbackNoLimit && limit > a.stateWaitLookbackLimit { - limit = a.stateWaitLookbackLimit - } - - return a.api.StateWaitMsg(ctx, msg, confidence, limit, allowReplaced) -} - -func (a *GatewayAPI) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return a.api.StateReadState(ctx, actor, tsk) -} - -func (a *GatewayAPI) StateMinerPower(ctx context.Context, m address.Address, tsk types.TipSetKey) (*api.MinerPower, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return a.api.StateMinerPower(ctx, m, tsk) -} - -func (a *GatewayAPI) StateMinerFaults(ctx context.Context, m address.Address, tsk types.TipSetKey) (bitfield.BitField, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return bitfield.BitField{}, err - } - return a.api.StateMinerFaults(ctx, m, tsk) -} -func (a *GatewayAPI) StateMinerRecoveries(ctx context.Context, m address.Address, tsk types.TipSetKey) (bitfield.BitField, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return bitfield.BitField{}, err - } - return a.api.StateMinerRecoveries(ctx, m, tsk) -} - -func (a *GatewayAPI) StateMinerInfo(ctx context.Context, m address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return miner.MinerInfo{}, err - } - return a.api.StateMinerInfo(ctx, m, tsk) -} - -func (a *GatewayAPI) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) ([]api.Deadline, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return a.api.StateMinerDeadlines(ctx, m, tsk) -} - -func (a *GatewayAPI) StateMinerAvailableBalance(ctx context.Context, m address.Address, tsk types.TipSetKey) (types.BigInt, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return types.BigInt{}, err - } - return a.api.StateMinerAvailableBalance(ctx, m, tsk) -} - -func (a *GatewayAPI) StateMinerProvingDeadline(ctx context.Context, m address.Address, tsk types.TipSetKey) (*dline.Info, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return a.api.StateMinerProvingDeadline(ctx, m, tsk) -} - -func (a *GatewayAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return types.BigInt{}, err - } - return a.api.StateCirculatingSupply(ctx, tsk) -} - -func (a *GatewayAPI) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return a.api.StateSectorGetInfo(ctx, maddr, n, tsk) -} - -func (a *GatewayAPI) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return a.api.StateVerifiedClientStatus(ctx, addr, tsk) -} - -func (a *GatewayAPI) StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return api.CirculatingSupply{}, err - } - return a.api.StateVMCirculatingSupplyInternal(ctx, tsk) -} - -func (a *GatewayAPI) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) { - return sigs.Verify(sig, k, msg) == nil, nil -} - -func (a *GatewayAPI) WalletBalance(ctx context.Context, k address.Address) (types.BigInt, error) { - return a.api.WalletBalance(ctx, k) -} - -var _ api.Gateway = (*GatewayAPI)(nil) -var _ full.ChainModuleAPI = (*GatewayAPI)(nil) -var _ full.GasModuleAPI = (*GatewayAPI)(nil) -var _ full.MpoolModuleAPI = (*GatewayAPI)(nil) -var _ full.StateModuleAPI = (*GatewayAPI)(nil) diff --git a/cmd/lotus-gateway/endtoend_test.go b/cmd/lotus-gateway/endtoend_test.go index 3fae221c3..373d9d595 100644 --- a/cmd/lotus-gateway/endtoend_test.go +++ b/cmd/lotus-gateway/endtoend_test.go @@ -11,6 +11,7 @@ import ( "github.com/filecoin-project/lotus/cli" clitest "github.com/filecoin-project/lotus/cli/test" + "github.com/filecoin-project/lotus/gateway" init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" @@ -275,7 +276,7 @@ func startNodes( fullNode := nodes[0] // Create a gateway server in front of the full node - gapiImpl := newGatewayAPI(fullNode, lookbackCap, stateWaitLookbackLimit) + gapiImpl := gateway.NewNode(fullNode, lookbackCap, stateWaitLookbackLimit) _, addr, err := builder.CreateRPCServer(t, map[string]interface{}{ "/rpc/v1": gapiImpl, "/rpc/v0": api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), gapiImpl), diff --git a/cmd/lotus-gateway/main.go b/cmd/lotus-gateway/main.go index 60f45f283..c35ab3cae 100644 --- a/cmd/lotus-gateway/main.go +++ b/cmd/lotus-gateway/main.go @@ -5,10 +5,12 @@ import ( "net" "net/http" "os" + "time" "contrib.go.opencensus.io/exporter/prometheus" "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/gateway" promclient "github.com/prometheus/client_golang/prometheus" "go.opencensus.io/tag" @@ -29,6 +31,11 @@ import ( var log = logging.Logger("gateway") +const ( + LookbackCap = time.Hour * 24 + StateWaitLookbackLimit = abi.ChainEpoch(20) +) + func main() { lotuslog.SetupLogLevels() @@ -122,7 +129,7 @@ var runCmd = &cli.Command{ waitLookback := abi.ChainEpoch(cctx.Int64("api-wait-lookback-limit")) - ma := metrics.MetricedGatewayAPI(newGatewayAPI(api, lookbackCap, waitLookback)) + ma := metrics.MetricedGatewayAPI(gateway.NewNode(api, lookbackCap, waitLookback)) serveRpc("/rpc/v1", ma) serveRpc("/rpc/v0", lapi.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), ma)) diff --git a/gateway/node.go b/gateway/node.go new file mode 100644 index 000000000..bd2ae3230 --- /dev/null +++ b/gateway/node.go @@ -0,0 +1,419 @@ +package gateway + +import ( + "context" + "fmt" + "time" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/sigs" + _ "github.com/filecoin-project/lotus/lib/sigs/bls" + _ "github.com/filecoin-project/lotus/lib/sigs/secp" + "github.com/filecoin-project/lotus/node/impl/full" + "github.com/ipfs/go-cid" +) + +// TargetAPI defines the API methods that the Node depends on +// (to make it easy to mock for tests) +type TargetAPI interface { + Version(context.Context) (api.APIVersion, error) + ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) + ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) + ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) + ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) + ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) + ChainHasObj(context.Context, cid.Cid) (bool, error) + ChainHead(ctx context.Context) (*types.TipSet, error) + ChainNotify(context.Context) (<-chan []*api.HeadChange, error) + ChainReadObj(context.Context, cid.Cid) ([]byte, error) + GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) + MpoolPushUntrusted(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) + MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) + MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) + MsigGetPending(ctx context.Context, addr address.Address, ts types.TipSetKey) ([]*api.MsigTransaction, error) + StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) + StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) + StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) + StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) + StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) + StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) + StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) + StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error) + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) + StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) + StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) + StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) + StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) + StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) + StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]api.Deadline, error) + StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) + StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) + StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error) + StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) + StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) + StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error) + WalletBalance(context.Context, address.Address) (types.BigInt, error) //perm:read +} + +var _ TargetAPI = *new(api.FullNode) // gateway depends on latest + +type Node struct { + target TargetAPI + lookbackCap time.Duration + stateWaitLookbackLimit abi.ChainEpoch + errLookback error +} + +var ( + _ api.Gateway = (*Node)(nil) + _ full.ChainModuleAPI = (*Node)(nil) + _ full.GasModuleAPI = (*Node)(nil) + _ full.MpoolModuleAPI = (*Node)(nil) + _ full.StateModuleAPI = (*Node)(nil) +) + +// NewNode creates a new gateway node. +func NewNode(api TargetAPI, lookbackCap time.Duration, stateWaitLookbackLimit abi.ChainEpoch) *Node { + return &Node{ + target: api, + lookbackCap: lookbackCap, + stateWaitLookbackLimit: stateWaitLookbackLimit, + errLookback: fmt.Errorf("lookbacks of more than %s are disallowed", lookbackCap), + } +} + +func (gw *Node) checkTipsetKey(ctx context.Context, tsk types.TipSetKey) error { + if tsk.IsEmpty() { + return nil + } + + ts, err := gw.target.ChainGetTipSet(ctx, tsk) + if err != nil { + return err + } + + return gw.checkTipset(ts) +} + +func (gw *Node) checkTipset(ts *types.TipSet) error { + at := time.Unix(int64(ts.Blocks()[0].Timestamp), 0) + if err := gw.checkTimestamp(at); err != nil { + return fmt.Errorf("bad tipset: %w", err) + } + return nil +} + +func (gw *Node) checkTipsetHeight(ts *types.TipSet, h abi.ChainEpoch) error { + tsBlock := ts.Blocks()[0] + heightDelta := time.Duration(uint64(tsBlock.Height-h)*build.BlockDelaySecs) * time.Second + timeAtHeight := time.Unix(int64(tsBlock.Timestamp), 0).Add(-heightDelta) + + if err := gw.checkTimestamp(timeAtHeight); err != nil { + return fmt.Errorf("bad tipset height: %w", err) + } + return nil +} + +func (gw *Node) checkTimestamp(at time.Time) error { + if time.Since(at) > gw.lookbackCap { + return gw.errLookback + } + return nil +} + +func (gw *Node) Version(ctx context.Context) (api.APIVersion, error) { + return gw.target.Version(ctx) +} + +func (gw *Node) ChainGetBlockMessages(ctx context.Context, c cid.Cid) (*api.BlockMessages, error) { + return gw.target.ChainGetBlockMessages(ctx, c) +} + +func (gw *Node) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) { + return gw.target.ChainHasObj(ctx, c) +} + +func (gw *Node) ChainHead(ctx context.Context) (*types.TipSet, error) { + // TODO: cache and invalidate cache when timestamp is up (or have internal ChainNotify) + + return gw.target.ChainHead(ctx) +} + +func (gw *Node) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) { + return gw.target.ChainGetMessage(ctx, mc) +} + +func (gw *Node) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) { + return gw.target.ChainGetTipSet(ctx, tsk) +} + +func (gw *Node) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) { + var ts *types.TipSet + if tsk.IsEmpty() { + head, err := gw.target.ChainHead(ctx) + if err != nil { + return nil, err + } + ts = head + } else { + gts, err := gw.target.ChainGetTipSet(ctx, tsk) + if err != nil { + return nil, err + } + ts = gts + } + + // Check if the tipset key refers to gw tipset that's too far in the past + if err := gw.checkTipset(ts); err != nil { + return nil, err + } + + // Check if the height is too far in the past + if err := gw.checkTipsetHeight(ts, h); err != nil { + return nil, err + } + + return gw.target.ChainGetTipSetByHeight(ctx, h, tsk) +} + +func (gw *Node) ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) { + return gw.target.ChainGetNode(ctx, p) +} + +func (gw *Node) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, error) { + return gw.target.ChainNotify(ctx) +} + +func (gw *Node) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { + return gw.target.ChainReadObj(ctx, c) +} + +func (gw *Node) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + + return gw.target.GasEstimateMessageGas(ctx, msg, spec, tsk) +} + +func (gw *Node) MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) { + // TODO: additional anti-spam checks + return gw.target.MpoolPushUntrusted(ctx, sm) +} + +func (gw *Node) MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return types.NewInt(0), err + } + + return gw.target.MsigGetAvailableBalance(ctx, addr, tsk) +} + +func (gw *Node) MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) { + if err := gw.checkTipsetKey(ctx, start); err != nil { + return types.NewInt(0), err + } + if err := gw.checkTipsetKey(ctx, end); err != nil { + return types.NewInt(0), err + } + + return gw.target.MsigGetVested(ctx, addr, start, end) +} + +func (gw *Node) MsigGetPending(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.MsigTransaction, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + + return gw.target.MsigGetPending(ctx, addr, tsk) +} + +func (gw *Node) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return address.Undef, err + } + + return gw.target.StateAccountKey(ctx, addr, tsk) +} + +func (gw *Node) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return api.DealCollateralBounds{}, err + } + + return gw.target.StateDealProviderCollateralBounds(ctx, size, verified, tsk) +} + +func (gw *Node) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + + return gw.target.StateGetActor(ctx, actor, tsk) +} + +func (gw *Node) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + + return gw.target.StateListMiners(ctx, tsk) +} + +func (gw *Node) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return address.Undef, err + } + + return gw.target.StateLookupID(ctx, addr, tsk) +} + +func (gw *Node) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return api.MarketBalance{}, err + } + + return gw.target.StateMarketBalance(ctx, addr, tsk) +} + +func (gw *Node) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + + return gw.target.StateMarketStorageDeal(ctx, dealId, tsk) +} + +func (gw *Node) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return network.VersionMax, err + } + + return gw.target.StateNetworkVersion(ctx, tsk) +} + +func (gw *Node) StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + if limit == api.LookbackNoLimit { + limit = gw.stateWaitLookbackLimit + } + if gw.stateWaitLookbackLimit != api.LookbackNoLimit && limit > gw.stateWaitLookbackLimit { + limit = gw.stateWaitLookbackLimit + } + if err := gw.checkTipsetKey(ctx, from); err != nil { + return nil, err + } + + return gw.target.StateSearchMsg(ctx, from, msg, limit, allowReplaced) +} + +func (gw *Node) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + if limit == api.LookbackNoLimit { + limit = gw.stateWaitLookbackLimit + } + if gw.stateWaitLookbackLimit != api.LookbackNoLimit && limit > gw.stateWaitLookbackLimit { + limit = gw.stateWaitLookbackLimit + } + + return gw.target.StateWaitMsg(ctx, msg, confidence, limit, allowReplaced) +} + +func (gw *Node) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateReadState(ctx, actor, tsk) +} + +func (gw *Node) StateMinerPower(ctx context.Context, m address.Address, tsk types.TipSetKey) (*api.MinerPower, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateMinerPower(ctx, m, tsk) +} + +func (gw *Node) StateMinerFaults(ctx context.Context, m address.Address, tsk types.TipSetKey) (bitfield.BitField, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return bitfield.BitField{}, err + } + return gw.target.StateMinerFaults(ctx, m, tsk) +} +func (gw *Node) StateMinerRecoveries(ctx context.Context, m address.Address, tsk types.TipSetKey) (bitfield.BitField, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return bitfield.BitField{}, err + } + return gw.target.StateMinerRecoveries(ctx, m, tsk) +} + +func (gw *Node) StateMinerInfo(ctx context.Context, m address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return miner.MinerInfo{}, err + } + return gw.target.StateMinerInfo(ctx, m, tsk) +} + +func (gw *Node) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) ([]api.Deadline, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateMinerDeadlines(ctx, m, tsk) +} + +func (gw *Node) StateMinerAvailableBalance(ctx context.Context, m address.Address, tsk types.TipSetKey) (types.BigInt, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return types.BigInt{}, err + } + return gw.target.StateMinerAvailableBalance(ctx, m, tsk) +} + +func (gw *Node) StateMinerProvingDeadline(ctx context.Context, m address.Address, tsk types.TipSetKey) (*dline.Info, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateMinerProvingDeadline(ctx, m, tsk) +} + +func (gw *Node) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return types.BigInt{}, err + } + return gw.target.StateCirculatingSupply(ctx, tsk) +} + +func (gw *Node) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateSectorGetInfo(ctx, maddr, n, tsk) +} + +func (gw *Node) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateVerifiedClientStatus(ctx, addr, tsk) +} + +func (gw *Node) StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) { + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return api.CirculatingSupply{}, err + } + return gw.target.StateVMCirculatingSupplyInternal(ctx, tsk) +} + +func (gw *Node) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) { + return sigs.Verify(sig, k, msg) == nil, nil +} + +func (gw *Node) WalletBalance(ctx context.Context, k address.Address) (types.BigInt, error) { + return gw.target.WalletBalance(ctx, k) +} diff --git a/cmd/lotus-gateway/api_test.go b/gateway/node_test.go similarity index 95% rename from cmd/lotus-gateway/api_test.go rename to gateway/node_test.go index 23d2cbf3a..50f846018 100644 --- a/cmd/lotus-gateway/api_test.go +++ b/gateway/node_test.go @@ -1,4 +1,4 @@ -package main +package gateway import ( "context" @@ -7,6 +7,7 @@ import ( "time" "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/build" @@ -17,15 +18,19 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" "github.com/ipfs/go-cid" ) +const ( + lookbackCap = time.Hour * 24 + stateWaitLookbackLimit = abi.ChainEpoch(20) +) + func TestGatewayAPIChainGetTipSetByHeight(t *testing.T) { ctx := context.Background() - lookbackTimestamp := uint64(time.Now().Unix()) - uint64(LookbackCap.Seconds()) + lookbackTimestamp := uint64(time.Now().Unix()) - uint64(lookbackCap.Seconds()) type args struct { h abi.ChainEpoch tskh abi.ChainEpoch @@ -91,7 +96,7 @@ func TestGatewayAPIChainGetTipSetByHeight(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { mock := &mockGatewayDepsAPI{} - a := NewGatewayAPI(mock) + a := NewNode(mock, lookbackCap, stateWaitLookbackLimit) // Create tipsets from genesis up to tskh and return the highest ts := mock.createTipSets(tt.args.tskh, tt.args.genesisTS) @@ -111,7 +116,7 @@ type mockGatewayDepsAPI struct { lk sync.RWMutex tipsets []*types.TipSet - gatewayDepsAPI // satisfies all interface requirements but will panic if + TargetAPI // satisfies all interface requirements but will panic if // methods are called. easier than filling out with panic stubs IMO } From 996feda1f75ea491f8da1b7593934f71f7701fe8 Mon Sep 17 00:00:00 2001 From: raulk Date: Wed, 19 May 2021 15:08:14 +0100 Subject: [PATCH 55/80] typo. Co-authored-by: dirkmc --- chain/store/store.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/store/store.go b/chain/store/store.go index 7318a1007..f8f1b0c49 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -858,7 +858,7 @@ func (cs *ChainStore) NearestCommonAncestor(a, b *types.TipSet) (*types.TipSet, // a common ancestor. It then returns the respective chain segments that fork // from the identified ancestor, in reverse order, where the first element of // each slice is the supplied tipset, and the last element is the common -// ancenstor. +// ancestor. // // If an error happens along the way, we return the error with nil slices. func (cs *ChainStore) ReorgOps(a, b *types.TipSet) ([]*types.TipSet, []*types.TipSet, error) { From ac4f3ab6840b550766c8847c0047fdef5f3e1298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Wed, 19 May 2021 17:30:06 +0100 Subject: [PATCH 56/80] remove duplicated vars. --- cmd/lotus-gateway/endtoend_test.go | 8 +++++--- cmd/lotus-gateway/main.go | 10 ++-------- gateway/node.go | 5 +++++ gateway/node_test.go | 25 +++++++++---------------- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/cmd/lotus-gateway/endtoend_test.go b/cmd/lotus-gateway/endtoend_test.go index 373d9d595..fc9f3d918 100644 --- a/cmd/lotus-gateway/endtoend_test.go +++ b/cmd/lotus-gateway/endtoend_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/cli" clitest "github.com/filecoin-project/lotus/cli/test" "github.com/filecoin-project/lotus/gateway" @@ -30,14 +31,15 @@ import ( "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/chain/actors/policy" - "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node" builder "github.com/filecoin-project/lotus/node/test" ) -const maxLookbackCap = time.Duration(math.MaxInt64) -const maxStateWaitLookbackLimit = stmgr.LookbackNoLimit +const ( + maxLookbackCap = time.Duration(math.MaxInt64) + maxStateWaitLookbackLimit = stmgr.LookbackNoLimit +) func init() { policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) diff --git a/cmd/lotus-gateway/main.go b/cmd/lotus-gateway/main.go index c35ab3cae..8d4876b71 100644 --- a/cmd/lotus-gateway/main.go +++ b/cmd/lotus-gateway/main.go @@ -5,7 +5,6 @@ import ( "net" "net/http" "os" - "time" "contrib.go.opencensus.io/exporter/prometheus" "github.com/filecoin-project/go-jsonrpc" @@ -31,11 +30,6 @@ import ( var log = logging.Logger("gateway") -const ( - LookbackCap = time.Hour * 24 - StateWaitLookbackLimit = abi.ChainEpoch(20) -) - func main() { lotuslog.SetupLogLevels() @@ -81,12 +75,12 @@ var runCmd = &cli.Command{ &cli.DurationFlag{ Name: "api-max-lookback", Usage: "maximum duration allowable for tipset lookbacks", - Value: LookbackCap, + Value: gateway.DefaultLookbackCap, }, &cli.Int64Flag{ Name: "api-wait-lookback-limit", Usage: "maximum number of blocks to search back through for message inclusion", - Value: int64(StateWaitLookbackLimit), + Value: int64(gateway.DefaultStateWaitLookbackLimit), }, }, Action: func(cctx *cli.Context) error { diff --git a/gateway/node.go b/gateway/node.go index bd2ae3230..3c7a67196 100644 --- a/gateway/node.go +++ b/gateway/node.go @@ -22,6 +22,11 @@ import ( "github.com/ipfs/go-cid" ) +const ( + DefaultLookbackCap = time.Hour * 24 + DefaultStateWaitLookbackLimit = abi.ChainEpoch(20) +) + // TargetAPI defines the API methods that the Node depends on // (to make it easy to mock for tests) type TargetAPI interface { diff --git a/gateway/node_test.go b/gateway/node_test.go index 50f846018..0d33daa35 100644 --- a/gateway/node_test.go +++ b/gateway/node_test.go @@ -6,31 +6,24 @@ import ( "testing" "time" - "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/actors/builtin/miner" - - "github.com/filecoin-project/lotus/build" - + "github.com/ipfs/go-cid" "github.com/stretchr/testify/require" - "github.com/filecoin-project/lotus/chain/types/mock" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/chain/types" - "github.com/ipfs/go-cid" -) + "github.com/filecoin-project/go-state-types/network" -const ( - lookbackCap = time.Hour * 24 - stateWaitLookbackLimit = abi.ChainEpoch(20) + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/types/mock" ) func TestGatewayAPIChainGetTipSetByHeight(t *testing.T) { ctx := context.Background() - lookbackTimestamp := uint64(time.Now().Unix()) - uint64(lookbackCap.Seconds()) + lookbackTimestamp := uint64(time.Now().Unix()) - uint64(DefaultLookbackCap.Seconds()) type args struct { h abi.ChainEpoch tskh abi.ChainEpoch @@ -96,7 +89,7 @@ func TestGatewayAPIChainGetTipSetByHeight(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { mock := &mockGatewayDepsAPI{} - a := NewNode(mock, lookbackCap, stateWaitLookbackLimit) + a := NewNode(mock, DefaultLookbackCap, DefaultStateWaitLookbackLimit) // Create tipsets from genesis up to tskh and return the highest ts := mock.createTipSets(tt.args.tskh, tt.args.genesisTS) From 706fdcbb80935b1b36fa0cae5b0ee73e49342d51 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Wed, 19 May 2021 12:48:28 -0600 Subject: [PATCH 57/80] feat: increase data transfer timeouts --- node/modules/client.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/node/modules/client.go b/node/modules/client.go index 150eea75b..7b5fe10f8 100644 --- a/node/modules/client.go +++ b/node/modules/client.go @@ -134,8 +134,8 @@ func NewClientGraphsyncDataTransfer(lc fx.Lifecycle, h host.Host, gs dtypes.Grap // data-transfer push / pull channel restart configuration: dtRestartConfig := dtimpl.ChannelRestartConfig(channelmonitor.Config{ - // Wait up to 30s for the other side to respond to an Open channel message - AcceptTimeout: 30 * time.Second, + // Wait up to 2m for the other side to respond to an Open channel message + AcceptTimeout: 2 * time.Minute, // When an error occurs, wait a little while until all related errors // have fired before sending a restart message RestartDebounce: 10 * time.Second, @@ -146,9 +146,9 @@ func NewClientGraphsyncDataTransfer(lc fx.Lifecycle, h host.Host, gs dtypes.Grap // After sending a restart message, the time to wait for the peer to // respond with an ack of the restart RestartAckTimeout: 30 * time.Second, - // Wait up to 30s for the other side to send a Complete message once all + // Wait up to 10m for the other side to send a Complete message once all // data has been sent / received - CompleteTimeout: 30 * time.Second, + CompleteTimeout: 10 * time.Minute, }) dt, err := dtimpl.NewDataTransfer(dtDs, filepath.Join(r.Path(), "data-transfer"), net, transport, dtRestartConfig) if err != nil { From e21d4d7a7e2c77bd4d8073f5b9be4f12fc103fa2 Mon Sep 17 00:00:00 2001 From: yaohcn Date: Thu, 20 May 2021 18:36:00 +0800 Subject: [PATCH 58/80] fix ticket expired --- extern/storage-sealing/states_sealing.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extern/storage-sealing/states_sealing.go b/extern/storage-sealing/states_sealing.go index e371ab33f..c55dd2005 100644 --- a/extern/storage-sealing/states_sealing.go +++ b/extern/storage-sealing/states_sealing.go @@ -99,8 +99,8 @@ func (m *Sealing) padSector(ctx context.Context, sectorID storage.SectorRef, exi return out, nil } -func checkTicketExpired(sector SectorInfo, epoch abi.ChainEpoch) bool { - return epoch-sector.TicketEpoch > MaxTicketAge // TODO: allow configuring expected seal durations +func checkTicketExpired(ticket, head abi.ChainEpoch) bool { + return head-ticket > MaxTicketAge // TODO: allow configuring expected seal durations } func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.SealRandomness, abi.ChainEpoch, error) { @@ -124,7 +124,7 @@ func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.Se if pci != nil { ticketEpoch = pci.Info.SealRandEpoch - if checkTicketExpired(sector, ticketEpoch) { + if checkTicketExpired(ticketEpoch, epoch) { return nil, 0, xerrors.Errorf("ticket expired for precommitted sector") } } @@ -186,7 +186,7 @@ func (m *Sealing) handlePreCommit1(ctx statemachine.Context, sector SectorInfo) return nil } - if checkTicketExpired(sector, height) { + if checkTicketExpired(sector.TicketEpoch, height) { return ctx.Send(SectorOldTicket{}) // go get new ticket } From 885564fe24c6287249a12b402d8a1f90c5ca31e6 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Thu, 20 May 2021 11:22:19 -0600 Subject: [PATCH 59/80] Revert "chore: update go-libp2p" This reverts commit f7fbaef361bf59aa3baaa70d3e84bd04cfa47000. --- documentation/en/api-v0-methods-miner.md | 12 +- documentation/en/api-v0-methods.md | 12 +- documentation/en/api-v1-unstable-methods.md | 12 +- go.mod | 32 ++-- go.sum | 153 +++++++------------- node/impl/common/common.go | 2 +- 6 files changed, 85 insertions(+), 138 deletions(-) diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index 1f6cc98e9..ea5ca75f8 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -885,8 +885,8 @@ Inputs: `null` Response: ```json { - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Addrs": [] + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" } ``` @@ -1035,8 +1035,8 @@ Inputs: ```json [ { - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Addrs": [] + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" } ] ``` @@ -1086,8 +1086,8 @@ Inputs: Response: ```json { - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Addrs": [] + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" } ``` diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index 1b7a630de..0372c0dab 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -2781,8 +2781,8 @@ Inputs: `null` Response: ```json { - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Addrs": [] + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" } ``` @@ -2931,8 +2931,8 @@ Inputs: ```json [ { - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Addrs": [] + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" } ] ``` @@ -2982,8 +2982,8 @@ Inputs: Response: ```json { - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Addrs": [] + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" } ``` diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index c041d4386..bf282745a 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -3008,8 +3008,8 @@ Inputs: `null` Response: ```json { - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Addrs": [] + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" } ``` @@ -3158,8 +3158,8 @@ Inputs: ```json [ { - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Addrs": [] + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" } ] ``` @@ -3209,8 +3209,8 @@ Inputs: Response: ```json { - "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Addrs": [] + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" } ``` diff --git a/go.mod b/go.mod index 540d97d0b..9c47ec848 100644 --- a/go.mod +++ b/go.mod @@ -88,7 +88,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.3 + github.com/ipfs/go-log/v2 v2.1.2 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 @@ -101,21 +101,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.14.0 + github.com/libp2p/go-libp2p v0.12.0 github.com/libp2p/go-libp2p-connmgr v0.2.4 - github.com/libp2p/go-libp2p-core v0.8.5 + github.com/libp2p/go-libp2p-core v0.7.0 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.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-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-pubsub v0.4.2-0.20210212194758-6c1addf493eb - github.com/libp2p/go-libp2p-quic-transport v0.10.0 + github.com/libp2p/go-libp2p-quic-transport v0.9.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.5.0 + github.com/libp2p/go-libp2p-swarm v0.3.1 github.com/libp2p/go-libp2p-tls v0.1.3 - github.com/libp2p/go-libp2p-yamux v0.5.3 + github.com/libp2p/go-libp2p-yamux v0.4.1 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 @@ -123,9 +123,10 @@ 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.3.1 + github.com/multiformats/go-multiaddr-dns v0.2.0 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 @@ -143,17 +144,18 @@ 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.23.0 + go.opencensus.io v0.22.5 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-20210423184538-5f58ad60dda6 - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210426080607-c94f62235c83 + 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/time v0.0.0-20191024005414-555d28b269f0 - golang.org/x/tools v0.0.0-20210106214847-113979e3529a + golang.org/x/tools v0.0.0-20201112185108-eeaa07dd7696 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 75e2f5a35..f26f4f931 100644 --- a/go.sum +++ b/go.sum @@ -107,18 +107,14 @@ 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= @@ -191,10 +187,8 @@ 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= @@ -329,9 +323,8 @@ 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= @@ -396,9 +389,8 @@ 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= @@ -428,9 +420,8 @@ 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= @@ -442,16 +433,14 @@ 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= @@ -692,9 +681,8 @@ 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= @@ -796,7 +784,6 @@ 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= @@ -827,9 +814,8 @@ 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= @@ -852,9 +838,8 @@ 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.0 h1:mYab0qShfAojYN/QTOtxPyQoK9knUHbUncwst4+wBcA= -github.com/libp2p/go-libp2p v0.14.0/go.mod h1:dsQrWLAoIn+GkHPN/U+yypizkHiB9tnv79Os+kSgQ4Q= 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= @@ -865,9 +850,8 @@ 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= @@ -914,12 +898,8 @@ 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= @@ -954,10 +934,8 @@ 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= @@ -969,8 +947,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.2.0 h1:wmk5nhB9a2w2RxMOyvsoKjizgJOEaJdfAakr0jN8gds= -github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= +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-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= @@ -985,9 +963,8 @@ 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= @@ -998,8 +975,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.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-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-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= @@ -1026,9 +1003,8 @@ 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= @@ -1036,9 +1012,8 @@ 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= @@ -1048,9 +1023,8 @@ 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= @@ -1060,9 +1034,8 @@ 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.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= -github.com/libp2p/go-libp2p-yamux v0.5.3 h1:x2bK2BWktdMdTrciiDmgTMIxYNBdkxewQFEjHDl7VgU= -github.com/libp2p/go-libp2p-yamux v0.5.3/go.mod h1:Vy3TMonBAfTMXHWopsMc8iX/XGRYrRlpUaMzaeuHV/s= +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-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= @@ -1074,9 +1047,8 @@ 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= @@ -1088,9 +1060,8 @@ 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= @@ -1106,9 +1077,8 @@ 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= @@ -1130,9 +1100,8 @@ 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= @@ -1144,14 +1113,12 @@ 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.1.1 h1:3RkXAnDmaXJPckF/QbDnNbA6lZXMgycNTVMMTQ2YlAI= -github.com/libp2p/go-yamux/v2 v2.1.1/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.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= -github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= +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/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= @@ -1166,13 +1133,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.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= +github.com/marten-seemann/qpack v0.2.0/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.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ= -github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +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/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= @@ -1206,8 +1173,6 @@ 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= @@ -1254,9 +1219,8 @@ 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= @@ -1286,10 +1250,8 @@ 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= @@ -1306,6 +1268,8 @@ 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= @@ -1323,7 +1287,6 @@ 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= @@ -1608,7 +1571,6 @@ 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= @@ -1637,8 +1599,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.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= 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= @@ -1691,19 +1653,16 @@ 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= @@ -1726,9 +1685,8 @@ 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= @@ -1739,7 +1697,6 @@ 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= @@ -1775,7 +1732,6 @@ 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= @@ -1783,11 +1739,8 @@ 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= @@ -1805,8 +1758,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-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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/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= @@ -1873,21 +1826,16 @@ 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= @@ -1931,12 +1879,10 @@ 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= @@ -2004,9 +1950,8 @@ 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= @@ -2022,8 +1967,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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +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/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 f1c57665c..7d99fb42a 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).GetAutoNat() + autonat := a.RawHost.(*basichost.BasicHost).AutoNat if autonat == nil { return api.NatInfo{ From 00a1e2c05b637622768b9ee5317af0f31461ee13 Mon Sep 17 00:00:00 2001 From: yaohcn Date: Fri, 21 May 2021 11:45:57 +0800 Subject: [PATCH 60/80] test ticket expired --- extern/storage-sealing/fsm_test.go | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/extern/storage-sealing/fsm_test.go b/extern/storage-sealing/fsm_test.go index b0ffdecf3..f3d6d87d1 100644 --- a/extern/storage-sealing/fsm_test.go +++ b/extern/storage-sealing/fsm_test.go @@ -210,3 +210,43 @@ func TestBrokenState(t *testing.T) { } } } + +func TestTicketExpired(t *testing.T) { + var notif []struct{ before, after SectorInfo } + ma, _ := address.NewIDAddress(55151) + m := test{ + s: &Sealing{ + maddr: ma, + stats: SectorStats{ + bySector: map[abi.SectorID]statSectorState{}, + }, + notifee: func(before, after SectorInfo) { + notif = append(notif, struct{ before, after SectorInfo }{before, after}) + }, + }, + t: t, + state: &SectorInfo{State: Packing}, + } + + m.planSingle(SectorPacked{}) + require.Equal(m.t, m.state.State, GetTicket) + + m.planSingle(SectorTicket{}) + require.Equal(m.t, m.state.State, PreCommit1) + + expired := checkTicketExpired(0, MaxTicketAge+1) + require.True(t, expired) + + m.planSingle(SectorOldTicket{}) + require.Equal(m.t, m.state.State, GetTicket) + + expected := []SectorState{Packing, GetTicket, PreCommit1, GetTicket} + for i, n := range notif { + if n.before.State != expected[i] { + t.Fatalf("expected before state: %s, got: %s", expected[i], n.before.State) + } + if n.after.State != expected[i+1] { + t.Fatalf("expected after state: %s, got: %s", expected[i+1], n.after.State) + } + } +} From 308d1e9b7c081a4673a26c00ee9694a0faa301c2 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Fri, 21 May 2021 15:00:21 +0200 Subject: [PATCH 61/80] Fix logging around mineOne - A nil MiningBaseInfo is *NOT* unexpected: it happens when one is in penalty https://github.com/filecoin-project/lotus/blob/v1.9.0/chain/stmgr/utils.go#L500-L502 - Remove the log from IsRoundWinner(): all we care about is the randbase epoch --- chain/gen/gen.go | 9 ------- miner/miner.go | 67 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index b4e04424c..fabe72e49 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -634,15 +634,6 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch, ep := &types.ElectionProof{VRFProof: vrfout} j := ep.ComputeWinCount(mbi.MinerPower, mbi.NetworkPower) ep.WinCount = j - - log.Infow("completed winAttemptVRF", - "beaconRound", brand.Round, - "beaconDataB64", b64.EncodeToString(brand.Data), - "electionRandB64", b64.EncodeToString(electionRand), - "vrfB64", b64.EncodeToString(vrfout), - "winCount", j, - ) - if j < 1 { return nil, nil } diff --git a/miner/miner.go b/miner/miner.go index a77e1c18b..5fbc9aae3 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -18,6 +18,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" lru "github.com/hashicorp/golang-lru" @@ -415,36 +416,51 @@ func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error) // This method does the following: // // 1. -func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, error) { +func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (minedBlock *types.BlockMsg, err error) { log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.TipSet.Cids())) start := build.Clock.Now() round := base.TipSet.Height() + base.NullRounds + 1 - mbi, err := m.api.MinerGetBaseInfo(ctx, m.address, round, base.TipSet.Key()) - if err != nil { - return nil, xerrors.Errorf("failed to get mining base info: %w", err) - } - if mbi == nil { - log.Warnf("mineOne: unexpectedly nil MiningBaseInfo for round %d, off tipset %d/%s", round, base.TipSet.Height(), base.TipSet.Key().String()) - return nil, nil - } - - // always write out a log from this point out + // always write out a log var winner *types.ElectionProof + var mbi *api.MiningBaseInfo + var rbase types.BeaconEntry defer func() { + // mbi can be nil if we are deep in penalty and there are 0 eligible sectors + // in the current deadline. If this case - put together a dummy one for reporting + // https://github.com/filecoin-project/lotus/blob/v1.9.0/chain/stmgr/utils.go#L500-L502 + if mbi == nil { + mbi = &api.MiningBaseInfo{ + NetworkPower: big.NewInt(-1), // we do not know how big the network is at this point + EligibleForMining: false, + MinerPower: big.NewInt(0), // but we do know we do not have anything + } + } + log.Infow( "completed mineOne", "forRound", int64(round), "baseEpoch", int64(base.TipSet.Height()), + "beaconEpoch", rbase.Round, "lookbackEpochs", int64(policy.ChainFinality), // hardcoded as it is unlikely to change again: https://github.com/filecoin-project/lotus/blob/v1.8.0/chain/actors/policy/policy.go#L180-L186 "networkPowerAtLookback", mbi.NetworkPower.String(), "minerPowerAtLookback", mbi.MinerPower.String(), "isEligible", mbi.EligibleForMining, "isWinner", (winner != nil), + "error", err, ) }() + mbi, err = m.api.MinerGetBaseInfo(ctx, m.address, round, base.TipSet.Key()) + if err != nil { + err = xerrors.Errorf("failed to get mining base info: %w", err) + return nil, err + } + if mbi == nil { + return nil, nil + } + if !mbi.EligibleForMining { // slashed or just have no power yet return nil, nil @@ -461,19 +477,21 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, log.Infof("Time delta between now and our mining base: %ds (nulls: %d)", uint64(build.Clock.Now().Unix())-base.TipSet.MinTimestamp(), base.NullRounds) - rbase := beaconPrev + rbase = beaconPrev if len(bvals) > 0 { rbase = bvals[len(bvals)-1] } ticket, err := m.computeTicket(ctx, &rbase, base, mbi) if err != nil { - return nil, xerrors.Errorf("scratching ticket failed: %w", err) + err = xerrors.Errorf("scratching ticket failed: %w", err) + return nil, err } winner, err = gen.IsRoundWinner(ctx, base.TipSet, round, m.address, rbase, mbi, m.api) if err != nil { - return nil, xerrors.Errorf("failed to check if we win next round: %w", err) + err = xerrors.Errorf("failed to check if we win next round: %w", err) + return nil, err } if winner == nil { @@ -484,12 +502,14 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, buf := new(bytes.Buffer) if err := m.address.MarshalCBOR(buf); err != nil { - return nil, xerrors.Errorf("failed to marshal miner address: %w", err) + err = xerrors.Errorf("failed to marshal miner address: %w", err) + return nil, err } rand, err := store.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, round, buf.Bytes()) if err != nil { - return nil, xerrors.Errorf("failed to get randomness for winning post: %w", err) + err = xerrors.Errorf("failed to get randomness for winning post: %w", err) + return nil, err } prand := abi.PoStRandomness(rand) @@ -498,7 +518,8 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, postProof, err := m.epp.ComputeProof(ctx, mbi.Sectors, prand) if err != nil { - return nil, xerrors.Errorf("failed to compute winning post proof: %w", err) + err = xerrors.Errorf("failed to compute winning post proof: %w", err) + return nil, err } tProof := build.Clock.Now() @@ -506,15 +527,17 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, // get pending messages early, msgs, err := m.api.MpoolSelect(context.TODO(), base.TipSet.Key(), ticket.Quality()) if err != nil { - return nil, xerrors.Errorf("failed to select messages for block: %w", err) + err = xerrors.Errorf("failed to select messages for block: %w", err) + return nil, err } tPending := build.Clock.Now() // TODO: winning post proof - b, err := m.createBlock(base, m.address, ticket, winner, bvals, postProof, msgs) + minedBlock, err = m.createBlock(base, m.address, ticket, winner, bvals, postProof, msgs) if err != nil { - return nil, xerrors.Errorf("failed to create block: %w", err) + err = xerrors.Errorf("failed to create block: %w", err) + return nil, err } tCreateBlock := build.Clock.Now() @@ -523,7 +546,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, for i, header := range base.TipSet.Blocks() { parentMiners[i] = header.Miner } - log.Infow("mined new block", "cid", b.Cid(), "height", int64(b.Header.Height), "miner", b.Header.Miner, "parents", parentMiners, "parentTipset", base.TipSet.Key().String(), "took", dur) + log.Infow("mined new block", "cid", minedBlock.Cid(), "height", int64(minedBlock.Header.Height), "miner", minedBlock.Header.Miner, "parents", parentMiners, "parentTipset", base.TipSet.Key().String(), "took", dur) if dur > time.Second*time.Duration(build.BlockDelaySecs) { log.Warnw("CAUTION: block production took longer than the block delay. Your computer may not be fast enough to keep up", "tMinerBaseInfo ", tMBI.Sub(start), @@ -536,7 +559,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, "tCreateBlock ", tCreateBlock.Sub(tPending)) } - return b, nil + return minedBlock, nil } func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, base *MiningBase, mbi *api.MiningBaseInfo) (*types.Ticket, error) { From aed7017ab2aeeb8f8aa7f9e980ad21cf0d608063 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Fri, 21 May 2021 15:30:08 +0200 Subject: [PATCH 62/80] Forgotten deadcode --- chain/gen/gen.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index fabe72e49..d06c755fa 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -3,7 +3,6 @@ package gen import ( "bytes" "context" - "encoding/base64" "fmt" "io" "io/ioutil" @@ -611,8 +610,6 @@ func (wpp *wppProvider) ComputeProof(context.Context, []proof2.SectorInfo, abi.P return ValidWpostForTesting, nil } -var b64 = base64.URLEncoding.WithPadding(base64.NoPadding) - func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch, miner address.Address, brand types.BeaconEntry, mbi *api.MiningBaseInfo, a MiningCheckAPI) (*types.ElectionProof, error) { From 714702f278751d3a31d2812f311ee03ece95e100 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Fri, 21 May 2021 10:37:09 -0600 Subject: [PATCH 63/80] feat: allow 8MB sectors in devnet --- build/params_2k.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/params_2k.go b/build/params_2k.go index 12d497c4b..32b010c32 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -44,7 +44,7 @@ var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ } func init() { - policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) + policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1, abi.RegisteredSealProof_StackedDrg8MiBV1) policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048)) policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) policy.SetPreCommitChallengeDelay(abi.ChainEpoch(10)) From 888c63b79c93c186242c59373f7024e793fbfd81 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Sat, 22 May 2021 17:39:56 +0200 Subject: [PATCH 64/80] Incorporate the 'Time delta between now...' log into the 'completed mineOne' --- miner/miner.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/miner/miner.go b/miner/miner.go index 5fbc9aae3..7b85e558e 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -440,9 +440,12 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (minedBlock *type log.Infow( "completed mineOne", + "tookMilliseconds", (build.Clock.Now().UnixNano()-start.UnixNano())/1_000_000, "forRound", int64(round), "baseEpoch", int64(base.TipSet.Height()), - "beaconEpoch", rbase.Round, + "baseDeltaSeconds", uint64(start.Unix())-base.TipSet.MinTimestamp(), + "nullRounds", int64(base.NullRounds), + "beaconEpoch", uint64(rbase.Round), "lookbackEpochs", int64(policy.ChainFinality), // hardcoded as it is unlikely to change again: https://github.com/filecoin-project/lotus/blob/v1.8.0/chain/actors/policy/policy.go#L180-L186 "networkPowerAtLookback", mbi.NetworkPower.String(), "minerPowerAtLookback", mbi.MinerPower.String(), @@ -475,8 +478,6 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (minedBlock *type tPowercheck := build.Clock.Now() - log.Infof("Time delta between now and our mining base: %ds (nulls: %d)", uint64(build.Clock.Now().Unix())-base.TipSet.MinTimestamp(), base.NullRounds) - rbase = beaconPrev if len(bvals) > 0 { rbase = bvals[len(bvals)-1] From 3a74ab8f8249587ae6374191f9c276ff2597a535 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Sat, 22 May 2021 23:55:32 +0200 Subject: [PATCH 65/80] Add a `lateStart` indicator, differentiate on Error/Warn/Info --- miner/miner.go | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/miner/miner.go b/miner/miner.go index 7b85e558e..b2da25d8e 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -13,6 +13,7 @@ import ( proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/gen/slashfilter" @@ -438,13 +439,15 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (minedBlock *type } } - log.Infow( - "completed mineOne", - "tookMilliseconds", (build.Clock.Now().UnixNano()-start.UnixNano())/1_000_000, + isLate := uint64(start.Unix()) > (base.TipSet.MinTimestamp() + uint64(base.NullRounds*builtin.EpochDurationSeconds) + build.PropagationDelaySecs) + + logStruct := []interface{}{ + "tookMilliseconds", (build.Clock.Now().UnixNano() - start.UnixNano()) / 1_000_000, "forRound", int64(round), "baseEpoch", int64(base.TipSet.Height()), - "baseDeltaSeconds", uint64(start.Unix())-base.TipSet.MinTimestamp(), + "baseDeltaSeconds", uint64(start.Unix()) - base.TipSet.MinTimestamp(), "nullRounds", int64(base.NullRounds), + "lateStart", isLate, "beaconEpoch", uint64(rbase.Round), "lookbackEpochs", int64(policy.ChainFinality), // hardcoded as it is unlikely to change again: https://github.com/filecoin-project/lotus/blob/v1.8.0/chain/actors/policy/policy.go#L180-L186 "networkPowerAtLookback", mbi.NetworkPower.String(), @@ -452,7 +455,15 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (minedBlock *type "isEligible", mbi.EligibleForMining, "isWinner", (winner != nil), "error", err, - ) + } + + if err != nil { + log.Errorw("completed mineOne", logStruct...) + } else if isLate { + log.Warnw("completed mineOne", logStruct...) + } else { + log.Infow("completed mineOne", logStruct...) + } }() mbi, err = m.api.MinerGetBaseInfo(ctx, m.address, round, base.TipSet.Key()) From 559c76a2142767c0250d6b06cb8fd6d4d72428cc Mon Sep 17 00:00:00 2001 From: Aloxaf Date: Mon, 24 May 2021 15:00:47 +0800 Subject: [PATCH 66/80] Fix shell completions --- Makefile | 7 ------ cmd/lotus-seal-worker/main.go | 7 +++--- scripts/bash-completion/lotus | 24 +++++++++++++------- scripts/bash-completion/lotus-miner | 10 --------- scripts/make-completions.sh | 9 -------- scripts/zsh-completion/lotus | 35 +++++++++++++++++++---------- scripts/zsh-completion/lotus-miner | 12 ---------- 7 files changed, 43 insertions(+), 61 deletions(-) delete mode 100644 scripts/bash-completion/lotus-miner delete mode 100755 scripts/make-completions.sh delete mode 100644 scripts/zsh-completion/lotus-miner diff --git a/Makefile b/Makefile index 67d26a71b..fb10a2b77 100644 --- a/Makefile +++ b/Makefile @@ -303,17 +303,10 @@ clean-services: clean-all-services buildall: $(BINS) -completions: - ./scripts/make-completions.sh lotus - ./scripts/make-completions.sh lotus-miner -.PHONY: completions - install-completions: mkdir -p /usr/share/bash-completion/completions /usr/local/share/zsh/site-functions/ install -C ./scripts/bash-completion/lotus /usr/share/bash-completion/completions/lotus - install -C ./scripts/bash-completion/lotus-miner /usr/share/bash-completion/completions/lotus-miner install -C ./scripts/zsh-completion/lotus /usr/local/share/zsh/site-functions/_lotus - install -C ./scripts/zsh-completion/lotus-miner /usr/local/share/zsh/site-functions/_lotus-miner clean: rm -rf $(CLEAN) $(BINS) diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index 693b833a5..a206d3371 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -63,9 +63,10 @@ func main() { } app := &cli.App{ - Name: "lotus-worker", - Usage: "Remote miner worker", - Version: build.UserVersion(), + Name: "lotus-worker", + Usage: "Remote miner worker", + Version: build.UserVersion(), + EnableBashCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ Name: FlagWorkerRepo, diff --git a/scripts/bash-completion/lotus b/scripts/bash-completion/lotus index 20c312b6c..b572ab320 100644 --- a/scripts/bash-completion/lotus +++ b/scripts/bash-completion/lotus @@ -1,10 +1,18 @@ #!/usr/bin/env bash + _cli_bash_autocomplete() { - local cur opts base; - COMPREPLY=(); - cur="${COMP_WORDS[COMP_CWORD]}"; - opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-completion ); - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ); - return 0; -}; -complete -F _cli_bash_autocomplete lotus \ No newline at end of file + if [[ "${COMP_WORDS[0]}" != "source" ]]; then + local cur opts base + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + if [[ "$cur" == "-"* ]]; then + opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --generate-bash-completion ) + else + opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion ) + fi + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi +} + +complete -o bashdefault -o default -o nospace -F _cli_bash_autocomplete lotus lotus-miner lotus-worker diff --git a/scripts/bash-completion/lotus-miner b/scripts/bash-completion/lotus-miner deleted file mode 100644 index df5cc01cc..000000000 --- a/scripts/bash-completion/lotus-miner +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash -_cli_bash_autocomplete() { - local cur opts base; - COMPREPLY=(); - cur="${COMP_WORDS[COMP_CWORD]}"; - opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-completion ); - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ); - return 0; -}; -complete -F _cli_bash_autocomplete lotus-miner \ No newline at end of file diff --git a/scripts/make-completions.sh b/scripts/make-completions.sh deleted file mode 100755 index 1bfd59bf3..000000000 --- a/scripts/make-completions.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -# scripts/make-completions.sh [progname] - -echo '#!/usr/bin/env bash' > "scripts/bash-completion/$1" -echo '#!/usr/bin/env zsh' > "scripts/zsh-completion/$1" - -$1 --init-completion=bash >> "scripts/bash-completion/$1" -$1 --init-completion=zsh >> "scripts/zsh-completion/$1" diff --git a/scripts/zsh-completion/lotus b/scripts/zsh-completion/lotus index bbd886ae4..8d21370b2 100644 --- a/scripts/zsh-completion/lotus +++ b/scripts/zsh-completion/lotus @@ -1,12 +1,23 @@ -#!/usr/bin/env zsh -autoload -U compinit && compinit; -autoload -U bashcompinit && bashcompinit; -_cli_bash_autocomplete() { - local cur opts base; - COMPREPLY=(); - cur="${COMP_WORDS[COMP_CWORD]}"; - opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-completion ); - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ); - return 0; -}; -complete -F _cli_bash_autocomplete lotus \ No newline at end of file +#compdef lotus lotus-miner lotus-worker + +_cli_zsh_autocomplete() { + + local -a opts + local cur + cur=${words[-1]} + if [[ "$cur" == "-"* ]]; then + opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} ${cur} --generate-bash-completion)}") + else + opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} --generate-bash-completion)}") + fi + + if [[ "${opts[1]}" != "" ]]; then + _describe 'values' opts + else + _files + fi + + return +} + +compdef _cli_zsh_autocomplete lotus lotus-miner lotus-worker diff --git a/scripts/zsh-completion/lotus-miner b/scripts/zsh-completion/lotus-miner deleted file mode 100644 index 3e23749e6..000000000 --- a/scripts/zsh-completion/lotus-miner +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env zsh -autoload -U compinit && compinit; -autoload -U bashcompinit && bashcompinit; -_cli_bash_autocomplete() { - local cur opts base; - COMPREPLY=(); - cur="${COMP_WORDS[COMP_CWORD]}"; - opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-completion ); - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ); - return 0; -}; -complete -F _cli_bash_autocomplete lotus-miner \ No newline at end of file From 391d6eca49f4ea0288547ce96fc982a97aaec63a Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Mon, 24 May 2021 10:04:37 -0400 Subject: [PATCH 67/80] make lint happy --- miner/miner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/miner.go b/miner/miner.go index b2da25d8e..62bec5b55 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -448,7 +448,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (minedBlock *type "baseDeltaSeconds", uint64(start.Unix()) - base.TipSet.MinTimestamp(), "nullRounds", int64(base.NullRounds), "lateStart", isLate, - "beaconEpoch", uint64(rbase.Round), + "beaconEpoch", rbase.Round, "lookbackEpochs", int64(policy.ChainFinality), // hardcoded as it is unlikely to change again: https://github.com/filecoin-project/lotus/blob/v1.8.0/chain/actors/policy/policy.go#L180-L186 "networkPowerAtLookback", mbi.NetworkPower.String(), "minerPowerAtLookback", mbi.MinerPower.String(), From 995efe4584f34d5a5dc17fe99561b2069da0ccf6 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 24 May 2021 16:31:50 -0700 Subject: [PATCH 68/80] feat: log dispute rate This way we can see if/when we need to optimize this code. --- cli/disputer.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cli/disputer.go b/cli/disputer.go index 235c4cf03..ceebeb939 100644 --- a/cli/disputer.go +++ b/cli/disputer.go @@ -238,6 +238,9 @@ var disputerStartCmd = &cli.Command{ dpmsgs := make([]*types.Message, 0) + startTime := time.Now() + proofsChecked := uint64(0) + // TODO: Parallelizeable for _, dl := range dls { fullDeadlines, err := api.StateMinerDeadlines(ctx, dl.miner, tsk) @@ -249,7 +252,10 @@ var disputerStartCmd = &cli.Command{ return xerrors.Errorf("deadline index %d not found in deadlines", dl.index) } - ms, err := makeDisputeWindowedPosts(ctx, api, dl, fullDeadlines[dl.index].DisputableProofCount, fromAddr) + disputableProofs := fullDeadlines[dl.index].DisputableProofCount + proofsChecked += disputableProofs + + ms, err := makeDisputeWindowedPosts(ctx, api, dl, disputableProofs, fromAddr) if err != nil { return xerrors.Errorf("failed to check for disputes: %w", err) } @@ -264,6 +270,8 @@ var disputerStartCmd = &cli.Command{ deadlineMap[dClose+Confidence] = append(deadlineMap[dClose+Confidence], *dl) } + disputeLog.Infow("checked proofs", "count", proofsChecked, "duration", time.Since(startTime)) + // TODO: Parallelizeable / can be integrated into the previous deadline-iterating for loop for _, dpmsg := range dpmsgs { disputeLog.Infow("disputing a PoSt", "miner", dpmsg.To) From 273368ed6a684f318027fce16ae4198f9c522862 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Tue, 25 May 2021 01:23:33 -0700 Subject: [PATCH 69/80] separate tracing environment variables --- lib/tracing/setup.go | 61 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/lib/tracing/setup.go b/lib/tracing/setup.go index 141683b39..9f30b7714 100644 --- a/lib/tracing/setup.go +++ b/lib/tracing/setup.go @@ -2,6 +2,7 @@ package tracing import ( "os" + "strings" "contrib.go.opencensus.io/exporter/jaeger" logging "github.com/ipfs/go-log/v2" @@ -10,17 +11,61 @@ import ( var log = logging.Logger("tracing") -func SetupJaegerTracing(serviceName string) *jaeger.Exporter { +const ( + // environment variable names + envCollectorEndpoint = "LOTUS_JAEGER_COLLECTOR_ENDPOINT" + envAgentEndpoint = "LOTUS_JAEGER_AGENT_ENDPOINT" + envAgentHost = "LOTUS_JAEGER_AGENT_HOST" + envAgentPort = "LOTUS_JAEGER_AGENT_PORT" + envUsername = "LOTUS_JAEGER_USERNAME" + envPassword = "LOTUS_JAEGER_PASSWORD" +) - if _, ok := os.LookupEnv("LOTUS_JAEGER"); !ok { +// When sending directly to the collector, agent options are ignored. +// The collector endpoint is an HTTP or HTTPs URL. +// The agent endpoint is a thrift/udp protocol given like "hostname:port" +// or separate host and port environment variables. +func jaegerOptsFromEnv(opts *jaeger.Options) bool { + var e string + var ok bool + if e, ok = os.LookupEnv(envUsername); ok { + if p, ok := os.LookupEnv(envPassword); ok { + opts.Username = e + opts.Password = p + } else { + log.Warn("jaeger username supplied with no password. authentication will not be used.") + } + } + if e, ok = os.LookupEnv(envCollectorEndpoint); ok { + opts.CollectorEndpoint = e + log.Infof("jaeger tracess will send to collector %s", e) + return true + } + if e, ok = os.LookupEnv(envAgentEndpoint); ok { + log.Infof("jaeger traces will be sent to agent %s", e) + opts.AgentEndpoint = e + return true + } + if e, ok = os.LookupEnv(envAgentHost); ok { + if p, ok := os.LookupEnv(envAgentPort); ok { + opts.AgentEndpoint = strings.Join([]string{e, p}, ":") + } else { + opts.AgentEndpoint = strings.Join([]string{e, "6831"}, ":") + } + log.Infof("jaeger traces will be sent to agent %s", opts.AgentEndpoint) + return true + } + log.Infof("jaeger tracing is not configured.") + return false +} + +func SetupJaegerTracing(serviceName string) *jaeger.Exporter { + opts := jaeger.Options{} + if !jaegerOptsFromEnv(&opts) { return nil } - agentEndpointURI := os.Getenv("LOTUS_JAEGER") - - je, err := jaeger.NewExporter(jaeger.Options{ - AgentEndpoint: agentEndpointURI, - ServiceName: serviceName, - }) + opts.ServiceName = serviceName + je, err := jaeger.NewExporter(opts) if err != nil { log.Errorw("Failed to create the Jaeger exporter", "error", err) return nil From d42eda43365455df106801e7e4ad9279223993ed Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 18 May 2021 21:41:21 -0400 Subject: [PATCH 70/80] Use new actor tags --- build/params_mainnet.go | 16 ++-------------- go.mod | 8 ++++---- go.sum | 10 ++++++++-- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/build/params_mainnet.go b/build/params_mainnet.go index ea4ae7d75..fe25b3745 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -8,12 +8,10 @@ package build import ( - "math" "os" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/chain/actors/policy" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) @@ -54,29 +52,19 @@ const UpgradeOrangeHeight = 336458 const UpgradeClausHeight = 343200 // 2021-03-04T00:00:30Z -var UpgradeActorsV3Height = abi.ChainEpoch(550321) +const UpgradeActorsV3Height = 550321 // 2021-04-12T22:00:00Z const UpgradeNorwegianHeight = 665280 // 2021-04-29T06:00:00Z -var UpgradeActorsV4Height = abi.ChainEpoch(712320) +const UpgradeActorsV4Height = 712320 func init() { - policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40)) - if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" { SetAddressNetwork(address.Mainnet) } - if os.Getenv("LOTUS_DISABLE_V3_ACTOR_MIGRATION") == "1" { - UpgradeActorsV3Height = math.MaxInt64 - } - - if os.Getenv("LOTUS_DISABLE_V4_ACTOR_MIGRATION") == "1" { - UpgradeActorsV4Height = math.MaxInt64 - } - Devnet = false BuildType = BuildMainnet diff --git a/go.mod b/go.mod index 9c47ec848..da658267a 100644 --- a/go.mod +++ b/go.mod @@ -44,10 +44,10 @@ require ( github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe github.com/filecoin-project/go-statestore v0.1.1 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/specs-actors v0.9.13 - github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb - github.com/filecoin-project/specs-actors/v3 v3.1.0 - github.com/filecoin-project/specs-actors/v4 v4.0.0 + github.com/filecoin-project/specs-actors v0.9.14 + github.com/filecoin-project/specs-actors/v2 v2.3.5 + github.com/filecoin-project/specs-actors/v3 v3.1.1 + github.com/filecoin-project/specs-actors/v4 v4.0.1 github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 github.com/filecoin-project/test-vectors/schema v0.0.5 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index f26f4f931..fab5b0dac 100644 --- a/go.sum +++ b/go.sum @@ -310,14 +310,20 @@ github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07 github.com/filecoin-project/specs-actors v0.9.12/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= github.com/filecoin-project/specs-actors v0.9.13 h1:rUEOQouefi9fuVY/2HOroROJlZbOzWYXXeIh41KF2M4= github.com/filecoin-project/specs-actors v0.9.13/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= +github.com/filecoin-project/specs-actors v0.9.14 h1:68PVstg2UB3ZsMLF+DKFTAs/YKsqhKWynkr0IqmVRQY= +github.com/filecoin-project/specs-actors v0.9.14/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= github.com/filecoin-project/specs-actors/v2 v2.0.1/go.mod h1:v2NZVYinNIKA9acEMBm5wWXxqv5+frFEbekBFemYghY= github.com/filecoin-project/specs-actors/v2 v2.3.2/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb h1:orr/sMzrDZUPAveRE+paBdu1kScIUO5zm+HYeh+VlhA= github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb/go.mod h1:LljnY2Mn2homxZsmokJZCpRuhOPxfXhvcek5gWkmqAc= +github.com/filecoin-project/specs-actors/v2 v2.3.5 h1:PbT4tPlSXZ8sRgajhb4D8AOEmiaaZ+jg6tc6BBv8VQc= +github.com/filecoin-project/specs-actors/v2 v2.3.5/go.mod h1:LljnY2Mn2homxZsmokJZCpRuhOPxfXhvcek5gWkmqAc= github.com/filecoin-project/specs-actors/v3 v3.1.0 h1:s4qiPw8pgypqBGAy853u/zdZJ7K9cTZdM1rTiSonHrg= github.com/filecoin-project/specs-actors/v3 v3.1.0/go.mod h1:mpynccOLlIRy0QnR008BwYBwT9fen+sPR13MA1VmMww= -github.com/filecoin-project/specs-actors/v4 v4.0.0 h1:vMALksY5G3J5rj3q9rbcyB+f4Tk1xrLqSgdB3jOok4s= -github.com/filecoin-project/specs-actors/v4 v4.0.0/go.mod h1:TkHXf/l7Wyw4ZejyXIPS2rK8bBO0rdwhTZyQQgaglng= +github.com/filecoin-project/specs-actors/v3 v3.1.1 h1:BE8fsns1GnEOxt1DTE5LxBK2FThXtWmCChgcJoHTg0E= +github.com/filecoin-project/specs-actors/v3 v3.1.1/go.mod h1:mpynccOLlIRy0QnR008BwYBwT9fen+sPR13MA1VmMww= +github.com/filecoin-project/specs-actors/v4 v4.0.1 h1:AiWrtvJZ63MHGe6rn7tPu4nSUY8bA1KDNszqJaD5+Fg= +github.com/filecoin-project/specs-actors/v4 v4.0.1/go.mod h1:TkHXf/l7Wyw4ZejyXIPS2rK8bBO0rdwhTZyQQgaglng= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg= From cf574ca9a14bb8b5cf10b6b076d3429612ef9958 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 14 May 2021 21:11:23 -0400 Subject: [PATCH 71/80] Allow starting networks from arbitrary actor versions --- build/openrpc/full.json.gz | Bin 23308 -> 23305 bytes build/params_2k.go | 20 +- build/params_shared_vals.go | 2 +- chain/actors/adt/temp | 0 chain/actors/aerrors/temp | 0 chain/actors/agen/main.go | 72 ++-- chain/actors/agen/temp | 0 chain/actors/builtin/account/account.go | 41 +++ .../actors/builtin/account/actor.go.template | 23 ++ .../actors/builtin/account/state.go.template | 10 + chain/actors/builtin/account/temp | 0 chain/actors/builtin/account/v0.go | 10 + chain/actors/builtin/account/v2.go | 10 + chain/actors/builtin/account/v3.go | 10 + chain/actors/builtin/account/v4.go | 10 + chain/actors/builtin/builtin.go.template | 94 ++--- chain/actors/builtin/cron/actor.go.template | 34 +- chain/actors/builtin/cron/cron.go | 54 +++ chain/actors/builtin/cron/state.go.template | 35 ++ chain/actors/builtin/cron/temp | 0 chain/actors/builtin/cron/v0.go | 35 ++ chain/actors/builtin/cron/v2.go | 35 ++ chain/actors/builtin/cron/v3.go | 35 ++ chain/actors/builtin/cron/v4.go | 35 ++ chain/actors/builtin/init/actor.go.template | 31 +- chain/actors/builtin/init/diff.go | 4 +- chain/actors/builtin/init/init.go | 49 ++- chain/actors/builtin/init/state.go.template | 38 +- chain/actors/builtin/init/temp | 0 chain/actors/builtin/init/v0.go | 31 +- chain/actors/builtin/init/v2.go | 31 +- chain/actors/builtin/init/v3.go | 31 +- chain/actors/builtin/init/v4.go | 31 +- chain/actors/builtin/market/actor.go.template | 80 +++-- chain/actors/builtin/market/market.go | 42 ++- chain/actors/builtin/market/state.go.template | 29 ++ chain/actors/builtin/market/temp | 0 chain/actors/builtin/market/v0.go | 22 ++ chain/actors/builtin/market/v2.go | 22 ++ chain/actors/builtin/market/v3.go | 17 + chain/actors/builtin/market/v4.go | 17 + chain/actors/builtin/miner/actor.go.template | 86 +++-- chain/actors/builtin/miner/miner.go | 46 +++ chain/actors/builtin/miner/state.go.template | 101 ++++-- chain/actors/builtin/miner/temp | 0 chain/actors/builtin/miner/v0.go | 21 ++ chain/actors/builtin/miner/v2.go | 51 +++ chain/actors/builtin/miner/v3.go | 51 +++ chain/actors/builtin/miner/v4.go | 51 +++ .../actors/builtin/multisig/actor.go.template | 24 +- .../builtin/multisig/message.go.template | 36 +- chain/actors/builtin/multisig/multisig.go | 40 +++ .../actors/builtin/multisig/state.go.template | 30 ++ chain/actors/builtin/multisig/temp | 0 chain/actors/builtin/multisig/v0.go | 23 ++ chain/actors/builtin/multisig/v2.go | 23 ++ chain/actors/builtin/multisig/v3.go | 23 ++ chain/actors/builtin/multisig/v4.go | 23 ++ chain/actors/builtin/paych/actor.go.template | 23 ++ .../actors/builtin/paych/message.go.template | 28 +- chain/actors/builtin/paych/mock/mock.go | 4 + chain/actors/builtin/paych/mock/temp | 0 chain/actors/builtin/paych/paych.go | 41 +++ chain/actors/builtin/paych/state.go.template | 10 + chain/actors/builtin/paych/temp | 0 chain/actors/builtin/paych/v0.go | 10 + chain/actors/builtin/paych/v2.go | 10 + chain/actors/builtin/paych/v3.go | 10 + chain/actors/builtin/paych/v4.go | 10 + chain/actors/builtin/power/actor.go.template | 31 +- chain/actors/builtin/power/power.go | 47 +++ chain/actors/builtin/power/state.go.template | 60 +++- chain/actors/builtin/power/temp | 0 chain/actors/builtin/power/v0.go | 42 +++ chain/actors/builtin/power/v2.go | 42 +++ chain/actors/builtin/power/v3.go | 37 ++ chain/actors/builtin/power/v4.go | 37 ++ chain/actors/builtin/reward/actor.go.template | 23 ++ chain/actors/builtin/reward/reward.go | 41 +++ chain/actors/builtin/reward/state.go.template | 10 + chain/actors/builtin/reward/temp | 0 chain/actors/builtin/reward/v0.go | 10 + chain/actors/builtin/reward/v2.go | 10 + chain/actors/builtin/reward/v3.go | 10 + chain/actors/builtin/reward/v4.go | 10 + chain/actors/builtin/system/actor.go.template | 41 +++ chain/actors/builtin/system/state.go.template | 35 ++ chain/actors/builtin/system/system.go | 63 ++++ chain/actors/builtin/system/temp | 0 chain/actors/builtin/system/v0.go | 35 ++ chain/actors/builtin/system/v2.go | 35 ++ chain/actors/builtin/system/v3.go | 35 ++ chain/actors/builtin/system/v4.go | 35 ++ chain/actors/builtin/temp | 0 .../actors/builtin/verifreg/actor.go.template | 24 ++ .../actors/builtin/verifreg/state.go.template | 26 +- chain/actors/builtin/verifreg/temp | 0 chain/actors/builtin/verifreg/v0.go | 17 + chain/actors/builtin/verifreg/v2.go | 17 + chain/actors/builtin/verifreg/v3.go | 17 + chain/actors/builtin/verifreg/v4.go | 17 + chain/actors/builtin/verifreg/verifreg.go | 41 +++ chain/actors/policy/policy.go.template | 164 ++++----- chain/actors/policy/temp | 0 chain/actors/temp | 0 chain/actors/version.go | 4 + chain/gen/gen.go | 3 + chain/gen/genesis/f00_system.go | 21 +- chain/gen/genesis/f01_init.go | 40 ++- chain/gen/genesis/f02_reward.go | 33 +- chain/gen/genesis/f03_cron.go | 34 +- chain/gen/genesis/f04_power.go | 31 +- chain/gen/genesis/f05_market.go | 30 +- chain/gen/genesis/f06_vreg.go | 25 +- chain/gen/genesis/genesis.go | 242 +++++++------ chain/gen/genesis/miners.go | 335 ++++++++++++++---- chain/gen/genesis/util.go | 29 -- chain/state/statetree.go | 17 +- chain/state/statetree_test.go | 48 ++- chain/vm/vm.go | 35 +- cmd/lotus-seed/genesis.go | 51 +++ cmd/lotus-seed/main.go | 7 +- documentation/en/api-v0-methods.md | 2 +- documentation/en/api-v1-unstable-methods.md | 2 +- genesis/types.go | 7 +- node/test/builder.go | 4 + 126 files changed, 3174 insertions(+), 653 deletions(-) create mode 100644 chain/actors/adt/temp create mode 100644 chain/actors/aerrors/temp create mode 100644 chain/actors/agen/temp create mode 100644 chain/actors/builtin/account/temp create mode 100644 chain/actors/builtin/cron/state.go.template create mode 100644 chain/actors/builtin/cron/temp create mode 100644 chain/actors/builtin/cron/v0.go create mode 100644 chain/actors/builtin/cron/v2.go create mode 100644 chain/actors/builtin/cron/v3.go create mode 100644 chain/actors/builtin/cron/v4.go create mode 100644 chain/actors/builtin/init/temp create mode 100644 chain/actors/builtin/market/temp create mode 100644 chain/actors/builtin/miner/temp create mode 100644 chain/actors/builtin/multisig/temp create mode 100644 chain/actors/builtin/paych/mock/temp create mode 100644 chain/actors/builtin/paych/temp create mode 100644 chain/actors/builtin/power/temp create mode 100644 chain/actors/builtin/reward/temp create mode 100644 chain/actors/builtin/system/actor.go.template create mode 100644 chain/actors/builtin/system/state.go.template create mode 100644 chain/actors/builtin/system/system.go create mode 100644 chain/actors/builtin/system/temp create mode 100644 chain/actors/builtin/system/v0.go create mode 100644 chain/actors/builtin/system/v2.go create mode 100644 chain/actors/builtin/system/v3.go create mode 100644 chain/actors/builtin/system/v4.go create mode 100644 chain/actors/builtin/temp create mode 100644 chain/actors/builtin/verifreg/temp create mode 100644 chain/actors/policy/temp create mode 100644 chain/actors/temp diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 4d9fb5284d1c6ed52d84f50d11610f338e15b4bf..394f1998be7c464c835d2474d93a843971cb659d 100644 GIT binary patch delta 4808 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 iHs;oFN6osE7n$w^^y?lB*hc(20bC~KQ# zFCA0se0gU0Eyb1QRBC!{9``-7jh!Ytl)54@?MkF&T}$MqD6~iXf3*YROUisiub6kL z4uBK~pZ5ChKf2>J+f9#04zAtKN<=BX-D+nNRe^DfKbKs2UXyPy~J zXo#@+jV@s-nSQ7<6#9K-m%_SlPxfJYm4${Zraod6d1Fjy|ANXMCLqSlN7p1sE~Oz% z^^72nr`mhUpv$DKe{0O?FG9Cx21Hryh-6J1%5xYI$*fE{!coB3CHN=~^{~k>8B*E} z8e#r2f-oXp(iEdF)%dewa_9pv^9??Fi3pV~sk|;6jQ5xPH1JVw;nzO#(E%~vPMJUx zEWEKQE*~pqXg*Iq^KcMAgsxR$bioi%9!DmB4BTK(1XI)1e_t_hbr(MOA#ej;EWp>( zK1H9to}FvI4c$V;xClq^SBwMMS(^Jn?vn%JuU*h@M2xjgoN&|9fQj+U805sVh>Qru zK{}ubp2{Tw93jjvD33i4I3LDAFii)VPIMn#kBK){mE?+{fLsE?$Y=2&fR{W3>Z^UZ zSH10UZl%One^w;JAw-gT9vmIYrJqV6`~&7X@hexm;euwxI2lna0ZShZVquyI0>s1^ zBE3!^AmVxfW%tiGiz5$y^??gQl_sozK`B$|^EJxpBM{!&b0;O;GSFy5XNDrr7keuC zZLuwRWF)Bo4)TOz#32~I)MW;8Q+TEg17Ib=Od?Xu7#ARjjK4E-zpK2`8jpU!{FqFLP&a=+VE!K9 z0EgMjf0GC%B%YWDpA?tu?QZmYCx#gG{!N4R|D5fQJ^J5c_}72^mjt<0cZUaq(1+1g zv_-Z(#^G9wr+oD4=JF=|Ye+Y*hu+^ildH|~gk6g3fq!#}Z??IDfuH#3)KiP|?uH1B zK-c@dQ^m@v2k-&&uPQ3^+ke!L1IASYpELztf8IKz9jWQr#~j`R?CWvKCtt20ddCIP z3G#C<^i46KSUC`6kIqRl`KK_9Y0|Qa9-+TNN8Wg+*b`y&Ji;2tyDeeACEiI~S5CBk z7$?@Eo%QrTy@AF!8fCHA&*FiELFRYM2HRdZkK35A%s?svcb9j}Jq#j0mA0|hiz87M ze}Sr|y^-DE^evBjVKF?nyRKgsJOocGEi}Pf+Fo83DeLz>np+uNqKbV?Z*Jr3lVGzw*j-BECsgG@GP(V z&elwYFC88f3xjI46P<~`f1m^rkaeDFek>Q<=Ds=C-MM8~pUX04sV!%fww<1nNfvPZ=T1C7xoj$$r5O10;xalSQ0HX5Vb_;%Cnz(Id(Ka~5?BH6l3RA6c=_Pdv zRU2`Dp zX@aoiST-ZDTqzs)Rm@peNK@B79bJnYZmqJfJu;55x!!aGyE>aWA5(wqqpu$^}(K`o>Nd;kb(9Dvz71%saAnXqf4)+#!YG1}MM67lD!=EL3Nisiw|y*74lKsG1*5|OACf3 zRRXv%Q?YA^?6^?%I4ok~Rn;se_{IVw4`)}MG)qao=7Od!8zewP@uo=KTA>U9711=g z!jv{7@F0MsxeJ=L^duE7jt#cZgU=q0vJSkWgvIKw-_pXbD0SRy@^MQj!YPah7t!>T zF|#oje;|-EjkO5tK1(%QP{VSk^YHjQVrWK_VDO|oN_zT*qlhsTYt!N6`-t*hBK@n* z8dj7-Y&AJEm~9^|0XaqYj+vqkXen|y$>F3GCW8(qEr$wjHyP-^VIn$5^e~m{=w24P zV-v-MikCqtiK))-V@kaPiOlw~-(F(MRh}a;Jx9;<^3D~5ifuM1hI0iq zf4Jm`4AXp25&=(eB$+>!LXn@OOfn$|`-zfBr%;Ljb4Hh^!*LjD#qzY624?3reQcp* zDWq(8WchD1Zg1{3J!6jkv(wE@( z(F8C}6Szq_!RRjn!4*XE{9Gb@ji+cBf3XQ7!Z}>shX(a?9F%<#&BGjVO+|npc;M%9 zr_LlirQRnTb>`cq?p(G#_atTwH6KG$uHpnf47liS>0Ob2)1Xf{iw6@T_9cJse@3aY`gQQ+g~rUP%qKpwfGNdBo1sdsEb=f#13=bU1nlcO zTq>DRKE>lX@hwtnkq^?=*Em^ z2uU|Mwb1BKnaPK?3@nj9a1UYnOH81}pfeWHao`!l={EQoYGngaJD_6T-i&9Ma_gJX zMN-?XdIf`PH~0z$+@*o8Ar4Z&@WeSlhU4z;NLC%P9HOu}G(`;9e~p|M8n6g)C5!G) z1$0ezIG?arrbsOUo+rIsyGq4QO?bSy`L@Ag_mxg?bh#GU)E5c$POpB)fg|&)L zZEtO@H&~tYdM&oGf0kl-$~V=l&`C?8nAX{!DmU0bh2tPTP8^W6AqwFUCeG&MY)+5n zz;D#uE1XjAcXI;HRkWH;r@q*P{Vn4GV}XrLs?>fnJt!8>?d0n*C{O&t?FW;{UIvn>E(rZ#W1*?Bf7auf4^%e^A@<7VvZQ%vdGJ=!lAW z=XSP>`XgH?S+FY)%rj$9E?n(RLTx3s=P_VE4bnAUD*s-&8@p9!C%-l|L@0gfuAG*R zS&hL{@6AIP;y4g>;SKCgTd|R9SB;ioH)rj>Kqort;10x)UEfg@1BV%XW>L zLT{6IHzAAK%PaZH_Q=OLWc&tGo2dFTeazeNx?q78hY`8L0?;L>JIA>*umCN7@F$?S z3UyvH*=rl8nR63eI^Zhix0-e-r&YN^wDVlZH@2t|f49ao@ksdCs~Yu$J{})&SIG4d z+lDx@R7T{Rop-7~VqT+qD9SP9X`g8)^OugpPNU3!G+BV}>B@8bE)45c;lQ<^4D-n=Y ztMw1xe}8m3@utD1vo4FEfN;T8M4X(y0T$waRXecs6{UHqDlvZ-N|EYEKk?}JZso(2 z+lx6qr5z+5_V#?;sC@Vg*By7~XSi;*ApHi@b7gky#-4Qh^LW!|xHj(pTwe#M7QnLf zm>Se^GLmCkyP$hlm;@@6q?F;*$am2o;C;lwe+xHX?Obl;{(Px&)kYWeEDjY@9I^<} zcmfgeaFA5rKri#PH_=P9e|#npWVS_?Y`8L$ZAYag&s(OQ*0GW$oz*vunv}CtE!^?Q zW(_P;VOVH&-g(Umn=8l_1|#)973{B^>-BpOW(!)fcY_*5Pb#s1Lp4m4se*gJc(dJ;)!|iNyT#R?dn^*Y6+@BMOJ2* z9g{IjEPuU!+GaRYU)}ZwQtrDuR5kNw8Hq8S(6&7#b8pj+S!~O6@p#hp9*y2~ZNJ3q zzt+`~&3=14rok{-pqq84ceYT=;I2>LIQM%Q$g#Ylet*;?w=|9hIU3ZF2IX%M=J)=} z0`tcjN_V?1g|Y^%$<>0zTtR1Ase|l#dAjPk%YU8B)1l4ONbg2v-U~QUbL&{CCVGw! z9`m)wC`Q*11TW16BQx%$q4hft=jxQww|LU(lEs?M2oV{!Pk)%N++IDW(*2Y)Ev=k` z(ysF1hgK{xIk2T7p0ZbD@`f`dFJ2kGvF#8&=_AO s*C!yKiU-o_X#*Q`YdEE!^D0{wxmDR`fBf_R0ssL2{{xC7k>8sH07~LgPyhe` diff --git a/build/params_2k.go b/build/params_2k.go index 32b010c32..3dd68c9c6 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -24,20 +24,20 @@ var UpgradeIgnitionHeight = abi.ChainEpoch(-2) var UpgradeRefuelHeight = abi.ChainEpoch(-3) var UpgradeTapeHeight = abi.ChainEpoch(-4) -var UpgradeActorsV2Height = abi.ChainEpoch(10) -var UpgradeLiftoffHeight = abi.ChainEpoch(-5) +var UpgradeActorsV2Height = abi.ChainEpoch(-5) +var UpgradeLiftoffHeight = abi.ChainEpoch(-6) -var UpgradeKumquatHeight = abi.ChainEpoch(15) -var UpgradeCalicoHeight = abi.ChainEpoch(20) -var UpgradePersianHeight = abi.ChainEpoch(25) -var UpgradeOrangeHeight = abi.ChainEpoch(27) -var UpgradeClausHeight = abi.ChainEpoch(30) +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 UpgradeActorsV3Height = abi.ChainEpoch(35) +var UpgradeActorsV3Height = abi.ChainEpoch(-12) -var UpgradeNorwegianHeight = abi.ChainEpoch(40) +var UpgradeNorwegianHeight = abi.ChainEpoch(-13) -var UpgradeActorsV4Height = abi.ChainEpoch(45) +var UpgradeActorsV4Height = abi.ChainEpoch(-14) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index 92bbc5db9..6b98b6a9c 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -25,7 +25,7 @@ const UnixfsLinksPerLevel = 1024 // Consensus / Network const AllowableClockDriftSecs = uint64(1) -const NewestNetworkVersion = network.Version11 +const NewestNetworkVersion = network.Version12 const ActorUpgradeNetworkVersion = network.Version4 // Epochs diff --git a/chain/actors/adt/temp b/chain/actors/adt/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/aerrors/temp b/chain/actors/aerrors/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/agen/main.go b/chain/actors/agen/main.go index 7269d9ae5..9a3b8fd20 100644 --- a/chain/actors/agen/main.go +++ b/chain/actors/agen/main.go @@ -6,33 +6,26 @@ import ( "io/ioutil" "os" "path/filepath" + "strconv" "text/template" + lotusactors "github.com/filecoin-project/lotus/chain/actors" + "golang.org/x/xerrors" ) -var latestVersion = 4 - -var versions = []int{0, 2, 3, latestVersion} - -var versionImports = map[int]string{ - 0: "/", - 2: "/v2/", - 3: "/v3/", - latestVersion: "/v4/", -} - var actors = map[string][]int{ - "account": versions, - "cron": versions, - "init": versions, - "market": versions, - "miner": versions, - "multisig": versions, - "paych": versions, - "power": versions, - "reward": versions, - "verifreg": versions, + "account": lotusactors.Versions, + "cron": lotusactors.Versions, + "init": lotusactors.Versions, + "market": lotusactors.Versions, + "miner": lotusactors.Versions, + "multisig": lotusactors.Versions, + "paych": lotusactors.Versions, + "power": lotusactors.Versions, + "system": lotusactors.Versions, + "reward": lotusactors.Versions, + "verifreg": lotusactors.Versions, } func main() { @@ -71,14 +64,14 @@ func generateAdapters() error { } tpl := template.Must(template.New("").Funcs(template.FuncMap{ - "import": func(v int) string { return versionImports[v] }, + "import": func(v int) string { return getVersionImports()[v] }, }).Parse(string(af))) var b bytes.Buffer err = tpl.Execute(&b, map[string]interface{}{ "versions": versions, - "latestVersion": latestVersion, + "latestVersion": lotusactors.LatestVersion, }) if err != nil { return err @@ -103,14 +96,14 @@ func generateState(actDir string) error { return xerrors.Errorf("loading state adapter template: %w", err) } - for _, version := range versions { + for _, version := range lotusactors.Versions { tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af))) var b bytes.Buffer err := tpl.Execute(&b, map[string]interface{}{ "v": version, - "import": versionImports[version], + "import": getVersionImports()[version], }) if err != nil { return err @@ -134,14 +127,14 @@ func generateMessages(actDir string) error { return xerrors.Errorf("loading message adapter template: %w", err) } - for _, version := range versions { + for _, version := range lotusactors.Versions { tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af))) var b bytes.Buffer err := tpl.Execute(&b, map[string]interface{}{ "v": version, - "import": versionImports[version], + "import": getVersionImports()[version], }) if err != nil { return err @@ -167,13 +160,13 @@ func generatePolicy(policyPath string) error { } tpl := template.Must(template.New("").Funcs(template.FuncMap{ - "import": func(v int) string { return versionImports[v] }, + "import": func(v int) string { return getVersionImports()[v] }, }).Parse(string(pf))) var b bytes.Buffer err = tpl.Execute(&b, map[string]interface{}{ - "versions": versions, - "latestVersion": latestVersion, + "versions": lotusactors.Versions, + "latestVersion": lotusactors.LatestVersion, }) if err != nil { return err @@ -198,13 +191,13 @@ func generateBuiltin(builtinPath string) error { } tpl := template.Must(template.New("").Funcs(template.FuncMap{ - "import": func(v int) string { return versionImports[v] }, + "import": func(v int) string { return getVersionImports()[v] }, }).Parse(string(bf))) var b bytes.Buffer err = tpl.Execute(&b, map[string]interface{}{ - "versions": versions, - "latestVersion": latestVersion, + "versions": lotusactors.Versions, + "latestVersion": lotusactors.LatestVersion, }) if err != nil { return err @@ -216,3 +209,16 @@ func generateBuiltin(builtinPath string) error { return nil } + +func getVersionImports() map[int]string { + versionImports := make(map[int]string, lotusactors.LatestVersion) + for _, v := range lotusactors.Versions { + if v == 0 { + versionImports[v] = "/" + } else { + versionImports[v] = "/v" + strconv.Itoa(v) + "/" + } + } + + return versionImports +} diff --git a/chain/actors/agen/temp b/chain/actors/agen/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go index 8242e300d..97811d08a 100644 --- a/chain/actors/builtin/account/account.go +++ b/chain/actors/builtin/account/account.go @@ -1,6 +1,7 @@ package account import ( + "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -60,8 +61,48 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, addr address.Address) (State, error) { + switch av { + + case actors.Version0: + return make0(store, addr) + + case actors.Version2: + return make2(store, addr) + + case actors.Version3: + return make3(store, addr) + + case actors.Version4: + return make4(store, addr) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.AccountActorCodeID, nil + + case actors.Version2: + return builtin2.AccountActorCodeID, nil + + case actors.Version3: + return builtin3.AccountActorCodeID, nil + + case actors.Version4: + return builtin4.AccountActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler PubkeyAddress() (address.Address, error) + GetState() interface{} } diff --git a/chain/actors/builtin/account/actor.go.template b/chain/actors/builtin/account/actor.go.template index f75af3dfb..53962cc94 100644 --- a/chain/actors/builtin/account/actor.go.template +++ b/chain/actors/builtin/account/actor.go.template @@ -1,6 +1,7 @@ package account import ( + "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -34,8 +35,30 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, addr address.Address) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store, addr) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.AccountActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler PubkeyAddress() (address.Address, error) + GetState() interface{} } diff --git a/chain/actors/builtin/account/state.go.template b/chain/actors/builtin/account/state.go.template index 65d874c80..5be262ece 100644 --- a/chain/actors/builtin/account/state.go.template +++ b/chain/actors/builtin/account/state.go.template @@ -20,6 +20,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store, addr address.Address) (State, error) { + out := state{{.v}}{store: store} + out.State = account{{.v}}.State{Address:addr} + return &out, nil +} + type state{{.v}} struct { account{{.v}}.State store adt.Store @@ -28,3 +34,7 @@ type state{{.v}} struct { func (s *state{{.v}}) PubkeyAddress() (address.Address, error) { return s.Address, nil } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/account/temp b/chain/actors/builtin/account/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/account/v0.go b/chain/actors/builtin/account/v0.go index 67c555c5d..bdfca2fd7 100644 --- a/chain/actors/builtin/account/v0.go +++ b/chain/actors/builtin/account/v0.go @@ -20,6 +20,12 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store, addr address.Address) (State, error) { + out := state0{store: store} + out.State = account0.State{Address: addr} + return &out, nil +} + type state0 struct { account0.State store adt.Store @@ -28,3 +34,7 @@ type state0 struct { func (s *state0) PubkeyAddress() (address.Address, error) { return s.Address, nil } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/account/v2.go b/chain/actors/builtin/account/v2.go index 2664631bc..66618e06a 100644 --- a/chain/actors/builtin/account/v2.go +++ b/chain/actors/builtin/account/v2.go @@ -20,6 +20,12 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store, addr address.Address) (State, error) { + out := state2{store: store} + out.State = account2.State{Address: addr} + return &out, nil +} + type state2 struct { account2.State store adt.Store @@ -28,3 +34,7 @@ type state2 struct { func (s *state2) PubkeyAddress() (address.Address, error) { return s.Address, nil } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/account/v3.go b/chain/actors/builtin/account/v3.go index 16b489a3e..dbe100a4f 100644 --- a/chain/actors/builtin/account/v3.go +++ b/chain/actors/builtin/account/v3.go @@ -20,6 +20,12 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store, addr address.Address) (State, error) { + out := state3{store: store} + out.State = account3.State{Address: addr} + return &out, nil +} + type state3 struct { account3.State store adt.Store @@ -28,3 +34,7 @@ type state3 struct { func (s *state3) PubkeyAddress() (address.Address, error) { return s.Address, nil } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/account/v4.go b/chain/actors/builtin/account/v4.go index 1a24007d8..53f71dcc5 100644 --- a/chain/actors/builtin/account/v4.go +++ b/chain/actors/builtin/account/v4.go @@ -20,6 +20,12 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store, addr address.Address) (State, error) { + out := state4{store: store} + out.State = account4.State{Address: addr} + return &out, nil +} + type state4 struct { account4.State store adt.Store @@ -28,3 +34,7 @@ type state4 struct { func (s *state4) PubkeyAddress() (address.Address, error) { return s.Address, nil } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/builtin.go.template b/chain/actors/builtin/builtin.go.template index 9b89b13f5..6eac2627e 100644 --- a/chain/actors/builtin/builtin.go.template +++ b/chain/actors/builtin/builtin.go.template @@ -6,9 +6,9 @@ import ( "golang.org/x/xerrors" {{range .versions}} - builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" - smoothing{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/util/smoothing" - {{end}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" + smoothing{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/util/smoothing" + {{end}} "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" @@ -17,7 +17,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" miner{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/miner" - proof{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/runtime/proof" + proof{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/runtime/proof" ) var SystemActorAddr = builtin{{.latestVersion}}.SystemActorAddr @@ -33,12 +33,12 @@ var ( const ( EpochDurationSeconds = builtin{{.latestVersion}}.EpochDurationSeconds - EpochsInDay = builtin{{.latestVersion}}.EpochsInDay - SecondsInDay = builtin{{.latestVersion}}.SecondsInDay + EpochsInDay = builtin{{.latestVersion}}.EpochsInDay + SecondsInDay = builtin{{.latestVersion}}.SecondsInDay ) const ( - MethodSend = builtin{{.latestVersion}}.MethodSend + MethodSend = builtin{{.latestVersion}}.MethodSend MethodConstructor = builtin{{.latestVersion}}.MethodConstructor ) @@ -53,13 +53,13 @@ func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, } {{range .versions}} - func FromV{{.}}FilterEstimate(v{{.}} smoothing{{.}}.FilterEstimate) FilterEstimate { + func FromV{{.}}FilterEstimate(v{{.}} smoothing{{.}}.FilterEstimate) FilterEstimate { {{if (eq . 0)}} - return (FilterEstimate)(v{{.}}) //nolint:unconvert - {{else}} - return (FilterEstimate)(v{{.}}) - {{end}} - } + return (FilterEstimate)(v{{.}}) //nolint:unconvert + {{else}} + return (FilterEstimate)(v{{.}}) + {{end}} + } {{end}} type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) @@ -80,58 +80,58 @@ func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) { func ActorNameByCode(c cid.Cid) string { switch { - {{range .versions}} - case builtin{{.}}.IsBuiltinActor(c): - return builtin{{.}}.ActorNameByCode(c) - {{end}} + {{range .versions}} + case builtin{{.}}.IsBuiltinActor(c): + return builtin{{.}}.ActorNameByCode(c) + {{end}} default: return "" } } func IsBuiltinActor(c cid.Cid) bool { - {{range .versions}} - if builtin{{.}}.IsBuiltinActor(c) { - return true - } - {{end}} - return false + {{range .versions}} + if builtin{{.}}.IsBuiltinActor(c) { + return true + } + {{end}} + return false } func IsAccountActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.AccountActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.AccountActorCodeID { + return true + } + {{end}} + return false } func IsStorageMinerActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.StorageMinerActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.StorageMinerActorCodeID { + return true + } + {{end}} + return false } func IsMultisigActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.MultisigActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.MultisigActorCodeID { + return true + } + {{end}} + return false } func IsPaymentChannelActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.PaymentChannelActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.PaymentChannelActorCodeID { + return true + } + {{end}} + return false } func makeAddress(addr string) address.Address { diff --git a/chain/actors/builtin/cron/actor.go.template b/chain/actors/builtin/cron/actor.go.template index 6b7449617..d73808556 100644 --- a/chain/actors/builtin/cron/actor.go.template +++ b/chain/actors/builtin/cron/actor.go.template @@ -1,10 +1,42 @@ package cron import ( - builtin{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "golang.org/x/xerrors" + "github.com/ipfs/go-cid" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} ) +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.CronActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + var ( Address = builtin{{.latestVersion}}.CronActorAddr Methods = builtin{{.latestVersion}}.MethodsCron ) + + +type State interface { + GetState() interface{} +} diff --git a/chain/actors/builtin/cron/cron.go b/chain/actors/builtin/cron/cron.go index 52a9fab07..62fa413a8 100644 --- a/chain/actors/builtin/cron/cron.go +++ b/chain/actors/builtin/cron/cron.go @@ -1,10 +1,64 @@ package cron import ( + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" ) +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.CronActorCodeID, nil + + case actors.Version2: + return builtin2.CronActorCodeID, nil + + case actors.Version3: + return builtin3.CronActorCodeID, nil + + case actors.Version4: + return builtin4.CronActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + var ( Address = builtin4.CronActorAddr Methods = builtin4.MethodsCron ) + +type State interface { + GetState() interface{} +} diff --git a/chain/actors/builtin/cron/state.go.template b/chain/actors/builtin/cron/state.go.template new file mode 100644 index 000000000..99a06d7f8 --- /dev/null +++ b/chain/actors/builtin/cron/state.go.template @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/cron" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + out.State = *cron{{.v}}.ConstructState(cron{{.v}}.BuiltInEntries()) + return &out, nil +} + +type state{{.v}} struct { + cron{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/cron/temp b/chain/actors/builtin/cron/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/cron/v0.go b/chain/actors/builtin/cron/v0.go new file mode 100644 index 000000000..6147b858c --- /dev/null +++ b/chain/actors/builtin/cron/v0.go @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron0 "github.com/filecoin-project/specs-actors/actors/builtin/cron" +) + +var _ State = (*state0)(nil) + +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make0(store adt.Store) (State, error) { + out := state0{store: store} + out.State = *cron0.ConstructState(cron0.BuiltInEntries()) + return &out, nil +} + +type state0 struct { + cron0.State + store adt.Store +} + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/cron/v2.go b/chain/actors/builtin/cron/v2.go new file mode 100644 index 000000000..51ca179d9 --- /dev/null +++ b/chain/actors/builtin/cron/v2.go @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/cron" +) + +var _ State = (*state2)(nil) + +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make2(store adt.Store) (State, error) { + out := state2{store: store} + out.State = *cron2.ConstructState(cron2.BuiltInEntries()) + return &out, nil +} + +type state2 struct { + cron2.State + store adt.Store +} + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/cron/v3.go b/chain/actors/builtin/cron/v3.go new file mode 100644 index 000000000..ff74d511d --- /dev/null +++ b/chain/actors/builtin/cron/v3.go @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/cron" +) + +var _ State = (*state3)(nil) + +func load3(store adt.Store, root cid.Cid) (State, error) { + out := state3{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make3(store adt.Store) (State, error) { + out := state3{store: store} + out.State = *cron3.ConstructState(cron3.BuiltInEntries()) + return &out, nil +} + +type state3 struct { + cron3.State + store adt.Store +} + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/cron/v4.go b/chain/actors/builtin/cron/v4.go new file mode 100644 index 000000000..1cff8cc28 --- /dev/null +++ b/chain/actors/builtin/cron/v4.go @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/cron" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make4(store adt.Store) (State, error) { + out := state4{store: store} + out.State = *cron4.ConstructState(cron4.BuiltInEntries()) + return &out, nil +} + +type state4 struct { + cron4.State + store adt.Store +} + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/init/actor.go.template b/chain/actors/builtin/init/actor.go.template index 5b700cec8..f825eb9fa 100644 --- a/chain/actors/builtin/init/actor.go.template +++ b/chain/actors/builtin/init/actor.go.template @@ -1,6 +1,7 @@ package init import ( + "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -39,6 +40,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, networkName string) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store, networkName) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.InitActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -56,5 +78,12 @@ type State interface { // Sets the network's name. This should only be used on upgrade/fork. SetNetworkName(name string) error - addressMap() (adt.Map, error) + // Sets the next ID for the init actor. This should only be used for testing. + SetNextID(id abi.ActorID) error + + // Sets the address map for the init actor. This should only be used for testing. + SetAddressMap(mcid cid.Cid) error + + AddressMap() (adt.Map, error) + GetState() interface{} } diff --git a/chain/actors/builtin/init/diff.go b/chain/actors/builtin/init/diff.go index 593171322..5eb8f3c75 100644 --- a/chain/actors/builtin/init/diff.go +++ b/chain/actors/builtin/init/diff.go @@ -11,12 +11,12 @@ import ( ) func DiffAddressMap(pre, cur State) (*AddressMapChanges, error) { - prem, err := pre.addressMap() + prem, err := pre.AddressMap() if err != nil { return nil, err } - curm, err := cur.addressMap() + curm, err := cur.AddressMap() if err != nil { return nil, err } diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index 730d21fd8..2091252ce 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -1,6 +1,7 @@ package init import ( + "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -65,6 +66,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, networkName string) (State, error) { + switch av { + + case actors.Version0: + return make0(store, networkName) + + case actors.Version2: + return make2(store, networkName) + + case actors.Version3: + return make3(store, networkName) + + case actors.Version4: + return make4(store, networkName) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.InitActorCodeID, nil + + case actors.Version2: + return builtin2.InitActorCodeID, nil + + case actors.Version3: + return builtin3.InitActorCodeID, nil + + case actors.Version4: + return builtin4.InitActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -82,5 +122,12 @@ type State interface { // Sets the network's name. This should only be used on upgrade/fork. SetNetworkName(name string) error - addressMap() (adt.Map, error) + // Sets the next ID for the init actor. This should only be used for testing. + SetNextID(id abi.ActorID) error + + // Sets the address map for the init actor. This should only be used for testing. + SetAddressMap(mcid cid.Cid) error + + AddressMap() (adt.Map, error) + GetState() interface{} } diff --git a/chain/actors/builtin/init/state.go.template b/chain/actors/builtin/init/state.go.template index 95f052bda..482ad4df5 100644 --- a/chain/actors/builtin/init/state.go.template +++ b/chain/actors/builtin/init/state.go.template @@ -29,6 +29,26 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store, networkName string) (State, error) { + out := state{{.v}}{store: store} + {{if (le .v 2)}} + mr, err := adt{{.v}}.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *init{{.v}}.ConstructState(mr, networkName) + {{else}} + s, err := init{{.v}}.ConstructState(store, networkName) + if err != nil { + return nil, err + } + + out.State = *s + {{end}} + return &out, nil +} + type state{{.v}} struct { init{{.v}}.State store adt.Store @@ -66,6 +86,11 @@ func (s *state{{.v}}) SetNetworkName(name string) error { return nil } +func (s *state{{.v}}) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + func (s *state{{.v}}) Remove(addrs ...address.Address) (err error) { m, err := adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) if err != nil { @@ -84,6 +109,15 @@ func (s *state{{.v}}) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state{{.v}}) addressMap() (adt.Map, error) { - return adt{{.v}}.AsMap(s.store, s.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) +func (s *state{{.v}}) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil } + +func (s *state{{.v}}) AddressMap() (adt.Map, error) { + return adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) +} + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/init/temp b/chain/actors/builtin/init/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/init/v0.go b/chain/actors/builtin/init/v0.go index c019705b1..ddd2dab94 100644 --- a/chain/actors/builtin/init/v0.go +++ b/chain/actors/builtin/init/v0.go @@ -25,6 +25,19 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store, networkName string) (State, error) { + out := state0{store: store} + + mr, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *init0.ConstructState(mr, networkName) + + return &out, nil +} + type state0 struct { init0.State store adt.Store @@ -62,6 +75,11 @@ func (s *state0) SetNetworkName(name string) error { return nil } +func (s *state0) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + func (s *state0) Remove(addrs ...address.Address) (err error) { m, err := adt0.AsMap(s.store, s.State.AddressMap) if err != nil { @@ -80,6 +98,15 @@ func (s *state0) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state0) addressMap() (adt.Map, error) { - return adt0.AsMap(s.store, s.AddressMap) +func (s *state0) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state0) AddressMap() (adt.Map, error) { + return adt0.AsMap(s.store, s.State.AddressMap) +} + +func (s *state0) GetState() interface{} { + return &s.State } diff --git a/chain/actors/builtin/init/v2.go b/chain/actors/builtin/init/v2.go index 420243be4..72e2d56a5 100644 --- a/chain/actors/builtin/init/v2.go +++ b/chain/actors/builtin/init/v2.go @@ -25,6 +25,19 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store, networkName string) (State, error) { + out := state2{store: store} + + mr, err := adt2.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *init2.ConstructState(mr, networkName) + + return &out, nil +} + type state2 struct { init2.State store adt.Store @@ -62,6 +75,11 @@ func (s *state2) SetNetworkName(name string) error { return nil } +func (s *state2) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + func (s *state2) Remove(addrs ...address.Address) (err error) { m, err := adt2.AsMap(s.store, s.State.AddressMap) if err != nil { @@ -80,6 +98,15 @@ func (s *state2) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state2) addressMap() (adt.Map, error) { - return adt2.AsMap(s.store, s.AddressMap) +func (s *state2) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state2) AddressMap() (adt.Map, error) { + return adt2.AsMap(s.store, s.State.AddressMap) +} + +func (s *state2) GetState() interface{} { + return &s.State } diff --git a/chain/actors/builtin/init/v3.go b/chain/actors/builtin/init/v3.go index eaa54dfd4..4609c94a3 100644 --- a/chain/actors/builtin/init/v3.go +++ b/chain/actors/builtin/init/v3.go @@ -27,6 +27,19 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store, networkName string) (State, error) { + out := state3{store: store} + + s, err := init3.ConstructState(store, networkName) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state3 struct { init3.State store adt.Store @@ -64,6 +77,11 @@ func (s *state3) SetNetworkName(name string) error { return nil } +func (s *state3) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + func (s *state3) Remove(addrs ...address.Address) (err error) { m, err := adt3.AsMap(s.store, s.State.AddressMap, builtin3.DefaultHamtBitwidth) if err != nil { @@ -82,6 +100,15 @@ func (s *state3) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state3) addressMap() (adt.Map, error) { - return adt3.AsMap(s.store, s.AddressMap, builtin3.DefaultHamtBitwidth) +func (s *state3) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state3) AddressMap() (adt.Map, error) { + return adt3.AsMap(s.store, s.State.AddressMap, builtin3.DefaultHamtBitwidth) +} + +func (s *state3) GetState() interface{} { + return &s.State } diff --git a/chain/actors/builtin/init/v4.go b/chain/actors/builtin/init/v4.go index 38749eed5..dc56d1f19 100644 --- a/chain/actors/builtin/init/v4.go +++ b/chain/actors/builtin/init/v4.go @@ -27,6 +27,19 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store, networkName string) (State, error) { + out := state4{store: store} + + s, err := init4.ConstructState(store, networkName) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state4 struct { init4.State store adt.Store @@ -64,6 +77,11 @@ func (s *state4) SetNetworkName(name string) error { return nil } +func (s *state4) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + func (s *state4) Remove(addrs ...address.Address) (err error) { m, err := adt4.AsMap(s.store, s.State.AddressMap, builtin4.DefaultHamtBitwidth) if err != nil { @@ -82,6 +100,15 @@ func (s *state4) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state4) addressMap() (adt.Map, error) { - return adt4.AsMap(s.store, s.AddressMap, builtin4.DefaultHamtBitwidth) +func (s *state4) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state4) AddressMap() (adt.Map, error) { + return adt4.AsMap(s.store, s.State.AddressMap, builtin4.DefaultHamtBitwidth) +} + +func (s *state4) GetState() interface{} { + return &s.State } diff --git a/chain/actors/builtin/market/actor.go.template b/chain/actors/builtin/market/actor.go.template index 39cfe1be7..5b67695e1 100644 --- a/chain/actors/builtin/market/actor.go.template +++ b/chain/actors/builtin/market/actor.go.template @@ -16,6 +16,7 @@ import ( {{end}} "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" ) @@ -42,6 +43,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.StorageMarketActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler BalancesChanged(State) (bool, error) @@ -56,6 +78,7 @@ type State interface { minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, ) (weight, verifiedWeight abi.DealWeight, err error) NextID() (abi.DealID, error) + GetState() interface{} } type BalanceTable interface { @@ -81,7 +104,6 @@ type DealProposals interface { type PublishStorageDealsParams = market0.PublishStorageDealsParams type PublishStorageDealsReturn = market0.PublishStorageDealsReturn -type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams type WithdrawBalanceParams = market0.WithdrawBalanceParams type ClientDealProposal = market0.ClientDealProposal @@ -89,71 +111,71 @@ type ClientDealProposal = market0.ClientDealProposal type DealState struct { SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated - SlashEpoch abi.ChainEpoch // -1 if deal never slashed + SlashEpoch abi.ChainEpoch // -1 if deal never slashed } type DealProposal struct { - PieceCID cid.Cid - PieceSize abi.PaddedPieceSize - VerifiedDeal bool - Client address.Address - Provider address.Address - Label string - StartEpoch abi.ChainEpoch - EndEpoch abi.ChainEpoch + PieceCID cid.Cid + PieceSize abi.PaddedPieceSize + VerifiedDeal bool + Client address.Address + Provider address.Address + Label string + StartEpoch abi.ChainEpoch + EndEpoch abi.ChainEpoch StoragePricePerEpoch abi.TokenAmount - ProviderCollateral abi.TokenAmount - ClientCollateral abi.TokenAmount + ProviderCollateral abi.TokenAmount + ClientCollateral abi.TokenAmount } type DealStateChanges struct { - Added []DealIDState + Added []DealIDState Modified []DealStateChange - Removed []DealIDState + Removed []DealIDState } type DealIDState struct { - ID abi.DealID + ID abi.DealID Deal DealState } // DealStateChange is a change in deal state from -> to type DealStateChange struct { - ID abi.DealID + ID abi.DealID From *DealState - To *DealState + To *DealState } type DealProposalChanges struct { - Added []ProposalIDState + Added []ProposalIDState Removed []ProposalIDState } type ProposalIDState struct { - ID abi.DealID + ID abi.DealID Proposal DealProposal } func EmptyDealState() *DealState { return &DealState{ SectorStartEpoch: -1, - SlashEpoch: -1, + SlashEpoch: -1, LastUpdatedEpoch: -1, } } // returns the earned fees and pending fees for a given deal func (deal DealProposal) GetDealFees(height abi.ChainEpoch) (abi.TokenAmount, abi.TokenAmount) { - tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch))) + tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch))) - ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch))) - if ef.LessThan(big.Zero()) { - ef = big.Zero() - } + ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch))) + if ef.LessThan(big.Zero()) { + ef = big.Zero() + } - if ef.GreaterThan(tf) { - ef = tf - } + if ef.GreaterThan(tf) { + ef = tf + } - return ef, big.Sub(tf, ef) + return ef, big.Sub(tf, ef) } diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index adf7ce33d..ffc826658 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -20,6 +20,7 @@ import ( builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" @@ -68,6 +69,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.StorageMarketActorCodeID, nil + + case actors.Version2: + return builtin2.StorageMarketActorCodeID, nil + + case actors.Version3: + return builtin3.StorageMarketActorCodeID, nil + + case actors.Version4: + return builtin4.StorageMarketActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler BalancesChanged(State) (bool, error) @@ -82,6 +122,7 @@ type State interface { minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, ) (weight, verifiedWeight abi.DealWeight, err error) NextID() (abi.DealID, error) + GetState() interface{} } type BalanceTable interface { @@ -107,7 +148,6 @@ type DealProposals interface { type PublishStorageDealsParams = market0.PublishStorageDealsParams type PublishStorageDealsReturn = market0.PublishStorageDealsReturn -type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams type WithdrawBalanceParams = market0.WithdrawBalanceParams type ClientDealProposal = market0.ClientDealProposal diff --git a/chain/actors/builtin/market/state.go.template b/chain/actors/builtin/market/state.go.template index a55743ce5..965c8d41f 100644 --- a/chain/actors/builtin/market/state.go.template +++ b/chain/actors/builtin/market/state.go.template @@ -26,6 +26,31 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + {{if (le .v 2)}} + ea, err := adt{{.v}}.MakeEmptyArray(store).Root() + if err != nil { + return nil, err + } + + em, err := adt{{.v}}.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *market{{.v}}.ConstructState(ea, em, em) + {{else}} + s, err := market{{.v}}.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + {{end}} + return &out, nil +} + type state{{.v}} struct { market{{.v}}.State store adt.Store @@ -207,3 +232,7 @@ func (s *dealProposals{{.v}}) array() adt.Array { func fromV{{.v}}DealProposal(v{{.v}} market{{.v}}.DealProposal) DealProposal { return (DealProposal)(v{{.v}}) } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/market/temp b/chain/actors/builtin/market/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/market/v0.go b/chain/actors/builtin/market/v0.go index 175c0a2ea..b3093b54b 100644 --- a/chain/actors/builtin/market/v0.go +++ b/chain/actors/builtin/market/v0.go @@ -26,6 +26,24 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store) (State, error) { + out := state0{store: store} + + ea, err := adt0.MakeEmptyArray(store).Root() + if err != nil { + return nil, err + } + + em, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *market0.ConstructState(ea, em, em) + + return &out, nil +} + type state0 struct { market0.State store adt.Store @@ -207,3 +225,7 @@ func (s *dealProposals0) array() adt.Array { func fromV0DealProposal(v0 market0.DealProposal) DealProposal { return (DealProposal)(v0) } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/market/v2.go b/chain/actors/builtin/market/v2.go index dafae8feb..fdedcce85 100644 --- a/chain/actors/builtin/market/v2.go +++ b/chain/actors/builtin/market/v2.go @@ -26,6 +26,24 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store) (State, error) { + out := state2{store: store} + + ea, err := adt2.MakeEmptyArray(store).Root() + if err != nil { + return nil, err + } + + em, err := adt2.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *market2.ConstructState(ea, em, em) + + return &out, nil +} + type state2 struct { market2.State store adt.Store @@ -207,3 +225,7 @@ func (s *dealProposals2) array() adt.Array { func fromV2DealProposal(v2 market2.DealProposal) DealProposal { return (DealProposal)(v2) } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/market/v3.go b/chain/actors/builtin/market/v3.go index dec8d6e25..53d266443 100644 --- a/chain/actors/builtin/market/v3.go +++ b/chain/actors/builtin/market/v3.go @@ -26,6 +26,19 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store) (State, error) { + out := state3{store: store} + + s, err := market3.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state3 struct { market3.State store adt.Store @@ -207,3 +220,7 @@ func (s *dealProposals3) array() adt.Array { func fromV3DealProposal(v3 market3.DealProposal) DealProposal { return (DealProposal)(v3) } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/market/v4.go b/chain/actors/builtin/market/v4.go index 22514395c..30aa26920 100644 --- a/chain/actors/builtin/market/v4.go +++ b/chain/actors/builtin/market/v4.go @@ -26,6 +26,19 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store) (State, error) { + out := state4{store: store} + + s, err := market4.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state4 struct { market4.State store adt.Store @@ -207,3 +220,7 @@ func (s *dealProposals4) array() adt.Array { func fromV4DealProposal(v4 market4.DealProposal) DealProposal { return (DealProposal)(v4) } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/miner/actor.go.template b/chain/actors/builtin/miner/actor.go.template index 4b3d8db5e..c7755ef71 100644 --- a/chain/actors/builtin/miner/actor.go.template +++ b/chain/actors/builtin/miner/actor.go.template @@ -3,6 +3,7 @@ package miner import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" cbg "github.com/whyrusleeping/cbor-gen" @@ -60,6 +61,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.StorageMinerActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -79,6 +101,11 @@ type State interface { NumLiveSectors() (uint64, error) IsAllocated(abi.SectorNumber) (bool, error) + // Note that ProvingPeriodStart is deprecated and will be renamed / removed in a future version of actors + GetProvingPeriodStart() (abi.ChainEpoch, error) + // Testing only + EraseAllUnproven() error + LoadDeadline(idx uint64) (Deadline, error) ForEachDeadline(cb func(idx uint64, dl Deadline) error) error NumDeadlines() (uint64, error) @@ -95,6 +122,7 @@ type State interface { decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error) precommits() (adt.Map, error) decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error) + GetState() interface{} } type Deadline interface { @@ -115,26 +143,26 @@ type Partition interface { } type SectorOnChainInfo struct { - SectorNumber abi.SectorNumber - SealProof abi.RegisteredSealProof - SealedCID cid.Cid - DealIDs []abi.DealID - Activation abi.ChainEpoch - Expiration abi.ChainEpoch - DealWeight abi.DealWeight - VerifiedDealWeight abi.DealWeight - InitialPledge abi.TokenAmount - ExpectedDayReward abi.TokenAmount + SectorNumber abi.SectorNumber + SealProof abi.RegisteredSealProof + SealedCID cid.Cid + DealIDs []abi.DealID + Activation abi.ChainEpoch + Expiration abi.ChainEpoch + DealWeight abi.DealWeight + VerifiedDealWeight abi.DealWeight + InitialPledge abi.TokenAmount + ExpectedDayReward abi.TokenAmount ExpectedStoragePledge abi.TokenAmount } type SectorPreCommitInfo = miner0.SectorPreCommitInfo type SectorPreCommitOnChainInfo struct { - Info SectorPreCommitInfo + Info SectorPreCommitInfo PreCommitDeposit abi.TokenAmount - PreCommitEpoch abi.ChainEpoch - DealWeight abi.DealWeight + PreCommitEpoch abi.ChainEpoch + DealWeight abi.DealWeight VerifiedDealWeight abi.DealWeight } @@ -203,17 +231,17 @@ func WinningPoStProofTypeFromWindowPoStProofType(nver network.Version, proof abi } type MinerInfo struct { - Owner address.Address // Must be an ID-address. - Worker address.Address // Must be an ID-address. - NewWorker address.Address // Must be an ID-address. - ControlAddresses []address.Address // Must be an ID-addresses. - WorkerChangeEpoch abi.ChainEpoch - PeerId *peer.ID - Multiaddrs []abi.Multiaddrs - WindowPoStProofType abi.RegisteredPoStProof - SectorSize abi.SectorSize + Owner address.Address // Must be an ID-address. + Worker address.Address // Must be an ID-address. + NewWorker address.Address // Must be an ID-address. + ControlAddresses []address.Address // Must be an ID-addresses. + WorkerChangeEpoch abi.ChainEpoch + PeerId *peer.ID + Multiaddrs []abi.Multiaddrs + WindowPoStProofType abi.RegisteredPoStProof + SectorSize abi.SectorSize WindowPoStPartitionSectors uint64 - ConsensusFaultElapsed abi.ChainEpoch + ConsensusFaultElapsed abi.ChainEpoch } func (mi MinerInfo) IsController(addr address.Address) bool { @@ -244,25 +272,25 @@ type SectorLocation struct { } type SectorChanges struct { - Added []SectorOnChainInfo + Added []SectorOnChainInfo Extended []SectorExtensions - Removed []SectorOnChainInfo + Removed []SectorOnChainInfo } type SectorExtensions struct { From SectorOnChainInfo - To SectorOnChainInfo + To SectorOnChainInfo } type PreCommitChanges struct { - Added []SectorPreCommitOnChainInfo + Added []SectorPreCommitOnChainInfo Removed []SectorPreCommitOnChainInfo } type LockedFunds struct { - VestingFunds abi.TokenAmount + VestingFunds abi.TokenAmount InitialPledgeRequirement abi.TokenAmount - PreCommitDeposits abi.TokenAmount + PreCommitDeposits abi.TokenAmount } func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount { diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index a426e063b..d9b872e3f 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -3,6 +3,7 @@ package miner import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" cbg "github.com/whyrusleeping/cbor-gen" @@ -86,6 +87,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.StorageMinerActorCodeID, nil + + case actors.Version2: + return builtin2.StorageMinerActorCodeID, nil + + case actors.Version3: + return builtin3.StorageMinerActorCodeID, nil + + case actors.Version4: + return builtin4.StorageMinerActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -105,6 +145,11 @@ type State interface { NumLiveSectors() (uint64, error) IsAllocated(abi.SectorNumber) (bool, error) + // Note that ProvingPeriodStart is deprecated and will be renamed / removed in a future version of actors + GetProvingPeriodStart() (abi.ChainEpoch, error) + // Testing only + EraseAllUnproven() error + LoadDeadline(idx uint64) (Deadline, error) ForEachDeadline(cb func(idx uint64, dl Deadline) error) error NumDeadlines() (uint64, error) @@ -121,6 +166,7 @@ type State interface { decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error) precommits() (adt.Map, error) decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error) + GetState() interface{} } type Deadline interface { diff --git a/chain/actors/builtin/miner/state.go.template b/chain/actors/builtin/miner/state.go.template index 0769eea10..270510a8c 100644 --- a/chain/actors/builtin/miner/state.go.template +++ b/chain/actors/builtin/miner/state.go.template @@ -35,6 +35,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + out.State = miner{{.v}}.State{} + return &out, nil +} + type state{{.v}} struct { miner{{.v}}.State store adt.Store @@ -68,9 +74,9 @@ func (s *state{{.v}}) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) func (s *state{{.v}}) LockedFunds() (LockedFunds, error) { return LockedFunds{ - VestingFunds: s.State.LockedFunds, + VestingFunds: s.State.LockedFunds, InitialPledgeRequirement: s.State.InitialPledge{{if (le .v 1)}}Requirement{{end}}, - PreCommitDeposits: s.State.PreCommitDeposits, + PreCommitDeposits: s.State.PreCommitDeposits, }, nil } @@ -245,6 +251,10 @@ func (s *state{{.v}}) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } +func (s *state{{.v}}) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + func (s *state{{.v}}) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -307,19 +317,19 @@ func (s *state{{.v}}) Info() (MinerInfo, error) { } {{end}} mi := MinerInfo{ - Owner: info.Owner, - Worker: info.Worker, + Owner: info.Owner, + Worker: info.Worker, ControlAddresses: info.ControlAddresses, - NewWorker: address.Undef, + NewWorker: address.Undef, WorkerChangeEpoch: -1, - PeerId: pid, - Multiaddrs: info.Multiaddrs, - WindowPoStProofType: {{if (ge .v 3)}}info.WindowPoStProofType{{else}}wpp{{end}}, - SectorSize: info.SectorSize, + PeerId: pid, + Multiaddrs: info.Multiaddrs, + WindowPoStProofType: {{if (ge .v 3)}}info.WindowPoStProofType{{else}}wpp{{end}}, + SectorSize: info.SectorSize, WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, - ConsensusFaultElapsed: {{if (ge .v 2)}}info.ConsensusFaultElapsed{{else}}-1{{end}}, + ConsensusFaultElapsed: {{if (ge .v 2)}}info.ConsensusFaultElapsed{{else}}-1{{end}}, } if info.PendingWorkerKey != nil { @@ -366,6 +376,45 @@ func (s *state{{.v}}) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (Secto return fromV{{.v}}SectorPreCommitOnChainInfo(sp), nil } +func (s *state{{.v}}) EraseAllUnproven() error { + {{if (ge .v 2)}} + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner{{.v}}.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner{{.v}}.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + + return s.State.SaveDeadlines(s.store, dls) + {{else}} + // field doesn't exist until v2 + {{end}} + return nil +} + func (d *deadline{{.v}}) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -428,16 +477,16 @@ func (p *partition{{.v}}) RecoveringSectors() (bitfield.BitField, error) { func fromV{{.v}}SectorOnChainInfo(v{{.v}} miner{{.v}}.SectorOnChainInfo) SectorOnChainInfo { {{if (ge .v 2)}} return SectorOnChainInfo{ - SectorNumber: v{{.v}}.SectorNumber, - SealProof: v{{.v}}.SealProof, - SealedCID: v{{.v}}.SealedCID, - DealIDs: v{{.v}}.DealIDs, - Activation: v{{.v}}.Activation, - Expiration: v{{.v}}.Expiration, - DealWeight: v{{.v}}.DealWeight, - VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, - InitialPledge: v{{.v}}.InitialPledge, - ExpectedDayReward: v{{.v}}.ExpectedDayReward, + SectorNumber: v{{.v}}.SectorNumber, + SealProof: v{{.v}}.SealProof, + SealedCID: v{{.v}}.SealedCID, + DealIDs: v{{.v}}.DealIDs, + Activation: v{{.v}}.Activation, + Expiration: v{{.v}}.Expiration, + DealWeight: v{{.v}}.DealWeight, + VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, + InitialPledge: v{{.v}}.InitialPledge, + ExpectedDayReward: v{{.v}}.ExpectedDayReward, ExpectedStoragePledge: v{{.v}}.ExpectedStoragePledge, } {{else}} @@ -448,13 +497,17 @@ func fromV{{.v}}SectorOnChainInfo(v{{.v}} miner{{.v}}.SectorOnChainInfo) SectorO func fromV{{.v}}SectorPreCommitOnChainInfo(v{{.v}} miner{{.v}}.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { {{if (ge .v 2)}} return SectorPreCommitOnChainInfo{ - Info: (SectorPreCommitInfo)(v{{.v}}.Info), - PreCommitDeposit: v{{.v}}.PreCommitDeposit, - PreCommitEpoch: v{{.v}}.PreCommitEpoch, - DealWeight: v{{.v}}.DealWeight, + Info: (SectorPreCommitInfo)(v{{.v}}.Info), + PreCommitDeposit: v{{.v}}.PreCommitDeposit, + PreCommitEpoch: v{{.v}}.PreCommitEpoch, + DealWeight: v{{.v}}.DealWeight, VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, } {{else}} return (SectorPreCommitOnChainInfo)(v0) {{end}} } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/miner/temp b/chain/actors/builtin/miner/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/miner/v0.go b/chain/actors/builtin/miner/v0.go index 2dc8ae23e..344be1993 100644 --- a/chain/actors/builtin/miner/v0.go +++ b/chain/actors/builtin/miner/v0.go @@ -32,6 +32,12 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store) (State, error) { + out := state0{store: store} + out.State = miner0.State{} + return &out, nil +} + type state0 struct { miner0.State store adt.Store @@ -242,6 +248,10 @@ func (s *state0) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } +func (s *state0) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + func (s *state0) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -363,6 +373,13 @@ func (s *state0) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV0SectorPreCommitOnChainInfo(sp), nil } +func (s *state0) EraseAllUnproven() error { + + // field doesn't exist until v2 + + return nil +} + func (d *deadline0) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -426,3 +443,7 @@ func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) Sect return (SectorPreCommitOnChainInfo)(v0) } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/miner/v2.go b/chain/actors/builtin/miner/v2.go index 7564dd8b8..3e76d0b69 100644 --- a/chain/actors/builtin/miner/v2.go +++ b/chain/actors/builtin/miner/v2.go @@ -30,6 +30,12 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store) (State, error) { + out := state2{store: store} + out.State = miner2.State{} + return &out, nil +} + type state2 struct { miner2.State store adt.Store @@ -240,6 +246,10 @@ func (s *state2) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } +func (s *state2) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + func (s *state2) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -361,6 +371,43 @@ func (s *state2) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV2SectorPreCommitOnChainInfo(sp), nil } +func (s *state2) EraseAllUnproven() error { + + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner2.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner2.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + + return s.State.SaveDeadlines(s.store, dls) + + return nil +} + func (d *deadline2) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -442,3 +489,7 @@ func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) Sect } } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/miner/v3.go b/chain/actors/builtin/miner/v3.go index 72a080f73..72986233d 100644 --- a/chain/actors/builtin/miner/v3.go +++ b/chain/actors/builtin/miner/v3.go @@ -32,6 +32,12 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store) (State, error) { + out := state3{store: store} + out.State = miner3.State{} + return &out, nil +} + type state3 struct { miner3.State store adt.Store @@ -242,6 +248,10 @@ func (s *state3) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } +func (s *state3) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + func (s *state3) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -358,6 +368,43 @@ func (s *state3) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV3SectorPreCommitOnChainInfo(sp), nil } +func (s *state3) EraseAllUnproven() error { + + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner3.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner3.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + + return s.State.SaveDeadlines(s.store, dls) + + return nil +} + func (d *deadline3) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -443,3 +490,7 @@ func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) Sect } } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/miner/v4.go b/chain/actors/builtin/miner/v4.go index 698bdf2f5..96ed21f04 100644 --- a/chain/actors/builtin/miner/v4.go +++ b/chain/actors/builtin/miner/v4.go @@ -32,6 +32,12 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store) (State, error) { + out := state4{store: store} + out.State = miner4.State{} + return &out, nil +} + type state4 struct { miner4.State store adt.Store @@ -242,6 +248,10 @@ func (s *state4) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } +func (s *state4) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + func (s *state4) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -358,6 +368,43 @@ func (s *state4) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV4SectorPreCommitOnChainInfo(sp), nil } +func (s *state4) EraseAllUnproven() error { + + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner4.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner4.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + + return s.State.SaveDeadlines(s.store, dls) + + return nil +} + func (d *deadline4) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -443,3 +490,7 @@ func fromV4SectorPreCommitOnChainInfo(v4 miner4.SectorPreCommitOnChainInfo) Sect } } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/multisig/actor.go.template b/chain/actors/builtin/multisig/actor.go.template index 19d99dcb7..3af270c60 100644 --- a/chain/actors/builtin/multisig/actor.go.template +++ b/chain/actors/builtin/multisig/actor.go.template @@ -40,6 +40,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store, signers, threshold, startEpoch, unlockDuration, initialBalance) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.MultisigActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -55,6 +76,7 @@ type State interface { transactions() (adt.Map, error) decodeTransaction(val *cbg.Deferred) (Transaction, error) + GetState() interface{} } type Transaction = msig{{.latestVersion}}.Transaction @@ -66,7 +88,7 @@ func Message(version actors.Version, from address.Address) MessageBuilder { {{range .versions}} case actors.Version{{.}}: return message{{.}}{{"{"}}{{if (ge . 2)}}message0{from}{{else}}from{{end}}} -{{end}} default: +{{end}} default: panic(fmt.Sprintf("unsupported actors version: %d", version)) } } diff --git a/chain/actors/builtin/multisig/message.go.template b/chain/actors/builtin/multisig/message.go.template index 6bff8983a..917e6944b 100644 --- a/chain/actors/builtin/multisig/message.go.template +++ b/chain/actors/builtin/multisig/message.go.template @@ -43,10 +43,10 @@ func (m message{{.v}}) Create( {{end}} // Set up constructor parameters for multisig msigParams := &multisig{{.v}}.ConstructorParams{ - Signers: signers, + Signers: signers, NumApprovalsThreshold: threshold, - UnlockDuration: unlockDuration,{{if (ge .v 2)}} - StartEpoch: unlockStart,{{end}} + UnlockDuration: unlockDuration,{{if (ge .v 2)}} + StartEpoch: unlockStart,{{end}} } enc, actErr := actors.SerializeParams(msigParams) @@ -56,7 +56,7 @@ func (m message{{.v}}) Create( // new actors are created by invoking 'exec' on the init actor with the constructor params execParams := &init{{.v}}.ExecParams{ - CodeCID: builtin{{.v}}.MultisigActorCodeID, + CodeCID: builtin{{.v}}.MultisigActorCodeID, ConstructorParams: enc, } @@ -66,11 +66,11 @@ func (m message{{.v}}) Create( } return &types.Message{ - To: init_.Address, - From: m.from, + To: init_.Address, + From: m.from, Method: builtin{{.v}}.MethodsInit.Exec, Params: enc, - Value: initialAmount, + Value: initialAmount, }, nil } @@ -96,8 +96,8 @@ func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount, } enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{ - To: to, - Value: amt, + To: to, + Value: amt, Method: method, Params: params, }) @@ -106,9 +106,9 @@ func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount, } return &types.Message{ - To: msig, - From: m.from, - Value: abi.NewTokenAmount(0), + To: msig, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin0.MethodsMultisig.Propose, Params: enc, }, nil @@ -121,9 +121,9 @@ func (m message0) Approve(msig address.Address, txID uint64, hashData *ProposalH } return &types.Message{ - To: msig, - From: m.from, - Value: types.NewInt(0), + To: msig, + From: m.from, + Value: types.NewInt(0), Method: builtin0.MethodsMultisig.Approve, Params: enc, }, nil @@ -136,9 +136,9 @@ func (m message0) Cancel(msig address.Address, txID uint64, hashData *ProposalHa } return &types.Message{ - To: msig, - From: m.from, - Value: types.NewInt(0), + To: msig, + From: m.from, + Value: types.NewInt(0), Method: builtin0.MethodsMultisig.Cancel, Params: enc, }, nil diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go index d8f6fabae..fd773f398 100644 --- a/chain/actors/builtin/multisig/multisig.go +++ b/chain/actors/builtin/multisig/multisig.go @@ -66,6 +66,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + switch av { + + case actors.Version0: + return make0(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + + case actors.Version2: + return make2(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + + case actors.Version3: + return make3(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + + case actors.Version4: + return make4(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.MultisigActorCodeID, nil + + case actors.Version2: + return builtin2.MultisigActorCodeID, nil + + case actors.Version3: + return builtin3.MultisigActorCodeID, nil + + case actors.Version4: + return builtin4.MultisigActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -81,6 +120,7 @@ type State interface { transactions() (adt.Map, error) decodeTransaction(val *cbg.Deferred) (Transaction, error) + GetState() interface{} } type Transaction = msig4.Transaction diff --git a/chain/actors/builtin/multisig/state.go.template b/chain/actors/builtin/multisig/state.go.template index 2316aadba..067415533 100644 --- a/chain/actors/builtin/multisig/state.go.template +++ b/chain/actors/builtin/multisig/state.go.template @@ -31,6 +31,32 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state{{.v}}{store: store} + out.State = msig{{.v}}.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + {{if (le .v 2)}} + em, err := adt{{.v}}.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + {{else}} + em, err := adt{{.v}}.StoreEmptyMap(store, builtin{{.v}}.DefaultHamtBitwidth) + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + {{end}} + return &out, nil +} + type state{{.v}} struct { msig{{.v}}.State store adt.Store @@ -95,3 +121,7 @@ func (s *state{{.v}}) decodeTransaction(val *cbg.Deferred) (Transaction, error) } return tx, nil } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/multisig/temp b/chain/actors/builtin/multisig/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/multisig/v0.go b/chain/actors/builtin/multisig/v0.go index 20c1557b0..973ac9209 100644 --- a/chain/actors/builtin/multisig/v0.go +++ b/chain/actors/builtin/multisig/v0.go @@ -28,6 +28,25 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state0{store: store} + out.State = msig0.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + type state0 struct { msig0.State store adt.Store @@ -92,3 +111,7 @@ func (s *state0) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/multisig/v2.go b/chain/actors/builtin/multisig/v2.go index ef317f903..5b830e695 100644 --- a/chain/actors/builtin/multisig/v2.go +++ b/chain/actors/builtin/multisig/v2.go @@ -28,6 +28,25 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state2{store: store} + out.State = msig2.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt2.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + type state2 struct { msig2.State store adt.Store @@ -92,3 +111,7 @@ func (s *state2) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/multisig/v3.go b/chain/actors/builtin/multisig/v3.go index 8834e4553..c4a2791b7 100644 --- a/chain/actors/builtin/multisig/v3.go +++ b/chain/actors/builtin/multisig/v3.go @@ -30,6 +30,25 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state3{store: store} + out.State = msig3.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt3.StoreEmptyMap(store, builtin3.DefaultHamtBitwidth) + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + type state3 struct { msig3.State store adt.Store @@ -94,3 +113,7 @@ func (s *state3) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/multisig/v4.go b/chain/actors/builtin/multisig/v4.go index 9f9dc7573..a35a890f8 100644 --- a/chain/actors/builtin/multisig/v4.go +++ b/chain/actors/builtin/multisig/v4.go @@ -30,6 +30,25 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state4{store: store} + out.State = msig4.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt4.StoreEmptyMap(store, builtin4.DefaultHamtBitwidth) + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + type state4 struct { msig4.State store adt.Store @@ -94,3 +113,7 @@ func (s *state4) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/paych/actor.go.template b/chain/actors/builtin/paych/actor.go.template index 3f68a5cfa..7699e76b6 100644 --- a/chain/actors/builtin/paych/actor.go.template +++ b/chain/actors/builtin/paych/actor.go.template @@ -42,6 +42,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.PaymentChannelActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + // State is an abstract version of payment channel state that works across // versions type State interface { @@ -62,6 +83,8 @@ type State interface { // Iterate lane states ForEachLaneState(cb func(idx uint64, dl LaneState) error) error + + GetState() interface{} } // LaneState is an abstract copy of the state of a single lane diff --git a/chain/actors/builtin/paych/message.go.template b/chain/actors/builtin/paych/message.go.template index 4a5ea2331..cb111d910 100644 --- a/chain/actors/builtin/paych/message.go.template +++ b/chain/actors/builtin/paych/message.go.template @@ -21,7 +21,7 @@ func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) return nil, aerr } enc, aerr := actors.SerializeParams(&init{{.v}}.ExecParams{ - CodeCID: builtin{{.v}}.PaymentChannelActorCodeID, + CodeCID: builtin{{.v}}.PaymentChannelActorCodeID, ConstructorParams: params, }) if aerr != nil { @@ -29,9 +29,9 @@ func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) } return &types.Message{ - To: init_.Address, - From: m.from, - Value: initialAmount, + To: init_.Address, + From: m.from, + Value: initialAmount, Method: builtin{{.v}}.MethodsInit.Exec, Params: enc, }, nil @@ -39,7 +39,7 @@ func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { params, aerr := actors.SerializeParams(&paych{{.v}}.UpdateChannelStateParams{ - Sv: *sv, + Sv: *sv, Secret: secret, }) if aerr != nil { @@ -47,9 +47,9 @@ func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret [ } return &types.Message{ - To: paych, - From: m.from, - Value: abi.NewTokenAmount(0), + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin{{.v}}.MethodsPaych.UpdateChannelState, Params: params, }, nil @@ -57,18 +57,18 @@ func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret [ func (m message{{.v}}) Settle(paych address.Address) (*types.Message, error) { return &types.Message{ - To: paych, - From: m.from, - Value: abi.NewTokenAmount(0), + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin{{.v}}.MethodsPaych.Settle, }, nil } func (m message{{.v}}) Collect(paych address.Address) (*types.Message, error) { return &types.Message{ - To: paych, - From: m.from, - Value: abi.NewTokenAmount(0), + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin{{.v}}.MethodsPaych.Collect, }, nil } diff --git a/chain/actors/builtin/paych/mock/mock.go b/chain/actors/builtin/paych/mock/mock.go index 3b82511ff..1ecfa1130 100644 --- a/chain/actors/builtin/paych/mock/mock.go +++ b/chain/actors/builtin/paych/mock/mock.go @@ -17,6 +17,10 @@ type mockState struct { lanes map[uint64]paych.LaneState } +func (ms *mockState) GetState() interface{} { + panic("implement me") +} + type mockLaneState struct { redeemed big.Int nonce uint64 diff --git a/chain/actors/builtin/paych/mock/temp b/chain/actors/builtin/paych/mock/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go index 30e4408d8..63638cda1 100644 --- a/chain/actors/builtin/paych/paych.go +++ b/chain/actors/builtin/paych/paych.go @@ -68,6 +68,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.PaymentChannelActorCodeID, nil + + case actors.Version2: + return builtin2.PaymentChannelActorCodeID, nil + + case actors.Version3: + return builtin3.PaymentChannelActorCodeID, nil + + case actors.Version4: + return builtin4.PaymentChannelActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + // State is an abstract version of payment channel state that works across // versions type State interface { @@ -88,6 +127,8 @@ type State interface { // Iterate lane states ForEachLaneState(cb func(idx uint64, dl LaneState) error) error + + GetState() interface{} } // LaneState is an abstract copy of the state of a single lane diff --git a/chain/actors/builtin/paych/state.go.template b/chain/actors/builtin/paych/state.go.template index b4b575a3e..3e41f5be5 100644 --- a/chain/actors/builtin/paych/state.go.template +++ b/chain/actors/builtin/paych/state.go.template @@ -24,6 +24,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + out.State = paych{{.v}}.State{} + return &out, nil +} + type state{{.v}} struct { paych{{.v}}.State store adt.Store @@ -74,6 +80,10 @@ func (s *state{{.v}}) LaneCount() (uint64, error) { return lsamt.Length(), nil } +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} + // Iterate lane states func (s *state{{.v}}) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/temp b/chain/actors/builtin/paych/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/paych/v0.go b/chain/actors/builtin/paych/v0.go index 8e0e3434e..e9bc30e3d 100644 --- a/chain/actors/builtin/paych/v0.go +++ b/chain/actors/builtin/paych/v0.go @@ -24,6 +24,12 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store) (State, error) { + out := state0{store: store} + out.State = paych0.State{} + return &out, nil +} + type state0 struct { paych0.State store adt.Store @@ -74,6 +80,10 @@ func (s *state0) LaneCount() (uint64, error) { return lsamt.Length(), nil } +func (s *state0) GetState() interface{} { + return &s.State +} + // Iterate lane states func (s *state0) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/v2.go b/chain/actors/builtin/paych/v2.go index fbf4b9fde..400305e2f 100644 --- a/chain/actors/builtin/paych/v2.go +++ b/chain/actors/builtin/paych/v2.go @@ -24,6 +24,12 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store) (State, error) { + out := state2{store: store} + out.State = paych2.State{} + return &out, nil +} + type state2 struct { paych2.State store adt.Store @@ -74,6 +80,10 @@ func (s *state2) LaneCount() (uint64, error) { return lsamt.Length(), nil } +func (s *state2) GetState() interface{} { + return &s.State +} + // Iterate lane states func (s *state2) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/v3.go b/chain/actors/builtin/paych/v3.go index 14bb4cb61..1d7c2f94b 100644 --- a/chain/actors/builtin/paych/v3.go +++ b/chain/actors/builtin/paych/v3.go @@ -24,6 +24,12 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store) (State, error) { + out := state3{store: store} + out.State = paych3.State{} + return &out, nil +} + type state3 struct { paych3.State store adt.Store @@ -74,6 +80,10 @@ func (s *state3) LaneCount() (uint64, error) { return lsamt.Length(), nil } +func (s *state3) GetState() interface{} { + return &s.State +} + // Iterate lane states func (s *state3) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/v4.go b/chain/actors/builtin/paych/v4.go index cf37eea5c..b7d1e52a5 100644 --- a/chain/actors/builtin/paych/v4.go +++ b/chain/actors/builtin/paych/v4.go @@ -24,6 +24,12 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store) (State, error) { + out := state4{store: store} + out.State = paych4.State{} + return &out, nil +} + type state4 struct { paych4.State store adt.Store @@ -74,6 +80,10 @@ func (s *state4) LaneCount() (uint64, error) { return lsamt.Length(), nil } +func (s *state4) GetState() interface{} { + return &s.State +} + // Iterate lane states func (s *state4) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/power/actor.go.template b/chain/actors/builtin/power/actor.go.template index 82f791e58..7ff3d0387 100644 --- a/chain/actors/builtin/power/actor.go.template +++ b/chain/actors/builtin/power/actor.go.template @@ -3,6 +3,7 @@ package power import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -40,6 +41,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.StoragePowerActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -47,6 +69,7 @@ type State interface { TotalPower() (Claim, error) TotalCommitted() (Claim, error) TotalPowerSmoothed() (builtin.FilterEstimate, error) + GetState() interface{} // MinerCounts returns the number of miners. Participating is the number // with power above the minimum miner threshold. @@ -57,6 +80,12 @@ type State interface { ForEachClaim(func(miner address.Address, claim Claim) error) error ClaimsChanged(State) (bool, error) + // Testing or genesis setup only + SetTotalQualityAdjPower(abi.StoragePower) error + SetTotalRawBytePower(abi.StoragePower) error + SetThisEpochQualityAdjPower(abi.StoragePower) error + SetThisEpochRawBytePower(abi.StoragePower) error + // Diff helpers. Used by Diff* functions internally. claims() (adt.Map, error) decodeClaim(*cbg.Deferred) (Claim, error) @@ -72,7 +101,7 @@ type Claim struct { func AddClaims(a Claim, b Claim) Claim { return Claim{ - RawBytePower: big.Add(a.RawBytePower, b.RawBytePower), + RawBytePower: big.Add(a.RawBytePower, b.RawBytePower), QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower), } } diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index bf530a21a..69ed6cf89 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -3,6 +3,7 @@ package power import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -66,6 +67,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.StoragePowerActorCodeID, nil + + case actors.Version2: + return builtin2.StoragePowerActorCodeID, nil + + case actors.Version3: + return builtin3.StoragePowerActorCodeID, nil + + case actors.Version4: + return builtin4.StoragePowerActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -73,6 +113,7 @@ type State interface { TotalPower() (Claim, error) TotalCommitted() (Claim, error) TotalPowerSmoothed() (builtin.FilterEstimate, error) + GetState() interface{} // MinerCounts returns the number of miners. Participating is the number // with power above the minimum miner threshold. @@ -83,6 +124,12 @@ type State interface { ForEachClaim(func(miner address.Address, claim Claim) error) error ClaimsChanged(State) (bool, error) + // Testing or genesis setup only + SetTotalQualityAdjPower(abi.StoragePower) error + SetTotalRawBytePower(abi.StoragePower) error + SetThisEpochQualityAdjPower(abi.StoragePower) error + SetThisEpochRawBytePower(abi.StoragePower) error + // Diff helpers. Used by Diff* functions internally. claims() (adt.Map, error) decodeClaim(*cbg.Deferred) (Claim, error) diff --git a/chain/actors/builtin/power/state.go.template b/chain/actors/builtin/power/state.go.template index 4cb904a1d..d0abba3fa 100644 --- a/chain/actors/builtin/power/state.go.template +++ b/chain/actors/builtin/power/state.go.template @@ -29,6 +29,32 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + {{if (le .v 2)}} + em, err := adt{{.v}}.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + emm, err := adt{{.v}}.MakeEmptyMultimap(store).Root() + if err != nil { + return nil, err + } + + out.State = *power{{.v}}.ConstructState(em, emm) + {{else}} + s, err := power{{.v}}.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + {{end}} + + return &out, nil +} + type state{{.v}} struct { power{{.v}}.State store adt.Store @@ -40,7 +66,7 @@ func (s *state{{.v}}) TotalLocked() (abi.TokenAmount, error) { func (s *state{{.v}}) TotalPower() (Claim, error) { return Claim{ - RawBytePower: s.TotalRawBytePower, + RawBytePower: s.TotalRawBytePower, QualityAdjPower: s.TotalQualityAdjPower, }, nil } @@ -48,7 +74,7 @@ func (s *state{{.v}}) TotalPower() (Claim, error) { // Committed power to the network. Includes miners below the minimum threshold. func (s *state{{.v}}) TotalCommitted() (Claim, error) { return Claim{ - RawBytePower: s.TotalBytesCommitted, + RawBytePower: s.TotalBytesCommitted, QualityAdjPower: s.TotalQABytesCommitted, }, nil } @@ -64,7 +90,7 @@ func (s *state{{.v}}) MinerPower(addr address.Address) (Claim, bool, error) { return Claim{}, false, err } return Claim{ - RawBytePower: claim.RawBytePower, + RawBytePower: claim.RawBytePower, QualityAdjPower: claim.QualityAdjPower, }, ok, nil } @@ -116,7 +142,7 @@ func (s *state{{.v}}) ForEachClaim(cb func(miner address.Address, claim Claim) e return err } return cb(a, Claim{ - RawBytePower: claim.RawBytePower, + RawBytePower: claim.RawBytePower, QualityAdjPower: claim.QualityAdjPower, }) }) @@ -131,6 +157,30 @@ func (s *state{{.v}}) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other{{.v}}.State.Claims), nil } +func (s *state{{.v}}) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state{{.v}}) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state{{.v}}) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state{{.v}}) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} + func (s *state{{.v}}) claims() (adt.Map, error) { return adt{{.v}}.AsMap(s.store, s.Claims{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) } @@ -145,7 +195,7 @@ func (s *state{{.v}}) decodeClaim(val *cbg.Deferred) (Claim, error) { func fromV{{.v}}Claim(v{{.v}} power{{.v}}.Claim) Claim { return Claim{ - RawBytePower: v{{.v}}.RawBytePower, + RawBytePower: v{{.v}}.RawBytePower, QualityAdjPower: v{{.v}}.QualityAdjPower, } } diff --git a/chain/actors/builtin/power/temp b/chain/actors/builtin/power/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/power/v0.go b/chain/actors/builtin/power/v0.go index 91fad8c57..465d16c5c 100644 --- a/chain/actors/builtin/power/v0.go +++ b/chain/actors/builtin/power/v0.go @@ -26,6 +26,24 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store) (State, error) { + out := state0{store: store} + + em, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + emm, err := adt0.MakeEmptyMultimap(store).Root() + if err != nil { + return nil, err + } + + out.State = *power0.ConstructState(em, emm) + + return &out, nil +} + type state0 struct { power0.State store adt.Store @@ -128,6 +146,30 @@ func (s *state0) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other0.State.Claims), nil } +func (s *state0) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state0) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state0) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state0) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state0) GetState() interface{} { + return &s.State +} + func (s *state0) claims() (adt.Map, error) { return adt0.AsMap(s.store, s.Claims) } diff --git a/chain/actors/builtin/power/v2.go b/chain/actors/builtin/power/v2.go index 313160a78..606534cef 100644 --- a/chain/actors/builtin/power/v2.go +++ b/chain/actors/builtin/power/v2.go @@ -26,6 +26,24 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store) (State, error) { + out := state2{store: store} + + em, err := adt2.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + emm, err := adt2.MakeEmptyMultimap(store).Root() + if err != nil { + return nil, err + } + + out.State = *power2.ConstructState(em, emm) + + return &out, nil +} + type state2 struct { power2.State store adt.Store @@ -128,6 +146,30 @@ func (s *state2) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other2.State.Claims), nil } +func (s *state2) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state2) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state2) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state2) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state2) GetState() interface{} { + return &s.State +} + func (s *state2) claims() (adt.Map, error) { return adt2.AsMap(s.store, s.Claims) } diff --git a/chain/actors/builtin/power/v3.go b/chain/actors/builtin/power/v3.go index 2ef1e2808..3dec3c63e 100644 --- a/chain/actors/builtin/power/v3.go +++ b/chain/actors/builtin/power/v3.go @@ -28,6 +28,19 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store) (State, error) { + out := state3{store: store} + + s, err := power3.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state3 struct { power3.State store adt.Store @@ -130,6 +143,30 @@ func (s *state3) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other3.State.Claims), nil } +func (s *state3) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state3) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state3) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state3) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state3) GetState() interface{} { + return &s.State +} + func (s *state3) claims() (adt.Map, error) { return adt3.AsMap(s.store, s.Claims, builtin3.DefaultHamtBitwidth) } diff --git a/chain/actors/builtin/power/v4.go b/chain/actors/builtin/power/v4.go index 686550456..b73eedf5a 100644 --- a/chain/actors/builtin/power/v4.go +++ b/chain/actors/builtin/power/v4.go @@ -28,6 +28,19 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store) (State, error) { + out := state4{store: store} + + s, err := power4.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state4 struct { power4.State store adt.Store @@ -130,6 +143,30 @@ func (s *state4) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other4.State.Claims), nil } +func (s *state4) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state4) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state4) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state4) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state4) GetState() interface{} { + return &s.State +} + func (s *state4) claims() (adt.Map, error) { return adt4.AsMap(s.store, s.Claims, builtin4.DefaultHamtBitwidth) } diff --git a/chain/actors/builtin/reward/actor.go.template b/chain/actors/builtin/reward/actor.go.template index 81437d26f..89cdddaec 100644 --- a/chain/actors/builtin/reward/actor.go.template +++ b/chain/actors/builtin/reward/actor.go.template @@ -4,6 +4,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" "github.com/ipfs/go-cid" + "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/cbor" @@ -38,6 +39,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, currRealizedPower abi.StoragePower) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store, currRealizedPower) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.RewardActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -55,6 +77,7 @@ type State interface { InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error) PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error) + GetState() interface{} } type AwardBlockRewardParams = reward0.AwardBlockRewardParams diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index 1037cf741..c325cc7b6 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -2,6 +2,7 @@ package reward import ( "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors" reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -64,6 +65,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, currRealizedPower abi.StoragePower) (State, error) { + switch av { + + case actors.Version0: + return make0(store, currRealizedPower) + + case actors.Version2: + return make2(store, currRealizedPower) + + case actors.Version3: + return make3(store, currRealizedPower) + + case actors.Version4: + return make4(store, currRealizedPower) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.RewardActorCodeID, nil + + case actors.Version2: + return builtin2.RewardActorCodeID, nil + + case actors.Version3: + return builtin3.RewardActorCodeID, nil + + case actors.Version4: + return builtin4.RewardActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -81,6 +121,7 @@ type State interface { InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error) PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error) + GetState() interface{} } type AwardBlockRewardParams = reward0.AwardBlockRewardParams diff --git a/chain/actors/builtin/reward/state.go.template b/chain/actors/builtin/reward/state.go.template index 1758d1413..67bfd5c85 100644 --- a/chain/actors/builtin/reward/state.go.template +++ b/chain/actors/builtin/reward/state.go.template @@ -23,6 +23,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state{{.v}}{store: store} + out.State = *reward{{.v}}.ConstructState(currRealizedPower) + return &out, nil +} + type state{{.v}} struct { reward{{.v}}.State store adt.Store @@ -101,3 +107,7 @@ func (s *state{{.v}}) PreCommitDepositForPower(networkQAPower builtin.FilterEsti }, sectorWeight), nil } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/reward/temp b/chain/actors/builtin/reward/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/reward/v0.go b/chain/actors/builtin/reward/v0.go index fe053cc16..cd098c151 100644 --- a/chain/actors/builtin/reward/v0.go +++ b/chain/actors/builtin/reward/v0.go @@ -23,6 +23,12 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state0{store: store} + out.State = *reward0.ConstructState(currRealizedPower) + return &out, nil +} + type state0 struct { reward0.State store adt.Store @@ -83,3 +89,7 @@ func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/reward/v2.go b/chain/actors/builtin/reward/v2.go index 90621e467..08e9a7bc3 100644 --- a/chain/actors/builtin/reward/v2.go +++ b/chain/actors/builtin/reward/v2.go @@ -23,6 +23,12 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state2{store: store} + out.State = *reward2.ConstructState(currRealizedPower) + return &out, nil +} + type state2 struct { reward2.State store adt.Store @@ -86,3 +92,7 @@ func (s *state2) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/reward/v3.go b/chain/actors/builtin/reward/v3.go index 926cc085b..fd9fa56e2 100644 --- a/chain/actors/builtin/reward/v3.go +++ b/chain/actors/builtin/reward/v3.go @@ -23,6 +23,12 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state3{store: store} + out.State = *reward3.ConstructState(currRealizedPower) + return &out, nil +} + type state3 struct { reward3.State store adt.Store @@ -86,3 +92,7 @@ func (s *state3) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/reward/v4.go b/chain/actors/builtin/reward/v4.go index f034b0018..310ca04e8 100644 --- a/chain/actors/builtin/reward/v4.go +++ b/chain/actors/builtin/reward/v4.go @@ -23,6 +23,12 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state4{store: store} + out.State = *reward4.ConstructState(currRealizedPower) + return &out, nil +} + type state4 struct { reward4.State store adt.Store @@ -86,3 +92,7 @@ func (s *state4) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/system/actor.go.template b/chain/actors/builtin/system/actor.go.template new file mode 100644 index 000000000..925319970 --- /dev/null +++ b/chain/actors/builtin/system/actor.go.template @@ -0,0 +1,41 @@ +package system + +import ( + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" + "golang.org/x/xerrors" + "github.com/ipfs/go-cid" + +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} +) + +var ( + Address = builtin{{.latestVersion}}.SystemActorAddr +) + +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.SystemActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + +type State interface { + GetState() interface{} +} diff --git a/chain/actors/builtin/system/state.go.template b/chain/actors/builtin/system/state.go.template new file mode 100644 index 000000000..fa644f8c7 --- /dev/null +++ b/chain/actors/builtin/system/state.go.template @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/system" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + out.State = system{{.v}}.State{} + return &out, nil +} + +type state{{.v}} struct { + system{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/system/system.go b/chain/actors/builtin/system/system.go new file mode 100644 index 000000000..b4ced850f --- /dev/null +++ b/chain/actors/builtin/system/system.go @@ -0,0 +1,63 @@ +package system + +import ( + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" +) + +var ( + Address = builtin4.SystemActorAddr +) + +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.SystemActorCodeID, nil + + case actors.Version2: + return builtin2.SystemActorCodeID, nil + + case actors.Version3: + return builtin3.SystemActorCodeID, nil + + case actors.Version4: + return builtin4.SystemActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + +type State interface { + GetState() interface{} +} diff --git a/chain/actors/builtin/system/temp b/chain/actors/builtin/system/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/system/v0.go b/chain/actors/builtin/system/v0.go new file mode 100644 index 000000000..64c6f53d3 --- /dev/null +++ b/chain/actors/builtin/system/v0.go @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system0 "github.com/filecoin-project/specs-actors/actors/builtin/system" +) + +var _ State = (*state0)(nil) + +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make0(store adt.Store) (State, error) { + out := state0{store: store} + out.State = system0.State{} + return &out, nil +} + +type state0 struct { + system0.State + store adt.Store +} + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/system/v2.go b/chain/actors/builtin/system/v2.go new file mode 100644 index 000000000..eb540891c --- /dev/null +++ b/chain/actors/builtin/system/v2.go @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/system" +) + +var _ State = (*state2)(nil) + +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make2(store adt.Store) (State, error) { + out := state2{store: store} + out.State = system2.State{} + return &out, nil +} + +type state2 struct { + system2.State + store adt.Store +} + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/system/v3.go b/chain/actors/builtin/system/v3.go new file mode 100644 index 000000000..5b04e189e --- /dev/null +++ b/chain/actors/builtin/system/v3.go @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/system" +) + +var _ State = (*state3)(nil) + +func load3(store adt.Store, root cid.Cid) (State, error) { + out := state3{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make3(store adt.Store) (State, error) { + out := state3{store: store} + out.State = system3.State{} + return &out, nil +} + +type state3 struct { + system3.State + store adt.Store +} + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/system/v4.go b/chain/actors/builtin/system/v4.go new file mode 100644 index 000000000..b6c924978 --- /dev/null +++ b/chain/actors/builtin/system/v4.go @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/system" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make4(store adt.Store) (State, error) { + out := state4{store: store} + out.State = system4.State{} + return &out, nil +} + +type state4 struct { + system4.State + store adt.Store +} + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/temp b/chain/actors/builtin/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/verifreg/actor.go.template b/chain/actors/builtin/verifreg/actor.go.template index 22e809ccf..9ea8e155a 100644 --- a/chain/actors/builtin/verifreg/actor.go.template +++ b/chain/actors/builtin/verifreg/actor.go.template @@ -14,6 +14,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) @@ -40,6 +41,28 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, rootKeyAddress address.Address) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store, rootKeyAddress) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.VerifiedRegistryActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + + type State interface { cbor.Marshaler @@ -48,4 +71,5 @@ type State interface { VerifierDataCap(address.Address) (bool, abi.StoragePower, error) ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error + GetState() interface{} } diff --git a/chain/actors/builtin/verifreg/state.go.template b/chain/actors/builtin/verifreg/state.go.template index 244d20932..96bebe25f 100644 --- a/chain/actors/builtin/verifreg/state.go.template +++ b/chain/actors/builtin/verifreg/state.go.template @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" {{if (ge .v 3)}} builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin" -{{end}} verifreg{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/verifreg" +{{end}} verifreg{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/verifreg" adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt" ) @@ -24,6 +24,26 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state{{.v}}{store: store} + {{if (le .v 2)}} + em, err := adt{{.v}}.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *verifreg{{.v}}.ConstructState(em, rootKeyAddress) + {{else}} + s, err := verifreg{{.v}}.ConstructState(store, rootKeyAddress) + if err != nil { + return nil, err + } + + out.State = *s + {{end}} + return &out, nil +} + type state{{.v}} struct { verifreg{{.v}}.State store adt.Store @@ -56,3 +76,7 @@ func (s *state{{.v}}) verifiedClients() (adt.Map, error) { func (s *state{{.v}}) verifiers() (adt.Map, error) { return adt{{.v}}.AsMap(s.store, s.Verifiers{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/verifreg/temp b/chain/actors/builtin/verifreg/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/verifreg/v0.go b/chain/actors/builtin/verifreg/v0.go index 0dc4696f4..e70b0e3c9 100644 --- a/chain/actors/builtin/verifreg/v0.go +++ b/chain/actors/builtin/verifreg/v0.go @@ -23,6 +23,19 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state0{store: store} + + em, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *verifreg0.ConstructState(em, rootKeyAddress) + + return &out, nil +} + type state0 struct { verifreg0.State store adt.Store @@ -55,3 +68,7 @@ func (s *state0) verifiedClients() (adt.Map, error) { func (s *state0) verifiers() (adt.Map, error) { return adt0.AsMap(s.store, s.Verifiers) } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/verifreg/v2.go b/chain/actors/builtin/verifreg/v2.go index a5ef84532..0bcbe0212 100644 --- a/chain/actors/builtin/verifreg/v2.go +++ b/chain/actors/builtin/verifreg/v2.go @@ -23,6 +23,19 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state2{store: store} + + em, err := adt2.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *verifreg2.ConstructState(em, rootKeyAddress) + + return &out, nil +} + type state2 struct { verifreg2.State store adt.Store @@ -55,3 +68,7 @@ func (s *state2) verifiedClients() (adt.Map, error) { func (s *state2) verifiers() (adt.Map, error) { return adt2.AsMap(s.store, s.Verifiers) } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/verifreg/v3.go b/chain/actors/builtin/verifreg/v3.go index fb0c46d0c..32003ca3a 100644 --- a/chain/actors/builtin/verifreg/v3.go +++ b/chain/actors/builtin/verifreg/v3.go @@ -24,6 +24,19 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state3{store: store} + + s, err := verifreg3.ConstructState(store, rootKeyAddress) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state3 struct { verifreg3.State store adt.Store @@ -56,3 +69,7 @@ func (s *state3) verifiedClients() (adt.Map, error) { func (s *state3) verifiers() (adt.Map, error) { return adt3.AsMap(s.store, s.Verifiers, builtin3.DefaultHamtBitwidth) } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/verifreg/v4.go b/chain/actors/builtin/verifreg/v4.go index 2419ef758..b752e747b 100644 --- a/chain/actors/builtin/verifreg/v4.go +++ b/chain/actors/builtin/verifreg/v4.go @@ -24,6 +24,19 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state4{store: store} + + s, err := verifreg4.ConstructState(store, rootKeyAddress) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state4 struct { verifreg4.State store adt.Store @@ -56,3 +69,7 @@ func (s *state4) verifiedClients() (adt.Map, error) { func (s *state4) verifiers() (adt.Map, error) { return adt4.AsMap(s.store, s.Verifiers, builtin4.DefaultHamtBitwidth) } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index 32f50a4ae..618907554 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -17,6 +17,7 @@ import ( builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" @@ -66,6 +67,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, rootKeyAddress address.Address) (State, error) { + switch av { + + case actors.Version0: + return make0(store, rootKeyAddress) + + case actors.Version2: + return make2(store, rootKeyAddress) + + case actors.Version3: + return make3(store, rootKeyAddress) + + case actors.Version4: + return make4(store, rootKeyAddress) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.VerifiedRegistryActorCodeID, nil + + case actors.Version2: + return builtin2.VerifiedRegistryActorCodeID, nil + + case actors.Version3: + return builtin3.VerifiedRegistryActorCodeID, nil + + case actors.Version4: + return builtin4.VerifiedRegistryActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -74,4 +114,5 @@ type State interface { VerifierDataCap(address.Address) (bool, abi.StoragePower, error) ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error + GetState() interface{} } diff --git a/chain/actors/policy/policy.go.template b/chain/actors/policy/policy.go.template index d395d7132..a1a47852b 100644 --- a/chain/actors/policy/policy.go.template +++ b/chain/actors/policy/policy.go.template @@ -8,20 +8,20 @@ import ( "github.com/filecoin-project/lotus/chain/actors" {{range .versions}} - {{if (ge . 2)}} builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" {{end}} + {{if (ge . 2)}} builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" {{end}} market{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/market" miner{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/miner" verifreg{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/verifreg" {{if (eq . 0)}} power{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/power" {{end}} - {{end}} + {{end}} - paych{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/paych" + paych{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/paych" ) const ( - ChainFinality = miner{{.latestVersion}}.ChainFinality - SealRandomnessLookback = ChainFinality - PaychSettleDelay = paych{{.latestVersion}}.SettleDelay + ChainFinality = miner{{.latestVersion}}.ChainFinality + SealRandomnessLookback = ChainFinality + PaychSettleDelay = paych{{.latestVersion}}.SettleDelay MaxPreCommitRandomnessLookback = builtin{{.latestVersion}}.EpochsInDay + SealRandomnessLookback ) @@ -29,13 +29,13 @@ const ( // This should only be used for testing. func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { {{range .versions}} - {{if (eq . 0)}} - miner{{.}}.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types)) - {{else}} - miner{{.}}.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types)) - miner{{.}}.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2) - miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) - {{end}} + {{if (eq . 0)}} + miner{{.}}.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types)) + {{else}} + miner{{.}}.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + miner{{.}}.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2) + miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + {{end}} {{end}} AddSupportedProofTypes(types...) @@ -51,15 +51,15 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { // Set for all miner versions. {{range .versions}} - {{if (eq . 0)}} - miner{{.}}.SupportedProofTypes[t] = struct{}{} - {{else}} - miner{{.}}.PreCommitSealProofTypesV0[t] = struct{}{} - miner{{.}}.PreCommitSealProofTypesV7[t] = struct{}{} - miner{{.}}.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} - miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} - {{end}} - {{end}} + {{if (eq . 0)}} + miner{{.}}.SupportedProofTypes[t] = struct{}{} + {{else}} + miner{{.}}.PreCommitSealProofTypesV0[t] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV7[t] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + {{end}} + {{end}} } } @@ -67,9 +67,9 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { // actors versions. Use for testing. func SetPreCommitChallengeDelay(delay abi.ChainEpoch) { // Set for all miner versions. - {{range .versions}} - miner{{.}}.PreCommitChallengeDelay = delay - {{end}} + {{range .versions}} + miner{{.}}.PreCommitChallengeDelay = delay + {{end}} } // TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay. @@ -81,42 +81,42 @@ func GetPreCommitChallengeDelay() abi.ChainEpoch { // meet for leader election, across all actor versions. This should only be used // for testing. func SetConsensusMinerMinPower(p abi.StoragePower) { - {{range .versions}} - {{if (eq . 0)}} - power{{.}}.ConsensusMinerMinPower = p - {{else if (eq . 2)}} - for _, policy := range builtin{{.}}.SealProofPolicies { - policy.ConsensusMinerMinPower = p - } - {{else}} - for _, policy := range builtin{{.}}.PoStProofPolicies { - policy.ConsensusMinerMinPower = p - } - {{end}} - {{end}} + {{range .versions}} + {{if (eq . 0)}} + power{{.}}.ConsensusMinerMinPower = p + {{else if (eq . 2)}} + for _, policy := range builtin{{.}}.SealProofPolicies { + policy.ConsensusMinerMinPower = p + } + {{else}} + for _, policy := range builtin{{.}}.PoStProofPolicies { + policy.ConsensusMinerMinPower = p + } + {{end}} + {{end}} } // SetMinVerifiedDealSize sets the minimum size of a verified deal. This should // only be used for testing. func SetMinVerifiedDealSize(size abi.StoragePower) { - {{range .versions}} - verifreg{{.}}.MinVerifiedDealSize = size - {{end}} + {{range .versions}} + verifreg{{.}}.MinVerifiedDealSize = size + {{end}} } func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch { switch ver { {{range .versions}} - case actors.Version{{.}}: - {{if (eq . 0)}} - return miner{{.}}.MaxSealDuration[t] - {{else}} - return miner{{.}}.MaxProveCommitDuration[t] - {{end}} - {{end}} - default: - panic("unsupported actors version") - } + case actors.Version{{.}}: + {{if (eq . 0)}} + return miner{{.}}.MaxSealDuration[t] + {{else}} + return miner{{.}}.MaxProveCommitDuration[t] + {{end}} + {{end}} + default: + panic("unsupported actors version") + } } func DealProviderCollateralBounds( @@ -125,14 +125,14 @@ func DealProviderCollateralBounds( circulatingFil abi.TokenAmount, nwVer network.Version, ) (min, max abi.TokenAmount) { switch actors.VersionForNetwork(nwVer) { - {{range .versions}} - case actors.Version{{.}}: - {{if (eq . 0)}} - return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) - {{else}} - return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) - {{end}} - {{end}} + {{range .versions}} + case actors.Version{{.}}: + {{if (eq . 0)}} + return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) + {{else}} + return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + {{end}} + {{end}} default: panic("unsupported actors version") } @@ -145,15 +145,15 @@ func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) // Sets the challenge window and scales the proving period to match (such that // there are always 48 challenge windows in a proving period). func SetWPoStChallengeWindow(period abi.ChainEpoch) { - {{range .versions}} - miner{{.}}.WPoStChallengeWindow = period - miner{{.}}.WPoStProvingPeriod = period * abi.ChainEpoch(miner{{.}}.WPoStPeriodDeadlines) - {{if (ge . 3)}} - // by default, this is 2x finality which is 30 periods. - // scale it if we're scaling the challenge period. - miner{{.}}.WPoStDisputeWindow = period * 30 - {{end}} - {{end}} + {{range .versions}} + miner{{.}}.WPoStChallengeWindow = period + miner{{.}}.WPoStProvingPeriod = period * abi.ChainEpoch(miner{{.}}.WPoStPeriodDeadlines) + {{if (ge . 3)}} + // by default, this is 2x finality which is 30 periods. + // scale it if we're scaling the challenge period. + miner{{.}}.WPoStDisputeWindow = period * 30 + {{end}} + {{end}} } func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { @@ -161,7 +161,7 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { return 10 } - // NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well + // NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well return ChainFinality } @@ -207,10 +207,10 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) func GetAddressedSectorsMax(nwVer network.Version) int { switch actors.VersionForNetwork(nwVer) { - {{range .versions}} - case actors.Version{{.}}: - return miner{{.}}.AddressedSectorsMax - {{end}} + {{range .versions}} + case actors.Version{{.}}: + return miner{{.}}.AddressedSectorsMax + {{end}} default: panic("unsupported network version") } @@ -218,15 +218,15 @@ func GetAddressedSectorsMax(nwVer network.Version) int { func GetDeclarationsMax(nwVer network.Version) int { switch actors.VersionForNetwork(nwVer) { - {{range .versions}} - case actors.Version{{.}}: - {{if (eq . 0)}} - // TODO: Should we instead panic here since the concept doesn't exist yet? - return miner{{.}}.AddressedPartitionsMax - {{else}} - return miner{{.}}.DeclarationsMax - {{end}} - {{end}} + {{range .versions}} + case actors.Version{{.}}: + {{if (eq . 0)}} + // TODO: Should we instead panic here since the concept doesn't exist yet? + return miner{{.}}.AddressedPartitionsMax + {{else}} + return miner{{.}}.DeclarationsMax + {{end}} + {{end}} default: panic("unsupported network version") } diff --git a/chain/actors/policy/temp b/chain/actors/policy/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/temp b/chain/actors/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/version.go b/chain/actors/version.go index bd7b708bd..a8b4c62b2 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -8,6 +8,10 @@ import ( type Version int +var LatestVersion = 4 + +var Versions = []int{0, 2, 3, LatestVersion} + const ( Version0 Version = 0 Version2 Version = 2 diff --git a/chain/gen/gen.go b/chain/gen/gen.go index d06c755fa..5c33ac4d7 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -9,6 +9,8 @@ import ( "sync/atomic" "time" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" @@ -197,6 +199,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { sys := vm.Syscalls(&genFakeVerifier{}) tpl := genesis.Template{ + NetworkVersion: network.Version0, Accounts: []genesis.Actor{ { Type: genesis.TAccount, diff --git a/chain/gen/genesis/f00_system.go b/chain/gen/genesis/f00_system.go index 015dfac4a..d1dd203b6 100644 --- a/chain/gen/genesis/f00_system.go +++ b/chain/gen/genesis/f00_system.go @@ -3,27 +3,36 @@ package genesis import ( "context" - "github.com/filecoin-project/specs-actors/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/system" - "github.com/filecoin-project/specs-actors/actors/builtin" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupSystemActor(bs bstore.Blockstore) (*types.Actor, error) { - var st system.State +func SetupSystemActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { cst := cbor.NewCborStore(bs) + st, err := system.MakeState(adt.WrapStore(ctx, cst), av) + if err != nil { + return nil, err + } - statecid, err := cst.Put(context.TODO(), &st) + statecid, err := cst.Put(ctx, st.GetState()) + if err != nil { + return nil, err + } + + actcid, err := system.GetActorCodeID(av) if err != nil { return nil, err } act := &types.Actor{ - Code: builtin.SystemActorCodeID, + Code: actcid, Head: statecid, } diff --git a/chain/gen/genesis/f01_init.go b/chain/gen/genesis/f01_init.go index 718eb4480..88d409221 100644 --- a/chain/gen/genesis/f01_init.go +++ b/chain/gen/genesis/f01_init.go @@ -5,13 +5,15 @@ import ( "encoding/json" "fmt" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/util/adt" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" cbor "github.com/ipfs/go-ipld-cbor" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -21,17 +23,25 @@ import ( "github.com/filecoin-project/lotus/genesis" ) -func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesis.Actor, rootVerifier genesis.Actor, remainder genesis.Actor) (int64, *types.Actor, map[address.Address]address.Address, error) { +func SetupInitActor(ctx context.Context, bs bstore.Blockstore, netname string, initialActors []genesis.Actor, rootVerifier genesis.Actor, remainder genesis.Actor, av actors.Version) (int64, *types.Actor, map[address.Address]address.Address, error) { if len(initialActors) > MaxAccounts { return 0, nil, nil, xerrors.New("too many initial actors") } - var ias init_.State - ias.NextID = MinerStart - ias.NetworkName = netname + cst := cbor.NewCborStore(bs) + ist, err := init_.MakeState(adt.WrapStore(ctx, cst), av, netname) + if err != nil { + return 0, nil, nil, err + } - store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) - amap := adt.MakeEmptyMap(store) + if err = ist.SetNextID(MinerStart); err != nil { + return 0, nil, nil, err + } + + amap, err := ist.AddressMap() + if err != nil { + return 0, nil, nil, err + } keyToId := map[address.Address]address.Address{} counter := int64(AccountStart) @@ -155,15 +165,23 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi if err != nil { return 0, nil, nil, err } - ias.AddressMap = amapaddr - statecid, err := store.Put(store.Context(), &ias) + if err = ist.SetAddressMap(amapaddr); err != nil { + return 0, nil, nil, err + } + + statecid, err := cst.Put(ctx, ist.GetState()) + if err != nil { + return 0, nil, nil, err + } + + actcid, err := init_.GetActorCodeID(av) if err != nil { return 0, nil, nil, err } act := &types.Actor{ - Code: builtin.InitActorCodeID, + Code: actcid, Head: statecid, } diff --git a/chain/gen/genesis/f02_reward.go b/chain/gen/genesis/f02_reward.go index e218da6fe..c8f479722 100644 --- a/chain/gen/genesis/f02_reward.go +++ b/chain/gen/genesis/f02_reward.go @@ -3,10 +3,12 @@ package genesis import ( "context" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/reward" + "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" @@ -14,19 +16,28 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func SetupRewardActor(bs bstore.Blockstore, qaPower big.Int) (*types.Actor, error) { +func SetupRewardActor(ctx context.Context, bs bstore.Blockstore, qaPower big.Int, av actors.Version) (*types.Actor, error) { cst := cbor.NewCborStore(bs) - - st := reward0.ConstructState(qaPower) - - hcid, err := cst.Put(context.TODO(), st) + rst, err := reward.MakeState(adt.WrapStore(ctx, cst), av, qaPower) if err != nil { return nil, err } - return &types.Actor{ - Code: builtin.RewardActorCodeID, + statecid, err := cst.Put(ctx, rst.GetState()) + if err != nil { + return nil, err + } + + actcid, err := reward.GetActorCodeID(av) + if err != nil { + return nil, err + } + + act := &types.Actor{ + Code: actcid, Balance: types.BigInt{Int: build.InitialRewardBalance}, - Head: hcid, - }, nil + Head: statecid, + } + + return act, nil } diff --git a/chain/gen/genesis/f03_cron.go b/chain/gen/genesis/f03_cron.go index dd43a59a4..c6fd2422a 100644 --- a/chain/gen/genesis/f03_cron.go +++ b/chain/gen/genesis/f03_cron.go @@ -3,27 +3,37 @@ package genesis import ( "context" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/cron" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/cron" + cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupCronActor(bs bstore.Blockstore) (*types.Actor, error) { +func SetupCronActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { cst := cbor.NewCborStore(bs) - cas := cron.ConstructState(cron.BuiltInEntries()) - - stcid, err := cst.Put(context.TODO(), cas) + st, err := cron.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av) if err != nil { return nil, err } - return &types.Actor{ - Code: builtin.CronActorCodeID, - Head: stcid, - Nonce: 0, - Balance: types.NewInt(0), - }, nil + statecid, err := cst.Put(ctx, st.GetState()) + if err != nil { + return nil, err + } + + actcid, err := cron.GetActorCodeID(av) + if err != nil { + return nil, err + } + + act := &types.Actor{ + Code: actcid, + Head: statecid, + } + + return act, nil } diff --git a/chain/gen/genesis/f04_power.go b/chain/gen/genesis/f04_power.go index ed349c18b..6fe4d75c0 100644 --- a/chain/gen/genesis/f04_power.go +++ b/chain/gen/genesis/f04_power.go @@ -3,44 +3,39 @@ package genesis import ( "context" - "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/power" + + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/specs-actors/actors/util/adt" - power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) { - store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) - emptyMap, err := adt.MakeEmptyMap(store).Root() +func SetupStoragePowerActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { + + cst := cbor.NewCborStore(bs) + pst, err := power.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av) if err != nil { return nil, err } - multiMap, err := adt.AsMultimap(store, emptyMap) + statecid, err := cst.Put(ctx, pst.GetState()) if err != nil { return nil, err } - emptyMultiMap, err := multiMap.Root() + actcid, err := power.GetActorCodeID(av) if err != nil { return nil, err } - sms := power0.ConstructState(emptyMap, emptyMultiMap) - - stcid, err := store.Put(store.Context(), sms) - if err != nil { - return nil, err + act := &types.Actor{ + Code: actcid, + Head: statecid, } - return &types.Actor{ - Code: builtin.StoragePowerActorCodeID, - Head: stcid, - Nonce: 0, - Balance: types.NewInt(0), - }, nil + return act, nil } diff --git a/chain/gen/genesis/f05_market.go b/chain/gen/genesis/f05_market.go index f7ac26f43..5c39ef38f 100644 --- a/chain/gen/genesis/f05_market.go +++ b/chain/gen/genesis/f05_market.go @@ -3,38 +3,36 @@ package genesis import ( "context" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/market" - "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" + cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) { - store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) - - a, err := adt.MakeEmptyArray(store).Root() - if err != nil { - return nil, err - } - h, err := adt.MakeEmptyMap(store).Root() +func SetupStorageMarketActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { + cst := cbor.NewCborStore(bs) + mst, err := market.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av) if err != nil { return nil, err } - sms := market.ConstructState(a, h, h) + statecid, err := cst.Put(ctx, mst.GetState()) + if err != nil { + return nil, err + } - stcid, err := store.Put(store.Context(), sms) + actcid, err := market.GetActorCodeID(av) if err != nil { return nil, err } act := &types.Actor{ - Code: builtin.StorageMarketActorCodeID, - Head: stcid, - Balance: types.NewInt(0), + Code: actcid, + Head: statecid, } return act, nil diff --git a/chain/gen/genesis/f06_vreg.go b/chain/gen/genesis/f06_vreg.go index 1ba8abede..d8f5ee2a0 100644 --- a/chain/gen/genesis/f06_vreg.go +++ b/chain/gen/genesis/f06_vreg.go @@ -3,11 +3,13 @@ package genesis import ( "context" + "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/go-address" cbor "github.com/ipfs/go-ipld-cbor" - "github.com/filecoin-project/specs-actors/actors/builtin" - verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" "github.com/filecoin-project/specs-actors/actors/util/adt" bstore "github.com/filecoin-project/lotus/blockstore" @@ -26,25 +28,26 @@ func init() { RootVerifierID = idk } -func SetupVerifiedRegistryActor(bs bstore.Blockstore) (*types.Actor, error) { - store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) - - h, err := adt.MakeEmptyMap(store).Root() +func SetupVerifiedRegistryActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { + cst := cbor.NewCborStore(bs) + vst, err := verifreg.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av, RootVerifierID) if err != nil { return nil, err } - sms := verifreg0.ConstructState(h, RootVerifierID) + statecid, err := cst.Put(ctx, vst.GetState()) + if err != nil { + return nil, err + } - stcid, err := store.Put(store.Context(), sms) + actcid, err := verifreg.GetActorCodeID(av) if err != nil { return nil, err } act := &types.Actor{ - Code: builtin.VerifiedRegistryActorCodeID, - Head: stcid, - Balance: types.NewInt(0), + Code: actcid, + Head: statecid, } return act, nil diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index 4b86db550..94badbbfb 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -6,6 +6,32 @@ import ( "encoding/json" "fmt" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + + "github.com/filecoin-project/go-state-types/network" + + "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/account" + + "github.com/filecoin-project/lotus/chain/actors" + + "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" + + "github.com/filecoin-project/lotus/chain/actors/builtin/market" + + "github.com/filecoin-project/lotus/chain/actors/builtin/power" + + "github.com/filecoin-project/lotus/chain/actors/builtin/cron" + + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/actors/builtin/reward" + + "github.com/filecoin-project/lotus/chain/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/journal" @@ -21,11 +47,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - account0 "github.com/filecoin-project/specs-actors/actors/builtin/account" - multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" @@ -118,94 +139,92 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return nil, nil, xerrors.Errorf("putting empty object: %w", err) } - state, err := state.NewStateTree(cst, types.StateTreeVersion0) + sv, err := state.VersionForNetwork(template.NetworkVersion) + if err != nil { + return nil, nil, xerrors.Errorf("getting state tree version: %w", err) + } + + state, err := state.NewStateTree(cst, sv) if err != nil { return nil, nil, xerrors.Errorf("making new state tree: %w", err) } + av := actors.VersionForNetwork(template.NetworkVersion) + // Create system actor - sysact, err := SetupSystemActor(bs) + sysact, err := SetupSystemActor(ctx, bs, av) if err != nil { - return nil, nil, xerrors.Errorf("setup init actor: %w", err) + return nil, nil, xerrors.Errorf("setup system actor: %w", err) } - if err := state.SetActor(builtin0.SystemActorAddr, sysact); err != nil { - return nil, nil, xerrors.Errorf("set init actor: %w", err) + if err := state.SetActor(system.Address, sysact); err != nil { + return nil, nil, xerrors.Errorf("set system actor: %w", err) } // Create init actor - idStart, initact, keyIDs, err := SetupInitActor(bs, template.NetworkName, template.Accounts, template.VerifregRootKey, template.RemainderAccount) + idStart, initact, keyIDs, err := SetupInitActor(ctx, bs, template.NetworkName, template.Accounts, template.VerifregRootKey, template.RemainderAccount, av) if err != nil { return nil, nil, xerrors.Errorf("setup init actor: %w", err) } - if err := state.SetActor(builtin0.InitActorAddr, initact); err != nil { + if err := state.SetActor(init_.Address, initact); err != nil { return nil, nil, xerrors.Errorf("set init actor: %w", err) } // Setup reward - // RewardActor's state is overrwritten by SetupStorageMiners - rewact, err := SetupRewardActor(bs, big.Zero()) + // RewardActor's state is overwritten by SetupStorageMiners, but needs to exist for miner creation messages + rewact, err := SetupRewardActor(ctx, bs, big.Zero(), av) if err != nil { - return nil, nil, xerrors.Errorf("setup init actor: %w", err) + return nil, nil, xerrors.Errorf("setup reward actor: %w", err) } - err = state.SetActor(builtin0.RewardActorAddr, rewact) + err = state.SetActor(reward.Address, rewact) if err != nil { - return nil, nil, xerrors.Errorf("set network account actor: %w", err) + return nil, nil, xerrors.Errorf("set reward actor: %w", err) } // Setup cron - cronact, err := SetupCronActor(bs) + cronact, err := SetupCronActor(ctx, bs, av) if err != nil { return nil, nil, xerrors.Errorf("setup cron actor: %w", err) } - if err := state.SetActor(builtin0.CronActorAddr, cronact); err != nil { + if err := state.SetActor(cron.Address, cronact); err != nil { return nil, nil, xerrors.Errorf("set cron actor: %w", err) } // Create empty power actor - spact, err := SetupStoragePowerActor(bs) + spact, err := SetupStoragePowerActor(ctx, bs, av) if err != nil { - return nil, nil, xerrors.Errorf("setup storage market actor: %w", err) + return nil, nil, xerrors.Errorf("setup storage power actor: %w", err) } - if err := state.SetActor(builtin0.StoragePowerActorAddr, spact); err != nil { - return nil, nil, xerrors.Errorf("set storage market actor: %w", err) + if err := state.SetActor(power.Address, spact); err != nil { + return nil, nil, xerrors.Errorf("set storage power actor: %w", err) } // Create empty market actor - marketact, err := SetupStorageMarketActor(bs) + marketact, err := SetupStorageMarketActor(ctx, bs, av) if err != nil { return nil, nil, xerrors.Errorf("setup storage market actor: %w", err) } - if err := state.SetActor(builtin0.StorageMarketActorAddr, marketact); err != nil { - return nil, nil, xerrors.Errorf("set market actor: %w", err) + if err := state.SetActor(market.Address, marketact); err != nil { + return nil, nil, xerrors.Errorf("set storage market actor: %w", err) } // Create verified registry - verifact, err := SetupVerifiedRegistryActor(bs) + verifact, err := SetupVerifiedRegistryActor(ctx, bs, av) if err != nil { - return nil, nil, xerrors.Errorf("setup storage market actor: %w", err) + return nil, nil, xerrors.Errorf("setup verified registry market actor: %w", err) } - if err := state.SetActor(builtin0.VerifiedRegistryActorAddr, verifact); err != nil { - return nil, nil, xerrors.Errorf("set market actor: %w", err) + if err := state.SetActor(verifreg.Address, verifact); err != nil { + return nil, nil, xerrors.Errorf("set verified registry actor: %w", err) } - burntRoot, err := cst.Put(ctx, &account0.State{ - Address: builtin0.BurntFundsActorAddr, - }) + bact, err := makeAccountActor(ctx, cst, av, builtin.BurntFundsActorAddr, big.Zero()) if err != nil { - return nil, nil, xerrors.Errorf("failed to setup burnt funds actor state: %w", err) + return nil, nil, xerrors.Errorf("setup burnt funds actor state: %w", err) } - - // Setup burnt-funds - err = state.SetActor(builtin0.BurntFundsActorAddr, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: types.NewInt(0), - Head: burntRoot, - }) - if err != nil { - return nil, nil, xerrors.Errorf("set burnt funds account actor: %w", err) + if err := state.SetActor(builtin.BurntFundsActorAddr, bact); err != nil { + return nil, nil, xerrors.Errorf("set burnt funds actor: %w", err) } // Create accounts @@ -213,7 +232,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge switch info.Type { case genesis.TAccount: - if err := createAccountActor(ctx, cst, state, info, keyIDs); err != nil { + if err := createAccountActor(ctx, cst, state, info, keyIDs, av); err != nil { return nil, nil, xerrors.Errorf("failed to create account actor: %w", err) } @@ -225,7 +244,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge } idStart++ - if err := createMultisigAccount(ctx, bs, cst, state, ida, info, keyIDs); err != nil { + if err := createMultisigAccount(ctx, cst, state, ida, info, keyIDs, av); err != nil { return nil, nil, err } default: @@ -240,26 +259,21 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge if err := json.Unmarshal(template.VerifregRootKey.Meta, &ainfo); err != nil { return nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err) } - st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner}) - if err != nil { - return nil, nil, err - } _, ok := keyIDs[ainfo.Owner] if ok { return nil, nil, fmt.Errorf("rootkey account has already been declared, cannot be assigned 80: %s", ainfo.Owner) } - err = state.SetActor(builtin.RootVerifierAddress, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: template.VerifregRootKey.Balance, - Head: st, - }) + vact, err := makeAccountActor(ctx, cst, av, ainfo.Owner, template.VerifregRootKey.Balance) if err != nil { - return nil, nil, xerrors.Errorf("setting verifreg rootkey account: %w", err) + return nil, nil, xerrors.Errorf("setup verifreg rootkey account state: %w", err) + } + if err = state.SetActor(builtin.RootVerifierAddress, vact); err != nil { + return nil, nil, xerrors.Errorf("set verifreg rootkey account actor: %w", err) } case genesis.TMultisig: - if err = createMultisigAccount(ctx, bs, cst, state, builtin.RootVerifierAddress, template.VerifregRootKey, keyIDs); err != nil { + if err = createMultisigAccount(ctx, cst, state, builtin.RootVerifierAddress, template.VerifregRootKey, keyIDs, av); err != nil { return nil, nil, xerrors.Errorf("failed to set up verified registry signer: %w", err) } default: @@ -288,18 +302,13 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return nil, nil, err } - verifierState, err := cst.Put(ctx, &account0.State{Address: verifierAd}) + verifierAct, err := makeAccountActor(ctx, cst, av, verifierAd, big.Zero()) if err != nil { - return nil, nil, err + return nil, nil, xerrors.Errorf("setup first verifier state: %w", err) } - err = state.SetActor(verifierId, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: types.NewInt(0), - Head: verifierState, - }) - if err != nil { - return nil, nil, xerrors.Errorf("setting account from actmap: %w", err) + if err = state.SetActor(verifierId, verifierAct); err != nil { + return nil, nil, xerrors.Errorf("set first verifier actor: %w", err) } totalFilAllocated := big.Zero() @@ -337,13 +346,13 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge } keyIDs[ainfo.Owner] = builtin.ReserveAddress - err = createAccountActor(ctx, cst, state, template.RemainderAccount, keyIDs) + err = createAccountActor(ctx, cst, state, template.RemainderAccount, keyIDs, av) if err != nil { return nil, nil, xerrors.Errorf("creating remainder acct: %w", err) } case genesis.TMultisig: - if err = createMultisigAccount(ctx, bs, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs); err != nil { + if err = createMultisigAccount(ctx, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs, av); err != nil { return nil, nil, xerrors.Errorf("failed to set up remainder: %w", err) } default: @@ -353,12 +362,38 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return state, keyIDs, nil } -func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.StateTree, info genesis.Actor, keyIDs map[address.Address]address.Address) error { +func makeAccountActor(ctx context.Context, cst cbor.IpldStore, av actors.Version, addr address.Address, bal types.BigInt) (*types.Actor, error) { + ast, err := account.MakeState(adt.WrapStore(ctx, cst), av, addr) + if err != nil { + return nil, err + } + + statecid, err := cst.Put(ctx, ast.GetState()) + if err != nil { + return nil, err + } + + actcid, err := account.GetActorCodeID(av) + if err != nil { + return nil, err + } + + act := &types.Actor{ + Code: actcid, + Head: statecid, + Balance: bal, + } + + return act, nil +} + +func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.StateTree, info genesis.Actor, keyIDs map[address.Address]address.Address, av actors.Version) error { var ainfo genesis.AccountMeta if err := json.Unmarshal(info.Meta, &ainfo); err != nil { return xerrors.Errorf("unmarshaling account meta: %w", err) } - st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner}) + + aa, err := makeAccountActor(ctx, cst, av, ainfo.Owner, info.Balance) if err != nil { return err } @@ -368,18 +403,14 @@ func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.St return fmt.Errorf("no registered ID for account actor: %s", ainfo.Owner) } - err = state.SetActor(ida, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: info.Balance, - Head: st, - }) + err = state.SetActor(ida, aa) if err != nil { return xerrors.Errorf("setting account from actmap: %w", err) } return nil } -func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.IpldStore, state *state.StateTree, ida address.Address, info genesis.Actor, keyIDs map[address.Address]address.Address) error { +func createMultisigAccount(ctx context.Context, cst cbor.IpldStore, state *state.StateTree, ida address.Address, info genesis.Actor, keyIDs map[address.Address]address.Address, av actors.Version) error { if info.Type != genesis.TMultisig { return fmt.Errorf("can only call createMultisigAccount with multisig Actor info") } @@ -387,10 +418,6 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I if err := json.Unmarshal(info.Meta, &ainfo); err != nil { return xerrors.Errorf("unmarshaling account meta: %w", err) } - pending, err := adt0.MakeEmptyMap(adt0.WrapStore(ctx, cst)).Root() - if err != nil { - return xerrors.Errorf("failed to create empty map: %v", err) - } var signers []address.Address @@ -407,44 +434,45 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I continue } - st, err := cst.Put(ctx, &account0.State{Address: e}) + aa, err := makeAccountActor(ctx, cst, av, e, big.Zero()) if err != nil { return err } - err = state.SetActor(idAddress, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: types.NewInt(0), - Head: st, - }) - if err != nil { + + if err = state.SetActor(idAddress, aa); err != nil { return xerrors.Errorf("setting account from actmap: %w", err) } signers = append(signers, idAddress) } - st, err := cst.Put(ctx, &multisig0.State{ - Signers: signers, - NumApprovalsThreshold: uint64(ainfo.Threshold), - StartEpoch: abi.ChainEpoch(ainfo.VestingStart), - UnlockDuration: abi.ChainEpoch(ainfo.VestingDuration), - PendingTxns: pending, - InitialBalance: info.Balance, - }) + mst, err := multisig.MakeState(adt.WrapStore(ctx, cst), av, signers, uint64(ainfo.Threshold), abi.ChainEpoch(ainfo.VestingStart), abi.ChainEpoch(ainfo.VestingDuration), info.Balance) if err != nil { return err } + + statecid, err := cst.Put(ctx, mst.GetState()) + if err != nil { + return err + } + + actcid, err := multisig.GetActorCodeID(av) + if err != nil { + return err + } + err = state.SetActor(ida, &types.Actor{ - Code: builtin0.MultisigActorCodeID, + Code: actcid, Balance: info.Balance, - Head: st, + Head: statecid, }) if err != nil { return xerrors.Errorf("setting account from actmap: %w", err) } + return nil } -func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot cid.Cid, template genesis.Template, keyIDs map[address.Address]address.Address) (cid.Cid, error) { +func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot cid.Cid, template genesis.Template, keyIDs map[address.Address]address.Address, nv network.Version) (cid.Cid, error) { verifNeeds := make(map[address.Address]abi.PaddedPieceSize) var sum abi.PaddedPieceSize @@ -455,8 +483,10 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci Bstore: cs.StateBlockstore(), Syscalls: mkFakedSigSyscalls(cs.VMSys()), CircSupplyCalc: nil, - NtwkVersion: genesisNetworkVersion, - BaseFee: types.NewInt(0), + NtwkVersion: func(_ context.Context, _ abi.ChainEpoch) network.Version { + return nv + }, + BaseFee: types.NewInt(0), } vm, err := vm.NewVM(ctx, &vmopt) if err != nil { @@ -485,7 +515,8 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci return cid.Undef, err } - _, err = doExecValue(ctx, vm, builtin0.VerifiedRegistryActorAddr, verifregRoot, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg0.AddVerifierParams{ + // Note: This is brittle, if the methodNum / param changes, it could break things + _, err = doExecValue(ctx, vm, verifreg.Address, verifregRoot, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg0.AddVerifierParams{ Address: verifier, Allowance: abi.NewStoragePower(int64(sum)), // eh, close enough @@ -496,7 +527,8 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci } for c, amt := range verifNeeds { - _, err := doExecValue(ctx, vm, builtin0.VerifiedRegistryActorAddr, verifier, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifiedClient, mustEnc(&verifreg0.AddVerifiedClientParams{ + // Note: This is brittle, if the methodNum / param changes, it could break things + _, err := doExecValue(ctx, vm, verifreg.Address, verifier, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifiedClient, mustEnc(&verifreg0.AddVerifiedClientParams{ Address: c, Allowance: abi.NewStoragePower(int64(amt)), })) @@ -531,17 +563,17 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto cs := store.NewChainStore(bs, bs, datastore.NewMapDatastore(), sys, j) // Verify PreSealed Data - stateroot, err = VerifyPreSealedData(ctx, cs, stateroot, template, keyIDs) + stateroot, err = VerifyPreSealedData(ctx, cs, stateroot, template, keyIDs, template.NetworkVersion) if err != nil { return nil, xerrors.Errorf("failed to verify presealed data: %w", err) } - stateroot, err = SetupStorageMiners(ctx, cs, stateroot, template.Miners) + stateroot, err = SetupStorageMiners(ctx, cs, stateroot, template.Miners, template.NetworkVersion) if err != nil { return nil, xerrors.Errorf("setup miners failed: %w", err) } - store := adt0.WrapStore(ctx, cbor.NewCborStore(bs)) + store := adt.WrapStore(ctx, cbor.NewCborStore(bs)) emptyroot, err := adt0.MakeEmptyArray(store).Root() if err != nil { return nil, xerrors.Errorf("amt build failed: %w", err) @@ -590,7 +622,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto } b := &types.BlockHeader{ - Miner: builtin0.SystemActorAddr, + Miner: system.Address, Ticket: genesisticket, Parents: []cid.Cid{filecoinGenesisCid}, Height: 0, diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index 297543886..17349b270 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -6,6 +6,22 @@ import ( "fmt" "math/rand" + power4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/power" + + reward4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/reward" + + market4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/market" + + "github.com/filecoin-project/lotus/chain/actors" + + "github.com/filecoin-project/lotus/chain/actors/builtin" + + "github.com/filecoin-project/lotus/chain/actors/policy" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + "github.com/filecoin-project/go-state-types/network" + market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/power" @@ -61,7 +77,12 @@ func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder { } } -func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner) (cid.Cid, error) { +// Note: Much of this is brittle, if the methodNum / param / return changes, it will break things +func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner, nv network.Version) (cid.Cid, error) { + + cst := cbor.NewCborStore(cs.StateBlockstore()) + av := actors.VersionForNetwork(nv) + csc := func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) { return big.Zero(), nil } @@ -73,8 +94,10 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid Bstore: cs.StateBlockstore(), Syscalls: mkFakedSigSyscalls(cs.VMSys()), CircSupplyCalc: csc, - NtwkVersion: genesisNetworkVersion, - BaseFee: types.NewInt(0), + NtwkVersion: func(_ context.Context, _ abi.ChainEpoch) network.Version { + return nv + }, + BaseFee: types.NewInt(0), } vm, err := vm.NewVM(ctx, vmopt) @@ -94,12 +117,13 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid dealIDs []abi.DealID }, len(miners)) + maxPeriods := policy.GetMaxSectorExpirationExtension() / miner.WPoStProvingPeriod for i, m := range miners { // Create miner through power actor i := i m := m - spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, GenesisNetworkVersion) + spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, nv) if err != nil { return cid.Undef, err } @@ -113,7 +137,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid } params := mustEnc(constructorParams) - rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, builtin0.MethodsPower.CreateMiner, params) + rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, power.Methods.CreateMiner, params) if err != nil { return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err) } @@ -129,23 +153,34 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid } minerInfos[i].maddr = ma.IDAddress - // TODO: ActorUpgrade - err = vm.MutateState(ctx, minerInfos[i].maddr, func(cst cbor.IpldStore, st *miner0.State) error { - maxPeriods := miner0.MaxSectorExpirationExtension / miner0.WPoStProvingPeriod - minerInfos[i].presealExp = (maxPeriods-1)*miner0.WPoStProvingPeriod + st.ProvingPeriodStart - 1 - - return nil - }) + _, err = vm.Flush(ctx) if err != nil { - return cid.Undef, xerrors.Errorf("mutating state: %w", err) + return cid.Undef, xerrors.Errorf("flushing vm: %w", err) } + + mact, err := vm.StateTree().GetActor(minerInfos[i].maddr) + if err != nil { + return cid.Undef, xerrors.Errorf("getting newly created miner actor: %w", err) + } + + mst, err := miner.Load(adt.WrapStore(ctx, cst), mact) + if err != nil { + return cid.Undef, xerrors.Errorf("getting newly created miner state: %w", err) + } + + pps, err := mst.GetProvingPeriodStart() + if err != nil { + return cid.Undef, xerrors.Errorf("getting newly created miner proving period start: %w", err) + } + + minerInfos[i].presealExp = (maxPeriods-1)*miner0.WPoStProvingPeriod + pps - 1 } // Add market funds if m.MarketBalance.GreaterThan(big.Zero()) { params := mustEnc(&minerInfos[i].maddr) - _, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin0.MethodsMarket.AddBalance, params) + _, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, market.Methods.AddBalance, params) if err != nil { return cid.Undef, xerrors.Errorf("failed to create genesis miner (add balance): %w", err) } @@ -203,35 +238,66 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid for pi := range m.Sectors { rawPow = types.BigAdd(rawPow, types.NewInt(uint64(m.SectorSize))) - dweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, []abi.DealID{minerInfos[i].dealIDs[pi]}, 0, minerInfos[i].presealExp) + dweight, vdweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, []abi.DealID{minerInfos[i].dealIDs[pi]}, 0, minerInfos[i].presealExp, av) if err != nil { return cid.Undef, xerrors.Errorf("getting deal weight: %w", err) } - sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight) + sectorWeight := builtin.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight, vdweight) qaPow = types.BigAdd(qaPow, sectorWeight) } } - err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error { - st.TotalQualityAdjPower = qaPow - st.TotalRawBytePower = rawPow - - st.ThisEpochQualityAdjPower = qaPow - st.ThisEpochRawBytePower = rawPow - return nil - }) + _, err = vm.Flush(ctx) if err != nil { - return cid.Undef, xerrors.Errorf("mutating state: %w", err) + return cid.Undef, xerrors.Errorf("flushing vm: %w", err) } - err = vm.MutateState(ctx, reward.Address, func(sct cbor.IpldStore, st *reward0.State) error { - *st = *reward0.ConstructState(qaPow) - return nil - }) + pact, err := vm.StateTree().GetActor(power.Address) if err != nil { - return cid.Undef, xerrors.Errorf("mutating state: %w", err) + return cid.Undef, xerrors.Errorf("getting power actor: %w", err) + } + + pst, err := power.Load(adt.WrapStore(ctx, cst), pact) + if err != nil { + return cid.Undef, xerrors.Errorf("getting power state: %w", err) + } + + if err = pst.SetTotalQualityAdjPower(qaPow); err != nil { + return cid.Undef, xerrors.Errorf("setting TotalQualityAdjPower in power state: %w", err) + } + + if err = pst.SetTotalRawBytePower(rawPow); err != nil { + return cid.Undef, xerrors.Errorf("setting TotalRawBytePower in power state: %w", err) + } + + if err = pst.SetThisEpochQualityAdjPower(qaPow); err != nil { + return cid.Undef, xerrors.Errorf("setting ThisEpochQualityAdjPower in power state: %w", err) + } + + if err = pst.SetThisEpochRawBytePower(rawPow); err != nil { + return cid.Undef, xerrors.Errorf("setting ThisEpochRawBytePower in power state: %w", err) + } + + pcid, err := cst.Put(ctx, pst.GetState()) + if err != nil { + return cid.Undef, xerrors.Errorf("putting power state: %w", err) + } + + pact.Head = pcid + + if err = vm.StateTree().SetActor(power.Address, pact); err != nil { + return cid.Undef, xerrors.Errorf("setting power state: %w", err) + } + + rewact, err := SetupRewardActor(ctx, cs.StateBlockstore(), big.Zero(), actors.VersionForNetwork(nv)) + if err != nil { + return cid.Undef, xerrors.Errorf("setup reward actor: %w", err) + } + + if err = vm.StateTree().SetActor(reward.Address, rewact); err != nil { + return cid.Undef, xerrors.Errorf("set reward actor: %w", err) } } @@ -248,24 +314,55 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid Expiration: minerInfos[i].presealExp, // TODO: Allow setting externally! } - dweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, params.DealIDs, 0, minerInfos[i].presealExp) + dweight, vdweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, params.DealIDs, 0, minerInfos[i].presealExp, av) if err != nil { return cid.Undef, xerrors.Errorf("getting deal weight: %w", err) } - sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight) + sectorWeight := builtin.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight, vdweight) // we've added fake power for this sector above, remove it now - err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error { - st.TotalQualityAdjPower = types.BigSub(st.TotalQualityAdjPower, sectorWeight) //nolint:scopelint - st.TotalRawBytePower = types.BigSub(st.TotalRawBytePower, types.NewInt(uint64(m.SectorSize))) - return nil - }) + + _, err = vm.Flush(ctx) if err != nil { - return cid.Undef, xerrors.Errorf("removing fake power: %w", err) + return cid.Undef, xerrors.Errorf("flushing vm: %w", err) } - epochReward, err := currentEpochBlockReward(ctx, vm, minerInfos[i].maddr) + pact, err := vm.StateTree().GetActor(power.Address) + if err != nil { + return cid.Undef, xerrors.Errorf("getting power actor: %w", err) + } + + pst, err := power.Load(adt.WrapStore(ctx, cst), pact) + if err != nil { + return cid.Undef, xerrors.Errorf("getting power state: %w", err) + } + + pc, err := pst.TotalPower() + if err != nil { + return cid.Undef, xerrors.Errorf("getting total power: %w", err) + } + + if err = pst.SetTotalRawBytePower(types.BigSub(pc.RawBytePower, types.NewInt(uint64(m.SectorSize)))); err != nil { + return cid.Undef, xerrors.Errorf("setting TotalRawBytePower in power state: %w", err) + } + + if err = pst.SetTotalQualityAdjPower(types.BigSub(pc.QualityAdjPower, sectorWeight)); err != nil { + return cid.Undef, xerrors.Errorf("setting TotalQualityAdjPower in power state: %w", err) + } + + pcid, err := cst.Put(ctx, pst.GetState()) + if err != nil { + return cid.Undef, xerrors.Errorf("putting power state: %w", err) + } + + pact.Head = pcid + + if err = vm.StateTree().SetActor(power.Address, pact); err != nil { + return cid.Undef, xerrors.Errorf("setting power state: %w", err) + } + + baselinePower, rewardSmoothed, err := currentEpochBlockReward(ctx, vm, minerInfos[i].maddr, av) if err != nil { return cid.Undef, xerrors.Errorf("getting current epoch reward: %w", err) } @@ -275,13 +372,13 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid return cid.Undef, xerrors.Errorf("getting current total power: %w", err) } - pcd := miner0.PreCommitDepositForPower(epochReward.ThisEpochRewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight) + pcd := miner0.PreCommitDepositForPower(&rewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight) pledge := miner0.InitialPledgeForPower( sectorWeight, - epochReward.ThisEpochBaselinePower, + baselinePower, tpow.PledgeCollateral, - epochReward.ThisEpochRewardSmoothed, + &rewardSmoothed, tpow.QualityAdjPowerSmoothed, circSupply(ctx, vm, minerInfos[i].maddr), ) @@ -289,7 +386,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid pledge = big.Add(pcd, pledge) fmt.Println(types.FIL(pledge)) - _, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, builtin0.MethodsMiner.PreCommitSector, mustEnc(params)) + _, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, miner.Methods.PreCommitSector, mustEnc(params)) if err != nil { return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) } @@ -299,28 +396,84 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid Sectors: []abi.SectorNumber{preseal.SectorID}, } - _, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin0.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams)) + _, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), miner.Methods.ConfirmSectorProofsValid, mustEnc(confirmParams)) if err != nil { return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) } + + if av > actors.Version2 { + // post v2, we need to explicitly Claim this power since ConfirmSectorProofsValid doesn't do it anymore + claimParams := &power4.UpdateClaimedPowerParams{ + RawByteDelta: types.NewInt(uint64(m.SectorSize)), + QualityAdjustedDelta: sectorWeight, + } + + _, err = doExecValue(ctx, vm, power.Address, minerInfos[i].maddr, big.Zero(), power.Methods.UpdateClaimedPower, mustEnc(claimParams)) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) + } + + _, err = vm.Flush(ctx) + if err != nil { + return cid.Undef, xerrors.Errorf("flushing vm: %w", err) + } + + mact, err := vm.StateTree().GetActor(minerInfos[i].maddr) + if err != nil { + return cid.Undef, xerrors.Errorf("getting miner actor: %w", err) + } + + mst, err := miner.Load(adt.WrapStore(ctx, cst), mact) + if err != nil { + return cid.Undef, xerrors.Errorf("getting miner state: %w", err) + } + + if err = mst.EraseAllUnproven(); err != nil { + return cid.Undef, xerrors.Errorf("failed to erase unproven sectors: %w", err) + } + + mcid, err := cst.Put(ctx, mst.GetState()) + if err != nil { + return cid.Undef, xerrors.Errorf("putting miner state: %w", err) + } + + mact.Head = mcid + + if err = vm.StateTree().SetActor(minerInfos[i].maddr, mact); err != nil { + return cid.Undef, xerrors.Errorf("setting miner state: %w", err) + } + } } } } // Sanity-check total network power - err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error { - if !st.TotalRawBytePower.Equals(rawPow) { - return xerrors.Errorf("st.TotalRawBytePower doesn't match previously calculated rawPow") - } - - if !st.TotalQualityAdjPower.Equals(qaPow) { - return xerrors.Errorf("st.TotalQualityAdjPower doesn't match previously calculated qaPow") - } - - return nil - }) + _, err = vm.Flush(ctx) if err != nil { - return cid.Undef, xerrors.Errorf("mutating state: %w", err) + return cid.Undef, xerrors.Errorf("flushing vm: %w", err) + } + + pact, err := vm.StateTree().GetActor(power.Address) + if err != nil { + return cid.Undef, xerrors.Errorf("getting power actor: %w", err) + } + + pst, err := power.Load(adt.WrapStore(ctx, cst), pact) + if err != nil { + return cid.Undef, xerrors.Errorf("getting power state: %w", err) + } + + pc, err := pst.TotalPower() + if err != nil { + return cid.Undef, xerrors.Errorf("getting total power: %w", err) + } + + if !pc.RawBytePower.Equals(rawPow) { + return cid.Undef, xerrors.Errorf("TotalRawBytePower (%s) doesn't match previously calculated rawPow (%s)", pc.RawBytePower, rawPow) + } + + if !pc.QualityAdjPower.Equals(qaPow) { + return cid.Undef, xerrors.Errorf("QualityAdjPower (%s) doesn't match previously calculated qaPow (%s)", pc.QualityAdjPower, qaPow) } // TODO: Should we re-ConstructState for the reward actor using rawPow as currRealizedPower here? @@ -360,43 +513,79 @@ func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (* return &pwr, nil } -func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch) (market0.VerifyDealsForActivationReturn, error) { - params := &market.VerifyDealsForActivationParams{ - DealIDs: dealIDs, - SectorStart: sectorStart, - SectorExpiry: sectorExpiry, - } +func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch, av actors.Version) (abi.DealWeight, abi.DealWeight, error) { + // TODO: This hack should move to market actor wrapper + if av <= actors.Version2 { + params := &market0.VerifyDealsForActivationParams{ + DealIDs: dealIDs, + SectorStart: sectorStart, + SectorExpiry: sectorExpiry, + } - var dealWeights market0.VerifyDealsForActivationReturn + var dealWeights market0.VerifyDealsForActivationReturn + ret, err := doExecValue(ctx, vm, + market.Address, + maddr, + abi.NewTokenAmount(0), + builtin0.MethodsMarket.VerifyDealsForActivation, + mustEnc(params), + ) + if err != nil { + return big.Zero(), big.Zero(), err + } + if err := dealWeights.UnmarshalCBOR(bytes.NewReader(ret)); err != nil { + return big.Zero(), big.Zero(), err + } + + return dealWeights.DealWeight, dealWeights.VerifiedDealWeight, nil + } + params := &market4.VerifyDealsForActivationParams{Sectors: []market4.SectorDeals{{ + SectorExpiry: sectorExpiry, + DealIDs: dealIDs, + }}} + + var dealWeights market4.VerifyDealsForActivationReturn ret, err := doExecValue(ctx, vm, market.Address, maddr, abi.NewTokenAmount(0), - builtin0.MethodsMarket.VerifyDealsForActivation, + market.Methods.VerifyDealsForActivation, mustEnc(params), ) if err != nil { - return market0.VerifyDealsForActivationReturn{}, err + return big.Zero(), big.Zero(), err } if err := dealWeights.UnmarshalCBOR(bytes.NewReader(ret)); err != nil { - return market0.VerifyDealsForActivationReturn{}, err + return big.Zero(), big.Zero(), err } - return dealWeights, nil + return dealWeights.Sectors[0].DealWeight, dealWeights.Sectors[0].VerifiedDealWeight, nil } -func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward0.ThisEpochRewardReturn, error) { - rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin0.MethodsReward.ThisEpochReward, nil) +func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address, av actors.Version) (abi.StoragePower, builtin.FilterEstimate, error) { + rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), reward.Methods.ThisEpochReward, nil) if err != nil { - return nil, err + return big.Zero(), builtin.FilterEstimate{}, err } - var epochReward reward0.ThisEpochRewardReturn + // TODO: This hack should move to reward actor wrapper + if av <= actors.Version2 { + var epochReward reward0.ThisEpochRewardReturn + + if err := epochReward.UnmarshalCBOR(bytes.NewReader(rwret)); err != nil { + return big.Zero(), builtin.FilterEstimate{}, err + } + + return epochReward.ThisEpochBaselinePower, *epochReward.ThisEpochRewardSmoothed, nil + } + + var epochReward reward4.ThisEpochRewardReturn + if err := epochReward.UnmarshalCBOR(bytes.NewReader(rwret)); err != nil { - return nil, err + return big.Zero(), builtin.FilterEstimate{}, err } - return &epochReward, nil + return epochReward.ThisEpochBaselinePower, builtin.FilterEstimate(epochReward.ThisEpochRewardSmoothed), nil } func circSupply(ctx context.Context, vmi *vm.VM, maddr address.Address) abi.TokenAmount { diff --git a/chain/gen/genesis/util.go b/chain/gen/genesis/util.go index 54cc30cc1..67a4e9579 100644 --- a/chain/gen/genesis/util.go +++ b/chain/gen/genesis/util.go @@ -3,9 +3,6 @@ package genesis import ( "context" - "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" cbg "github.com/whyrusleeping/cbor-gen" @@ -49,29 +46,3 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value return ret.Return, nil } - -// TODO: Get from build -// TODO: make a list/schedule of these. -var GenesisNetworkVersion = func() network.Version { - // returns the version _before_ the first upgrade. - if build.UpgradeBreezeHeight >= 0 { - return network.Version0 - } - if build.UpgradeSmokeHeight >= 0 { - return network.Version1 - } - if build.UpgradeIgnitionHeight >= 0 { - return network.Version2 - } - if build.UpgradeActorsV2Height >= 0 { - return network.Version3 - } - if build.UpgradeLiftoffHeight >= 0 { - return network.Version3 - } - return build.ActorUpgradeNetworkVersion - 1 // genesis requires actors v0. -}() - -func genesisNetworkVersion(context.Context, abi.ChainEpoch) network.Version { // TODO: Get from build/ - return GenesisNetworkVersion // TODO: Get from build/ -} // TODO: Get from build/ diff --git a/chain/state/statetree.go b/chain/state/statetree.go index 2a7b436b8..a31ec2396 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -14,7 +14,6 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/chain/actors" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" cbg "github.com/whyrusleeping/cbor-gen" @@ -142,11 +141,19 @@ func (ss *stateSnaps) deleteActor(addr address.Address) { // VersionForNetwork returns the state tree version for the given network // version. -func VersionForNetwork(ver network.Version) types.StateTreeVersion { - if actors.VersionForNetwork(ver) == actors.Version0 { - return types.StateTreeVersion0 +func VersionForNetwork(ver network.Version) (types.StateTreeVersion, error) { + switch ver { + case network.Version0, network.Version1, network.Version2, network.Version3: + return types.StateTreeVersion0, nil + case network.Version4, network.Version5, network.Version6, network.Version7, network.Version8, network.Version9: + return types.StateTreeVersion1, nil + case network.Version10, network.Version11: + return types.StateTreeVersion2, nil + case network.Version12: + return types.StateTreeVersion3, nil + default: + panic(fmt.Sprintf("unsupported network version %d", ver)) } - return types.StateTreeVersion1 } func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, error) { diff --git a/chain/state/statetree_test.go b/chain/state/statetree_test.go index 91674337b..9177af312 100644 --- a/chain/state/statetree_test.go +++ b/chain/state/statetree_test.go @@ -5,11 +5,12 @@ import ( "fmt" "testing" + "github.com/filecoin-project/go-state-types/network" + "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" address "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-state-types/network" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/build" @@ -45,7 +46,12 @@ func BenchmarkStateTreeSet(b *testing.B) { func BenchmarkStateTreeSetFlush(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + sv, err := VersionForNetwork(build.NewestNetworkVersion) + if err != nil { + b.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { b.Fatal(err) } @@ -75,7 +81,12 @@ func BenchmarkStateTreeSetFlush(b *testing.B) { func TestResolveCache(t *testing.T) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + sv, err := VersionForNetwork(build.NewestNetworkVersion) + if err != nil { + t.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { t.Fatal(err) } @@ -172,7 +183,12 @@ func TestResolveCache(t *testing.T) { func BenchmarkStateTree10kGetActor(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + sv, err := VersionForNetwork(build.NewestNetworkVersion) + if err != nil { + b.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { b.Fatal(err) } @@ -214,7 +230,12 @@ func BenchmarkStateTree10kGetActor(b *testing.B) { func TestSetCache(t *testing.T) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + sv, err := VersionForNetwork(build.NewestNetworkVersion) + if err != nil { + t.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { t.Fatal(err) } @@ -251,7 +272,13 @@ func TestSetCache(t *testing.T) { func TestSnapshots(t *testing.T) { ctx := context.Background() cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + + sv, err := VersionForNetwork(build.NewestNetworkVersion) + if err != nil { + t.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { t.Fatal(err) } @@ -334,8 +361,15 @@ func assertNotHas(t *testing.T, st *StateTree, addr address.Address) { func TestStateTreeConsistency(t *testing.T) { cst := cbor.NewMemCborStore() + // TODO: ActorUpgrade: this test tests pre actors v2 - st, err := NewStateTree(cst, VersionForNetwork(network.Version3)) + + sv, err := VersionForNetwork(network.Version3) + if err != nil { + t.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { t.Fatal(err) } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index afc74e744..f488c7864 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "fmt" - "reflect" "sync/atomic" "time" @@ -203,7 +202,8 @@ type ( ) type VM struct { - cstate *state.StateTree + cstate *state.StateTree + // TODO: Is base actually used? Can we delete it? base cid.Cid cst *cbor.BasicIpldStore buf *blockstore.BufferedBlockstore @@ -662,37 +662,6 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) { return root, nil } -// MutateState usage: MutateState(ctx, idAddr, func(cst cbor.IpldStore, st *ActorStateType) error {...}) -func (vm *VM) MutateState(ctx context.Context, addr address.Address, fn interface{}) error { - act, err := vm.cstate.GetActor(addr) - if err != nil { - return xerrors.Errorf("actor not found: %w", err) - } - - st := reflect.New(reflect.TypeOf(fn).In(1).Elem()) - if err := vm.cst.Get(ctx, act.Head, st.Interface()); err != nil { - return xerrors.Errorf("read actor head: %w", err) - } - - out := reflect.ValueOf(fn).Call([]reflect.Value{reflect.ValueOf(vm.cst), st}) - if !out[0].IsNil() && out[0].Interface().(error) != nil { - return out[0].Interface().(error) - } - - head, err := vm.cst.Put(ctx, st.Interface()) - if err != nil { - return xerrors.Errorf("put new actor head: %w", err) - } - - act.Head = head - - if err := vm.cstate.SetActor(addr, act); err != nil { - return xerrors.Errorf("set actor: %w", err) - } - - return nil -} - func linksForObj(blk block.Block, cb func(cid.Cid)) error { switch blk.Cid().Prefix().Codec { case cid.DagCBOR: diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go index d5f1d5ad6..87493c58a 100644 --- a/cmd/lotus-seed/genesis.go +++ b/cmd/lotus-seed/genesis.go @@ -9,6 +9,8 @@ import ( "strconv" "strings" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" @@ -39,6 +41,7 @@ var genesisCmd = &cli.Command{ genesisAddMsigsCmd, genesisSetVRKCmd, genesisSetRemainderCmd, + genesisSetActorVersionCmd, genesisCarCmd, }, } @@ -56,6 +59,7 @@ var genesisNewCmd = &cli.Command{ return xerrors.New("seed genesis new [genesis.json]") } out := genesis.Template{ + NetworkVersion: network.Version0, Accounts: []genesis.Actor{}, Miners: []genesis.Miner{}, VerifregRootKey: gen.DefaultVerifregRootkeyActor, @@ -503,6 +507,53 @@ var genesisSetRemainderCmd = &cli.Command{ }, } +var genesisSetActorVersionCmd = &cli.Command{ + Name: "set-network-version", + Usage: "Set the version that this network will start from", + ArgsUsage: " ", + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() != 2 { + return fmt.Errorf("must specify genesis file and network version (e.g. '0'") + } + + genf, err := homedir.Expand(cctx.Args().First()) + if err != nil { + return err + } + + var template genesis.Template + b, err := ioutil.ReadFile(genf) + if err != nil { + return xerrors.Errorf("read genesis template: %w", err) + } + + if err := json.Unmarshal(b, &template); err != nil { + return xerrors.Errorf("unmarshal genesis template: %w", err) + } + + nv, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64) + if err != nil { + return xerrors.Errorf("parsing network version: %w", err) + } + + if nv > uint64(build.NewestNetworkVersion) { + return xerrors.Errorf("invalid network version: %d", nv) + } + + template.NetworkVersion = network.Version(nv) + + b, err = json.MarshalIndent(&template, "", " ") + if err != nil { + return err + } + + if err := ioutil.WriteFile(genf, b, 0644); err != nil { + return err + } + return nil + }, +} + var genesisCarCmd = &cli.Command{ Name: "car", Description: "write genesis car file", diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index c4e62b419..c92397125 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -94,6 +94,11 @@ var preSealCmd = &cli.Command{ Name: "fake-sectors", Value: false, }, + &cli.IntFlag{ + Name: "network-version", + Value: 0, + Usage: "specify network version", + }, }, Action: func(c *cli.Context) error { sdir := c.String("sector-dir") @@ -129,7 +134,7 @@ var preSealCmd = &cli.Command{ } sectorSize := abi.SectorSize(sectorSizeInt) - spt, err := miner.SealProofTypeFromSectorSize(sectorSize, network.Version0) + spt, err := miner.SealProofTypeFromSectorSize(sectorSize, network.Version(c.Uint64("network-version"))) if err != nil { return err } diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index 0372c0dab..a8b760f8a 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -4551,7 +4551,7 @@ Inputs: ] ``` -Response: `11` +Response: `12` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index bf282745a..be326b3e8 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -4772,7 +4772,7 @@ Inputs: ] ``` -Response: `11` +Response: `12` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/genesis/types.go b/genesis/types.go index db8d32a3b..d4c04113a 100644 --- a/genesis/types.go +++ b/genesis/types.go @@ -3,6 +3,8 @@ package genesis import ( "encoding/json" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" @@ -75,8 +77,9 @@ type Actor struct { } type Template struct { - Accounts []Actor - Miners []Miner + NetworkVersion network.Version + Accounts []Actor + Miners []Miner NetworkName string Timestamp uint64 `json:",omitempty"` diff --git a/node/test/builder.go b/node/test/builder.go index 7e26966a8..bd180ee41 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -12,6 +12,8 @@ import ( "testing" "time" + "github.com/filecoin-project/go-state-types/network" + "github.com/gorilla/mux" "golang.org/x/xerrors" @@ -277,6 +279,7 @@ func mockBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []test. genms = append(genms, *genm) } templ := &genesis.Template{ + NetworkVersion: network.Version0, Accounts: genaccs, Miners: genms, NetworkName: "test", @@ -440,6 +443,7 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes genms = append(genms, *genm) } templ := &genesis.Template{ + NetworkVersion: network.Version0, Accounts: genaccs, Miners: genms, NetworkName: "test", From e6b631078f2da81471bcbac07fed02c2db805f93 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Tue, 25 May 2021 23:53:08 -0700 Subject: [PATCH 72/80] update jaeger documentation --- documentation/en/jaeger-tracing.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/documentation/en/jaeger-tracing.md b/documentation/en/jaeger-tracing.md index bbe4d3052..ec9351d53 100644 --- a/documentation/en/jaeger-tracing.md +++ b/documentation/en/jaeger-tracing.md @@ -12,7 +12,20 @@ Currently it is set up to use Jaeger, though other tracing backends should be fa To easily run and view tracing locally, first, install jaeger. The easiest way to do this is to [download the binaries](https://www.jaegertracing.io/download/) and then run the `jaeger-all-in-one` binary. This will start up jaeger, listen for spans on `localhost:6831`, and expose a web UI for viewing traces on `http://localhost:16686/`. -Now, to start sending traces from Lotus to Jaeger, set the environment variable `LOTUS_JAEGER` to `localhost:6831`, and start the `lotus daemon`. +Now, to start sending traces from Lotus to Jaeger, set the environment variable and start the daemon. + +```bash +export LOTUS_JAEGER_AGENT_ENDPOINT=127.0.0.1:6831 +lotus daemon +``` + +Alternatively, the agent endpoint can also be configured by a pair of environemnt variables to provide the host and port. The following snipit is functionally equivilent to the previous. + +```bash +export LOTUS_JAEGER_AGENT_HOST=127.0.0.1 +export LOTUS_JAEGER_AGENT_PORT=6831 +lotus daemon +``` Now, to view any generated traces, open up `http://localhost:16686/` in your browser. From d50b59b4c70fd0428a46bf2c28662f4be1be9f53 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Tue, 25 May 2021 23:55:46 -0700 Subject: [PATCH 73/80] don't scare the gosec linter --- lib/tracing/setup.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/tracing/setup.go b/lib/tracing/setup.go index 9f30b7714..1ace962e5 100644 --- a/lib/tracing/setup.go +++ b/lib/tracing/setup.go @@ -17,19 +17,20 @@ const ( envAgentEndpoint = "LOTUS_JAEGER_AGENT_ENDPOINT" envAgentHost = "LOTUS_JAEGER_AGENT_HOST" envAgentPort = "LOTUS_JAEGER_AGENT_PORT" - envUsername = "LOTUS_JAEGER_USERNAME" - envPassword = "LOTUS_JAEGER_PASSWORD" + envJaegerUser = "LOTUS_JAEGER_USERNAME" + envJaegerCred = "LOTUS_JAEGER_PASSWORD" ) // When sending directly to the collector, agent options are ignored. // The collector endpoint is an HTTP or HTTPs URL. -// The agent endpoint is a thrift/udp protocol given like "hostname:port" -// or separate host and port environment variables. +// The agent endpoint is a thrift/udp protocol and should be given +// as a string like "hostname:port". The agent can also be configured +// with separate host and port variables. func jaegerOptsFromEnv(opts *jaeger.Options) bool { var e string var ok bool - if e, ok = os.LookupEnv(envUsername); ok { - if p, ok := os.LookupEnv(envPassword); ok { + if e, ok = os.LookupEnv(envJaegerUser); ok { + if p, ok := os.LookupEnv(envJaegerCred); ok { opts.Username = e opts.Password = p } else { @@ -67,7 +68,7 @@ func SetupJaegerTracing(serviceName string) *jaeger.Exporter { opts.ServiceName = serviceName je, err := jaeger.NewExporter(opts) if err != nil { - log.Errorw("Failed to create the Jaeger exporter", "error", err) + log.Errorw("failed to create the jaeger exporter", "error", err) return nil } From 43c62f4406298b892fa7a8ca87dfe1f89de162ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 26 May 2021 12:33:08 +0200 Subject: [PATCH 74/80] Revert "Allow starting networks from arbitrary actor versions" --- build/openrpc/full.json.gz | Bin 23305 -> 23308 bytes build/params_2k.go | 20 +- build/params_shared_vals.go | 2 +- chain/actors/adt/temp | 0 chain/actors/aerrors/temp | 0 chain/actors/agen/main.go | 72 ++-- chain/actors/agen/temp | 0 chain/actors/builtin/account/account.go | 41 --- .../actors/builtin/account/actor.go.template | 23 -- .../actors/builtin/account/state.go.template | 10 - chain/actors/builtin/account/temp | 0 chain/actors/builtin/account/v0.go | 10 - chain/actors/builtin/account/v2.go | 10 - chain/actors/builtin/account/v3.go | 10 - chain/actors/builtin/account/v4.go | 10 - chain/actors/builtin/builtin.go.template | 94 ++--- chain/actors/builtin/cron/actor.go.template | 34 +- chain/actors/builtin/cron/cron.go | 54 --- chain/actors/builtin/cron/state.go.template | 35 -- chain/actors/builtin/cron/temp | 0 chain/actors/builtin/cron/v0.go | 35 -- chain/actors/builtin/cron/v2.go | 35 -- chain/actors/builtin/cron/v3.go | 35 -- chain/actors/builtin/cron/v4.go | 35 -- chain/actors/builtin/init/actor.go.template | 31 +- chain/actors/builtin/init/diff.go | 4 +- chain/actors/builtin/init/init.go | 49 +-- chain/actors/builtin/init/state.go.template | 38 +- chain/actors/builtin/init/temp | 0 chain/actors/builtin/init/v0.go | 31 +- chain/actors/builtin/init/v2.go | 31 +- chain/actors/builtin/init/v3.go | 31 +- chain/actors/builtin/init/v4.go | 31 +- chain/actors/builtin/market/actor.go.template | 80 ++--- chain/actors/builtin/market/market.go | 42 +-- chain/actors/builtin/market/state.go.template | 29 -- chain/actors/builtin/market/temp | 0 chain/actors/builtin/market/v0.go | 22 -- chain/actors/builtin/market/v2.go | 22 -- chain/actors/builtin/market/v3.go | 17 - chain/actors/builtin/market/v4.go | 17 - chain/actors/builtin/miner/actor.go.template | 86 ++--- chain/actors/builtin/miner/miner.go | 46 --- chain/actors/builtin/miner/state.go.template | 101 ++---- chain/actors/builtin/miner/temp | 0 chain/actors/builtin/miner/v0.go | 21 -- chain/actors/builtin/miner/v2.go | 51 --- chain/actors/builtin/miner/v3.go | 51 --- chain/actors/builtin/miner/v4.go | 51 --- .../actors/builtin/multisig/actor.go.template | 24 +- .../builtin/multisig/message.go.template | 36 +- chain/actors/builtin/multisig/multisig.go | 40 --- .../actors/builtin/multisig/state.go.template | 30 -- chain/actors/builtin/multisig/temp | 0 chain/actors/builtin/multisig/v0.go | 23 -- chain/actors/builtin/multisig/v2.go | 23 -- chain/actors/builtin/multisig/v3.go | 23 -- chain/actors/builtin/multisig/v4.go | 23 -- chain/actors/builtin/paych/actor.go.template | 23 -- .../actors/builtin/paych/message.go.template | 28 +- chain/actors/builtin/paych/mock/mock.go | 4 - chain/actors/builtin/paych/mock/temp | 0 chain/actors/builtin/paych/paych.go | 41 --- chain/actors/builtin/paych/state.go.template | 10 - chain/actors/builtin/paych/temp | 0 chain/actors/builtin/paych/v0.go | 10 - chain/actors/builtin/paych/v2.go | 10 - chain/actors/builtin/paych/v3.go | 10 - chain/actors/builtin/paych/v4.go | 10 - chain/actors/builtin/power/actor.go.template | 31 +- chain/actors/builtin/power/power.go | 47 --- chain/actors/builtin/power/state.go.template | 60 +--- chain/actors/builtin/power/temp | 0 chain/actors/builtin/power/v0.go | 42 --- chain/actors/builtin/power/v2.go | 42 --- chain/actors/builtin/power/v3.go | 37 -- chain/actors/builtin/power/v4.go | 37 -- chain/actors/builtin/reward/actor.go.template | 23 -- chain/actors/builtin/reward/reward.go | 41 --- chain/actors/builtin/reward/state.go.template | 10 - chain/actors/builtin/reward/temp | 0 chain/actors/builtin/reward/v0.go | 10 - chain/actors/builtin/reward/v2.go | 10 - chain/actors/builtin/reward/v3.go | 10 - chain/actors/builtin/reward/v4.go | 10 - chain/actors/builtin/system/actor.go.template | 41 --- chain/actors/builtin/system/state.go.template | 35 -- chain/actors/builtin/system/system.go | 63 ---- chain/actors/builtin/system/temp | 0 chain/actors/builtin/system/v0.go | 35 -- chain/actors/builtin/system/v2.go | 35 -- chain/actors/builtin/system/v3.go | 35 -- chain/actors/builtin/system/v4.go | 35 -- chain/actors/builtin/temp | 0 .../actors/builtin/verifreg/actor.go.template | 24 -- .../actors/builtin/verifreg/state.go.template | 26 +- chain/actors/builtin/verifreg/temp | 0 chain/actors/builtin/verifreg/v0.go | 17 - chain/actors/builtin/verifreg/v2.go | 17 - chain/actors/builtin/verifreg/v3.go | 17 - chain/actors/builtin/verifreg/v4.go | 17 - chain/actors/builtin/verifreg/verifreg.go | 41 --- chain/actors/policy/policy.go.template | 164 ++++----- chain/actors/policy/temp | 0 chain/actors/temp | 0 chain/actors/version.go | 4 - chain/gen/gen.go | 3 - chain/gen/genesis/f00_system.go | 21 +- chain/gen/genesis/f01_init.go | 40 +-- chain/gen/genesis/f02_reward.go | 33 +- chain/gen/genesis/f03_cron.go | 34 +- chain/gen/genesis/f04_power.go | 31 +- chain/gen/genesis/f05_market.go | 30 +- chain/gen/genesis/f06_vreg.go | 25 +- chain/gen/genesis/genesis.go | 252 ++++++------- chain/gen/genesis/miners.go | 331 ++++-------------- chain/gen/genesis/util.go | 29 ++ chain/state/statetree.go | 17 +- chain/state/statetree_test.go | 48 +-- chain/vm/vm.go | 35 +- cmd/lotus-seed/genesis.go | 51 --- cmd/lotus-seed/main.go | 7 +- documentation/en/api-v0-methods.md | 2 +- documentation/en/api-v1-unstable-methods.md | 2 +- genesis/types.go | 7 +- node/test/builder.go | 4 - 126 files changed, 656 insertions(+), 3177 deletions(-) delete mode 100644 chain/actors/adt/temp delete mode 100644 chain/actors/aerrors/temp delete mode 100644 chain/actors/agen/temp delete mode 100644 chain/actors/builtin/account/temp delete mode 100644 chain/actors/builtin/cron/state.go.template delete mode 100644 chain/actors/builtin/cron/temp delete mode 100644 chain/actors/builtin/cron/v0.go delete mode 100644 chain/actors/builtin/cron/v2.go delete mode 100644 chain/actors/builtin/cron/v3.go delete mode 100644 chain/actors/builtin/cron/v4.go delete mode 100644 chain/actors/builtin/init/temp delete mode 100644 chain/actors/builtin/market/temp delete mode 100644 chain/actors/builtin/miner/temp delete mode 100644 chain/actors/builtin/multisig/temp delete mode 100644 chain/actors/builtin/paych/mock/temp delete mode 100644 chain/actors/builtin/paych/temp delete mode 100644 chain/actors/builtin/power/temp delete mode 100644 chain/actors/builtin/reward/temp delete mode 100644 chain/actors/builtin/system/actor.go.template delete mode 100644 chain/actors/builtin/system/state.go.template delete mode 100644 chain/actors/builtin/system/system.go delete mode 100644 chain/actors/builtin/system/temp delete mode 100644 chain/actors/builtin/system/v0.go delete mode 100644 chain/actors/builtin/system/v2.go delete mode 100644 chain/actors/builtin/system/v3.go delete mode 100644 chain/actors/builtin/system/v4.go delete mode 100644 chain/actors/builtin/temp delete mode 100644 chain/actors/builtin/verifreg/temp delete mode 100644 chain/actors/policy/temp delete mode 100644 chain/actors/temp diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 394f1998be7c464c835d2474d93a843971cb659d..4d9fb5284d1c6ed52d84f50d11610f338e15b4bf 100644 GIT binary patch delta 4870 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 delta 4808 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 iHs;oFN" } } func IsBuiltinActor(c cid.Cid) bool { - {{range .versions}} - if builtin{{.}}.IsBuiltinActor(c) { - return true - } - {{end}} - return false + {{range .versions}} + if builtin{{.}}.IsBuiltinActor(c) { + return true + } + {{end}} + return false } func IsAccountActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.AccountActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.AccountActorCodeID { + return true + } + {{end}} + return false } func IsStorageMinerActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.StorageMinerActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.StorageMinerActorCodeID { + return true + } + {{end}} + return false } func IsMultisigActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.MultisigActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.MultisigActorCodeID { + return true + } + {{end}} + return false } func IsPaymentChannelActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.PaymentChannelActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.PaymentChannelActorCodeID { + return true + } + {{end}} + return false } func makeAddress(addr string) address.Address { diff --git a/chain/actors/builtin/cron/actor.go.template b/chain/actors/builtin/cron/actor.go.template index d73808556..6b7449617 100644 --- a/chain/actors/builtin/cron/actor.go.template +++ b/chain/actors/builtin/cron/actor.go.template @@ -1,42 +1,10 @@ package cron import ( - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/actors/adt" - "golang.org/x/xerrors" - "github.com/ipfs/go-cid" -{{range .versions}} - builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" -{{end}} + builtin{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin" ) -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return make{{.}}(store) -{{end}} -} - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return builtin{{.}}.CronActorCodeID, nil -{{end}} - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - var ( Address = builtin{{.latestVersion}}.CronActorAddr Methods = builtin{{.latestVersion}}.MethodsCron ) - - -type State interface { - GetState() interface{} -} diff --git a/chain/actors/builtin/cron/cron.go b/chain/actors/builtin/cron/cron.go index 62fa413a8..52a9fab07 100644 --- a/chain/actors/builtin/cron/cron.go +++ b/chain/actors/builtin/cron/cron.go @@ -1,64 +1,10 @@ package cron import ( - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/ipfs/go-cid" - "golang.org/x/xerrors" - - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - - builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" - - builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" - builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" ) -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { - - case actors.Version0: - return make0(store) - - case actors.Version2: - return make2(store) - - case actors.Version3: - return make3(store) - - case actors.Version4: - return make4(store) - - } - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { - - case actors.Version0: - return builtin0.CronActorCodeID, nil - - case actors.Version2: - return builtin2.CronActorCodeID, nil - - case actors.Version3: - return builtin3.CronActorCodeID, nil - - case actors.Version4: - return builtin4.CronActorCodeID, nil - - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - var ( Address = builtin4.CronActorAddr Methods = builtin4.MethodsCron ) - -type State interface { - GetState() interface{} -} diff --git a/chain/actors/builtin/cron/state.go.template b/chain/actors/builtin/cron/state.go.template deleted file mode 100644 index 99a06d7f8..000000000 --- a/chain/actors/builtin/cron/state.go.template +++ /dev/null @@ -1,35 +0,0 @@ -package cron - -import ( - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - cron{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/cron" -) - -var _ State = (*state{{.v}})(nil) - -func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { - out := state{{.v}}{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -func make{{.v}}(store adt.Store) (State, error) { - out := state{{.v}}{store: store} - out.State = *cron{{.v}}.ConstructState(cron{{.v}}.BuiltInEntries()) - return &out, nil -} - -type state{{.v}} struct { - cron{{.v}}.State - store adt.Store -} - -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} \ No newline at end of file diff --git a/chain/actors/builtin/cron/temp b/chain/actors/builtin/cron/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/cron/v0.go b/chain/actors/builtin/cron/v0.go deleted file mode 100644 index 6147b858c..000000000 --- a/chain/actors/builtin/cron/v0.go +++ /dev/null @@ -1,35 +0,0 @@ -package cron - -import ( - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - cron0 "github.com/filecoin-project/specs-actors/actors/builtin/cron" -) - -var _ State = (*state0)(nil) - -func load0(store adt.Store, root cid.Cid) (State, error) { - out := state0{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -func make0(store adt.Store) (State, error) { - out := state0{store: store} - out.State = *cron0.ConstructState(cron0.BuiltInEntries()) - return &out, nil -} - -type state0 struct { - cron0.State - store adt.Store -} - -func (s *state0) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/cron/v2.go b/chain/actors/builtin/cron/v2.go deleted file mode 100644 index 51ca179d9..000000000 --- a/chain/actors/builtin/cron/v2.go +++ /dev/null @@ -1,35 +0,0 @@ -package cron - -import ( - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - cron2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/cron" -) - -var _ State = (*state2)(nil) - -func load2(store adt.Store, root cid.Cid) (State, error) { - out := state2{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -func make2(store adt.Store) (State, error) { - out := state2{store: store} - out.State = *cron2.ConstructState(cron2.BuiltInEntries()) - return &out, nil -} - -type state2 struct { - cron2.State - store adt.Store -} - -func (s *state2) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/cron/v3.go b/chain/actors/builtin/cron/v3.go deleted file mode 100644 index ff74d511d..000000000 --- a/chain/actors/builtin/cron/v3.go +++ /dev/null @@ -1,35 +0,0 @@ -package cron - -import ( - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - cron3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/cron" -) - -var _ State = (*state3)(nil) - -func load3(store adt.Store, root cid.Cid) (State, error) { - out := state3{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -func make3(store adt.Store) (State, error) { - out := state3{store: store} - out.State = *cron3.ConstructState(cron3.BuiltInEntries()) - return &out, nil -} - -type state3 struct { - cron3.State - store adt.Store -} - -func (s *state3) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/cron/v4.go b/chain/actors/builtin/cron/v4.go deleted file mode 100644 index 1cff8cc28..000000000 --- a/chain/actors/builtin/cron/v4.go +++ /dev/null @@ -1,35 +0,0 @@ -package cron - -import ( - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - cron4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/cron" -) - -var _ State = (*state4)(nil) - -func load4(store adt.Store, root cid.Cid) (State, error) { - out := state4{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -func make4(store adt.Store) (State, error) { - out := state4{store: store} - out.State = *cron4.ConstructState(cron4.BuiltInEntries()) - return &out, nil -} - -type state4 struct { - cron4.State - store adt.Store -} - -func (s *state4) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/init/actor.go.template b/chain/actors/builtin/init/actor.go.template index f825eb9fa..5b700cec8 100644 --- a/chain/actors/builtin/init/actor.go.template +++ b/chain/actors/builtin/init/actor.go.template @@ -1,7 +1,6 @@ package init import ( - "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -40,27 +39,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version, networkName string) (State, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return make{{.}}(store, networkName) -{{end}} -} - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return builtin{{.}}.InitActorCodeID, nil -{{end}} - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -78,12 +56,5 @@ type State interface { // Sets the network's name. This should only be used on upgrade/fork. SetNetworkName(name string) error - // Sets the next ID for the init actor. This should only be used for testing. - SetNextID(id abi.ActorID) error - - // Sets the address map for the init actor. This should only be used for testing. - SetAddressMap(mcid cid.Cid) error - - AddressMap() (adt.Map, error) - GetState() interface{} + addressMap() (adt.Map, error) } diff --git a/chain/actors/builtin/init/diff.go b/chain/actors/builtin/init/diff.go index 5eb8f3c75..593171322 100644 --- a/chain/actors/builtin/init/diff.go +++ b/chain/actors/builtin/init/diff.go @@ -11,12 +11,12 @@ import ( ) func DiffAddressMap(pre, cur State) (*AddressMapChanges, error) { - prem, err := pre.AddressMap() + prem, err := pre.addressMap() if err != nil { return nil, err } - curm, err := cur.AddressMap() + curm, err := cur.addressMap() if err != nil { return nil, err } diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index 2091252ce..730d21fd8 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -1,7 +1,6 @@ package init import ( - "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -66,45 +65,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version, networkName string) (State, error) { - switch av { - - case actors.Version0: - return make0(store, networkName) - - case actors.Version2: - return make2(store, networkName) - - case actors.Version3: - return make3(store, networkName) - - case actors.Version4: - return make4(store, networkName) - - } - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { - - case actors.Version0: - return builtin0.InitActorCodeID, nil - - case actors.Version2: - return builtin2.InitActorCodeID, nil - - case actors.Version3: - return builtin3.InitActorCodeID, nil - - case actors.Version4: - return builtin4.InitActorCodeID, nil - - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -122,12 +82,5 @@ type State interface { // Sets the network's name. This should only be used on upgrade/fork. SetNetworkName(name string) error - // Sets the next ID for the init actor. This should only be used for testing. - SetNextID(id abi.ActorID) error - - // Sets the address map for the init actor. This should only be used for testing. - SetAddressMap(mcid cid.Cid) error - - AddressMap() (adt.Map, error) - GetState() interface{} + addressMap() (adt.Map, error) } diff --git a/chain/actors/builtin/init/state.go.template b/chain/actors/builtin/init/state.go.template index 482ad4df5..95f052bda 100644 --- a/chain/actors/builtin/init/state.go.template +++ b/chain/actors/builtin/init/state.go.template @@ -29,26 +29,6 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make{{.v}}(store adt.Store, networkName string) (State, error) { - out := state{{.v}}{store: store} - {{if (le .v 2)}} - mr, err := adt{{.v}}.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State = *init{{.v}}.ConstructState(mr, networkName) - {{else}} - s, err := init{{.v}}.ConstructState(store, networkName) - if err != nil { - return nil, err - } - - out.State = *s - {{end}} - return &out, nil -} - type state{{.v}} struct { init{{.v}}.State store adt.Store @@ -86,11 +66,6 @@ func (s *state{{.v}}) SetNetworkName(name string) error { return nil } -func (s *state{{.v}}) SetNextID(id abi.ActorID) error { - s.State.NextID = id - return nil -} - func (s *state{{.v}}) Remove(addrs ...address.Address) (err error) { m, err := adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) if err != nil { @@ -109,15 +84,6 @@ func (s *state{{.v}}) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state{{.v}}) SetAddressMap(mcid cid.Cid) error { - s.State.AddressMap = mcid - return nil +func (s *state{{.v}}) addressMap() (adt.Map, error) { + return adt{{.v}}.AsMap(s.store, s.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) } - -func (s *state{{.v}}) AddressMap() (adt.Map, error) { - return adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) -} - -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} \ No newline at end of file diff --git a/chain/actors/builtin/init/temp b/chain/actors/builtin/init/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/init/v0.go b/chain/actors/builtin/init/v0.go index ddd2dab94..c019705b1 100644 --- a/chain/actors/builtin/init/v0.go +++ b/chain/actors/builtin/init/v0.go @@ -25,19 +25,6 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make0(store adt.Store, networkName string) (State, error) { - out := state0{store: store} - - mr, err := adt0.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State = *init0.ConstructState(mr, networkName) - - return &out, nil -} - type state0 struct { init0.State store adt.Store @@ -75,11 +62,6 @@ func (s *state0) SetNetworkName(name string) error { return nil } -func (s *state0) SetNextID(id abi.ActorID) error { - s.State.NextID = id - return nil -} - func (s *state0) Remove(addrs ...address.Address) (err error) { m, err := adt0.AsMap(s.store, s.State.AddressMap) if err != nil { @@ -98,15 +80,6 @@ func (s *state0) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state0) SetAddressMap(mcid cid.Cid) error { - s.State.AddressMap = mcid - return nil -} - -func (s *state0) AddressMap() (adt.Map, error) { - return adt0.AsMap(s.store, s.State.AddressMap) -} - -func (s *state0) GetState() interface{} { - return &s.State +func (s *state0) addressMap() (adt.Map, error) { + return adt0.AsMap(s.store, s.AddressMap) } diff --git a/chain/actors/builtin/init/v2.go b/chain/actors/builtin/init/v2.go index 72e2d56a5..420243be4 100644 --- a/chain/actors/builtin/init/v2.go +++ b/chain/actors/builtin/init/v2.go @@ -25,19 +25,6 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make2(store adt.Store, networkName string) (State, error) { - out := state2{store: store} - - mr, err := adt2.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State = *init2.ConstructState(mr, networkName) - - return &out, nil -} - type state2 struct { init2.State store adt.Store @@ -75,11 +62,6 @@ func (s *state2) SetNetworkName(name string) error { return nil } -func (s *state2) SetNextID(id abi.ActorID) error { - s.State.NextID = id - return nil -} - func (s *state2) Remove(addrs ...address.Address) (err error) { m, err := adt2.AsMap(s.store, s.State.AddressMap) if err != nil { @@ -98,15 +80,6 @@ func (s *state2) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state2) SetAddressMap(mcid cid.Cid) error { - s.State.AddressMap = mcid - return nil -} - -func (s *state2) AddressMap() (adt.Map, error) { - return adt2.AsMap(s.store, s.State.AddressMap) -} - -func (s *state2) GetState() interface{} { - return &s.State +func (s *state2) addressMap() (adt.Map, error) { + return adt2.AsMap(s.store, s.AddressMap) } diff --git a/chain/actors/builtin/init/v3.go b/chain/actors/builtin/init/v3.go index 4609c94a3..eaa54dfd4 100644 --- a/chain/actors/builtin/init/v3.go +++ b/chain/actors/builtin/init/v3.go @@ -27,19 +27,6 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make3(store adt.Store, networkName string) (State, error) { - out := state3{store: store} - - s, err := init3.ConstructState(store, networkName) - if err != nil { - return nil, err - } - - out.State = *s - - return &out, nil -} - type state3 struct { init3.State store adt.Store @@ -77,11 +64,6 @@ func (s *state3) SetNetworkName(name string) error { return nil } -func (s *state3) SetNextID(id abi.ActorID) error { - s.State.NextID = id - return nil -} - func (s *state3) Remove(addrs ...address.Address) (err error) { m, err := adt3.AsMap(s.store, s.State.AddressMap, builtin3.DefaultHamtBitwidth) if err != nil { @@ -100,15 +82,6 @@ func (s *state3) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state3) SetAddressMap(mcid cid.Cid) error { - s.State.AddressMap = mcid - return nil -} - -func (s *state3) AddressMap() (adt.Map, error) { - return adt3.AsMap(s.store, s.State.AddressMap, builtin3.DefaultHamtBitwidth) -} - -func (s *state3) GetState() interface{} { - return &s.State +func (s *state3) addressMap() (adt.Map, error) { + return adt3.AsMap(s.store, s.AddressMap, builtin3.DefaultHamtBitwidth) } diff --git a/chain/actors/builtin/init/v4.go b/chain/actors/builtin/init/v4.go index dc56d1f19..38749eed5 100644 --- a/chain/actors/builtin/init/v4.go +++ b/chain/actors/builtin/init/v4.go @@ -27,19 +27,6 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make4(store adt.Store, networkName string) (State, error) { - out := state4{store: store} - - s, err := init4.ConstructState(store, networkName) - if err != nil { - return nil, err - } - - out.State = *s - - return &out, nil -} - type state4 struct { init4.State store adt.Store @@ -77,11 +64,6 @@ func (s *state4) SetNetworkName(name string) error { return nil } -func (s *state4) SetNextID(id abi.ActorID) error { - s.State.NextID = id - return nil -} - func (s *state4) Remove(addrs ...address.Address) (err error) { m, err := adt4.AsMap(s.store, s.State.AddressMap, builtin4.DefaultHamtBitwidth) if err != nil { @@ -100,15 +82,6 @@ func (s *state4) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state4) SetAddressMap(mcid cid.Cid) error { - s.State.AddressMap = mcid - return nil -} - -func (s *state4) AddressMap() (adt.Map, error) { - return adt4.AsMap(s.store, s.State.AddressMap, builtin4.DefaultHamtBitwidth) -} - -func (s *state4) GetState() interface{} { - return &s.State +func (s *state4) addressMap() (adt.Map, error) { + return adt4.AsMap(s.store, s.AddressMap, builtin4.DefaultHamtBitwidth) } diff --git a/chain/actors/builtin/market/actor.go.template b/chain/actors/builtin/market/actor.go.template index 5b67695e1..39cfe1be7 100644 --- a/chain/actors/builtin/market/actor.go.template +++ b/chain/actors/builtin/market/actor.go.template @@ -16,7 +16,6 @@ import ( {{end}} "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" ) @@ -43,27 +42,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return make{{.}}(store) -{{end}} -} - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return builtin{{.}}.StorageMarketActorCodeID, nil -{{end}} - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler BalancesChanged(State) (bool, error) @@ -78,7 +56,6 @@ type State interface { minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, ) (weight, verifiedWeight abi.DealWeight, err error) NextID() (abi.DealID, error) - GetState() interface{} } type BalanceTable interface { @@ -104,6 +81,7 @@ type DealProposals interface { type PublishStorageDealsParams = market0.PublishStorageDealsParams type PublishStorageDealsReturn = market0.PublishStorageDealsReturn +type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams type WithdrawBalanceParams = market0.WithdrawBalanceParams type ClientDealProposal = market0.ClientDealProposal @@ -111,71 +89,71 @@ type ClientDealProposal = market0.ClientDealProposal type DealState struct { SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated - SlashEpoch abi.ChainEpoch // -1 if deal never slashed + SlashEpoch abi.ChainEpoch // -1 if deal never slashed } type DealProposal struct { - PieceCID cid.Cid - PieceSize abi.PaddedPieceSize - VerifiedDeal bool - Client address.Address - Provider address.Address - Label string - StartEpoch abi.ChainEpoch - EndEpoch abi.ChainEpoch + PieceCID cid.Cid + PieceSize abi.PaddedPieceSize + VerifiedDeal bool + Client address.Address + Provider address.Address + Label string + StartEpoch abi.ChainEpoch + EndEpoch abi.ChainEpoch StoragePricePerEpoch abi.TokenAmount - ProviderCollateral abi.TokenAmount - ClientCollateral abi.TokenAmount + ProviderCollateral abi.TokenAmount + ClientCollateral abi.TokenAmount } type DealStateChanges struct { - Added []DealIDState + Added []DealIDState Modified []DealStateChange - Removed []DealIDState + Removed []DealIDState } type DealIDState struct { - ID abi.DealID + ID abi.DealID Deal DealState } // DealStateChange is a change in deal state from -> to type DealStateChange struct { - ID abi.DealID + ID abi.DealID From *DealState - To *DealState + To *DealState } type DealProposalChanges struct { - Added []ProposalIDState + Added []ProposalIDState Removed []ProposalIDState } type ProposalIDState struct { - ID abi.DealID + ID abi.DealID Proposal DealProposal } func EmptyDealState() *DealState { return &DealState{ SectorStartEpoch: -1, - SlashEpoch: -1, + SlashEpoch: -1, LastUpdatedEpoch: -1, } } // returns the earned fees and pending fees for a given deal func (deal DealProposal) GetDealFees(height abi.ChainEpoch) (abi.TokenAmount, abi.TokenAmount) { - tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch))) + tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch))) - ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch))) - if ef.LessThan(big.Zero()) { - ef = big.Zero() - } + ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch))) + if ef.LessThan(big.Zero()) { + ef = big.Zero() + } - if ef.GreaterThan(tf) { - ef = tf - } + if ef.GreaterThan(tf) { + ef = tf + } - return ef, big.Sub(tf, ef) + return ef, big.Sub(tf, ef) } diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index ffc826658..adf7ce33d 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -20,7 +20,6 @@ import ( builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" @@ -69,45 +68,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { - - case actors.Version0: - return make0(store) - - case actors.Version2: - return make2(store) - - case actors.Version3: - return make3(store) - - case actors.Version4: - return make4(store) - - } - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { - - case actors.Version0: - return builtin0.StorageMarketActorCodeID, nil - - case actors.Version2: - return builtin2.StorageMarketActorCodeID, nil - - case actors.Version3: - return builtin3.StorageMarketActorCodeID, nil - - case actors.Version4: - return builtin4.StorageMarketActorCodeID, nil - - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler BalancesChanged(State) (bool, error) @@ -122,7 +82,6 @@ type State interface { minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, ) (weight, verifiedWeight abi.DealWeight, err error) NextID() (abi.DealID, error) - GetState() interface{} } type BalanceTable interface { @@ -148,6 +107,7 @@ type DealProposals interface { type PublishStorageDealsParams = market0.PublishStorageDealsParams type PublishStorageDealsReturn = market0.PublishStorageDealsReturn +type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams type WithdrawBalanceParams = market0.WithdrawBalanceParams type ClientDealProposal = market0.ClientDealProposal diff --git a/chain/actors/builtin/market/state.go.template b/chain/actors/builtin/market/state.go.template index 965c8d41f..a55743ce5 100644 --- a/chain/actors/builtin/market/state.go.template +++ b/chain/actors/builtin/market/state.go.template @@ -26,31 +26,6 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make{{.v}}(store adt.Store) (State, error) { - out := state{{.v}}{store: store} - {{if (le .v 2)}} - ea, err := adt{{.v}}.MakeEmptyArray(store).Root() - if err != nil { - return nil, err - } - - em, err := adt{{.v}}.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State = *market{{.v}}.ConstructState(ea, em, em) - {{else}} - s, err := market{{.v}}.ConstructState(store) - if err != nil { - return nil, err - } - - out.State = *s - {{end}} - return &out, nil -} - type state{{.v}} struct { market{{.v}}.State store adt.Store @@ -232,7 +207,3 @@ func (s *dealProposals{{.v}}) array() adt.Array { func fromV{{.v}}DealProposal(v{{.v}} market{{.v}}.DealProposal) DealProposal { return (DealProposal)(v{{.v}}) } - -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} \ No newline at end of file diff --git a/chain/actors/builtin/market/temp b/chain/actors/builtin/market/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/market/v0.go b/chain/actors/builtin/market/v0.go index b3093b54b..175c0a2ea 100644 --- a/chain/actors/builtin/market/v0.go +++ b/chain/actors/builtin/market/v0.go @@ -26,24 +26,6 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make0(store adt.Store) (State, error) { - out := state0{store: store} - - ea, err := adt0.MakeEmptyArray(store).Root() - if err != nil { - return nil, err - } - - em, err := adt0.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State = *market0.ConstructState(ea, em, em) - - return &out, nil -} - type state0 struct { market0.State store adt.Store @@ -225,7 +207,3 @@ func (s *dealProposals0) array() adt.Array { func fromV0DealProposal(v0 market0.DealProposal) DealProposal { return (DealProposal)(v0) } - -func (s *state0) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/market/v2.go b/chain/actors/builtin/market/v2.go index fdedcce85..dafae8feb 100644 --- a/chain/actors/builtin/market/v2.go +++ b/chain/actors/builtin/market/v2.go @@ -26,24 +26,6 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make2(store adt.Store) (State, error) { - out := state2{store: store} - - ea, err := adt2.MakeEmptyArray(store).Root() - if err != nil { - return nil, err - } - - em, err := adt2.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State = *market2.ConstructState(ea, em, em) - - return &out, nil -} - type state2 struct { market2.State store adt.Store @@ -225,7 +207,3 @@ func (s *dealProposals2) array() adt.Array { func fromV2DealProposal(v2 market2.DealProposal) DealProposal { return (DealProposal)(v2) } - -func (s *state2) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/market/v3.go b/chain/actors/builtin/market/v3.go index 53d266443..dec8d6e25 100644 --- a/chain/actors/builtin/market/v3.go +++ b/chain/actors/builtin/market/v3.go @@ -26,19 +26,6 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make3(store adt.Store) (State, error) { - out := state3{store: store} - - s, err := market3.ConstructState(store) - if err != nil { - return nil, err - } - - out.State = *s - - return &out, nil -} - type state3 struct { market3.State store adt.Store @@ -220,7 +207,3 @@ func (s *dealProposals3) array() adt.Array { func fromV3DealProposal(v3 market3.DealProposal) DealProposal { return (DealProposal)(v3) } - -func (s *state3) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/market/v4.go b/chain/actors/builtin/market/v4.go index 30aa26920..22514395c 100644 --- a/chain/actors/builtin/market/v4.go +++ b/chain/actors/builtin/market/v4.go @@ -26,19 +26,6 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make4(store adt.Store) (State, error) { - out := state4{store: store} - - s, err := market4.ConstructState(store) - if err != nil { - return nil, err - } - - out.State = *s - - return &out, nil -} - type state4 struct { market4.State store adt.Store @@ -220,7 +207,3 @@ func (s *dealProposals4) array() adt.Array { func fromV4DealProposal(v4 market4.DealProposal) DealProposal { return (DealProposal)(v4) } - -func (s *state4) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/miner/actor.go.template b/chain/actors/builtin/miner/actor.go.template index c7755ef71..4b3d8db5e 100644 --- a/chain/actors/builtin/miner/actor.go.template +++ b/chain/actors/builtin/miner/actor.go.template @@ -3,7 +3,6 @@ package miner import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" cbg "github.com/whyrusleeping/cbor-gen" @@ -61,27 +60,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return make{{.}}(store) -{{end}} -} - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return builtin{{.}}.StorageMinerActorCodeID, nil -{{end}} - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -101,11 +79,6 @@ type State interface { NumLiveSectors() (uint64, error) IsAllocated(abi.SectorNumber) (bool, error) - // Note that ProvingPeriodStart is deprecated and will be renamed / removed in a future version of actors - GetProvingPeriodStart() (abi.ChainEpoch, error) - // Testing only - EraseAllUnproven() error - LoadDeadline(idx uint64) (Deadline, error) ForEachDeadline(cb func(idx uint64, dl Deadline) error) error NumDeadlines() (uint64, error) @@ -122,7 +95,6 @@ type State interface { decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error) precommits() (adt.Map, error) decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error) - GetState() interface{} } type Deadline interface { @@ -143,26 +115,26 @@ type Partition interface { } type SectorOnChainInfo struct { - SectorNumber abi.SectorNumber - SealProof abi.RegisteredSealProof - SealedCID cid.Cid - DealIDs []abi.DealID - Activation abi.ChainEpoch - Expiration abi.ChainEpoch - DealWeight abi.DealWeight - VerifiedDealWeight abi.DealWeight - InitialPledge abi.TokenAmount - ExpectedDayReward abi.TokenAmount + SectorNumber abi.SectorNumber + SealProof abi.RegisteredSealProof + SealedCID cid.Cid + DealIDs []abi.DealID + Activation abi.ChainEpoch + Expiration abi.ChainEpoch + DealWeight abi.DealWeight + VerifiedDealWeight abi.DealWeight + InitialPledge abi.TokenAmount + ExpectedDayReward abi.TokenAmount ExpectedStoragePledge abi.TokenAmount } type SectorPreCommitInfo = miner0.SectorPreCommitInfo type SectorPreCommitOnChainInfo struct { - Info SectorPreCommitInfo + Info SectorPreCommitInfo PreCommitDeposit abi.TokenAmount - PreCommitEpoch abi.ChainEpoch - DealWeight abi.DealWeight + PreCommitEpoch abi.ChainEpoch + DealWeight abi.DealWeight VerifiedDealWeight abi.DealWeight } @@ -231,17 +203,17 @@ func WinningPoStProofTypeFromWindowPoStProofType(nver network.Version, proof abi } type MinerInfo struct { - Owner address.Address // Must be an ID-address. - Worker address.Address // Must be an ID-address. - NewWorker address.Address // Must be an ID-address. - ControlAddresses []address.Address // Must be an ID-addresses. - WorkerChangeEpoch abi.ChainEpoch - PeerId *peer.ID - Multiaddrs []abi.Multiaddrs - WindowPoStProofType abi.RegisteredPoStProof - SectorSize abi.SectorSize + Owner address.Address // Must be an ID-address. + Worker address.Address // Must be an ID-address. + NewWorker address.Address // Must be an ID-address. + ControlAddresses []address.Address // Must be an ID-addresses. + WorkerChangeEpoch abi.ChainEpoch + PeerId *peer.ID + Multiaddrs []abi.Multiaddrs + WindowPoStProofType abi.RegisteredPoStProof + SectorSize abi.SectorSize WindowPoStPartitionSectors uint64 - ConsensusFaultElapsed abi.ChainEpoch + ConsensusFaultElapsed abi.ChainEpoch } func (mi MinerInfo) IsController(addr address.Address) bool { @@ -272,25 +244,25 @@ type SectorLocation struct { } type SectorChanges struct { - Added []SectorOnChainInfo + Added []SectorOnChainInfo Extended []SectorExtensions - Removed []SectorOnChainInfo + Removed []SectorOnChainInfo } type SectorExtensions struct { From SectorOnChainInfo - To SectorOnChainInfo + To SectorOnChainInfo } type PreCommitChanges struct { - Added []SectorPreCommitOnChainInfo + Added []SectorPreCommitOnChainInfo Removed []SectorPreCommitOnChainInfo } type LockedFunds struct { - VestingFunds abi.TokenAmount + VestingFunds abi.TokenAmount InitialPledgeRequirement abi.TokenAmount - PreCommitDeposits abi.TokenAmount + PreCommitDeposits abi.TokenAmount } func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount { diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index d9b872e3f..a426e063b 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -3,7 +3,6 @@ package miner import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" cbg "github.com/whyrusleeping/cbor-gen" @@ -87,45 +86,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { - - case actors.Version0: - return make0(store) - - case actors.Version2: - return make2(store) - - case actors.Version3: - return make3(store) - - case actors.Version4: - return make4(store) - - } - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { - - case actors.Version0: - return builtin0.StorageMinerActorCodeID, nil - - case actors.Version2: - return builtin2.StorageMinerActorCodeID, nil - - case actors.Version3: - return builtin3.StorageMinerActorCodeID, nil - - case actors.Version4: - return builtin4.StorageMinerActorCodeID, nil - - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -145,11 +105,6 @@ type State interface { NumLiveSectors() (uint64, error) IsAllocated(abi.SectorNumber) (bool, error) - // Note that ProvingPeriodStart is deprecated and will be renamed / removed in a future version of actors - GetProvingPeriodStart() (abi.ChainEpoch, error) - // Testing only - EraseAllUnproven() error - LoadDeadline(idx uint64) (Deadline, error) ForEachDeadline(cb func(idx uint64, dl Deadline) error) error NumDeadlines() (uint64, error) @@ -166,7 +121,6 @@ type State interface { decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error) precommits() (adt.Map, error) decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error) - GetState() interface{} } type Deadline interface { diff --git a/chain/actors/builtin/miner/state.go.template b/chain/actors/builtin/miner/state.go.template index 270510a8c..0769eea10 100644 --- a/chain/actors/builtin/miner/state.go.template +++ b/chain/actors/builtin/miner/state.go.template @@ -35,12 +35,6 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make{{.v}}(store adt.Store) (State, error) { - out := state{{.v}}{store: store} - out.State = miner{{.v}}.State{} - return &out, nil -} - type state{{.v}} struct { miner{{.v}}.State store adt.Store @@ -74,9 +68,9 @@ func (s *state{{.v}}) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) func (s *state{{.v}}) LockedFunds() (LockedFunds, error) { return LockedFunds{ - VestingFunds: s.State.LockedFunds, + VestingFunds: s.State.LockedFunds, InitialPledgeRequirement: s.State.InitialPledge{{if (le .v 1)}}Requirement{{end}}, - PreCommitDeposits: s.State.PreCommitDeposits, + PreCommitDeposits: s.State.PreCommitDeposits, }, nil } @@ -251,10 +245,6 @@ func (s *state{{.v}}) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } -func (s *state{{.v}}) GetProvingPeriodStart() (abi.ChainEpoch, error) { - return s.State.ProvingPeriodStart, nil -} - func (s *state{{.v}}) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -317,19 +307,19 @@ func (s *state{{.v}}) Info() (MinerInfo, error) { } {{end}} mi := MinerInfo{ - Owner: info.Owner, - Worker: info.Worker, + Owner: info.Owner, + Worker: info.Worker, ControlAddresses: info.ControlAddresses, - NewWorker: address.Undef, + NewWorker: address.Undef, WorkerChangeEpoch: -1, - PeerId: pid, - Multiaddrs: info.Multiaddrs, - WindowPoStProofType: {{if (ge .v 3)}}info.WindowPoStProofType{{else}}wpp{{end}}, - SectorSize: info.SectorSize, + PeerId: pid, + Multiaddrs: info.Multiaddrs, + WindowPoStProofType: {{if (ge .v 3)}}info.WindowPoStProofType{{else}}wpp{{end}}, + SectorSize: info.SectorSize, WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, - ConsensusFaultElapsed: {{if (ge .v 2)}}info.ConsensusFaultElapsed{{else}}-1{{end}}, + ConsensusFaultElapsed: {{if (ge .v 2)}}info.ConsensusFaultElapsed{{else}}-1{{end}}, } if info.PendingWorkerKey != nil { @@ -376,45 +366,6 @@ func (s *state{{.v}}) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (Secto return fromV{{.v}}SectorPreCommitOnChainInfo(sp), nil } -func (s *state{{.v}}) EraseAllUnproven() error { - {{if (ge .v 2)}} - dls, err := s.State.LoadDeadlines(s.store) - if err != nil { - return err - } - - err = dls.ForEach(s.store, func(dindx uint64, dl *miner{{.v}}.Deadline) error { - ps, err := dl.PartitionsArray(s.store) - if err != nil { - return err - } - - var part miner{{.v}}.Partition - err = ps.ForEach(&part, func(pindx int64) error { - _ = part.ActivateUnproven() - err = ps.Set(uint64(pindx), &part) - return nil - }) - - if err != nil { - return err - } - - dl.Partitions, err = ps.Root() - if err != nil { - return err - } - - return dls.UpdateDeadline(s.store, dindx, dl) - }) - - return s.State.SaveDeadlines(s.store, dls) - {{else}} - // field doesn't exist until v2 - {{end}} - return nil -} - func (d *deadline{{.v}}) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -477,16 +428,16 @@ func (p *partition{{.v}}) RecoveringSectors() (bitfield.BitField, error) { func fromV{{.v}}SectorOnChainInfo(v{{.v}} miner{{.v}}.SectorOnChainInfo) SectorOnChainInfo { {{if (ge .v 2)}} return SectorOnChainInfo{ - SectorNumber: v{{.v}}.SectorNumber, - SealProof: v{{.v}}.SealProof, - SealedCID: v{{.v}}.SealedCID, - DealIDs: v{{.v}}.DealIDs, - Activation: v{{.v}}.Activation, - Expiration: v{{.v}}.Expiration, - DealWeight: v{{.v}}.DealWeight, - VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, - InitialPledge: v{{.v}}.InitialPledge, - ExpectedDayReward: v{{.v}}.ExpectedDayReward, + SectorNumber: v{{.v}}.SectorNumber, + SealProof: v{{.v}}.SealProof, + SealedCID: v{{.v}}.SealedCID, + DealIDs: v{{.v}}.DealIDs, + Activation: v{{.v}}.Activation, + Expiration: v{{.v}}.Expiration, + DealWeight: v{{.v}}.DealWeight, + VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, + InitialPledge: v{{.v}}.InitialPledge, + ExpectedDayReward: v{{.v}}.ExpectedDayReward, ExpectedStoragePledge: v{{.v}}.ExpectedStoragePledge, } {{else}} @@ -497,17 +448,13 @@ func fromV{{.v}}SectorOnChainInfo(v{{.v}} miner{{.v}}.SectorOnChainInfo) SectorO func fromV{{.v}}SectorPreCommitOnChainInfo(v{{.v}} miner{{.v}}.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { {{if (ge .v 2)}} return SectorPreCommitOnChainInfo{ - Info: (SectorPreCommitInfo)(v{{.v}}.Info), - PreCommitDeposit: v{{.v}}.PreCommitDeposit, - PreCommitEpoch: v{{.v}}.PreCommitEpoch, - DealWeight: v{{.v}}.DealWeight, + Info: (SectorPreCommitInfo)(v{{.v}}.Info), + PreCommitDeposit: v{{.v}}.PreCommitDeposit, + PreCommitEpoch: v{{.v}}.PreCommitEpoch, + DealWeight: v{{.v}}.DealWeight, VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, } {{else}} return (SectorPreCommitOnChainInfo)(v0) {{end}} } - -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} \ No newline at end of file diff --git a/chain/actors/builtin/miner/temp b/chain/actors/builtin/miner/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/miner/v0.go b/chain/actors/builtin/miner/v0.go index 344be1993..2dc8ae23e 100644 --- a/chain/actors/builtin/miner/v0.go +++ b/chain/actors/builtin/miner/v0.go @@ -32,12 +32,6 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make0(store adt.Store) (State, error) { - out := state0{store: store} - out.State = miner0.State{} - return &out, nil -} - type state0 struct { miner0.State store adt.Store @@ -248,10 +242,6 @@ func (s *state0) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } -func (s *state0) GetProvingPeriodStart() (abi.ChainEpoch, error) { - return s.State.ProvingPeriodStart, nil -} - func (s *state0) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -373,13 +363,6 @@ func (s *state0) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV0SectorPreCommitOnChainInfo(sp), nil } -func (s *state0) EraseAllUnproven() error { - - // field doesn't exist until v2 - - return nil -} - func (d *deadline0) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -443,7 +426,3 @@ func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) Sect return (SectorPreCommitOnChainInfo)(v0) } - -func (s *state0) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/miner/v2.go b/chain/actors/builtin/miner/v2.go index 3e76d0b69..7564dd8b8 100644 --- a/chain/actors/builtin/miner/v2.go +++ b/chain/actors/builtin/miner/v2.go @@ -30,12 +30,6 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make2(store adt.Store) (State, error) { - out := state2{store: store} - out.State = miner2.State{} - return &out, nil -} - type state2 struct { miner2.State store adt.Store @@ -246,10 +240,6 @@ func (s *state2) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } -func (s *state2) GetProvingPeriodStart() (abi.ChainEpoch, error) { - return s.State.ProvingPeriodStart, nil -} - func (s *state2) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -371,43 +361,6 @@ func (s *state2) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV2SectorPreCommitOnChainInfo(sp), nil } -func (s *state2) EraseAllUnproven() error { - - dls, err := s.State.LoadDeadlines(s.store) - if err != nil { - return err - } - - err = dls.ForEach(s.store, func(dindx uint64, dl *miner2.Deadline) error { - ps, err := dl.PartitionsArray(s.store) - if err != nil { - return err - } - - var part miner2.Partition - err = ps.ForEach(&part, func(pindx int64) error { - _ = part.ActivateUnproven() - err = ps.Set(uint64(pindx), &part) - return nil - }) - - if err != nil { - return err - } - - dl.Partitions, err = ps.Root() - if err != nil { - return err - } - - return dls.UpdateDeadline(s.store, dindx, dl) - }) - - return s.State.SaveDeadlines(s.store, dls) - - return nil -} - func (d *deadline2) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -489,7 +442,3 @@ func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) Sect } } - -func (s *state2) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/miner/v3.go b/chain/actors/builtin/miner/v3.go index 72986233d..72a080f73 100644 --- a/chain/actors/builtin/miner/v3.go +++ b/chain/actors/builtin/miner/v3.go @@ -32,12 +32,6 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make3(store adt.Store) (State, error) { - out := state3{store: store} - out.State = miner3.State{} - return &out, nil -} - type state3 struct { miner3.State store adt.Store @@ -248,10 +242,6 @@ func (s *state3) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } -func (s *state3) GetProvingPeriodStart() (abi.ChainEpoch, error) { - return s.State.ProvingPeriodStart, nil -} - func (s *state3) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -368,43 +358,6 @@ func (s *state3) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV3SectorPreCommitOnChainInfo(sp), nil } -func (s *state3) EraseAllUnproven() error { - - dls, err := s.State.LoadDeadlines(s.store) - if err != nil { - return err - } - - err = dls.ForEach(s.store, func(dindx uint64, dl *miner3.Deadline) error { - ps, err := dl.PartitionsArray(s.store) - if err != nil { - return err - } - - var part miner3.Partition - err = ps.ForEach(&part, func(pindx int64) error { - _ = part.ActivateUnproven() - err = ps.Set(uint64(pindx), &part) - return nil - }) - - if err != nil { - return err - } - - dl.Partitions, err = ps.Root() - if err != nil { - return err - } - - return dls.UpdateDeadline(s.store, dindx, dl) - }) - - return s.State.SaveDeadlines(s.store, dls) - - return nil -} - func (d *deadline3) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -490,7 +443,3 @@ func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) Sect } } - -func (s *state3) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/miner/v4.go b/chain/actors/builtin/miner/v4.go index 96ed21f04..698bdf2f5 100644 --- a/chain/actors/builtin/miner/v4.go +++ b/chain/actors/builtin/miner/v4.go @@ -32,12 +32,6 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make4(store adt.Store) (State, error) { - out := state4{store: store} - out.State = miner4.State{} - return &out, nil -} - type state4 struct { miner4.State store adt.Store @@ -248,10 +242,6 @@ func (s *state4) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } -func (s *state4) GetProvingPeriodStart() (abi.ChainEpoch, error) { - return s.State.ProvingPeriodStart, nil -} - func (s *state4) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -368,43 +358,6 @@ func (s *state4) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV4SectorPreCommitOnChainInfo(sp), nil } -func (s *state4) EraseAllUnproven() error { - - dls, err := s.State.LoadDeadlines(s.store) - if err != nil { - return err - } - - err = dls.ForEach(s.store, func(dindx uint64, dl *miner4.Deadline) error { - ps, err := dl.PartitionsArray(s.store) - if err != nil { - return err - } - - var part miner4.Partition - err = ps.ForEach(&part, func(pindx int64) error { - _ = part.ActivateUnproven() - err = ps.Set(uint64(pindx), &part) - return nil - }) - - if err != nil { - return err - } - - dl.Partitions, err = ps.Root() - if err != nil { - return err - } - - return dls.UpdateDeadline(s.store, dindx, dl) - }) - - return s.State.SaveDeadlines(s.store, dls) - - return nil -} - func (d *deadline4) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -490,7 +443,3 @@ func fromV4SectorPreCommitOnChainInfo(v4 miner4.SectorPreCommitOnChainInfo) Sect } } - -func (s *state4) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/multisig/actor.go.template b/chain/actors/builtin/multisig/actor.go.template index 3af270c60..19d99dcb7 100644 --- a/chain/actors/builtin/multisig/actor.go.template +++ b/chain/actors/builtin/multisig/actor.go.template @@ -40,27 +40,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return make{{.}}(store, signers, threshold, startEpoch, unlockDuration, initialBalance) -{{end}} -} - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return builtin{{.}}.MultisigActorCodeID, nil -{{end}} - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -76,7 +55,6 @@ type State interface { transactions() (adt.Map, error) decodeTransaction(val *cbg.Deferred) (Transaction, error) - GetState() interface{} } type Transaction = msig{{.latestVersion}}.Transaction @@ -88,7 +66,7 @@ func Message(version actors.Version, from address.Address) MessageBuilder { {{range .versions}} case actors.Version{{.}}: return message{{.}}{{"{"}}{{if (ge . 2)}}message0{from}{{else}}from{{end}}} -{{end}} default: +{{end}} default: panic(fmt.Sprintf("unsupported actors version: %d", version)) } } diff --git a/chain/actors/builtin/multisig/message.go.template b/chain/actors/builtin/multisig/message.go.template index 917e6944b..6bff8983a 100644 --- a/chain/actors/builtin/multisig/message.go.template +++ b/chain/actors/builtin/multisig/message.go.template @@ -43,10 +43,10 @@ func (m message{{.v}}) Create( {{end}} // Set up constructor parameters for multisig msigParams := &multisig{{.v}}.ConstructorParams{ - Signers: signers, + Signers: signers, NumApprovalsThreshold: threshold, - UnlockDuration: unlockDuration,{{if (ge .v 2)}} - StartEpoch: unlockStart,{{end}} + UnlockDuration: unlockDuration,{{if (ge .v 2)}} + StartEpoch: unlockStart,{{end}} } enc, actErr := actors.SerializeParams(msigParams) @@ -56,7 +56,7 @@ func (m message{{.v}}) Create( // new actors are created by invoking 'exec' on the init actor with the constructor params execParams := &init{{.v}}.ExecParams{ - CodeCID: builtin{{.v}}.MultisigActorCodeID, + CodeCID: builtin{{.v}}.MultisigActorCodeID, ConstructorParams: enc, } @@ -66,11 +66,11 @@ func (m message{{.v}}) Create( } return &types.Message{ - To: init_.Address, - From: m.from, + To: init_.Address, + From: m.from, Method: builtin{{.v}}.MethodsInit.Exec, Params: enc, - Value: initialAmount, + Value: initialAmount, }, nil } @@ -96,8 +96,8 @@ func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount, } enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{ - To: to, - Value: amt, + To: to, + Value: amt, Method: method, Params: params, }) @@ -106,9 +106,9 @@ func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount, } return &types.Message{ - To: msig, - From: m.from, - Value: abi.NewTokenAmount(0), + To: msig, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin0.MethodsMultisig.Propose, Params: enc, }, nil @@ -121,9 +121,9 @@ func (m message0) Approve(msig address.Address, txID uint64, hashData *ProposalH } return &types.Message{ - To: msig, - From: m.from, - Value: types.NewInt(0), + To: msig, + From: m.from, + Value: types.NewInt(0), Method: builtin0.MethodsMultisig.Approve, Params: enc, }, nil @@ -136,9 +136,9 @@ func (m message0) Cancel(msig address.Address, txID uint64, hashData *ProposalHa } return &types.Message{ - To: msig, - From: m.from, - Value: types.NewInt(0), + To: msig, + From: m.from, + Value: types.NewInt(0), Method: builtin0.MethodsMultisig.Cancel, Params: enc, }, nil diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go index fd773f398..d8f6fabae 100644 --- a/chain/actors/builtin/multisig/multisig.go +++ b/chain/actors/builtin/multisig/multisig.go @@ -66,45 +66,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { - switch av { - - case actors.Version0: - return make0(store, signers, threshold, startEpoch, unlockDuration, initialBalance) - - case actors.Version2: - return make2(store, signers, threshold, startEpoch, unlockDuration, initialBalance) - - case actors.Version3: - return make3(store, signers, threshold, startEpoch, unlockDuration, initialBalance) - - case actors.Version4: - return make4(store, signers, threshold, startEpoch, unlockDuration, initialBalance) - - } - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { - - case actors.Version0: - return builtin0.MultisigActorCodeID, nil - - case actors.Version2: - return builtin2.MultisigActorCodeID, nil - - case actors.Version3: - return builtin3.MultisigActorCodeID, nil - - case actors.Version4: - return builtin4.MultisigActorCodeID, nil - - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -120,7 +81,6 @@ type State interface { transactions() (adt.Map, error) decodeTransaction(val *cbg.Deferred) (Transaction, error) - GetState() interface{} } type Transaction = msig4.Transaction diff --git a/chain/actors/builtin/multisig/state.go.template b/chain/actors/builtin/multisig/state.go.template index 067415533..2316aadba 100644 --- a/chain/actors/builtin/multisig/state.go.template +++ b/chain/actors/builtin/multisig/state.go.template @@ -31,32 +31,6 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make{{.v}}(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { - out := state{{.v}}{store: store} - out.State = msig{{.v}}.State{} - out.State.Signers = signers - out.State.NumApprovalsThreshold = threshold - out.State.StartEpoch = startEpoch - out.State.UnlockDuration = unlockDuration - out.State.InitialBalance = initialBalance - {{if (le .v 2)}} - em, err := adt{{.v}}.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State.PendingTxns = em - {{else}} - em, err := adt{{.v}}.StoreEmptyMap(store, builtin{{.v}}.DefaultHamtBitwidth) - if err != nil { - return nil, err - } - - out.State.PendingTxns = em - {{end}} - return &out, nil -} - type state{{.v}} struct { msig{{.v}}.State store adt.Store @@ -121,7 +95,3 @@ func (s *state{{.v}}) decodeTransaction(val *cbg.Deferred) (Transaction, error) } return tx, nil } - -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} \ No newline at end of file diff --git a/chain/actors/builtin/multisig/temp b/chain/actors/builtin/multisig/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/multisig/v0.go b/chain/actors/builtin/multisig/v0.go index 973ac9209..20c1557b0 100644 --- a/chain/actors/builtin/multisig/v0.go +++ b/chain/actors/builtin/multisig/v0.go @@ -28,25 +28,6 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make0(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { - out := state0{store: store} - out.State = msig0.State{} - out.State.Signers = signers - out.State.NumApprovalsThreshold = threshold - out.State.StartEpoch = startEpoch - out.State.UnlockDuration = unlockDuration - out.State.InitialBalance = initialBalance - - em, err := adt0.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State.PendingTxns = em - - return &out, nil -} - type state0 struct { msig0.State store adt.Store @@ -111,7 +92,3 @@ func (s *state0) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } - -func (s *state0) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/multisig/v2.go b/chain/actors/builtin/multisig/v2.go index 5b830e695..ef317f903 100644 --- a/chain/actors/builtin/multisig/v2.go +++ b/chain/actors/builtin/multisig/v2.go @@ -28,25 +28,6 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make2(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { - out := state2{store: store} - out.State = msig2.State{} - out.State.Signers = signers - out.State.NumApprovalsThreshold = threshold - out.State.StartEpoch = startEpoch - out.State.UnlockDuration = unlockDuration - out.State.InitialBalance = initialBalance - - em, err := adt2.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State.PendingTxns = em - - return &out, nil -} - type state2 struct { msig2.State store adt.Store @@ -111,7 +92,3 @@ func (s *state2) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } - -func (s *state2) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/multisig/v3.go b/chain/actors/builtin/multisig/v3.go index c4a2791b7..8834e4553 100644 --- a/chain/actors/builtin/multisig/v3.go +++ b/chain/actors/builtin/multisig/v3.go @@ -30,25 +30,6 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make3(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { - out := state3{store: store} - out.State = msig3.State{} - out.State.Signers = signers - out.State.NumApprovalsThreshold = threshold - out.State.StartEpoch = startEpoch - out.State.UnlockDuration = unlockDuration - out.State.InitialBalance = initialBalance - - em, err := adt3.StoreEmptyMap(store, builtin3.DefaultHamtBitwidth) - if err != nil { - return nil, err - } - - out.State.PendingTxns = em - - return &out, nil -} - type state3 struct { msig3.State store adt.Store @@ -113,7 +94,3 @@ func (s *state3) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } - -func (s *state3) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/multisig/v4.go b/chain/actors/builtin/multisig/v4.go index a35a890f8..9f9dc7573 100644 --- a/chain/actors/builtin/multisig/v4.go +++ b/chain/actors/builtin/multisig/v4.go @@ -30,25 +30,6 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make4(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { - out := state4{store: store} - out.State = msig4.State{} - out.State.Signers = signers - out.State.NumApprovalsThreshold = threshold - out.State.StartEpoch = startEpoch - out.State.UnlockDuration = unlockDuration - out.State.InitialBalance = initialBalance - - em, err := adt4.StoreEmptyMap(store, builtin4.DefaultHamtBitwidth) - if err != nil { - return nil, err - } - - out.State.PendingTxns = em - - return &out, nil -} - type state4 struct { msig4.State store adt.Store @@ -113,7 +94,3 @@ func (s *state4) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } - -func (s *state4) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/paych/actor.go.template b/chain/actors/builtin/paych/actor.go.template index 7699e76b6..3f68a5cfa 100644 --- a/chain/actors/builtin/paych/actor.go.template +++ b/chain/actors/builtin/paych/actor.go.template @@ -42,27 +42,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return make{{.}}(store) -{{end}} -} - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return builtin{{.}}.PaymentChannelActorCodeID, nil -{{end}} - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - // State is an abstract version of payment channel state that works across // versions type State interface { @@ -83,8 +62,6 @@ type State interface { // Iterate lane states ForEachLaneState(cb func(idx uint64, dl LaneState) error) error - - GetState() interface{} } // LaneState is an abstract copy of the state of a single lane diff --git a/chain/actors/builtin/paych/message.go.template b/chain/actors/builtin/paych/message.go.template index cb111d910..4a5ea2331 100644 --- a/chain/actors/builtin/paych/message.go.template +++ b/chain/actors/builtin/paych/message.go.template @@ -21,7 +21,7 @@ func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) return nil, aerr } enc, aerr := actors.SerializeParams(&init{{.v}}.ExecParams{ - CodeCID: builtin{{.v}}.PaymentChannelActorCodeID, + CodeCID: builtin{{.v}}.PaymentChannelActorCodeID, ConstructorParams: params, }) if aerr != nil { @@ -29,9 +29,9 @@ func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) } return &types.Message{ - To: init_.Address, - From: m.from, - Value: initialAmount, + To: init_.Address, + From: m.from, + Value: initialAmount, Method: builtin{{.v}}.MethodsInit.Exec, Params: enc, }, nil @@ -39,7 +39,7 @@ func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { params, aerr := actors.SerializeParams(&paych{{.v}}.UpdateChannelStateParams{ - Sv: *sv, + Sv: *sv, Secret: secret, }) if aerr != nil { @@ -47,9 +47,9 @@ func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret [ } return &types.Message{ - To: paych, - From: m.from, - Value: abi.NewTokenAmount(0), + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin{{.v}}.MethodsPaych.UpdateChannelState, Params: params, }, nil @@ -57,18 +57,18 @@ func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret [ func (m message{{.v}}) Settle(paych address.Address) (*types.Message, error) { return &types.Message{ - To: paych, - From: m.from, - Value: abi.NewTokenAmount(0), + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin{{.v}}.MethodsPaych.Settle, }, nil } func (m message{{.v}}) Collect(paych address.Address) (*types.Message, error) { return &types.Message{ - To: paych, - From: m.from, - Value: abi.NewTokenAmount(0), + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin{{.v}}.MethodsPaych.Collect, }, nil } diff --git a/chain/actors/builtin/paych/mock/mock.go b/chain/actors/builtin/paych/mock/mock.go index 1ecfa1130..3b82511ff 100644 --- a/chain/actors/builtin/paych/mock/mock.go +++ b/chain/actors/builtin/paych/mock/mock.go @@ -17,10 +17,6 @@ type mockState struct { lanes map[uint64]paych.LaneState } -func (ms *mockState) GetState() interface{} { - panic("implement me") -} - type mockLaneState struct { redeemed big.Int nonce uint64 diff --git a/chain/actors/builtin/paych/mock/temp b/chain/actors/builtin/paych/mock/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go index 63638cda1..30e4408d8 100644 --- a/chain/actors/builtin/paych/paych.go +++ b/chain/actors/builtin/paych/paych.go @@ -68,45 +68,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { - - case actors.Version0: - return make0(store) - - case actors.Version2: - return make2(store) - - case actors.Version3: - return make3(store) - - case actors.Version4: - return make4(store) - - } - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { - - case actors.Version0: - return builtin0.PaymentChannelActorCodeID, nil - - case actors.Version2: - return builtin2.PaymentChannelActorCodeID, nil - - case actors.Version3: - return builtin3.PaymentChannelActorCodeID, nil - - case actors.Version4: - return builtin4.PaymentChannelActorCodeID, nil - - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - // State is an abstract version of payment channel state that works across // versions type State interface { @@ -127,8 +88,6 @@ type State interface { // Iterate lane states ForEachLaneState(cb func(idx uint64, dl LaneState) error) error - - GetState() interface{} } // LaneState is an abstract copy of the state of a single lane diff --git a/chain/actors/builtin/paych/state.go.template b/chain/actors/builtin/paych/state.go.template index 3e41f5be5..b4b575a3e 100644 --- a/chain/actors/builtin/paych/state.go.template +++ b/chain/actors/builtin/paych/state.go.template @@ -24,12 +24,6 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make{{.v}}(store adt.Store) (State, error) { - out := state{{.v}}{store: store} - out.State = paych{{.v}}.State{} - return &out, nil -} - type state{{.v}} struct { paych{{.v}}.State store adt.Store @@ -80,10 +74,6 @@ func (s *state{{.v}}) LaneCount() (uint64, error) { return lsamt.Length(), nil } -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} - // Iterate lane states func (s *state{{.v}}) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/temp b/chain/actors/builtin/paych/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/paych/v0.go b/chain/actors/builtin/paych/v0.go index e9bc30e3d..8e0e3434e 100644 --- a/chain/actors/builtin/paych/v0.go +++ b/chain/actors/builtin/paych/v0.go @@ -24,12 +24,6 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make0(store adt.Store) (State, error) { - out := state0{store: store} - out.State = paych0.State{} - return &out, nil -} - type state0 struct { paych0.State store adt.Store @@ -80,10 +74,6 @@ func (s *state0) LaneCount() (uint64, error) { return lsamt.Length(), nil } -func (s *state0) GetState() interface{} { - return &s.State -} - // Iterate lane states func (s *state0) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/v2.go b/chain/actors/builtin/paych/v2.go index 400305e2f..fbf4b9fde 100644 --- a/chain/actors/builtin/paych/v2.go +++ b/chain/actors/builtin/paych/v2.go @@ -24,12 +24,6 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make2(store adt.Store) (State, error) { - out := state2{store: store} - out.State = paych2.State{} - return &out, nil -} - type state2 struct { paych2.State store adt.Store @@ -80,10 +74,6 @@ func (s *state2) LaneCount() (uint64, error) { return lsamt.Length(), nil } -func (s *state2) GetState() interface{} { - return &s.State -} - // Iterate lane states func (s *state2) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/v3.go b/chain/actors/builtin/paych/v3.go index 1d7c2f94b..14bb4cb61 100644 --- a/chain/actors/builtin/paych/v3.go +++ b/chain/actors/builtin/paych/v3.go @@ -24,12 +24,6 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make3(store adt.Store) (State, error) { - out := state3{store: store} - out.State = paych3.State{} - return &out, nil -} - type state3 struct { paych3.State store adt.Store @@ -80,10 +74,6 @@ func (s *state3) LaneCount() (uint64, error) { return lsamt.Length(), nil } -func (s *state3) GetState() interface{} { - return &s.State -} - // Iterate lane states func (s *state3) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/v4.go b/chain/actors/builtin/paych/v4.go index b7d1e52a5..cf37eea5c 100644 --- a/chain/actors/builtin/paych/v4.go +++ b/chain/actors/builtin/paych/v4.go @@ -24,12 +24,6 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make4(store adt.Store) (State, error) { - out := state4{store: store} - out.State = paych4.State{} - return &out, nil -} - type state4 struct { paych4.State store adt.Store @@ -80,10 +74,6 @@ func (s *state4) LaneCount() (uint64, error) { return lsamt.Length(), nil } -func (s *state4) GetState() interface{} { - return &s.State -} - // Iterate lane states func (s *state4) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/power/actor.go.template b/chain/actors/builtin/power/actor.go.template index 7ff3d0387..82f791e58 100644 --- a/chain/actors/builtin/power/actor.go.template +++ b/chain/actors/builtin/power/actor.go.template @@ -3,7 +3,6 @@ package power import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -41,27 +40,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return make{{.}}(store) -{{end}} -} - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return builtin{{.}}.StoragePowerActorCodeID, nil -{{end}} - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -69,7 +47,6 @@ type State interface { TotalPower() (Claim, error) TotalCommitted() (Claim, error) TotalPowerSmoothed() (builtin.FilterEstimate, error) - GetState() interface{} // MinerCounts returns the number of miners. Participating is the number // with power above the minimum miner threshold. @@ -80,12 +57,6 @@ type State interface { ForEachClaim(func(miner address.Address, claim Claim) error) error ClaimsChanged(State) (bool, error) - // Testing or genesis setup only - SetTotalQualityAdjPower(abi.StoragePower) error - SetTotalRawBytePower(abi.StoragePower) error - SetThisEpochQualityAdjPower(abi.StoragePower) error - SetThisEpochRawBytePower(abi.StoragePower) error - // Diff helpers. Used by Diff* functions internally. claims() (adt.Map, error) decodeClaim(*cbg.Deferred) (Claim, error) @@ -101,7 +72,7 @@ type Claim struct { func AddClaims(a Claim, b Claim) Claim { return Claim{ - RawBytePower: big.Add(a.RawBytePower, b.RawBytePower), + RawBytePower: big.Add(a.RawBytePower, b.RawBytePower), QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower), } } diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index 69ed6cf89..bf530a21a 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -3,7 +3,6 @@ package power import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -67,45 +66,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { - - case actors.Version0: - return make0(store) - - case actors.Version2: - return make2(store) - - case actors.Version3: - return make3(store) - - case actors.Version4: - return make4(store) - - } - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { - - case actors.Version0: - return builtin0.StoragePowerActorCodeID, nil - - case actors.Version2: - return builtin2.StoragePowerActorCodeID, nil - - case actors.Version3: - return builtin3.StoragePowerActorCodeID, nil - - case actors.Version4: - return builtin4.StoragePowerActorCodeID, nil - - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -113,7 +73,6 @@ type State interface { TotalPower() (Claim, error) TotalCommitted() (Claim, error) TotalPowerSmoothed() (builtin.FilterEstimate, error) - GetState() interface{} // MinerCounts returns the number of miners. Participating is the number // with power above the minimum miner threshold. @@ -124,12 +83,6 @@ type State interface { ForEachClaim(func(miner address.Address, claim Claim) error) error ClaimsChanged(State) (bool, error) - // Testing or genesis setup only - SetTotalQualityAdjPower(abi.StoragePower) error - SetTotalRawBytePower(abi.StoragePower) error - SetThisEpochQualityAdjPower(abi.StoragePower) error - SetThisEpochRawBytePower(abi.StoragePower) error - // Diff helpers. Used by Diff* functions internally. claims() (adt.Map, error) decodeClaim(*cbg.Deferred) (Claim, error) diff --git a/chain/actors/builtin/power/state.go.template b/chain/actors/builtin/power/state.go.template index d0abba3fa..4cb904a1d 100644 --- a/chain/actors/builtin/power/state.go.template +++ b/chain/actors/builtin/power/state.go.template @@ -29,32 +29,6 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make{{.v}}(store adt.Store) (State, error) { - out := state{{.v}}{store: store} - {{if (le .v 2)}} - em, err := adt{{.v}}.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - emm, err := adt{{.v}}.MakeEmptyMultimap(store).Root() - if err != nil { - return nil, err - } - - out.State = *power{{.v}}.ConstructState(em, emm) - {{else}} - s, err := power{{.v}}.ConstructState(store) - if err != nil { - return nil, err - } - - out.State = *s - {{end}} - - return &out, nil -} - type state{{.v}} struct { power{{.v}}.State store adt.Store @@ -66,7 +40,7 @@ func (s *state{{.v}}) TotalLocked() (abi.TokenAmount, error) { func (s *state{{.v}}) TotalPower() (Claim, error) { return Claim{ - RawBytePower: s.TotalRawBytePower, + RawBytePower: s.TotalRawBytePower, QualityAdjPower: s.TotalQualityAdjPower, }, nil } @@ -74,7 +48,7 @@ func (s *state{{.v}}) TotalPower() (Claim, error) { // Committed power to the network. Includes miners below the minimum threshold. func (s *state{{.v}}) TotalCommitted() (Claim, error) { return Claim{ - RawBytePower: s.TotalBytesCommitted, + RawBytePower: s.TotalBytesCommitted, QualityAdjPower: s.TotalQABytesCommitted, }, nil } @@ -90,7 +64,7 @@ func (s *state{{.v}}) MinerPower(addr address.Address) (Claim, bool, error) { return Claim{}, false, err } return Claim{ - RawBytePower: claim.RawBytePower, + RawBytePower: claim.RawBytePower, QualityAdjPower: claim.QualityAdjPower, }, ok, nil } @@ -142,7 +116,7 @@ func (s *state{{.v}}) ForEachClaim(cb func(miner address.Address, claim Claim) e return err } return cb(a, Claim{ - RawBytePower: claim.RawBytePower, + RawBytePower: claim.RawBytePower, QualityAdjPower: claim.QualityAdjPower, }) }) @@ -157,30 +131,6 @@ func (s *state{{.v}}) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other{{.v}}.State.Claims), nil } -func (s *state{{.v}}) SetTotalQualityAdjPower(p abi.StoragePower) error { - s.State.TotalQualityAdjPower = p - return nil -} - -func (s *state{{.v}}) SetTotalRawBytePower(p abi.StoragePower) error { - s.State.TotalRawBytePower = p - return nil -} - -func (s *state{{.v}}) SetThisEpochQualityAdjPower(p abi.StoragePower) error { - s.State.ThisEpochQualityAdjPower = p - return nil -} - -func (s *state{{.v}}) SetThisEpochRawBytePower(p abi.StoragePower) error { - s.State.ThisEpochRawBytePower = p - return nil -} - -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} - func (s *state{{.v}}) claims() (adt.Map, error) { return adt{{.v}}.AsMap(s.store, s.Claims{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) } @@ -195,7 +145,7 @@ func (s *state{{.v}}) decodeClaim(val *cbg.Deferred) (Claim, error) { func fromV{{.v}}Claim(v{{.v}} power{{.v}}.Claim) Claim { return Claim{ - RawBytePower: v{{.v}}.RawBytePower, + RawBytePower: v{{.v}}.RawBytePower, QualityAdjPower: v{{.v}}.QualityAdjPower, } } diff --git a/chain/actors/builtin/power/temp b/chain/actors/builtin/power/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/power/v0.go b/chain/actors/builtin/power/v0.go index 465d16c5c..91fad8c57 100644 --- a/chain/actors/builtin/power/v0.go +++ b/chain/actors/builtin/power/v0.go @@ -26,24 +26,6 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make0(store adt.Store) (State, error) { - out := state0{store: store} - - em, err := adt0.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - emm, err := adt0.MakeEmptyMultimap(store).Root() - if err != nil { - return nil, err - } - - out.State = *power0.ConstructState(em, emm) - - return &out, nil -} - type state0 struct { power0.State store adt.Store @@ -146,30 +128,6 @@ func (s *state0) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other0.State.Claims), nil } -func (s *state0) SetTotalQualityAdjPower(p abi.StoragePower) error { - s.State.TotalQualityAdjPower = p - return nil -} - -func (s *state0) SetTotalRawBytePower(p abi.StoragePower) error { - s.State.TotalRawBytePower = p - return nil -} - -func (s *state0) SetThisEpochQualityAdjPower(p abi.StoragePower) error { - s.State.ThisEpochQualityAdjPower = p - return nil -} - -func (s *state0) SetThisEpochRawBytePower(p abi.StoragePower) error { - s.State.ThisEpochRawBytePower = p - return nil -} - -func (s *state0) GetState() interface{} { - return &s.State -} - func (s *state0) claims() (adt.Map, error) { return adt0.AsMap(s.store, s.Claims) } diff --git a/chain/actors/builtin/power/v2.go b/chain/actors/builtin/power/v2.go index 606534cef..313160a78 100644 --- a/chain/actors/builtin/power/v2.go +++ b/chain/actors/builtin/power/v2.go @@ -26,24 +26,6 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make2(store adt.Store) (State, error) { - out := state2{store: store} - - em, err := adt2.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - emm, err := adt2.MakeEmptyMultimap(store).Root() - if err != nil { - return nil, err - } - - out.State = *power2.ConstructState(em, emm) - - return &out, nil -} - type state2 struct { power2.State store adt.Store @@ -146,30 +128,6 @@ func (s *state2) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other2.State.Claims), nil } -func (s *state2) SetTotalQualityAdjPower(p abi.StoragePower) error { - s.State.TotalQualityAdjPower = p - return nil -} - -func (s *state2) SetTotalRawBytePower(p abi.StoragePower) error { - s.State.TotalRawBytePower = p - return nil -} - -func (s *state2) SetThisEpochQualityAdjPower(p abi.StoragePower) error { - s.State.ThisEpochQualityAdjPower = p - return nil -} - -func (s *state2) SetThisEpochRawBytePower(p abi.StoragePower) error { - s.State.ThisEpochRawBytePower = p - return nil -} - -func (s *state2) GetState() interface{} { - return &s.State -} - func (s *state2) claims() (adt.Map, error) { return adt2.AsMap(s.store, s.Claims) } diff --git a/chain/actors/builtin/power/v3.go b/chain/actors/builtin/power/v3.go index 3dec3c63e..2ef1e2808 100644 --- a/chain/actors/builtin/power/v3.go +++ b/chain/actors/builtin/power/v3.go @@ -28,19 +28,6 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make3(store adt.Store) (State, error) { - out := state3{store: store} - - s, err := power3.ConstructState(store) - if err != nil { - return nil, err - } - - out.State = *s - - return &out, nil -} - type state3 struct { power3.State store adt.Store @@ -143,30 +130,6 @@ func (s *state3) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other3.State.Claims), nil } -func (s *state3) SetTotalQualityAdjPower(p abi.StoragePower) error { - s.State.TotalQualityAdjPower = p - return nil -} - -func (s *state3) SetTotalRawBytePower(p abi.StoragePower) error { - s.State.TotalRawBytePower = p - return nil -} - -func (s *state3) SetThisEpochQualityAdjPower(p abi.StoragePower) error { - s.State.ThisEpochQualityAdjPower = p - return nil -} - -func (s *state3) SetThisEpochRawBytePower(p abi.StoragePower) error { - s.State.ThisEpochRawBytePower = p - return nil -} - -func (s *state3) GetState() interface{} { - return &s.State -} - func (s *state3) claims() (adt.Map, error) { return adt3.AsMap(s.store, s.Claims, builtin3.DefaultHamtBitwidth) } diff --git a/chain/actors/builtin/power/v4.go b/chain/actors/builtin/power/v4.go index b73eedf5a..686550456 100644 --- a/chain/actors/builtin/power/v4.go +++ b/chain/actors/builtin/power/v4.go @@ -28,19 +28,6 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make4(store adt.Store) (State, error) { - out := state4{store: store} - - s, err := power4.ConstructState(store) - if err != nil { - return nil, err - } - - out.State = *s - - return &out, nil -} - type state4 struct { power4.State store adt.Store @@ -143,30 +130,6 @@ func (s *state4) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other4.State.Claims), nil } -func (s *state4) SetTotalQualityAdjPower(p abi.StoragePower) error { - s.State.TotalQualityAdjPower = p - return nil -} - -func (s *state4) SetTotalRawBytePower(p abi.StoragePower) error { - s.State.TotalRawBytePower = p - return nil -} - -func (s *state4) SetThisEpochQualityAdjPower(p abi.StoragePower) error { - s.State.ThisEpochQualityAdjPower = p - return nil -} - -func (s *state4) SetThisEpochRawBytePower(p abi.StoragePower) error { - s.State.ThisEpochRawBytePower = p - return nil -} - -func (s *state4) GetState() interface{} { - return &s.State -} - func (s *state4) claims() (adt.Map, error) { return adt4.AsMap(s.store, s.Claims, builtin4.DefaultHamtBitwidth) } diff --git a/chain/actors/builtin/reward/actor.go.template b/chain/actors/builtin/reward/actor.go.template index 89cdddaec..81437d26f 100644 --- a/chain/actors/builtin/reward/actor.go.template +++ b/chain/actors/builtin/reward/actor.go.template @@ -4,7 +4,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" "github.com/ipfs/go-cid" - "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/cbor" @@ -39,27 +38,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version, currRealizedPower abi.StoragePower) (State, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return make{{.}}(store, currRealizedPower) -{{end}} -} - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return builtin{{.}}.RewardActorCodeID, nil -{{end}} - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -77,7 +55,6 @@ type State interface { InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error) PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error) - GetState() interface{} } type AwardBlockRewardParams = reward0.AwardBlockRewardParams diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index c325cc7b6..1037cf741 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -2,7 +2,6 @@ package reward import ( "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/chain/actors" reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -65,45 +64,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version, currRealizedPower abi.StoragePower) (State, error) { - switch av { - - case actors.Version0: - return make0(store, currRealizedPower) - - case actors.Version2: - return make2(store, currRealizedPower) - - case actors.Version3: - return make3(store, currRealizedPower) - - case actors.Version4: - return make4(store, currRealizedPower) - - } - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { - - case actors.Version0: - return builtin0.RewardActorCodeID, nil - - case actors.Version2: - return builtin2.RewardActorCodeID, nil - - case actors.Version3: - return builtin3.RewardActorCodeID, nil - - case actors.Version4: - return builtin4.RewardActorCodeID, nil - - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -121,7 +81,6 @@ type State interface { InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error) PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error) - GetState() interface{} } type AwardBlockRewardParams = reward0.AwardBlockRewardParams diff --git a/chain/actors/builtin/reward/state.go.template b/chain/actors/builtin/reward/state.go.template index 67bfd5c85..1758d1413 100644 --- a/chain/actors/builtin/reward/state.go.template +++ b/chain/actors/builtin/reward/state.go.template @@ -23,12 +23,6 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make{{.v}}(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { - out := state{{.v}}{store: store} - out.State = *reward{{.v}}.ConstructState(currRealizedPower) - return &out, nil -} - type state{{.v}} struct { reward{{.v}}.State store adt.Store @@ -107,7 +101,3 @@ func (s *state{{.v}}) PreCommitDepositForPower(networkQAPower builtin.FilterEsti }, sectorWeight), nil } - -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} \ No newline at end of file diff --git a/chain/actors/builtin/reward/temp b/chain/actors/builtin/reward/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/reward/v0.go b/chain/actors/builtin/reward/v0.go index cd098c151..fe053cc16 100644 --- a/chain/actors/builtin/reward/v0.go +++ b/chain/actors/builtin/reward/v0.go @@ -23,12 +23,6 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make0(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { - out := state0{store: store} - out.State = *reward0.ConstructState(currRealizedPower) - return &out, nil -} - type state0 struct { reward0.State store adt.Store @@ -89,7 +83,3 @@ func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } - -func (s *state0) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/reward/v2.go b/chain/actors/builtin/reward/v2.go index 08e9a7bc3..90621e467 100644 --- a/chain/actors/builtin/reward/v2.go +++ b/chain/actors/builtin/reward/v2.go @@ -23,12 +23,6 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make2(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { - out := state2{store: store} - out.State = *reward2.ConstructState(currRealizedPower) - return &out, nil -} - type state2 struct { reward2.State store adt.Store @@ -92,7 +86,3 @@ func (s *state2) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } - -func (s *state2) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/reward/v3.go b/chain/actors/builtin/reward/v3.go index fd9fa56e2..926cc085b 100644 --- a/chain/actors/builtin/reward/v3.go +++ b/chain/actors/builtin/reward/v3.go @@ -23,12 +23,6 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make3(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { - out := state3{store: store} - out.State = *reward3.ConstructState(currRealizedPower) - return &out, nil -} - type state3 struct { reward3.State store adt.Store @@ -92,7 +86,3 @@ func (s *state3) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } - -func (s *state3) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/reward/v4.go b/chain/actors/builtin/reward/v4.go index 310ca04e8..f034b0018 100644 --- a/chain/actors/builtin/reward/v4.go +++ b/chain/actors/builtin/reward/v4.go @@ -23,12 +23,6 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make4(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { - out := state4{store: store} - out.State = *reward4.ConstructState(currRealizedPower) - return &out, nil -} - type state4 struct { reward4.State store adt.Store @@ -92,7 +86,3 @@ func (s *state4) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } - -func (s *state4) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/system/actor.go.template b/chain/actors/builtin/system/actor.go.template deleted file mode 100644 index 925319970..000000000 --- a/chain/actors/builtin/system/actor.go.template +++ /dev/null @@ -1,41 +0,0 @@ -package system - -import ( - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors" - "golang.org/x/xerrors" - "github.com/ipfs/go-cid" - -{{range .versions}} - builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" -{{end}} -) - -var ( - Address = builtin{{.latestVersion}}.SystemActorAddr -) - -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return make{{.}}(store) -{{end}} -} - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return builtin{{.}}.SystemActorCodeID, nil -{{end}} - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - -type State interface { - GetState() interface{} -} diff --git a/chain/actors/builtin/system/state.go.template b/chain/actors/builtin/system/state.go.template deleted file mode 100644 index fa644f8c7..000000000 --- a/chain/actors/builtin/system/state.go.template +++ /dev/null @@ -1,35 +0,0 @@ -package system - -import ( - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - system{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/system" -) - -var _ State = (*state{{.v}})(nil) - -func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { - out := state{{.v}}{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -func make{{.v}}(store adt.Store) (State, error) { - out := state{{.v}}{store: store} - out.State = system{{.v}}.State{} - return &out, nil -} - -type state{{.v}} struct { - system{{.v}}.State - store adt.Store -} - -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} \ No newline at end of file diff --git a/chain/actors/builtin/system/system.go b/chain/actors/builtin/system/system.go deleted file mode 100644 index b4ced850f..000000000 --- a/chain/actors/builtin/system/system.go +++ /dev/null @@ -1,63 +0,0 @@ -package system - -import ( - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/ipfs/go-cid" - "golang.org/x/xerrors" - - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - - builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" - - builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" - - builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" -) - -var ( - Address = builtin4.SystemActorAddr -) - -func MakeState(store adt.Store, av actors.Version) (State, error) { - switch av { - - case actors.Version0: - return make0(store) - - case actors.Version2: - return make2(store) - - case actors.Version3: - return make3(store) - - case actors.Version4: - return make4(store) - - } - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { - - case actors.Version0: - return builtin0.SystemActorCodeID, nil - - case actors.Version2: - return builtin2.SystemActorCodeID, nil - - case actors.Version3: - return builtin3.SystemActorCodeID, nil - - case actors.Version4: - return builtin4.SystemActorCodeID, nil - - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - -type State interface { - GetState() interface{} -} diff --git a/chain/actors/builtin/system/temp b/chain/actors/builtin/system/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/system/v0.go b/chain/actors/builtin/system/v0.go deleted file mode 100644 index 64c6f53d3..000000000 --- a/chain/actors/builtin/system/v0.go +++ /dev/null @@ -1,35 +0,0 @@ -package system - -import ( - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - system0 "github.com/filecoin-project/specs-actors/actors/builtin/system" -) - -var _ State = (*state0)(nil) - -func load0(store adt.Store, root cid.Cid) (State, error) { - out := state0{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -func make0(store adt.Store) (State, error) { - out := state0{store: store} - out.State = system0.State{} - return &out, nil -} - -type state0 struct { - system0.State - store adt.Store -} - -func (s *state0) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/system/v2.go b/chain/actors/builtin/system/v2.go deleted file mode 100644 index eb540891c..000000000 --- a/chain/actors/builtin/system/v2.go +++ /dev/null @@ -1,35 +0,0 @@ -package system - -import ( - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - system2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/system" -) - -var _ State = (*state2)(nil) - -func load2(store adt.Store, root cid.Cid) (State, error) { - out := state2{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -func make2(store adt.Store) (State, error) { - out := state2{store: store} - out.State = system2.State{} - return &out, nil -} - -type state2 struct { - system2.State - store adt.Store -} - -func (s *state2) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/system/v3.go b/chain/actors/builtin/system/v3.go deleted file mode 100644 index 5b04e189e..000000000 --- a/chain/actors/builtin/system/v3.go +++ /dev/null @@ -1,35 +0,0 @@ -package system - -import ( - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - system3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/system" -) - -var _ State = (*state3)(nil) - -func load3(store adt.Store, root cid.Cid) (State, error) { - out := state3{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -func make3(store adt.Store) (State, error) { - out := state3{store: store} - out.State = system3.State{} - return &out, nil -} - -type state3 struct { - system3.State - store adt.Store -} - -func (s *state3) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/system/v4.go b/chain/actors/builtin/system/v4.go deleted file mode 100644 index b6c924978..000000000 --- a/chain/actors/builtin/system/v4.go +++ /dev/null @@ -1,35 +0,0 @@ -package system - -import ( - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - system4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/system" -) - -var _ State = (*state4)(nil) - -func load4(store adt.Store, root cid.Cid) (State, error) { - out := state4{store: store} - err := store.Get(store.Context(), root, &out) - if err != nil { - return nil, err - } - return &out, nil -} - -func make4(store adt.Store) (State, error) { - out := state4{store: store} - out.State = system4.State{} - return &out, nil -} - -type state4 struct { - system4.State - store adt.Store -} - -func (s *state4) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/temp b/chain/actors/builtin/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/verifreg/actor.go.template b/chain/actors/builtin/verifreg/actor.go.template index 9ea8e155a..22e809ccf 100644 --- a/chain/actors/builtin/verifreg/actor.go.template +++ b/chain/actors/builtin/verifreg/actor.go.template @@ -14,7 +14,6 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) @@ -41,28 +40,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version, rootKeyAddress address.Address) (State, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return make{{.}}(store, rootKeyAddress) -{{end}} -} - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { -{{range .versions}} - case actors.Version{{.}}: - return builtin{{.}}.VerifiedRegistryActorCodeID, nil -{{end}} - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - - type State interface { cbor.Marshaler @@ -71,5 +48,4 @@ type State interface { VerifierDataCap(address.Address) (bool, abi.StoragePower, error) ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error - GetState() interface{} } diff --git a/chain/actors/builtin/verifreg/state.go.template b/chain/actors/builtin/verifreg/state.go.template index 96bebe25f..244d20932 100644 --- a/chain/actors/builtin/verifreg/state.go.template +++ b/chain/actors/builtin/verifreg/state.go.template @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" {{if (ge .v 3)}} builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin" -{{end}} verifreg{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/verifreg" +{{end}} verifreg{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/verifreg" adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt" ) @@ -24,26 +24,6 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make{{.v}}(store adt.Store, rootKeyAddress address.Address) (State, error) { - out := state{{.v}}{store: store} - {{if (le .v 2)}} - em, err := adt{{.v}}.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State = *verifreg{{.v}}.ConstructState(em, rootKeyAddress) - {{else}} - s, err := verifreg{{.v}}.ConstructState(store, rootKeyAddress) - if err != nil { - return nil, err - } - - out.State = *s - {{end}} - return &out, nil -} - type state{{.v}} struct { verifreg{{.v}}.State store adt.Store @@ -76,7 +56,3 @@ func (s *state{{.v}}) verifiedClients() (adt.Map, error) { func (s *state{{.v}}) verifiers() (adt.Map, error) { return adt{{.v}}.AsMap(s.store, s.Verifiers{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) } - -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} \ No newline at end of file diff --git a/chain/actors/builtin/verifreg/temp b/chain/actors/builtin/verifreg/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/builtin/verifreg/v0.go b/chain/actors/builtin/verifreg/v0.go index e70b0e3c9..0dc4696f4 100644 --- a/chain/actors/builtin/verifreg/v0.go +++ b/chain/actors/builtin/verifreg/v0.go @@ -23,19 +23,6 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make0(store adt.Store, rootKeyAddress address.Address) (State, error) { - out := state0{store: store} - - em, err := adt0.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State = *verifreg0.ConstructState(em, rootKeyAddress) - - return &out, nil -} - type state0 struct { verifreg0.State store adt.Store @@ -68,7 +55,3 @@ func (s *state0) verifiedClients() (adt.Map, error) { func (s *state0) verifiers() (adt.Map, error) { return adt0.AsMap(s.store, s.Verifiers) } - -func (s *state0) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/verifreg/v2.go b/chain/actors/builtin/verifreg/v2.go index 0bcbe0212..a5ef84532 100644 --- a/chain/actors/builtin/verifreg/v2.go +++ b/chain/actors/builtin/verifreg/v2.go @@ -23,19 +23,6 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make2(store adt.Store, rootKeyAddress address.Address) (State, error) { - out := state2{store: store} - - em, err := adt2.MakeEmptyMap(store).Root() - if err != nil { - return nil, err - } - - out.State = *verifreg2.ConstructState(em, rootKeyAddress) - - return &out, nil -} - type state2 struct { verifreg2.State store adt.Store @@ -68,7 +55,3 @@ func (s *state2) verifiedClients() (adt.Map, error) { func (s *state2) verifiers() (adt.Map, error) { return adt2.AsMap(s.store, s.Verifiers) } - -func (s *state2) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/verifreg/v3.go b/chain/actors/builtin/verifreg/v3.go index 32003ca3a..fb0c46d0c 100644 --- a/chain/actors/builtin/verifreg/v3.go +++ b/chain/actors/builtin/verifreg/v3.go @@ -24,19 +24,6 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make3(store adt.Store, rootKeyAddress address.Address) (State, error) { - out := state3{store: store} - - s, err := verifreg3.ConstructState(store, rootKeyAddress) - if err != nil { - return nil, err - } - - out.State = *s - - return &out, nil -} - type state3 struct { verifreg3.State store adt.Store @@ -69,7 +56,3 @@ func (s *state3) verifiedClients() (adt.Map, error) { func (s *state3) verifiers() (adt.Map, error) { return adt3.AsMap(s.store, s.Verifiers, builtin3.DefaultHamtBitwidth) } - -func (s *state3) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/verifreg/v4.go b/chain/actors/builtin/verifreg/v4.go index b752e747b..2419ef758 100644 --- a/chain/actors/builtin/verifreg/v4.go +++ b/chain/actors/builtin/verifreg/v4.go @@ -24,19 +24,6 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } -func make4(store adt.Store, rootKeyAddress address.Address) (State, error) { - out := state4{store: store} - - s, err := verifreg4.ConstructState(store, rootKeyAddress) - if err != nil { - return nil, err - } - - out.State = *s - - return &out, nil -} - type state4 struct { verifreg4.State store adt.Store @@ -69,7 +56,3 @@ func (s *state4) verifiedClients() (adt.Map, error) { func (s *state4) verifiers() (adt.Map, error) { return adt4.AsMap(s.store, s.Verifiers, builtin4.DefaultHamtBitwidth) } - -func (s *state4) GetState() interface{} { - return &s.State -} diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index 618907554..32f50a4ae 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -17,7 +17,6 @@ import ( builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" @@ -67,45 +66,6 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } -func MakeState(store adt.Store, av actors.Version, rootKeyAddress address.Address) (State, error) { - switch av { - - case actors.Version0: - return make0(store, rootKeyAddress) - - case actors.Version2: - return make2(store, rootKeyAddress) - - case actors.Version3: - return make3(store, rootKeyAddress) - - case actors.Version4: - return make4(store, rootKeyAddress) - - } - return nil, xerrors.Errorf("unknown actor version %d", av) -} - -func GetActorCodeID(av actors.Version) (cid.Cid, error) { - switch av { - - case actors.Version0: - return builtin0.VerifiedRegistryActorCodeID, nil - - case actors.Version2: - return builtin2.VerifiedRegistryActorCodeID, nil - - case actors.Version3: - return builtin3.VerifiedRegistryActorCodeID, nil - - case actors.Version4: - return builtin4.VerifiedRegistryActorCodeID, nil - - } - - return cid.Undef, xerrors.Errorf("unknown actor version %d", av) -} - type State interface { cbor.Marshaler @@ -114,5 +74,4 @@ type State interface { VerifierDataCap(address.Address) (bool, abi.StoragePower, error) ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error - GetState() interface{} } diff --git a/chain/actors/policy/policy.go.template b/chain/actors/policy/policy.go.template index a1a47852b..d395d7132 100644 --- a/chain/actors/policy/policy.go.template +++ b/chain/actors/policy/policy.go.template @@ -8,20 +8,20 @@ import ( "github.com/filecoin-project/lotus/chain/actors" {{range .versions}} - {{if (ge . 2)}} builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" {{end}} + {{if (ge . 2)}} builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" {{end}} market{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/market" miner{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/miner" verifreg{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/verifreg" {{if (eq . 0)}} power{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/power" {{end}} - {{end}} + {{end}} - paych{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/paych" + paych{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/paych" ) const ( - ChainFinality = miner{{.latestVersion}}.ChainFinality - SealRandomnessLookback = ChainFinality - PaychSettleDelay = paych{{.latestVersion}}.SettleDelay + ChainFinality = miner{{.latestVersion}}.ChainFinality + SealRandomnessLookback = ChainFinality + PaychSettleDelay = paych{{.latestVersion}}.SettleDelay MaxPreCommitRandomnessLookback = builtin{{.latestVersion}}.EpochsInDay + SealRandomnessLookback ) @@ -29,13 +29,13 @@ const ( // This should only be used for testing. func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { {{range .versions}} - {{if (eq . 0)}} - miner{{.}}.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types)) - {{else}} - miner{{.}}.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types)) - miner{{.}}.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2) - miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) - {{end}} + {{if (eq . 0)}} + miner{{.}}.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types)) + {{else}} + miner{{.}}.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + miner{{.}}.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2) + miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + {{end}} {{end}} AddSupportedProofTypes(types...) @@ -51,15 +51,15 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { // Set for all miner versions. {{range .versions}} - {{if (eq . 0)}} - miner{{.}}.SupportedProofTypes[t] = struct{}{} - {{else}} - miner{{.}}.PreCommitSealProofTypesV0[t] = struct{}{} - miner{{.}}.PreCommitSealProofTypesV7[t] = struct{}{} - miner{{.}}.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} - miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} - {{end}} - {{end}} + {{if (eq . 0)}} + miner{{.}}.SupportedProofTypes[t] = struct{}{} + {{else}} + miner{{.}}.PreCommitSealProofTypesV0[t] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV7[t] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + {{end}} + {{end}} } } @@ -67,9 +67,9 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { // actors versions. Use for testing. func SetPreCommitChallengeDelay(delay abi.ChainEpoch) { // Set for all miner versions. - {{range .versions}} - miner{{.}}.PreCommitChallengeDelay = delay - {{end}} + {{range .versions}} + miner{{.}}.PreCommitChallengeDelay = delay + {{end}} } // TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay. @@ -81,42 +81,42 @@ func GetPreCommitChallengeDelay() abi.ChainEpoch { // meet for leader election, across all actor versions. This should only be used // for testing. func SetConsensusMinerMinPower(p abi.StoragePower) { - {{range .versions}} - {{if (eq . 0)}} - power{{.}}.ConsensusMinerMinPower = p - {{else if (eq . 2)}} - for _, policy := range builtin{{.}}.SealProofPolicies { - policy.ConsensusMinerMinPower = p - } - {{else}} - for _, policy := range builtin{{.}}.PoStProofPolicies { - policy.ConsensusMinerMinPower = p - } - {{end}} - {{end}} + {{range .versions}} + {{if (eq . 0)}} + power{{.}}.ConsensusMinerMinPower = p + {{else if (eq . 2)}} + for _, policy := range builtin{{.}}.SealProofPolicies { + policy.ConsensusMinerMinPower = p + } + {{else}} + for _, policy := range builtin{{.}}.PoStProofPolicies { + policy.ConsensusMinerMinPower = p + } + {{end}} + {{end}} } // SetMinVerifiedDealSize sets the minimum size of a verified deal. This should // only be used for testing. func SetMinVerifiedDealSize(size abi.StoragePower) { - {{range .versions}} - verifreg{{.}}.MinVerifiedDealSize = size - {{end}} + {{range .versions}} + verifreg{{.}}.MinVerifiedDealSize = size + {{end}} } func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch { switch ver { {{range .versions}} - case actors.Version{{.}}: - {{if (eq . 0)}} - return miner{{.}}.MaxSealDuration[t] - {{else}} - return miner{{.}}.MaxProveCommitDuration[t] - {{end}} - {{end}} - default: - panic("unsupported actors version") - } + case actors.Version{{.}}: + {{if (eq . 0)}} + return miner{{.}}.MaxSealDuration[t] + {{else}} + return miner{{.}}.MaxProveCommitDuration[t] + {{end}} + {{end}} + default: + panic("unsupported actors version") + } } func DealProviderCollateralBounds( @@ -125,14 +125,14 @@ func DealProviderCollateralBounds( circulatingFil abi.TokenAmount, nwVer network.Version, ) (min, max abi.TokenAmount) { switch actors.VersionForNetwork(nwVer) { - {{range .versions}} - case actors.Version{{.}}: - {{if (eq . 0)}} - return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) - {{else}} - return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) - {{end}} - {{end}} + {{range .versions}} + case actors.Version{{.}}: + {{if (eq . 0)}} + return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) + {{else}} + return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + {{end}} + {{end}} default: panic("unsupported actors version") } @@ -145,15 +145,15 @@ func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) // Sets the challenge window and scales the proving period to match (such that // there are always 48 challenge windows in a proving period). func SetWPoStChallengeWindow(period abi.ChainEpoch) { - {{range .versions}} - miner{{.}}.WPoStChallengeWindow = period - miner{{.}}.WPoStProvingPeriod = period * abi.ChainEpoch(miner{{.}}.WPoStPeriodDeadlines) - {{if (ge . 3)}} - // by default, this is 2x finality which is 30 periods. - // scale it if we're scaling the challenge period. - miner{{.}}.WPoStDisputeWindow = period * 30 - {{end}} - {{end}} + {{range .versions}} + miner{{.}}.WPoStChallengeWindow = period + miner{{.}}.WPoStProvingPeriod = period * abi.ChainEpoch(miner{{.}}.WPoStPeriodDeadlines) + {{if (ge . 3)}} + // by default, this is 2x finality which is 30 periods. + // scale it if we're scaling the challenge period. + miner{{.}}.WPoStDisputeWindow = period * 30 + {{end}} + {{end}} } func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { @@ -161,7 +161,7 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { return 10 } - // NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well + // NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well return ChainFinality } @@ -207,10 +207,10 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) func GetAddressedSectorsMax(nwVer network.Version) int { switch actors.VersionForNetwork(nwVer) { - {{range .versions}} - case actors.Version{{.}}: - return miner{{.}}.AddressedSectorsMax - {{end}} + {{range .versions}} + case actors.Version{{.}}: + return miner{{.}}.AddressedSectorsMax + {{end}} default: panic("unsupported network version") } @@ -218,15 +218,15 @@ func GetAddressedSectorsMax(nwVer network.Version) int { func GetDeclarationsMax(nwVer network.Version) int { switch actors.VersionForNetwork(nwVer) { - {{range .versions}} - case actors.Version{{.}}: - {{if (eq . 0)}} - // TODO: Should we instead panic here since the concept doesn't exist yet? - return miner{{.}}.AddressedPartitionsMax - {{else}} - return miner{{.}}.DeclarationsMax - {{end}} - {{end}} + {{range .versions}} + case actors.Version{{.}}: + {{if (eq . 0)}} + // TODO: Should we instead panic here since the concept doesn't exist yet? + return miner{{.}}.AddressedPartitionsMax + {{else}} + return miner{{.}}.DeclarationsMax + {{end}} + {{end}} default: panic("unsupported network version") } diff --git a/chain/actors/policy/temp b/chain/actors/policy/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/temp b/chain/actors/temp deleted file mode 100644 index e69de29bb..000000000 diff --git a/chain/actors/version.go b/chain/actors/version.go index a8b4c62b2..bd7b708bd 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -8,10 +8,6 @@ import ( type Version int -var LatestVersion = 4 - -var Versions = []int{0, 2, 3, LatestVersion} - const ( Version0 Version = 0 Version2 Version = 2 diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 5c33ac4d7..d06c755fa 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -9,8 +9,6 @@ import ( "sync/atomic" "time" - "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" @@ -199,7 +197,6 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { sys := vm.Syscalls(&genFakeVerifier{}) tpl := genesis.Template{ - NetworkVersion: network.Version0, Accounts: []genesis.Actor{ { Type: genesis.TAccount, diff --git a/chain/gen/genesis/f00_system.go b/chain/gen/genesis/f00_system.go index d1dd203b6..015dfac4a 100644 --- a/chain/gen/genesis/f00_system.go +++ b/chain/gen/genesis/f00_system.go @@ -3,36 +3,27 @@ package genesis import ( "context" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors/builtin/system" + "github.com/filecoin-project/specs-actors/actors/builtin/system" + "github.com/filecoin-project/specs-actors/actors/builtin" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupSystemActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { +func SetupSystemActor(bs bstore.Blockstore) (*types.Actor, error) { + var st system.State cst := cbor.NewCborStore(bs) - st, err := system.MakeState(adt.WrapStore(ctx, cst), av) - if err != nil { - return nil, err - } - statecid, err := cst.Put(ctx, st.GetState()) - if err != nil { - return nil, err - } - - actcid, err := system.GetActorCodeID(av) + statecid, err := cst.Put(context.TODO(), &st) if err != nil { return nil, err } act := &types.Actor{ - Code: actcid, + Code: builtin.SystemActorCodeID, Head: statecid, } diff --git a/chain/gen/genesis/f01_init.go b/chain/gen/genesis/f01_init.go index 88d409221..718eb4480 100644 --- a/chain/gen/genesis/f01_init.go +++ b/chain/gen/genesis/f01_init.go @@ -5,15 +5,13 @@ import ( "encoding/json" "fmt" - init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" - - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/util/adt" + init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" cbor "github.com/ipfs/go-ipld-cbor" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -23,25 +21,17 @@ import ( "github.com/filecoin-project/lotus/genesis" ) -func SetupInitActor(ctx context.Context, bs bstore.Blockstore, netname string, initialActors []genesis.Actor, rootVerifier genesis.Actor, remainder genesis.Actor, av actors.Version) (int64, *types.Actor, map[address.Address]address.Address, error) { +func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesis.Actor, rootVerifier genesis.Actor, remainder genesis.Actor) (int64, *types.Actor, map[address.Address]address.Address, error) { if len(initialActors) > MaxAccounts { return 0, nil, nil, xerrors.New("too many initial actors") } - cst := cbor.NewCborStore(bs) - ist, err := init_.MakeState(adt.WrapStore(ctx, cst), av, netname) - if err != nil { - return 0, nil, nil, err - } + var ias init_.State + ias.NextID = MinerStart + ias.NetworkName = netname - if err = ist.SetNextID(MinerStart); err != nil { - return 0, nil, nil, err - } - - amap, err := ist.AddressMap() - if err != nil { - return 0, nil, nil, err - } + store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) + amap := adt.MakeEmptyMap(store) keyToId := map[address.Address]address.Address{} counter := int64(AccountStart) @@ -165,23 +155,15 @@ func SetupInitActor(ctx context.Context, bs bstore.Blockstore, netname string, i if err != nil { return 0, nil, nil, err } + ias.AddressMap = amapaddr - if err = ist.SetAddressMap(amapaddr); err != nil { - return 0, nil, nil, err - } - - statecid, err := cst.Put(ctx, ist.GetState()) - if err != nil { - return 0, nil, nil, err - } - - actcid, err := init_.GetActorCodeID(av) + statecid, err := store.Put(store.Context(), &ias) if err != nil { return 0, nil, nil, err } act := &types.Actor{ - Code: actcid, + Code: builtin.InitActorCodeID, Head: statecid, } diff --git a/chain/gen/genesis/f02_reward.go b/chain/gen/genesis/f02_reward.go index c8f479722..e218da6fe 100644 --- a/chain/gen/genesis/f02_reward.go +++ b/chain/gen/genesis/f02_reward.go @@ -3,12 +3,10 @@ package genesis import ( "context" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors/builtin/reward" - "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/specs-actors/actors/builtin" + reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" @@ -16,28 +14,19 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func SetupRewardActor(ctx context.Context, bs bstore.Blockstore, qaPower big.Int, av actors.Version) (*types.Actor, error) { +func SetupRewardActor(bs bstore.Blockstore, qaPower big.Int) (*types.Actor, error) { cst := cbor.NewCborStore(bs) - rst, err := reward.MakeState(adt.WrapStore(ctx, cst), av, qaPower) + + st := reward0.ConstructState(qaPower) + + hcid, err := cst.Put(context.TODO(), st) if err != nil { return nil, err } - statecid, err := cst.Put(ctx, rst.GetState()) - if err != nil { - return nil, err - } - - actcid, err := reward.GetActorCodeID(av) - if err != nil { - return nil, err - } - - act := &types.Actor{ - Code: actcid, + return &types.Actor{ + Code: builtin.RewardActorCodeID, Balance: types.BigInt{Int: build.InitialRewardBalance}, - Head: statecid, - } - - return act, nil + Head: hcid, + }, nil } diff --git a/chain/gen/genesis/f03_cron.go b/chain/gen/genesis/f03_cron.go index c6fd2422a..dd43a59a4 100644 --- a/chain/gen/genesis/f03_cron.go +++ b/chain/gen/genesis/f03_cron.go @@ -3,37 +3,27 @@ package genesis import ( "context" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors/builtin/cron" - + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/cron" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupCronActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { +func SetupCronActor(bs bstore.Blockstore) (*types.Actor, error) { cst := cbor.NewCborStore(bs) - st, err := cron.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av) + cas := cron.ConstructState(cron.BuiltInEntries()) + + stcid, err := cst.Put(context.TODO(), cas) if err != nil { return nil, err } - statecid, err := cst.Put(ctx, st.GetState()) - if err != nil { - return nil, err - } - - actcid, err := cron.GetActorCodeID(av) - if err != nil { - return nil, err - } - - act := &types.Actor{ - Code: actcid, - Head: statecid, - } - - return act, nil + return &types.Actor{ + Code: builtin.CronActorCodeID, + Head: stcid, + Nonce: 0, + Balance: types.NewInt(0), + }, nil } diff --git a/chain/gen/genesis/f04_power.go b/chain/gen/genesis/f04_power.go index 6fe4d75c0..ed349c18b 100644 --- a/chain/gen/genesis/f04_power.go +++ b/chain/gen/genesis/f04_power.go @@ -3,39 +3,44 @@ package genesis import ( "context" - "github.com/filecoin-project/lotus/chain/actors/builtin/power" - - "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/util/adt" + power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupStoragePowerActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { - - cst := cbor.NewCborStore(bs) - pst, err := power.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av) +func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) { + store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) + emptyMap, err := adt.MakeEmptyMap(store).Root() if err != nil { return nil, err } - statecid, err := cst.Put(ctx, pst.GetState()) + multiMap, err := adt.AsMultimap(store, emptyMap) if err != nil { return nil, err } - actcid, err := power.GetActorCodeID(av) + emptyMultiMap, err := multiMap.Root() if err != nil { return nil, err } - act := &types.Actor{ - Code: actcid, - Head: statecid, + sms := power0.ConstructState(emptyMap, emptyMultiMap) + + stcid, err := store.Put(store.Context(), sms) + if err != nil { + return nil, err } - return act, nil + return &types.Actor{ + Code: builtin.StoragePowerActorCodeID, + Head: stcid, + Nonce: 0, + Balance: types.NewInt(0), + }, nil } diff --git a/chain/gen/genesis/f05_market.go b/chain/gen/genesis/f05_market.go index 5c39ef38f..f7ac26f43 100644 --- a/chain/gen/genesis/f05_market.go +++ b/chain/gen/genesis/f05_market.go @@ -3,36 +3,38 @@ package genesis import ( "context" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors/builtin/market" - + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/util/adt" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupStorageMarketActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { - cst := cbor.NewCborStore(bs) - mst, err := market.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av) +func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) { + store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) + + a, err := adt.MakeEmptyArray(store).Root() + if err != nil { + return nil, err + } + h, err := adt.MakeEmptyMap(store).Root() if err != nil { return nil, err } - statecid, err := cst.Put(ctx, mst.GetState()) - if err != nil { - return nil, err - } + sms := market.ConstructState(a, h, h) - actcid, err := market.GetActorCodeID(av) + stcid, err := store.Put(store.Context(), sms) if err != nil { return nil, err } act := &types.Actor{ - Code: actcid, - Head: statecid, + Code: builtin.StorageMarketActorCodeID, + Head: stcid, + Balance: types.NewInt(0), } return act, nil diff --git a/chain/gen/genesis/f06_vreg.go b/chain/gen/genesis/f06_vreg.go index d8f5ee2a0..1ba8abede 100644 --- a/chain/gen/genesis/f06_vreg.go +++ b/chain/gen/genesis/f06_vreg.go @@ -3,13 +3,11 @@ package genesis import ( "context" - "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" - - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/go-address" cbor "github.com/ipfs/go-ipld-cbor" + "github.com/filecoin-project/specs-actors/actors/builtin" + verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" "github.com/filecoin-project/specs-actors/actors/util/adt" bstore "github.com/filecoin-project/lotus/blockstore" @@ -28,26 +26,25 @@ func init() { RootVerifierID = idk } -func SetupVerifiedRegistryActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { - cst := cbor.NewCborStore(bs) - vst, err := verifreg.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av, RootVerifierID) +func SetupVerifiedRegistryActor(bs bstore.Blockstore) (*types.Actor, error) { + store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) + + h, err := adt.MakeEmptyMap(store).Root() if err != nil { return nil, err } - statecid, err := cst.Put(ctx, vst.GetState()) - if err != nil { - return nil, err - } + sms := verifreg0.ConstructState(h, RootVerifierID) - actcid, err := verifreg.GetActorCodeID(av) + stcid, err := store.Put(store.Context(), sms) if err != nil { return nil, err } act := &types.Actor{ - Code: actcid, - Head: statecid, + Code: builtin.VerifiedRegistryActorCodeID, + Head: stcid, + Balance: types.NewInt(0), } return act, nil diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index 94badbbfb..4b86db550 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -6,32 +6,6 @@ import ( "encoding/json" "fmt" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" - - "github.com/filecoin-project/go-state-types/network" - - "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" - - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors/builtin/account" - - "github.com/filecoin-project/lotus/chain/actors" - - "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" - - "github.com/filecoin-project/lotus/chain/actors/builtin/market" - - "github.com/filecoin-project/lotus/chain/actors/builtin/power" - - "github.com/filecoin-project/lotus/chain/actors/builtin/cron" - - init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" - "github.com/filecoin-project/lotus/chain/actors/builtin/reward" - - "github.com/filecoin-project/lotus/chain/actors/builtin/system" - "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/journal" @@ -47,6 +21,11 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + account0 "github.com/filecoin-project/specs-actors/actors/builtin/account" + multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" @@ -139,92 +118,94 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return nil, nil, xerrors.Errorf("putting empty object: %w", err) } - sv, err := state.VersionForNetwork(template.NetworkVersion) - if err != nil { - return nil, nil, xerrors.Errorf("getting state tree version: %w", err) - } - - state, err := state.NewStateTree(cst, sv) + state, err := state.NewStateTree(cst, types.StateTreeVersion0) if err != nil { return nil, nil, xerrors.Errorf("making new state tree: %w", err) } - av := actors.VersionForNetwork(template.NetworkVersion) - // Create system actor - sysact, err := SetupSystemActor(ctx, bs, av) + sysact, err := SetupSystemActor(bs) if err != nil { - return nil, nil, xerrors.Errorf("setup system actor: %w", err) + return nil, nil, xerrors.Errorf("setup init actor: %w", err) } - if err := state.SetActor(system.Address, sysact); err != nil { - return nil, nil, xerrors.Errorf("set system actor: %w", err) + if err := state.SetActor(builtin0.SystemActorAddr, sysact); err != nil { + return nil, nil, xerrors.Errorf("set init actor: %w", err) } // Create init actor - idStart, initact, keyIDs, err := SetupInitActor(ctx, bs, template.NetworkName, template.Accounts, template.VerifregRootKey, template.RemainderAccount, av) + idStart, initact, keyIDs, err := SetupInitActor(bs, template.NetworkName, template.Accounts, template.VerifregRootKey, template.RemainderAccount) if err != nil { return nil, nil, xerrors.Errorf("setup init actor: %w", err) } - if err := state.SetActor(init_.Address, initact); err != nil { + if err := state.SetActor(builtin0.InitActorAddr, initact); err != nil { return nil, nil, xerrors.Errorf("set init actor: %w", err) } // Setup reward - // RewardActor's state is overwritten by SetupStorageMiners, but needs to exist for miner creation messages - rewact, err := SetupRewardActor(ctx, bs, big.Zero(), av) + // RewardActor's state is overrwritten by SetupStorageMiners + rewact, err := SetupRewardActor(bs, big.Zero()) if err != nil { - return nil, nil, xerrors.Errorf("setup reward actor: %w", err) + return nil, nil, xerrors.Errorf("setup init actor: %w", err) } - err = state.SetActor(reward.Address, rewact) + err = state.SetActor(builtin0.RewardActorAddr, rewact) if err != nil { - return nil, nil, xerrors.Errorf("set reward actor: %w", err) + return nil, nil, xerrors.Errorf("set network account actor: %w", err) } // Setup cron - cronact, err := SetupCronActor(ctx, bs, av) + cronact, err := SetupCronActor(bs) if err != nil { return nil, nil, xerrors.Errorf("setup cron actor: %w", err) } - if err := state.SetActor(cron.Address, cronact); err != nil { + if err := state.SetActor(builtin0.CronActorAddr, cronact); err != nil { return nil, nil, xerrors.Errorf("set cron actor: %w", err) } // Create empty power actor - spact, err := SetupStoragePowerActor(ctx, bs, av) - if err != nil { - return nil, nil, xerrors.Errorf("setup storage power actor: %w", err) - } - if err := state.SetActor(power.Address, spact); err != nil { - return nil, nil, xerrors.Errorf("set storage power actor: %w", err) - } - - // Create empty market actor - marketact, err := SetupStorageMarketActor(ctx, bs, av) + spact, err := SetupStoragePowerActor(bs) if err != nil { return nil, nil, xerrors.Errorf("setup storage market actor: %w", err) } - if err := state.SetActor(market.Address, marketact); err != nil { + if err := state.SetActor(builtin0.StoragePowerActorAddr, spact); err != nil { return nil, nil, xerrors.Errorf("set storage market actor: %w", err) } - // Create verified registry - verifact, err := SetupVerifiedRegistryActor(ctx, bs, av) + // Create empty market actor + marketact, err := SetupStorageMarketActor(bs) if err != nil { - return nil, nil, xerrors.Errorf("setup verified registry market actor: %w", err) + return nil, nil, xerrors.Errorf("setup storage market actor: %w", err) } - if err := state.SetActor(verifreg.Address, verifact); err != nil { - return nil, nil, xerrors.Errorf("set verified registry actor: %w", err) + if err := state.SetActor(builtin0.StorageMarketActorAddr, marketact); err != nil { + return nil, nil, xerrors.Errorf("set market actor: %w", err) } - bact, err := makeAccountActor(ctx, cst, av, builtin.BurntFundsActorAddr, big.Zero()) + // Create verified registry + verifact, err := SetupVerifiedRegistryActor(bs) if err != nil { - return nil, nil, xerrors.Errorf("setup burnt funds actor state: %w", err) + return nil, nil, xerrors.Errorf("setup storage market actor: %w", err) } - if err := state.SetActor(builtin.BurntFundsActorAddr, bact); err != nil { - return nil, nil, xerrors.Errorf("set burnt funds actor: %w", err) + if err := state.SetActor(builtin0.VerifiedRegistryActorAddr, verifact); err != nil { + return nil, nil, xerrors.Errorf("set market actor: %w", err) + } + + burntRoot, err := cst.Put(ctx, &account0.State{ + Address: builtin0.BurntFundsActorAddr, + }) + if err != nil { + return nil, nil, xerrors.Errorf("failed to setup burnt funds actor state: %w", err) + } + + // Setup burnt-funds + err = state.SetActor(builtin0.BurntFundsActorAddr, &types.Actor{ + Code: builtin0.AccountActorCodeID, + Balance: types.NewInt(0), + Head: burntRoot, + }) + if err != nil { + return nil, nil, xerrors.Errorf("set burnt funds account actor: %w", err) } // Create accounts @@ -232,7 +213,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge switch info.Type { case genesis.TAccount: - if err := createAccountActor(ctx, cst, state, info, keyIDs, av); err != nil { + if err := createAccountActor(ctx, cst, state, info, keyIDs); err != nil { return nil, nil, xerrors.Errorf("failed to create account actor: %w", err) } @@ -244,7 +225,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge } idStart++ - if err := createMultisigAccount(ctx, cst, state, ida, info, keyIDs, av); err != nil { + if err := createMultisigAccount(ctx, bs, cst, state, ida, info, keyIDs); err != nil { return nil, nil, err } default: @@ -259,21 +240,26 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge if err := json.Unmarshal(template.VerifregRootKey.Meta, &ainfo); err != nil { return nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err) } + st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner}) + if err != nil { + return nil, nil, err + } _, ok := keyIDs[ainfo.Owner] if ok { return nil, nil, fmt.Errorf("rootkey account has already been declared, cannot be assigned 80: %s", ainfo.Owner) } - vact, err := makeAccountActor(ctx, cst, av, ainfo.Owner, template.VerifregRootKey.Balance) + err = state.SetActor(builtin.RootVerifierAddress, &types.Actor{ + Code: builtin0.AccountActorCodeID, + Balance: template.VerifregRootKey.Balance, + Head: st, + }) if err != nil { - return nil, nil, xerrors.Errorf("setup verifreg rootkey account state: %w", err) - } - if err = state.SetActor(builtin.RootVerifierAddress, vact); err != nil { - return nil, nil, xerrors.Errorf("set verifreg rootkey account actor: %w", err) + return nil, nil, xerrors.Errorf("setting verifreg rootkey account: %w", err) } case genesis.TMultisig: - if err = createMultisigAccount(ctx, cst, state, builtin.RootVerifierAddress, template.VerifregRootKey, keyIDs, av); err != nil { + if err = createMultisigAccount(ctx, bs, cst, state, builtin.RootVerifierAddress, template.VerifregRootKey, keyIDs); err != nil { return nil, nil, xerrors.Errorf("failed to set up verified registry signer: %w", err) } default: @@ -302,13 +288,18 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return nil, nil, err } - verifierAct, err := makeAccountActor(ctx, cst, av, verifierAd, big.Zero()) + verifierState, err := cst.Put(ctx, &account0.State{Address: verifierAd}) if err != nil { - return nil, nil, xerrors.Errorf("setup first verifier state: %w", err) + return nil, nil, err } - if err = state.SetActor(verifierId, verifierAct); err != nil { - return nil, nil, xerrors.Errorf("set first verifier actor: %w", err) + err = state.SetActor(verifierId, &types.Actor{ + Code: builtin0.AccountActorCodeID, + Balance: types.NewInt(0), + Head: verifierState, + }) + if err != nil { + return nil, nil, xerrors.Errorf("setting account from actmap: %w", err) } totalFilAllocated := big.Zero() @@ -346,13 +337,13 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge } keyIDs[ainfo.Owner] = builtin.ReserveAddress - err = createAccountActor(ctx, cst, state, template.RemainderAccount, keyIDs, av) + err = createAccountActor(ctx, cst, state, template.RemainderAccount, keyIDs) if err != nil { return nil, nil, xerrors.Errorf("creating remainder acct: %w", err) } case genesis.TMultisig: - if err = createMultisigAccount(ctx, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs, av); err != nil { + if err = createMultisigAccount(ctx, bs, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs); err != nil { return nil, nil, xerrors.Errorf("failed to set up remainder: %w", err) } default: @@ -362,38 +353,12 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return state, keyIDs, nil } -func makeAccountActor(ctx context.Context, cst cbor.IpldStore, av actors.Version, addr address.Address, bal types.BigInt) (*types.Actor, error) { - ast, err := account.MakeState(adt.WrapStore(ctx, cst), av, addr) - if err != nil { - return nil, err - } - - statecid, err := cst.Put(ctx, ast.GetState()) - if err != nil { - return nil, err - } - - actcid, err := account.GetActorCodeID(av) - if err != nil { - return nil, err - } - - act := &types.Actor{ - Code: actcid, - Head: statecid, - Balance: bal, - } - - return act, nil -} - -func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.StateTree, info genesis.Actor, keyIDs map[address.Address]address.Address, av actors.Version) error { +func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.StateTree, info genesis.Actor, keyIDs map[address.Address]address.Address) error { var ainfo genesis.AccountMeta if err := json.Unmarshal(info.Meta, &ainfo); err != nil { return xerrors.Errorf("unmarshaling account meta: %w", err) } - - aa, err := makeAccountActor(ctx, cst, av, ainfo.Owner, info.Balance) + st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner}) if err != nil { return err } @@ -403,14 +368,18 @@ func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.St return fmt.Errorf("no registered ID for account actor: %s", ainfo.Owner) } - err = state.SetActor(ida, aa) + err = state.SetActor(ida, &types.Actor{ + Code: builtin0.AccountActorCodeID, + Balance: info.Balance, + Head: st, + }) if err != nil { return xerrors.Errorf("setting account from actmap: %w", err) } return nil } -func createMultisigAccount(ctx context.Context, cst cbor.IpldStore, state *state.StateTree, ida address.Address, info genesis.Actor, keyIDs map[address.Address]address.Address, av actors.Version) error { +func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.IpldStore, state *state.StateTree, ida address.Address, info genesis.Actor, keyIDs map[address.Address]address.Address) error { if info.Type != genesis.TMultisig { return fmt.Errorf("can only call createMultisigAccount with multisig Actor info") } @@ -418,6 +387,10 @@ func createMultisigAccount(ctx context.Context, cst cbor.IpldStore, state *state if err := json.Unmarshal(info.Meta, &ainfo); err != nil { return xerrors.Errorf("unmarshaling account meta: %w", err) } + pending, err := adt0.MakeEmptyMap(adt0.WrapStore(ctx, cst)).Root() + if err != nil { + return xerrors.Errorf("failed to create empty map: %v", err) + } var signers []address.Address @@ -434,45 +407,44 @@ func createMultisigAccount(ctx context.Context, cst cbor.IpldStore, state *state continue } - aa, err := makeAccountActor(ctx, cst, av, e, big.Zero()) + st, err := cst.Put(ctx, &account0.State{Address: e}) if err != nil { return err } - - if err = state.SetActor(idAddress, aa); err != nil { + err = state.SetActor(idAddress, &types.Actor{ + Code: builtin0.AccountActorCodeID, + Balance: types.NewInt(0), + Head: st, + }) + if err != nil { return xerrors.Errorf("setting account from actmap: %w", err) } signers = append(signers, idAddress) } - mst, err := multisig.MakeState(adt.WrapStore(ctx, cst), av, signers, uint64(ainfo.Threshold), abi.ChainEpoch(ainfo.VestingStart), abi.ChainEpoch(ainfo.VestingDuration), info.Balance) + st, err := cst.Put(ctx, &multisig0.State{ + Signers: signers, + NumApprovalsThreshold: uint64(ainfo.Threshold), + StartEpoch: abi.ChainEpoch(ainfo.VestingStart), + UnlockDuration: abi.ChainEpoch(ainfo.VestingDuration), + PendingTxns: pending, + InitialBalance: info.Balance, + }) if err != nil { return err } - - statecid, err := cst.Put(ctx, mst.GetState()) - if err != nil { - return err - } - - actcid, err := multisig.GetActorCodeID(av) - if err != nil { - return err - } - err = state.SetActor(ida, &types.Actor{ - Code: actcid, + Code: builtin0.MultisigActorCodeID, Balance: info.Balance, - Head: statecid, + Head: st, }) if err != nil { return xerrors.Errorf("setting account from actmap: %w", err) } - return nil } -func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot cid.Cid, template genesis.Template, keyIDs map[address.Address]address.Address, nv network.Version) (cid.Cid, error) { +func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot cid.Cid, template genesis.Template, keyIDs map[address.Address]address.Address) (cid.Cid, error) { verifNeeds := make(map[address.Address]abi.PaddedPieceSize) var sum abi.PaddedPieceSize @@ -483,10 +455,8 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci Bstore: cs.StateBlockstore(), Syscalls: mkFakedSigSyscalls(cs.VMSys()), CircSupplyCalc: nil, - NtwkVersion: func(_ context.Context, _ abi.ChainEpoch) network.Version { - return nv - }, - BaseFee: types.NewInt(0), + NtwkVersion: genesisNetworkVersion, + BaseFee: types.NewInt(0), } vm, err := vm.NewVM(ctx, &vmopt) if err != nil { @@ -515,8 +485,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci return cid.Undef, err } - // Note: This is brittle, if the methodNum / param changes, it could break things - _, err = doExecValue(ctx, vm, verifreg.Address, verifregRoot, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg0.AddVerifierParams{ + _, err = doExecValue(ctx, vm, builtin0.VerifiedRegistryActorAddr, verifregRoot, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg0.AddVerifierParams{ Address: verifier, Allowance: abi.NewStoragePower(int64(sum)), // eh, close enough @@ -527,8 +496,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci } for c, amt := range verifNeeds { - // Note: This is brittle, if the methodNum / param changes, it could break things - _, err := doExecValue(ctx, vm, verifreg.Address, verifier, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifiedClient, mustEnc(&verifreg0.AddVerifiedClientParams{ + _, err := doExecValue(ctx, vm, builtin0.VerifiedRegistryActorAddr, verifier, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifiedClient, mustEnc(&verifreg0.AddVerifiedClientParams{ Address: c, Allowance: abi.NewStoragePower(int64(amt)), })) @@ -563,17 +531,17 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto cs := store.NewChainStore(bs, bs, datastore.NewMapDatastore(), sys, j) // Verify PreSealed Data - stateroot, err = VerifyPreSealedData(ctx, cs, stateroot, template, keyIDs, template.NetworkVersion) + stateroot, err = VerifyPreSealedData(ctx, cs, stateroot, template, keyIDs) if err != nil { return nil, xerrors.Errorf("failed to verify presealed data: %w", err) } - stateroot, err = SetupStorageMiners(ctx, cs, stateroot, template.Miners, template.NetworkVersion) + stateroot, err = SetupStorageMiners(ctx, cs, stateroot, template.Miners) if err != nil { return nil, xerrors.Errorf("setup miners failed: %w", err) } - store := adt.WrapStore(ctx, cbor.NewCborStore(bs)) + store := adt0.WrapStore(ctx, cbor.NewCborStore(bs)) emptyroot, err := adt0.MakeEmptyArray(store).Root() if err != nil { return nil, xerrors.Errorf("amt build failed: %w", err) @@ -622,7 +590,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto } b := &types.BlockHeader{ - Miner: system.Address, + Miner: builtin0.SystemActorAddr, Ticket: genesisticket, Parents: []cid.Cid{filecoinGenesisCid}, Height: 0, diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index 17349b270..297543886 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -6,22 +6,6 @@ import ( "fmt" "math/rand" - power4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/power" - - reward4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/reward" - - market4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/market" - - "github.com/filecoin-project/lotus/chain/actors" - - "github.com/filecoin-project/lotus/chain/actors/builtin" - - "github.com/filecoin-project/lotus/chain/actors/policy" - - "github.com/filecoin-project/lotus/chain/actors/adt" - - "github.com/filecoin-project/go-state-types/network" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/power" @@ -77,12 +61,7 @@ func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder { } } -// Note: Much of this is brittle, if the methodNum / param / return changes, it will break things -func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner, nv network.Version) (cid.Cid, error) { - - cst := cbor.NewCborStore(cs.StateBlockstore()) - av := actors.VersionForNetwork(nv) - +func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner) (cid.Cid, error) { csc := func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) { return big.Zero(), nil } @@ -94,10 +73,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid Bstore: cs.StateBlockstore(), Syscalls: mkFakedSigSyscalls(cs.VMSys()), CircSupplyCalc: csc, - NtwkVersion: func(_ context.Context, _ abi.ChainEpoch) network.Version { - return nv - }, - BaseFee: types.NewInt(0), + NtwkVersion: genesisNetworkVersion, + BaseFee: types.NewInt(0), } vm, err := vm.NewVM(ctx, vmopt) @@ -117,13 +94,12 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid dealIDs []abi.DealID }, len(miners)) - maxPeriods := policy.GetMaxSectorExpirationExtension() / miner.WPoStProvingPeriod for i, m := range miners { // Create miner through power actor i := i m := m - spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, nv) + spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, GenesisNetworkVersion) if err != nil { return cid.Undef, err } @@ -137,7 +113,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid } params := mustEnc(constructorParams) - rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, power.Methods.CreateMiner, params) + rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, builtin0.MethodsPower.CreateMiner, params) if err != nil { return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err) } @@ -153,34 +129,23 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid } minerInfos[i].maddr = ma.IDAddress - _, err = vm.Flush(ctx) - if err != nil { - return cid.Undef, xerrors.Errorf("flushing vm: %w", err) - } + // TODO: ActorUpgrade + err = vm.MutateState(ctx, minerInfos[i].maddr, func(cst cbor.IpldStore, st *miner0.State) error { + maxPeriods := miner0.MaxSectorExpirationExtension / miner0.WPoStProvingPeriod + minerInfos[i].presealExp = (maxPeriods-1)*miner0.WPoStProvingPeriod + st.ProvingPeriodStart - 1 - mact, err := vm.StateTree().GetActor(minerInfos[i].maddr) + return nil + }) if err != nil { - return cid.Undef, xerrors.Errorf("getting newly created miner actor: %w", err) + return cid.Undef, xerrors.Errorf("mutating state: %w", err) } - - mst, err := miner.Load(adt.WrapStore(ctx, cst), mact) - if err != nil { - return cid.Undef, xerrors.Errorf("getting newly created miner state: %w", err) - } - - pps, err := mst.GetProvingPeriodStart() - if err != nil { - return cid.Undef, xerrors.Errorf("getting newly created miner proving period start: %w", err) - } - - minerInfos[i].presealExp = (maxPeriods-1)*miner0.WPoStProvingPeriod + pps - 1 } // Add market funds if m.MarketBalance.GreaterThan(big.Zero()) { params := mustEnc(&minerInfos[i].maddr) - _, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, market.Methods.AddBalance, params) + _, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin0.MethodsMarket.AddBalance, params) if err != nil { return cid.Undef, xerrors.Errorf("failed to create genesis miner (add balance): %w", err) } @@ -238,66 +203,35 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid for pi := range m.Sectors { rawPow = types.BigAdd(rawPow, types.NewInt(uint64(m.SectorSize))) - dweight, vdweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, []abi.DealID{minerInfos[i].dealIDs[pi]}, 0, minerInfos[i].presealExp, av) + dweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, []abi.DealID{minerInfos[i].dealIDs[pi]}, 0, minerInfos[i].presealExp) if err != nil { return cid.Undef, xerrors.Errorf("getting deal weight: %w", err) } - sectorWeight := builtin.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight, vdweight) + sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight) qaPow = types.BigAdd(qaPow, sectorWeight) } } - _, err = vm.Flush(ctx) + err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error { + st.TotalQualityAdjPower = qaPow + st.TotalRawBytePower = rawPow + + st.ThisEpochQualityAdjPower = qaPow + st.ThisEpochRawBytePower = rawPow + return nil + }) if err != nil { - return cid.Undef, xerrors.Errorf("flushing vm: %w", err) + return cid.Undef, xerrors.Errorf("mutating state: %w", err) } - pact, err := vm.StateTree().GetActor(power.Address) + err = vm.MutateState(ctx, reward.Address, func(sct cbor.IpldStore, st *reward0.State) error { + *st = *reward0.ConstructState(qaPow) + return nil + }) if err != nil { - return cid.Undef, xerrors.Errorf("getting power actor: %w", err) - } - - pst, err := power.Load(adt.WrapStore(ctx, cst), pact) - if err != nil { - return cid.Undef, xerrors.Errorf("getting power state: %w", err) - } - - if err = pst.SetTotalQualityAdjPower(qaPow); err != nil { - return cid.Undef, xerrors.Errorf("setting TotalQualityAdjPower in power state: %w", err) - } - - if err = pst.SetTotalRawBytePower(rawPow); err != nil { - return cid.Undef, xerrors.Errorf("setting TotalRawBytePower in power state: %w", err) - } - - if err = pst.SetThisEpochQualityAdjPower(qaPow); err != nil { - return cid.Undef, xerrors.Errorf("setting ThisEpochQualityAdjPower in power state: %w", err) - } - - if err = pst.SetThisEpochRawBytePower(rawPow); err != nil { - return cid.Undef, xerrors.Errorf("setting ThisEpochRawBytePower in power state: %w", err) - } - - pcid, err := cst.Put(ctx, pst.GetState()) - if err != nil { - return cid.Undef, xerrors.Errorf("putting power state: %w", err) - } - - pact.Head = pcid - - if err = vm.StateTree().SetActor(power.Address, pact); err != nil { - return cid.Undef, xerrors.Errorf("setting power state: %w", err) - } - - rewact, err := SetupRewardActor(ctx, cs.StateBlockstore(), big.Zero(), actors.VersionForNetwork(nv)) - if err != nil { - return cid.Undef, xerrors.Errorf("setup reward actor: %w", err) - } - - if err = vm.StateTree().SetActor(reward.Address, rewact); err != nil { - return cid.Undef, xerrors.Errorf("set reward actor: %w", err) + return cid.Undef, xerrors.Errorf("mutating state: %w", err) } } @@ -314,55 +248,24 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid Expiration: minerInfos[i].presealExp, // TODO: Allow setting externally! } - dweight, vdweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, params.DealIDs, 0, minerInfos[i].presealExp, av) + dweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, params.DealIDs, 0, minerInfos[i].presealExp) if err != nil { return cid.Undef, xerrors.Errorf("getting deal weight: %w", err) } - sectorWeight := builtin.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight, vdweight) + sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight) // we've added fake power for this sector above, remove it now - - _, err = vm.Flush(ctx) + err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error { + st.TotalQualityAdjPower = types.BigSub(st.TotalQualityAdjPower, sectorWeight) //nolint:scopelint + st.TotalRawBytePower = types.BigSub(st.TotalRawBytePower, types.NewInt(uint64(m.SectorSize))) + return nil + }) if err != nil { - return cid.Undef, xerrors.Errorf("flushing vm: %w", err) + return cid.Undef, xerrors.Errorf("removing fake power: %w", err) } - pact, err := vm.StateTree().GetActor(power.Address) - if err != nil { - return cid.Undef, xerrors.Errorf("getting power actor: %w", err) - } - - pst, err := power.Load(adt.WrapStore(ctx, cst), pact) - if err != nil { - return cid.Undef, xerrors.Errorf("getting power state: %w", err) - } - - pc, err := pst.TotalPower() - if err != nil { - return cid.Undef, xerrors.Errorf("getting total power: %w", err) - } - - if err = pst.SetTotalRawBytePower(types.BigSub(pc.RawBytePower, types.NewInt(uint64(m.SectorSize)))); err != nil { - return cid.Undef, xerrors.Errorf("setting TotalRawBytePower in power state: %w", err) - } - - if err = pst.SetTotalQualityAdjPower(types.BigSub(pc.QualityAdjPower, sectorWeight)); err != nil { - return cid.Undef, xerrors.Errorf("setting TotalQualityAdjPower in power state: %w", err) - } - - pcid, err := cst.Put(ctx, pst.GetState()) - if err != nil { - return cid.Undef, xerrors.Errorf("putting power state: %w", err) - } - - pact.Head = pcid - - if err = vm.StateTree().SetActor(power.Address, pact); err != nil { - return cid.Undef, xerrors.Errorf("setting power state: %w", err) - } - - baselinePower, rewardSmoothed, err := currentEpochBlockReward(ctx, vm, minerInfos[i].maddr, av) + epochReward, err := currentEpochBlockReward(ctx, vm, minerInfos[i].maddr) if err != nil { return cid.Undef, xerrors.Errorf("getting current epoch reward: %w", err) } @@ -372,13 +275,13 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid return cid.Undef, xerrors.Errorf("getting current total power: %w", err) } - pcd := miner0.PreCommitDepositForPower(&rewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight) + pcd := miner0.PreCommitDepositForPower(epochReward.ThisEpochRewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight) pledge := miner0.InitialPledgeForPower( sectorWeight, - baselinePower, + epochReward.ThisEpochBaselinePower, tpow.PledgeCollateral, - &rewardSmoothed, + epochReward.ThisEpochRewardSmoothed, tpow.QualityAdjPowerSmoothed, circSupply(ctx, vm, minerInfos[i].maddr), ) @@ -386,7 +289,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid pledge = big.Add(pcd, pledge) fmt.Println(types.FIL(pledge)) - _, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, miner.Methods.PreCommitSector, mustEnc(params)) + _, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, builtin0.MethodsMiner.PreCommitSector, mustEnc(params)) if err != nil { return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) } @@ -396,84 +299,28 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid Sectors: []abi.SectorNumber{preseal.SectorID}, } - _, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), miner.Methods.ConfirmSectorProofsValid, mustEnc(confirmParams)) + _, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin0.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams)) if err != nil { return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) } - - if av > actors.Version2 { - // post v2, we need to explicitly Claim this power since ConfirmSectorProofsValid doesn't do it anymore - claimParams := &power4.UpdateClaimedPowerParams{ - RawByteDelta: types.NewInt(uint64(m.SectorSize)), - QualityAdjustedDelta: sectorWeight, - } - - _, err = doExecValue(ctx, vm, power.Address, minerInfos[i].maddr, big.Zero(), power.Methods.UpdateClaimedPower, mustEnc(claimParams)) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) - } - - _, err = vm.Flush(ctx) - if err != nil { - return cid.Undef, xerrors.Errorf("flushing vm: %w", err) - } - - mact, err := vm.StateTree().GetActor(minerInfos[i].maddr) - if err != nil { - return cid.Undef, xerrors.Errorf("getting miner actor: %w", err) - } - - mst, err := miner.Load(adt.WrapStore(ctx, cst), mact) - if err != nil { - return cid.Undef, xerrors.Errorf("getting miner state: %w", err) - } - - if err = mst.EraseAllUnproven(); err != nil { - return cid.Undef, xerrors.Errorf("failed to erase unproven sectors: %w", err) - } - - mcid, err := cst.Put(ctx, mst.GetState()) - if err != nil { - return cid.Undef, xerrors.Errorf("putting miner state: %w", err) - } - - mact.Head = mcid - - if err = vm.StateTree().SetActor(minerInfos[i].maddr, mact); err != nil { - return cid.Undef, xerrors.Errorf("setting miner state: %w", err) - } - } } } } // Sanity-check total network power - _, err = vm.Flush(ctx) + err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error { + if !st.TotalRawBytePower.Equals(rawPow) { + return xerrors.Errorf("st.TotalRawBytePower doesn't match previously calculated rawPow") + } + + if !st.TotalQualityAdjPower.Equals(qaPow) { + return xerrors.Errorf("st.TotalQualityAdjPower doesn't match previously calculated qaPow") + } + + return nil + }) if err != nil { - return cid.Undef, xerrors.Errorf("flushing vm: %w", err) - } - - pact, err := vm.StateTree().GetActor(power.Address) - if err != nil { - return cid.Undef, xerrors.Errorf("getting power actor: %w", err) - } - - pst, err := power.Load(adt.WrapStore(ctx, cst), pact) - if err != nil { - return cid.Undef, xerrors.Errorf("getting power state: %w", err) - } - - pc, err := pst.TotalPower() - if err != nil { - return cid.Undef, xerrors.Errorf("getting total power: %w", err) - } - - if !pc.RawBytePower.Equals(rawPow) { - return cid.Undef, xerrors.Errorf("TotalRawBytePower (%s) doesn't match previously calculated rawPow (%s)", pc.RawBytePower, rawPow) - } - - if !pc.QualityAdjPower.Equals(qaPow) { - return cid.Undef, xerrors.Errorf("QualityAdjPower (%s) doesn't match previously calculated qaPow (%s)", pc.QualityAdjPower, qaPow) + return cid.Undef, xerrors.Errorf("mutating state: %w", err) } // TODO: Should we re-ConstructState for the reward actor using rawPow as currRealizedPower here? @@ -513,79 +360,43 @@ func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (* return &pwr, nil } -func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch, av actors.Version) (abi.DealWeight, abi.DealWeight, error) { - // TODO: This hack should move to market actor wrapper - if av <= actors.Version2 { - params := &market0.VerifyDealsForActivationParams{ - DealIDs: dealIDs, - SectorStart: sectorStart, - SectorExpiry: sectorExpiry, - } - - var dealWeights market0.VerifyDealsForActivationReturn - ret, err := doExecValue(ctx, vm, - market.Address, - maddr, - abi.NewTokenAmount(0), - builtin0.MethodsMarket.VerifyDealsForActivation, - mustEnc(params), - ) - if err != nil { - return big.Zero(), big.Zero(), err - } - if err := dealWeights.UnmarshalCBOR(bytes.NewReader(ret)); err != nil { - return big.Zero(), big.Zero(), err - } - - return dealWeights.DealWeight, dealWeights.VerifiedDealWeight, nil - } - params := &market4.VerifyDealsForActivationParams{Sectors: []market4.SectorDeals{{ - SectorExpiry: sectorExpiry, +func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch) (market0.VerifyDealsForActivationReturn, error) { + params := &market.VerifyDealsForActivationParams{ DealIDs: dealIDs, - }}} + SectorStart: sectorStart, + SectorExpiry: sectorExpiry, + } - var dealWeights market4.VerifyDealsForActivationReturn + var dealWeights market0.VerifyDealsForActivationReturn ret, err := doExecValue(ctx, vm, market.Address, maddr, abi.NewTokenAmount(0), - market.Methods.VerifyDealsForActivation, + builtin0.MethodsMarket.VerifyDealsForActivation, mustEnc(params), ) if err != nil { - return big.Zero(), big.Zero(), err + return market0.VerifyDealsForActivationReturn{}, err } if err := dealWeights.UnmarshalCBOR(bytes.NewReader(ret)); err != nil { - return big.Zero(), big.Zero(), err + return market0.VerifyDealsForActivationReturn{}, err } - return dealWeights.Sectors[0].DealWeight, dealWeights.Sectors[0].VerifiedDealWeight, nil + return dealWeights, nil } -func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address, av actors.Version) (abi.StoragePower, builtin.FilterEstimate, error) { - rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), reward.Methods.ThisEpochReward, nil) +func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward0.ThisEpochRewardReturn, error) { + rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin0.MethodsReward.ThisEpochReward, nil) if err != nil { - return big.Zero(), builtin.FilterEstimate{}, err + return nil, err } - // TODO: This hack should move to reward actor wrapper - if av <= actors.Version2 { - var epochReward reward0.ThisEpochRewardReturn - - if err := epochReward.UnmarshalCBOR(bytes.NewReader(rwret)); err != nil { - return big.Zero(), builtin.FilterEstimate{}, err - } - - return epochReward.ThisEpochBaselinePower, *epochReward.ThisEpochRewardSmoothed, nil - } - - var epochReward reward4.ThisEpochRewardReturn - + var epochReward reward0.ThisEpochRewardReturn if err := epochReward.UnmarshalCBOR(bytes.NewReader(rwret)); err != nil { - return big.Zero(), builtin.FilterEstimate{}, err + return nil, err } - return epochReward.ThisEpochBaselinePower, builtin.FilterEstimate(epochReward.ThisEpochRewardSmoothed), nil + return &epochReward, nil } func circSupply(ctx context.Context, vmi *vm.VM, maddr address.Address) abi.TokenAmount { diff --git a/chain/gen/genesis/util.go b/chain/gen/genesis/util.go index 67a4e9579..54cc30cc1 100644 --- a/chain/gen/genesis/util.go +++ b/chain/gen/genesis/util.go @@ -3,6 +3,9 @@ package genesis import ( "context" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" cbg "github.com/whyrusleeping/cbor-gen" @@ -46,3 +49,29 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value return ret.Return, nil } + +// TODO: Get from build +// TODO: make a list/schedule of these. +var GenesisNetworkVersion = func() network.Version { + // returns the version _before_ the first upgrade. + if build.UpgradeBreezeHeight >= 0 { + return network.Version0 + } + if build.UpgradeSmokeHeight >= 0 { + return network.Version1 + } + if build.UpgradeIgnitionHeight >= 0 { + return network.Version2 + } + if build.UpgradeActorsV2Height >= 0 { + return network.Version3 + } + if build.UpgradeLiftoffHeight >= 0 { + return network.Version3 + } + return build.ActorUpgradeNetworkVersion - 1 // genesis requires actors v0. +}() + +func genesisNetworkVersion(context.Context, abi.ChainEpoch) network.Version { // TODO: Get from build/ + return GenesisNetworkVersion // TODO: Get from build/ +} // TODO: Get from build/ diff --git a/chain/state/statetree.go b/chain/state/statetree.go index a31ec2396..2a7b436b8 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -14,6 +14,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/chain/actors" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" cbg "github.com/whyrusleeping/cbor-gen" @@ -141,19 +142,11 @@ func (ss *stateSnaps) deleteActor(addr address.Address) { // VersionForNetwork returns the state tree version for the given network // version. -func VersionForNetwork(ver network.Version) (types.StateTreeVersion, error) { - switch ver { - case network.Version0, network.Version1, network.Version2, network.Version3: - return types.StateTreeVersion0, nil - case network.Version4, network.Version5, network.Version6, network.Version7, network.Version8, network.Version9: - return types.StateTreeVersion1, nil - case network.Version10, network.Version11: - return types.StateTreeVersion2, nil - case network.Version12: - return types.StateTreeVersion3, nil - default: - panic(fmt.Sprintf("unsupported network version %d", ver)) +func VersionForNetwork(ver network.Version) types.StateTreeVersion { + if actors.VersionForNetwork(ver) == actors.Version0 { + return types.StateTreeVersion0 } + return types.StateTreeVersion1 } func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, error) { diff --git a/chain/state/statetree_test.go b/chain/state/statetree_test.go index 9177af312..91674337b 100644 --- a/chain/state/statetree_test.go +++ b/chain/state/statetree_test.go @@ -5,12 +5,11 @@ import ( "fmt" "testing" - "github.com/filecoin-project/go-state-types/network" - "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" address "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/network" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/build" @@ -46,12 +45,7 @@ func BenchmarkStateTreeSet(b *testing.B) { func BenchmarkStateTreeSetFlush(b *testing.B) { cst := cbor.NewMemCborStore() - sv, err := VersionForNetwork(build.NewestNetworkVersion) - if err != nil { - b.Fatal(err) - } - - st, err := NewStateTree(cst, sv) + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) if err != nil { b.Fatal(err) } @@ -81,12 +75,7 @@ func BenchmarkStateTreeSetFlush(b *testing.B) { func TestResolveCache(t *testing.T) { cst := cbor.NewMemCborStore() - sv, err := VersionForNetwork(build.NewestNetworkVersion) - if err != nil { - t.Fatal(err) - } - - st, err := NewStateTree(cst, sv) + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) if err != nil { t.Fatal(err) } @@ -183,12 +172,7 @@ func TestResolveCache(t *testing.T) { func BenchmarkStateTree10kGetActor(b *testing.B) { cst := cbor.NewMemCborStore() - sv, err := VersionForNetwork(build.NewestNetworkVersion) - if err != nil { - b.Fatal(err) - } - - st, err := NewStateTree(cst, sv) + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) if err != nil { b.Fatal(err) } @@ -230,12 +214,7 @@ func BenchmarkStateTree10kGetActor(b *testing.B) { func TestSetCache(t *testing.T) { cst := cbor.NewMemCborStore() - sv, err := VersionForNetwork(build.NewestNetworkVersion) - if err != nil { - t.Fatal(err) - } - - st, err := NewStateTree(cst, sv) + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) if err != nil { t.Fatal(err) } @@ -272,13 +251,7 @@ func TestSetCache(t *testing.T) { func TestSnapshots(t *testing.T) { ctx := context.Background() cst := cbor.NewMemCborStore() - - sv, err := VersionForNetwork(build.NewestNetworkVersion) - if err != nil { - t.Fatal(err) - } - - st, err := NewStateTree(cst, sv) + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) if err != nil { t.Fatal(err) } @@ -361,15 +334,8 @@ func assertNotHas(t *testing.T, st *StateTree, addr address.Address) { func TestStateTreeConsistency(t *testing.T) { cst := cbor.NewMemCborStore() - // TODO: ActorUpgrade: this test tests pre actors v2 - - sv, err := VersionForNetwork(network.Version3) - if err != nil { - t.Fatal(err) - } - - st, err := NewStateTree(cst, sv) + st, err := NewStateTree(cst, VersionForNetwork(network.Version3)) if err != nil { t.Fatal(err) } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index f488c7864..afc74e744 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "reflect" "sync/atomic" "time" @@ -202,8 +203,7 @@ type ( ) type VM struct { - cstate *state.StateTree - // TODO: Is base actually used? Can we delete it? + cstate *state.StateTree base cid.Cid cst *cbor.BasicIpldStore buf *blockstore.BufferedBlockstore @@ -662,6 +662,37 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) { return root, nil } +// MutateState usage: MutateState(ctx, idAddr, func(cst cbor.IpldStore, st *ActorStateType) error {...}) +func (vm *VM) MutateState(ctx context.Context, addr address.Address, fn interface{}) error { + act, err := vm.cstate.GetActor(addr) + if err != nil { + return xerrors.Errorf("actor not found: %w", err) + } + + st := reflect.New(reflect.TypeOf(fn).In(1).Elem()) + if err := vm.cst.Get(ctx, act.Head, st.Interface()); err != nil { + return xerrors.Errorf("read actor head: %w", err) + } + + out := reflect.ValueOf(fn).Call([]reflect.Value{reflect.ValueOf(vm.cst), st}) + if !out[0].IsNil() && out[0].Interface().(error) != nil { + return out[0].Interface().(error) + } + + head, err := vm.cst.Put(ctx, st.Interface()) + if err != nil { + return xerrors.Errorf("put new actor head: %w", err) + } + + act.Head = head + + if err := vm.cstate.SetActor(addr, act); err != nil { + return xerrors.Errorf("set actor: %w", err) + } + + return nil +} + func linksForObj(blk block.Block, cb func(cid.Cid)) error { switch blk.Cid().Prefix().Codec { case cid.DagCBOR: diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go index 87493c58a..d5f1d5ad6 100644 --- a/cmd/lotus-seed/genesis.go +++ b/cmd/lotus-seed/genesis.go @@ -9,8 +9,6 @@ import ( "strconv" "strings" - "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" @@ -41,7 +39,6 @@ var genesisCmd = &cli.Command{ genesisAddMsigsCmd, genesisSetVRKCmd, genesisSetRemainderCmd, - genesisSetActorVersionCmd, genesisCarCmd, }, } @@ -59,7 +56,6 @@ var genesisNewCmd = &cli.Command{ return xerrors.New("seed genesis new [genesis.json]") } out := genesis.Template{ - NetworkVersion: network.Version0, Accounts: []genesis.Actor{}, Miners: []genesis.Miner{}, VerifregRootKey: gen.DefaultVerifregRootkeyActor, @@ -507,53 +503,6 @@ var genesisSetRemainderCmd = &cli.Command{ }, } -var genesisSetActorVersionCmd = &cli.Command{ - Name: "set-network-version", - Usage: "Set the version that this network will start from", - ArgsUsage: " ", - Action: func(cctx *cli.Context) error { - if cctx.Args().Len() != 2 { - return fmt.Errorf("must specify genesis file and network version (e.g. '0'") - } - - genf, err := homedir.Expand(cctx.Args().First()) - if err != nil { - return err - } - - var template genesis.Template - b, err := ioutil.ReadFile(genf) - if err != nil { - return xerrors.Errorf("read genesis template: %w", err) - } - - if err := json.Unmarshal(b, &template); err != nil { - return xerrors.Errorf("unmarshal genesis template: %w", err) - } - - nv, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64) - if err != nil { - return xerrors.Errorf("parsing network version: %w", err) - } - - if nv > uint64(build.NewestNetworkVersion) { - return xerrors.Errorf("invalid network version: %d", nv) - } - - template.NetworkVersion = network.Version(nv) - - b, err = json.MarshalIndent(&template, "", " ") - if err != nil { - return err - } - - if err := ioutil.WriteFile(genf, b, 0644); err != nil { - return err - } - return nil - }, -} - var genesisCarCmd = &cli.Command{ Name: "car", Description: "write genesis car file", diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index c92397125..c4e62b419 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -94,11 +94,6 @@ var preSealCmd = &cli.Command{ Name: "fake-sectors", Value: false, }, - &cli.IntFlag{ - Name: "network-version", - Value: 0, - Usage: "specify network version", - }, }, Action: func(c *cli.Context) error { sdir := c.String("sector-dir") @@ -134,7 +129,7 @@ var preSealCmd = &cli.Command{ } sectorSize := abi.SectorSize(sectorSizeInt) - spt, err := miner.SealProofTypeFromSectorSize(sectorSize, network.Version(c.Uint64("network-version"))) + spt, err := miner.SealProofTypeFromSectorSize(sectorSize, network.Version0) if err != nil { return err } diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index a8b760f8a..0372c0dab 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -4551,7 +4551,7 @@ Inputs: ] ``` -Response: `12` +Response: `11` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index be326b3e8..bf282745a 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -4772,7 +4772,7 @@ Inputs: ] ``` -Response: `12` +Response: `11` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/genesis/types.go b/genesis/types.go index d4c04113a..db8d32a3b 100644 --- a/genesis/types.go +++ b/genesis/types.go @@ -3,8 +3,6 @@ package genesis import ( "encoding/json" - "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" @@ -77,9 +75,8 @@ type Actor struct { } type Template struct { - NetworkVersion network.Version - Accounts []Actor - Miners []Miner + Accounts []Actor + Miners []Miner NetworkName string Timestamp uint64 `json:",omitempty"` diff --git a/node/test/builder.go b/node/test/builder.go index bd180ee41..7e26966a8 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -12,8 +12,6 @@ import ( "testing" "time" - "github.com/filecoin-project/go-state-types/network" - "github.com/gorilla/mux" "golang.org/x/xerrors" @@ -279,7 +277,6 @@ func mockBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []test. genms = append(genms, *genm) } templ := &genesis.Template{ - NetworkVersion: network.Version0, Accounts: genaccs, Miners: genms, NetworkName: "test", @@ -443,7 +440,6 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes genms = append(genms, *genm) } templ := &genesis.Template{ - NetworkVersion: network.Version0, Accounts: genaccs, Miners: genms, NetworkName: "test", From 77145372395544e24fe4431f16e69e38503c77f2 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 14 May 2021 21:11:23 -0400 Subject: [PATCH 75/80] Allow starting networks from arbitrary actor versions --- build/openrpc/full.json.gz | Bin 23308 -> 23305 bytes build/params_2k.go | 20 +- build/params_shared_vals.go | 2 +- chain/actors/adt/temp | 0 chain/actors/aerrors/temp | 0 chain/actors/agen/main.go | 72 ++-- chain/actors/agen/temp | 0 chain/actors/builtin/account/account.go | 41 +++ .../actors/builtin/account/actor.go.template | 23 ++ .../actors/builtin/account/state.go.template | 10 + chain/actors/builtin/account/temp | 0 chain/actors/builtin/account/v0.go | 10 + chain/actors/builtin/account/v2.go | 10 + chain/actors/builtin/account/v3.go | 10 + chain/actors/builtin/account/v4.go | 10 + chain/actors/builtin/builtin.go.template | 94 ++--- chain/actors/builtin/cron/actor.go.template | 34 +- chain/actors/builtin/cron/cron.go | 54 +++ chain/actors/builtin/cron/state.go.template | 35 ++ chain/actors/builtin/cron/temp | 0 chain/actors/builtin/cron/v0.go | 35 ++ chain/actors/builtin/cron/v2.go | 35 ++ chain/actors/builtin/cron/v3.go | 35 ++ chain/actors/builtin/cron/v4.go | 35 ++ chain/actors/builtin/init/actor.go.template | 31 +- chain/actors/builtin/init/diff.go | 4 +- chain/actors/builtin/init/init.go | 49 ++- chain/actors/builtin/init/state.go.template | 38 +- chain/actors/builtin/init/temp | 0 chain/actors/builtin/init/v0.go | 31 +- chain/actors/builtin/init/v2.go | 31 +- chain/actors/builtin/init/v3.go | 31 +- chain/actors/builtin/init/v4.go | 31 +- chain/actors/builtin/market/actor.go.template | 80 +++-- chain/actors/builtin/market/market.go | 42 ++- chain/actors/builtin/market/state.go.template | 29 ++ chain/actors/builtin/market/temp | 0 chain/actors/builtin/market/v0.go | 22 ++ chain/actors/builtin/market/v2.go | 22 ++ chain/actors/builtin/market/v3.go | 17 + chain/actors/builtin/market/v4.go | 17 + chain/actors/builtin/miner/actor.go.template | 86 +++-- chain/actors/builtin/miner/miner.go | 46 +++ chain/actors/builtin/miner/state.go.template | 101 ++++-- chain/actors/builtin/miner/temp | 0 chain/actors/builtin/miner/v0.go | 21 ++ chain/actors/builtin/miner/v2.go | 51 +++ chain/actors/builtin/miner/v3.go | 51 +++ chain/actors/builtin/miner/v4.go | 51 +++ .../actors/builtin/multisig/actor.go.template | 24 +- .../builtin/multisig/message.go.template | 36 +- chain/actors/builtin/multisig/multisig.go | 40 +++ .../actors/builtin/multisig/state.go.template | 30 ++ chain/actors/builtin/multisig/temp | 0 chain/actors/builtin/multisig/v0.go | 23 ++ chain/actors/builtin/multisig/v2.go | 23 ++ chain/actors/builtin/multisig/v3.go | 23 ++ chain/actors/builtin/multisig/v4.go | 23 ++ chain/actors/builtin/paych/actor.go.template | 23 ++ .../actors/builtin/paych/message.go.template | 28 +- chain/actors/builtin/paych/mock/mock.go | 4 + chain/actors/builtin/paych/mock/temp | 0 chain/actors/builtin/paych/paych.go | 41 +++ chain/actors/builtin/paych/state.go.template | 10 + chain/actors/builtin/paych/temp | 0 chain/actors/builtin/paych/v0.go | 10 + chain/actors/builtin/paych/v2.go | 10 + chain/actors/builtin/paych/v3.go | 10 + chain/actors/builtin/paych/v4.go | 10 + chain/actors/builtin/power/actor.go.template | 31 +- chain/actors/builtin/power/power.go | 47 +++ chain/actors/builtin/power/state.go.template | 60 +++- chain/actors/builtin/power/temp | 0 chain/actors/builtin/power/v0.go | 42 +++ chain/actors/builtin/power/v2.go | 42 +++ chain/actors/builtin/power/v3.go | 37 ++ chain/actors/builtin/power/v4.go | 37 ++ chain/actors/builtin/reward/actor.go.template | 23 ++ chain/actors/builtin/reward/reward.go | 41 +++ chain/actors/builtin/reward/state.go.template | 10 + chain/actors/builtin/reward/temp | 0 chain/actors/builtin/reward/v0.go | 10 + chain/actors/builtin/reward/v2.go | 10 + chain/actors/builtin/reward/v3.go | 10 + chain/actors/builtin/reward/v4.go | 10 + chain/actors/builtin/system/actor.go.template | 41 +++ chain/actors/builtin/system/state.go.template | 35 ++ chain/actors/builtin/system/system.go | 63 ++++ chain/actors/builtin/system/temp | 0 chain/actors/builtin/system/v0.go | 35 ++ chain/actors/builtin/system/v2.go | 35 ++ chain/actors/builtin/system/v3.go | 35 ++ chain/actors/builtin/system/v4.go | 35 ++ chain/actors/builtin/temp | 0 .../actors/builtin/verifreg/actor.go.template | 24 ++ .../actors/builtin/verifreg/state.go.template | 26 +- chain/actors/builtin/verifreg/temp | 0 chain/actors/builtin/verifreg/v0.go | 17 + chain/actors/builtin/verifreg/v2.go | 17 + chain/actors/builtin/verifreg/v3.go | 17 + chain/actors/builtin/verifreg/v4.go | 17 + chain/actors/builtin/verifreg/verifreg.go | 41 +++ chain/actors/policy/policy.go.template | 164 ++++----- chain/actors/policy/temp | 0 chain/actors/temp | 0 chain/actors/version.go | 4 + chain/gen/gen.go | 3 + chain/gen/genesis/f00_system.go | 21 +- chain/gen/genesis/f01_init.go | 40 ++- chain/gen/genesis/f02_reward.go | 33 +- chain/gen/genesis/f03_cron.go | 34 +- chain/gen/genesis/f04_power.go | 31 +- chain/gen/genesis/f05_market.go | 30 +- chain/gen/genesis/f06_vreg.go | 25 +- chain/gen/genesis/genesis.go | 242 +++++++------ chain/gen/genesis/miners.go | 335 ++++++++++++++---- chain/gen/genesis/util.go | 29 -- chain/state/statetree.go | 17 +- chain/state/statetree_test.go | 48 ++- chain/vm/vm.go | 35 +- cmd/lotus-seed/genesis.go | 51 +++ cmd/lotus-seed/main.go | 7 +- documentation/en/api-v0-methods.md | 2 +- documentation/en/api-v1-unstable-methods.md | 2 +- genesis/types.go | 7 +- node/test/builder.go | 4 + 126 files changed, 3174 insertions(+), 653 deletions(-) create mode 100644 chain/actors/adt/temp create mode 100644 chain/actors/aerrors/temp create mode 100644 chain/actors/agen/temp create mode 100644 chain/actors/builtin/account/temp create mode 100644 chain/actors/builtin/cron/state.go.template create mode 100644 chain/actors/builtin/cron/temp create mode 100644 chain/actors/builtin/cron/v0.go create mode 100644 chain/actors/builtin/cron/v2.go create mode 100644 chain/actors/builtin/cron/v3.go create mode 100644 chain/actors/builtin/cron/v4.go create mode 100644 chain/actors/builtin/init/temp create mode 100644 chain/actors/builtin/market/temp create mode 100644 chain/actors/builtin/miner/temp create mode 100644 chain/actors/builtin/multisig/temp create mode 100644 chain/actors/builtin/paych/mock/temp create mode 100644 chain/actors/builtin/paych/temp create mode 100644 chain/actors/builtin/power/temp create mode 100644 chain/actors/builtin/reward/temp create mode 100644 chain/actors/builtin/system/actor.go.template create mode 100644 chain/actors/builtin/system/state.go.template create mode 100644 chain/actors/builtin/system/system.go create mode 100644 chain/actors/builtin/system/temp create mode 100644 chain/actors/builtin/system/v0.go create mode 100644 chain/actors/builtin/system/v2.go create mode 100644 chain/actors/builtin/system/v3.go create mode 100644 chain/actors/builtin/system/v4.go create mode 100644 chain/actors/builtin/temp create mode 100644 chain/actors/builtin/verifreg/temp create mode 100644 chain/actors/policy/temp create mode 100644 chain/actors/temp diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 4d9fb5284d1c6ed52d84f50d11610f338e15b4bf..394f1998be7c464c835d2474d93a843971cb659d 100644 GIT binary patch delta 4808 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 iHs;oFN6osE7n$w^^y?lB*hc(20bC~KQ# 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 diff --git a/build/params_2k.go b/build/params_2k.go index 32b010c32..3dd68c9c6 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -24,20 +24,20 @@ var UpgradeIgnitionHeight = abi.ChainEpoch(-2) var UpgradeRefuelHeight = abi.ChainEpoch(-3) var UpgradeTapeHeight = abi.ChainEpoch(-4) -var UpgradeActorsV2Height = abi.ChainEpoch(10) -var UpgradeLiftoffHeight = abi.ChainEpoch(-5) +var UpgradeActorsV2Height = abi.ChainEpoch(-5) +var UpgradeLiftoffHeight = abi.ChainEpoch(-6) -var UpgradeKumquatHeight = abi.ChainEpoch(15) -var UpgradeCalicoHeight = abi.ChainEpoch(20) -var UpgradePersianHeight = abi.ChainEpoch(25) -var UpgradeOrangeHeight = abi.ChainEpoch(27) -var UpgradeClausHeight = abi.ChainEpoch(30) +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 UpgradeActorsV3Height = abi.ChainEpoch(35) +var UpgradeActorsV3Height = abi.ChainEpoch(-12) -var UpgradeNorwegianHeight = abi.ChainEpoch(40) +var UpgradeNorwegianHeight = abi.ChainEpoch(-13) -var UpgradeActorsV4Height = abi.ChainEpoch(45) +var UpgradeActorsV4Height = abi.ChainEpoch(-14) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index 92bbc5db9..6b98b6a9c 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -25,7 +25,7 @@ const UnixfsLinksPerLevel = 1024 // Consensus / Network const AllowableClockDriftSecs = uint64(1) -const NewestNetworkVersion = network.Version11 +const NewestNetworkVersion = network.Version12 const ActorUpgradeNetworkVersion = network.Version4 // Epochs diff --git a/chain/actors/adt/temp b/chain/actors/adt/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/aerrors/temp b/chain/actors/aerrors/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/agen/main.go b/chain/actors/agen/main.go index 7269d9ae5..9a3b8fd20 100644 --- a/chain/actors/agen/main.go +++ b/chain/actors/agen/main.go @@ -6,33 +6,26 @@ import ( "io/ioutil" "os" "path/filepath" + "strconv" "text/template" + lotusactors "github.com/filecoin-project/lotus/chain/actors" + "golang.org/x/xerrors" ) -var latestVersion = 4 - -var versions = []int{0, 2, 3, latestVersion} - -var versionImports = map[int]string{ - 0: "/", - 2: "/v2/", - 3: "/v3/", - latestVersion: "/v4/", -} - var actors = map[string][]int{ - "account": versions, - "cron": versions, - "init": versions, - "market": versions, - "miner": versions, - "multisig": versions, - "paych": versions, - "power": versions, - "reward": versions, - "verifreg": versions, + "account": lotusactors.Versions, + "cron": lotusactors.Versions, + "init": lotusactors.Versions, + "market": lotusactors.Versions, + "miner": lotusactors.Versions, + "multisig": lotusactors.Versions, + "paych": lotusactors.Versions, + "power": lotusactors.Versions, + "system": lotusactors.Versions, + "reward": lotusactors.Versions, + "verifreg": lotusactors.Versions, } func main() { @@ -71,14 +64,14 @@ func generateAdapters() error { } tpl := template.Must(template.New("").Funcs(template.FuncMap{ - "import": func(v int) string { return versionImports[v] }, + "import": func(v int) string { return getVersionImports()[v] }, }).Parse(string(af))) var b bytes.Buffer err = tpl.Execute(&b, map[string]interface{}{ "versions": versions, - "latestVersion": latestVersion, + "latestVersion": lotusactors.LatestVersion, }) if err != nil { return err @@ -103,14 +96,14 @@ func generateState(actDir string) error { return xerrors.Errorf("loading state adapter template: %w", err) } - for _, version := range versions { + for _, version := range lotusactors.Versions { tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af))) var b bytes.Buffer err := tpl.Execute(&b, map[string]interface{}{ "v": version, - "import": versionImports[version], + "import": getVersionImports()[version], }) if err != nil { return err @@ -134,14 +127,14 @@ func generateMessages(actDir string) error { return xerrors.Errorf("loading message adapter template: %w", err) } - for _, version := range versions { + for _, version := range lotusactors.Versions { tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af))) var b bytes.Buffer err := tpl.Execute(&b, map[string]interface{}{ "v": version, - "import": versionImports[version], + "import": getVersionImports()[version], }) if err != nil { return err @@ -167,13 +160,13 @@ func generatePolicy(policyPath string) error { } tpl := template.Must(template.New("").Funcs(template.FuncMap{ - "import": func(v int) string { return versionImports[v] }, + "import": func(v int) string { return getVersionImports()[v] }, }).Parse(string(pf))) var b bytes.Buffer err = tpl.Execute(&b, map[string]interface{}{ - "versions": versions, - "latestVersion": latestVersion, + "versions": lotusactors.Versions, + "latestVersion": lotusactors.LatestVersion, }) if err != nil { return err @@ -198,13 +191,13 @@ func generateBuiltin(builtinPath string) error { } tpl := template.Must(template.New("").Funcs(template.FuncMap{ - "import": func(v int) string { return versionImports[v] }, + "import": func(v int) string { return getVersionImports()[v] }, }).Parse(string(bf))) var b bytes.Buffer err = tpl.Execute(&b, map[string]interface{}{ - "versions": versions, - "latestVersion": latestVersion, + "versions": lotusactors.Versions, + "latestVersion": lotusactors.LatestVersion, }) if err != nil { return err @@ -216,3 +209,16 @@ func generateBuiltin(builtinPath string) error { return nil } + +func getVersionImports() map[int]string { + versionImports := make(map[int]string, lotusactors.LatestVersion) + for _, v := range lotusactors.Versions { + if v == 0 { + versionImports[v] = "/" + } else { + versionImports[v] = "/v" + strconv.Itoa(v) + "/" + } + } + + return versionImports +} diff --git a/chain/actors/agen/temp b/chain/actors/agen/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go index 8242e300d..97811d08a 100644 --- a/chain/actors/builtin/account/account.go +++ b/chain/actors/builtin/account/account.go @@ -1,6 +1,7 @@ package account import ( + "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -60,8 +61,48 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, addr address.Address) (State, error) { + switch av { + + case actors.Version0: + return make0(store, addr) + + case actors.Version2: + return make2(store, addr) + + case actors.Version3: + return make3(store, addr) + + case actors.Version4: + return make4(store, addr) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.AccountActorCodeID, nil + + case actors.Version2: + return builtin2.AccountActorCodeID, nil + + case actors.Version3: + return builtin3.AccountActorCodeID, nil + + case actors.Version4: + return builtin4.AccountActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler PubkeyAddress() (address.Address, error) + GetState() interface{} } diff --git a/chain/actors/builtin/account/actor.go.template b/chain/actors/builtin/account/actor.go.template index f75af3dfb..53962cc94 100644 --- a/chain/actors/builtin/account/actor.go.template +++ b/chain/actors/builtin/account/actor.go.template @@ -1,6 +1,7 @@ package account import ( + "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -34,8 +35,30 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, addr address.Address) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store, addr) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.AccountActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler PubkeyAddress() (address.Address, error) + GetState() interface{} } diff --git a/chain/actors/builtin/account/state.go.template b/chain/actors/builtin/account/state.go.template index 65d874c80..5be262ece 100644 --- a/chain/actors/builtin/account/state.go.template +++ b/chain/actors/builtin/account/state.go.template @@ -20,6 +20,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store, addr address.Address) (State, error) { + out := state{{.v}}{store: store} + out.State = account{{.v}}.State{Address:addr} + return &out, nil +} + type state{{.v}} struct { account{{.v}}.State store adt.Store @@ -28,3 +34,7 @@ type state{{.v}} struct { func (s *state{{.v}}) PubkeyAddress() (address.Address, error) { return s.Address, nil } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/account/temp b/chain/actors/builtin/account/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/account/v0.go b/chain/actors/builtin/account/v0.go index 67c555c5d..bdfca2fd7 100644 --- a/chain/actors/builtin/account/v0.go +++ b/chain/actors/builtin/account/v0.go @@ -20,6 +20,12 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store, addr address.Address) (State, error) { + out := state0{store: store} + out.State = account0.State{Address: addr} + return &out, nil +} + type state0 struct { account0.State store adt.Store @@ -28,3 +34,7 @@ type state0 struct { func (s *state0) PubkeyAddress() (address.Address, error) { return s.Address, nil } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/account/v2.go b/chain/actors/builtin/account/v2.go index 2664631bc..66618e06a 100644 --- a/chain/actors/builtin/account/v2.go +++ b/chain/actors/builtin/account/v2.go @@ -20,6 +20,12 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store, addr address.Address) (State, error) { + out := state2{store: store} + out.State = account2.State{Address: addr} + return &out, nil +} + type state2 struct { account2.State store adt.Store @@ -28,3 +34,7 @@ type state2 struct { func (s *state2) PubkeyAddress() (address.Address, error) { return s.Address, nil } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/account/v3.go b/chain/actors/builtin/account/v3.go index 16b489a3e..dbe100a4f 100644 --- a/chain/actors/builtin/account/v3.go +++ b/chain/actors/builtin/account/v3.go @@ -20,6 +20,12 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store, addr address.Address) (State, error) { + out := state3{store: store} + out.State = account3.State{Address: addr} + return &out, nil +} + type state3 struct { account3.State store adt.Store @@ -28,3 +34,7 @@ type state3 struct { func (s *state3) PubkeyAddress() (address.Address, error) { return s.Address, nil } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/account/v4.go b/chain/actors/builtin/account/v4.go index 1a24007d8..53f71dcc5 100644 --- a/chain/actors/builtin/account/v4.go +++ b/chain/actors/builtin/account/v4.go @@ -20,6 +20,12 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store, addr address.Address) (State, error) { + out := state4{store: store} + out.State = account4.State{Address: addr} + return &out, nil +} + type state4 struct { account4.State store adt.Store @@ -28,3 +34,7 @@ type state4 struct { func (s *state4) PubkeyAddress() (address.Address, error) { return s.Address, nil } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/builtin.go.template b/chain/actors/builtin/builtin.go.template index 9b89b13f5..6eac2627e 100644 --- a/chain/actors/builtin/builtin.go.template +++ b/chain/actors/builtin/builtin.go.template @@ -6,9 +6,9 @@ import ( "golang.org/x/xerrors" {{range .versions}} - builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" - smoothing{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/util/smoothing" - {{end}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" + smoothing{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/util/smoothing" + {{end}} "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" @@ -17,7 +17,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" miner{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/miner" - proof{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/runtime/proof" + proof{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/runtime/proof" ) var SystemActorAddr = builtin{{.latestVersion}}.SystemActorAddr @@ -33,12 +33,12 @@ var ( const ( EpochDurationSeconds = builtin{{.latestVersion}}.EpochDurationSeconds - EpochsInDay = builtin{{.latestVersion}}.EpochsInDay - SecondsInDay = builtin{{.latestVersion}}.SecondsInDay + EpochsInDay = builtin{{.latestVersion}}.EpochsInDay + SecondsInDay = builtin{{.latestVersion}}.SecondsInDay ) const ( - MethodSend = builtin{{.latestVersion}}.MethodSend + MethodSend = builtin{{.latestVersion}}.MethodSend MethodConstructor = builtin{{.latestVersion}}.MethodConstructor ) @@ -53,13 +53,13 @@ func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, } {{range .versions}} - func FromV{{.}}FilterEstimate(v{{.}} smoothing{{.}}.FilterEstimate) FilterEstimate { + func FromV{{.}}FilterEstimate(v{{.}} smoothing{{.}}.FilterEstimate) FilterEstimate { {{if (eq . 0)}} - return (FilterEstimate)(v{{.}}) //nolint:unconvert - {{else}} - return (FilterEstimate)(v{{.}}) - {{end}} - } + return (FilterEstimate)(v{{.}}) //nolint:unconvert + {{else}} + return (FilterEstimate)(v{{.}}) + {{end}} + } {{end}} type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) @@ -80,58 +80,58 @@ func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) { func ActorNameByCode(c cid.Cid) string { switch { - {{range .versions}} - case builtin{{.}}.IsBuiltinActor(c): - return builtin{{.}}.ActorNameByCode(c) - {{end}} + {{range .versions}} + case builtin{{.}}.IsBuiltinActor(c): + return builtin{{.}}.ActorNameByCode(c) + {{end}} default: return "" } } func IsBuiltinActor(c cid.Cid) bool { - {{range .versions}} - if builtin{{.}}.IsBuiltinActor(c) { - return true - } - {{end}} - return false + {{range .versions}} + if builtin{{.}}.IsBuiltinActor(c) { + return true + } + {{end}} + return false } func IsAccountActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.AccountActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.AccountActorCodeID { + return true + } + {{end}} + return false } func IsStorageMinerActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.StorageMinerActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.StorageMinerActorCodeID { + return true + } + {{end}} + return false } func IsMultisigActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.MultisigActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.MultisigActorCodeID { + return true + } + {{end}} + return false } func IsPaymentChannelActor(c cid.Cid) bool { - {{range .versions}} - if c == builtin{{.}}.PaymentChannelActorCodeID { - return true - } - {{end}} - return false + {{range .versions}} + if c == builtin{{.}}.PaymentChannelActorCodeID { + return true + } + {{end}} + return false } func makeAddress(addr string) address.Address { diff --git a/chain/actors/builtin/cron/actor.go.template b/chain/actors/builtin/cron/actor.go.template index 6b7449617..d73808556 100644 --- a/chain/actors/builtin/cron/actor.go.template +++ b/chain/actors/builtin/cron/actor.go.template @@ -1,10 +1,42 @@ package cron import ( - builtin{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "golang.org/x/xerrors" + "github.com/ipfs/go-cid" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} ) +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.CronActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + var ( Address = builtin{{.latestVersion}}.CronActorAddr Methods = builtin{{.latestVersion}}.MethodsCron ) + + +type State interface { + GetState() interface{} +} diff --git a/chain/actors/builtin/cron/cron.go b/chain/actors/builtin/cron/cron.go index 52a9fab07..62fa413a8 100644 --- a/chain/actors/builtin/cron/cron.go +++ b/chain/actors/builtin/cron/cron.go @@ -1,10 +1,64 @@ package cron import ( + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" ) +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.CronActorCodeID, nil + + case actors.Version2: + return builtin2.CronActorCodeID, nil + + case actors.Version3: + return builtin3.CronActorCodeID, nil + + case actors.Version4: + return builtin4.CronActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + var ( Address = builtin4.CronActorAddr Methods = builtin4.MethodsCron ) + +type State interface { + GetState() interface{} +} diff --git a/chain/actors/builtin/cron/state.go.template b/chain/actors/builtin/cron/state.go.template new file mode 100644 index 000000000..99a06d7f8 --- /dev/null +++ b/chain/actors/builtin/cron/state.go.template @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/cron" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + out.State = *cron{{.v}}.ConstructState(cron{{.v}}.BuiltInEntries()) + return &out, nil +} + +type state{{.v}} struct { + cron{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/cron/temp b/chain/actors/builtin/cron/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/cron/v0.go b/chain/actors/builtin/cron/v0.go new file mode 100644 index 000000000..6147b858c --- /dev/null +++ b/chain/actors/builtin/cron/v0.go @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron0 "github.com/filecoin-project/specs-actors/actors/builtin/cron" +) + +var _ State = (*state0)(nil) + +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make0(store adt.Store) (State, error) { + out := state0{store: store} + out.State = *cron0.ConstructState(cron0.BuiltInEntries()) + return &out, nil +} + +type state0 struct { + cron0.State + store adt.Store +} + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/cron/v2.go b/chain/actors/builtin/cron/v2.go new file mode 100644 index 000000000..51ca179d9 --- /dev/null +++ b/chain/actors/builtin/cron/v2.go @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/cron" +) + +var _ State = (*state2)(nil) + +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make2(store adt.Store) (State, error) { + out := state2{store: store} + out.State = *cron2.ConstructState(cron2.BuiltInEntries()) + return &out, nil +} + +type state2 struct { + cron2.State + store adt.Store +} + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/cron/v3.go b/chain/actors/builtin/cron/v3.go new file mode 100644 index 000000000..ff74d511d --- /dev/null +++ b/chain/actors/builtin/cron/v3.go @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/cron" +) + +var _ State = (*state3)(nil) + +func load3(store adt.Store, root cid.Cid) (State, error) { + out := state3{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make3(store adt.Store) (State, error) { + out := state3{store: store} + out.State = *cron3.ConstructState(cron3.BuiltInEntries()) + return &out, nil +} + +type state3 struct { + cron3.State + store adt.Store +} + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/cron/v4.go b/chain/actors/builtin/cron/v4.go new file mode 100644 index 000000000..1cff8cc28 --- /dev/null +++ b/chain/actors/builtin/cron/v4.go @@ -0,0 +1,35 @@ +package cron + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + cron4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/cron" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make4(store adt.Store) (State, error) { + out := state4{store: store} + out.State = *cron4.ConstructState(cron4.BuiltInEntries()) + return &out, nil +} + +type state4 struct { + cron4.State + store adt.Store +} + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/init/actor.go.template b/chain/actors/builtin/init/actor.go.template index 5b700cec8..f825eb9fa 100644 --- a/chain/actors/builtin/init/actor.go.template +++ b/chain/actors/builtin/init/actor.go.template @@ -1,6 +1,7 @@ package init import ( + "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -39,6 +40,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, networkName string) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store, networkName) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.InitActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -56,5 +78,12 @@ type State interface { // Sets the network's name. This should only be used on upgrade/fork. SetNetworkName(name string) error - addressMap() (adt.Map, error) + // Sets the next ID for the init actor. This should only be used for testing. + SetNextID(id abi.ActorID) error + + // Sets the address map for the init actor. This should only be used for testing. + SetAddressMap(mcid cid.Cid) error + + AddressMap() (adt.Map, error) + GetState() interface{} } diff --git a/chain/actors/builtin/init/diff.go b/chain/actors/builtin/init/diff.go index 593171322..5eb8f3c75 100644 --- a/chain/actors/builtin/init/diff.go +++ b/chain/actors/builtin/init/diff.go @@ -11,12 +11,12 @@ import ( ) func DiffAddressMap(pre, cur State) (*AddressMapChanges, error) { - prem, err := pre.addressMap() + prem, err := pre.AddressMap() if err != nil { return nil, err } - curm, err := cur.addressMap() + curm, err := cur.AddressMap() if err != nil { return nil, err } diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index 730d21fd8..2091252ce 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -1,6 +1,7 @@ package init import ( + "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -65,6 +66,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, networkName string) (State, error) { + switch av { + + case actors.Version0: + return make0(store, networkName) + + case actors.Version2: + return make2(store, networkName) + + case actors.Version3: + return make3(store, networkName) + + case actors.Version4: + return make4(store, networkName) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.InitActorCodeID, nil + + case actors.Version2: + return builtin2.InitActorCodeID, nil + + case actors.Version3: + return builtin3.InitActorCodeID, nil + + case actors.Version4: + return builtin4.InitActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -82,5 +122,12 @@ type State interface { // Sets the network's name. This should only be used on upgrade/fork. SetNetworkName(name string) error - addressMap() (adt.Map, error) + // Sets the next ID for the init actor. This should only be used for testing. + SetNextID(id abi.ActorID) error + + // Sets the address map for the init actor. This should only be used for testing. + SetAddressMap(mcid cid.Cid) error + + AddressMap() (adt.Map, error) + GetState() interface{} } diff --git a/chain/actors/builtin/init/state.go.template b/chain/actors/builtin/init/state.go.template index 95f052bda..482ad4df5 100644 --- a/chain/actors/builtin/init/state.go.template +++ b/chain/actors/builtin/init/state.go.template @@ -29,6 +29,26 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store, networkName string) (State, error) { + out := state{{.v}}{store: store} + {{if (le .v 2)}} + mr, err := adt{{.v}}.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *init{{.v}}.ConstructState(mr, networkName) + {{else}} + s, err := init{{.v}}.ConstructState(store, networkName) + if err != nil { + return nil, err + } + + out.State = *s + {{end}} + return &out, nil +} + type state{{.v}} struct { init{{.v}}.State store adt.Store @@ -66,6 +86,11 @@ func (s *state{{.v}}) SetNetworkName(name string) error { return nil } +func (s *state{{.v}}) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + func (s *state{{.v}}) Remove(addrs ...address.Address) (err error) { m, err := adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) if err != nil { @@ -84,6 +109,15 @@ func (s *state{{.v}}) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state{{.v}}) addressMap() (adt.Map, error) { - return adt{{.v}}.AsMap(s.store, s.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) +func (s *state{{.v}}) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil } + +func (s *state{{.v}}) AddressMap() (adt.Map, error) { + return adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) +} + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/init/temp b/chain/actors/builtin/init/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/init/v0.go b/chain/actors/builtin/init/v0.go index c019705b1..ddd2dab94 100644 --- a/chain/actors/builtin/init/v0.go +++ b/chain/actors/builtin/init/v0.go @@ -25,6 +25,19 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store, networkName string) (State, error) { + out := state0{store: store} + + mr, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *init0.ConstructState(mr, networkName) + + return &out, nil +} + type state0 struct { init0.State store adt.Store @@ -62,6 +75,11 @@ func (s *state0) SetNetworkName(name string) error { return nil } +func (s *state0) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + func (s *state0) Remove(addrs ...address.Address) (err error) { m, err := adt0.AsMap(s.store, s.State.AddressMap) if err != nil { @@ -80,6 +98,15 @@ func (s *state0) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state0) addressMap() (adt.Map, error) { - return adt0.AsMap(s.store, s.AddressMap) +func (s *state0) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state0) AddressMap() (adt.Map, error) { + return adt0.AsMap(s.store, s.State.AddressMap) +} + +func (s *state0) GetState() interface{} { + return &s.State } diff --git a/chain/actors/builtin/init/v2.go b/chain/actors/builtin/init/v2.go index 420243be4..72e2d56a5 100644 --- a/chain/actors/builtin/init/v2.go +++ b/chain/actors/builtin/init/v2.go @@ -25,6 +25,19 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store, networkName string) (State, error) { + out := state2{store: store} + + mr, err := adt2.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *init2.ConstructState(mr, networkName) + + return &out, nil +} + type state2 struct { init2.State store adt.Store @@ -62,6 +75,11 @@ func (s *state2) SetNetworkName(name string) error { return nil } +func (s *state2) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + func (s *state2) Remove(addrs ...address.Address) (err error) { m, err := adt2.AsMap(s.store, s.State.AddressMap) if err != nil { @@ -80,6 +98,15 @@ func (s *state2) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state2) addressMap() (adt.Map, error) { - return adt2.AsMap(s.store, s.AddressMap) +func (s *state2) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state2) AddressMap() (adt.Map, error) { + return adt2.AsMap(s.store, s.State.AddressMap) +} + +func (s *state2) GetState() interface{} { + return &s.State } diff --git a/chain/actors/builtin/init/v3.go b/chain/actors/builtin/init/v3.go index eaa54dfd4..4609c94a3 100644 --- a/chain/actors/builtin/init/v3.go +++ b/chain/actors/builtin/init/v3.go @@ -27,6 +27,19 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store, networkName string) (State, error) { + out := state3{store: store} + + s, err := init3.ConstructState(store, networkName) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state3 struct { init3.State store adt.Store @@ -64,6 +77,11 @@ func (s *state3) SetNetworkName(name string) error { return nil } +func (s *state3) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + func (s *state3) Remove(addrs ...address.Address) (err error) { m, err := adt3.AsMap(s.store, s.State.AddressMap, builtin3.DefaultHamtBitwidth) if err != nil { @@ -82,6 +100,15 @@ func (s *state3) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state3) addressMap() (adt.Map, error) { - return adt3.AsMap(s.store, s.AddressMap, builtin3.DefaultHamtBitwidth) +func (s *state3) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state3) AddressMap() (adt.Map, error) { + return adt3.AsMap(s.store, s.State.AddressMap, builtin3.DefaultHamtBitwidth) +} + +func (s *state3) GetState() interface{} { + return &s.State } diff --git a/chain/actors/builtin/init/v4.go b/chain/actors/builtin/init/v4.go index 38749eed5..dc56d1f19 100644 --- a/chain/actors/builtin/init/v4.go +++ b/chain/actors/builtin/init/v4.go @@ -27,6 +27,19 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store, networkName string) (State, error) { + out := state4{store: store} + + s, err := init4.ConstructState(store, networkName) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state4 struct { init4.State store adt.Store @@ -64,6 +77,11 @@ func (s *state4) SetNetworkName(name string) error { return nil } +func (s *state4) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + func (s *state4) Remove(addrs ...address.Address) (err error) { m, err := adt4.AsMap(s.store, s.State.AddressMap, builtin4.DefaultHamtBitwidth) if err != nil { @@ -82,6 +100,15 @@ func (s *state4) Remove(addrs ...address.Address) (err error) { return nil } -func (s *state4) addressMap() (adt.Map, error) { - return adt4.AsMap(s.store, s.AddressMap, builtin4.DefaultHamtBitwidth) +func (s *state4) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state4) AddressMap() (adt.Map, error) { + return adt4.AsMap(s.store, s.State.AddressMap, builtin4.DefaultHamtBitwidth) +} + +func (s *state4) GetState() interface{} { + return &s.State } diff --git a/chain/actors/builtin/market/actor.go.template b/chain/actors/builtin/market/actor.go.template index 39cfe1be7..5b67695e1 100644 --- a/chain/actors/builtin/market/actor.go.template +++ b/chain/actors/builtin/market/actor.go.template @@ -16,6 +16,7 @@ import ( {{end}} "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" ) @@ -42,6 +43,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.StorageMarketActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler BalancesChanged(State) (bool, error) @@ -56,6 +78,7 @@ type State interface { minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, ) (weight, verifiedWeight abi.DealWeight, err error) NextID() (abi.DealID, error) + GetState() interface{} } type BalanceTable interface { @@ -81,7 +104,6 @@ type DealProposals interface { type PublishStorageDealsParams = market0.PublishStorageDealsParams type PublishStorageDealsReturn = market0.PublishStorageDealsReturn -type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams type WithdrawBalanceParams = market0.WithdrawBalanceParams type ClientDealProposal = market0.ClientDealProposal @@ -89,71 +111,71 @@ type ClientDealProposal = market0.ClientDealProposal type DealState struct { SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated - SlashEpoch abi.ChainEpoch // -1 if deal never slashed + SlashEpoch abi.ChainEpoch // -1 if deal never slashed } type DealProposal struct { - PieceCID cid.Cid - PieceSize abi.PaddedPieceSize - VerifiedDeal bool - Client address.Address - Provider address.Address - Label string - StartEpoch abi.ChainEpoch - EndEpoch abi.ChainEpoch + PieceCID cid.Cid + PieceSize abi.PaddedPieceSize + VerifiedDeal bool + Client address.Address + Provider address.Address + Label string + StartEpoch abi.ChainEpoch + EndEpoch abi.ChainEpoch StoragePricePerEpoch abi.TokenAmount - ProviderCollateral abi.TokenAmount - ClientCollateral abi.TokenAmount + ProviderCollateral abi.TokenAmount + ClientCollateral abi.TokenAmount } type DealStateChanges struct { - Added []DealIDState + Added []DealIDState Modified []DealStateChange - Removed []DealIDState + Removed []DealIDState } type DealIDState struct { - ID abi.DealID + ID abi.DealID Deal DealState } // DealStateChange is a change in deal state from -> to type DealStateChange struct { - ID abi.DealID + ID abi.DealID From *DealState - To *DealState + To *DealState } type DealProposalChanges struct { - Added []ProposalIDState + Added []ProposalIDState Removed []ProposalIDState } type ProposalIDState struct { - ID abi.DealID + ID abi.DealID Proposal DealProposal } func EmptyDealState() *DealState { return &DealState{ SectorStartEpoch: -1, - SlashEpoch: -1, + SlashEpoch: -1, LastUpdatedEpoch: -1, } } // returns the earned fees and pending fees for a given deal func (deal DealProposal) GetDealFees(height abi.ChainEpoch) (abi.TokenAmount, abi.TokenAmount) { - tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch))) + tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch))) - ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch))) - if ef.LessThan(big.Zero()) { - ef = big.Zero() - } + ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch))) + if ef.LessThan(big.Zero()) { + ef = big.Zero() + } - if ef.GreaterThan(tf) { - ef = tf - } + if ef.GreaterThan(tf) { + ef = tf + } - return ef, big.Sub(tf, ef) + return ef, big.Sub(tf, ef) } diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index adf7ce33d..ffc826658 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -20,6 +20,7 @@ import ( builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" @@ -68,6 +69,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.StorageMarketActorCodeID, nil + + case actors.Version2: + return builtin2.StorageMarketActorCodeID, nil + + case actors.Version3: + return builtin3.StorageMarketActorCodeID, nil + + case actors.Version4: + return builtin4.StorageMarketActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler BalancesChanged(State) (bool, error) @@ -82,6 +122,7 @@ type State interface { minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, ) (weight, verifiedWeight abi.DealWeight, err error) NextID() (abi.DealID, error) + GetState() interface{} } type BalanceTable interface { @@ -107,7 +148,6 @@ type DealProposals interface { type PublishStorageDealsParams = market0.PublishStorageDealsParams type PublishStorageDealsReturn = market0.PublishStorageDealsReturn -type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams type WithdrawBalanceParams = market0.WithdrawBalanceParams type ClientDealProposal = market0.ClientDealProposal diff --git a/chain/actors/builtin/market/state.go.template b/chain/actors/builtin/market/state.go.template index a55743ce5..965c8d41f 100644 --- a/chain/actors/builtin/market/state.go.template +++ b/chain/actors/builtin/market/state.go.template @@ -26,6 +26,31 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + {{if (le .v 2)}} + ea, err := adt{{.v}}.MakeEmptyArray(store).Root() + if err != nil { + return nil, err + } + + em, err := adt{{.v}}.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *market{{.v}}.ConstructState(ea, em, em) + {{else}} + s, err := market{{.v}}.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + {{end}} + return &out, nil +} + type state{{.v}} struct { market{{.v}}.State store adt.Store @@ -207,3 +232,7 @@ func (s *dealProposals{{.v}}) array() adt.Array { func fromV{{.v}}DealProposal(v{{.v}} market{{.v}}.DealProposal) DealProposal { return (DealProposal)(v{{.v}}) } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/market/temp b/chain/actors/builtin/market/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/market/v0.go b/chain/actors/builtin/market/v0.go index 175c0a2ea..b3093b54b 100644 --- a/chain/actors/builtin/market/v0.go +++ b/chain/actors/builtin/market/v0.go @@ -26,6 +26,24 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store) (State, error) { + out := state0{store: store} + + ea, err := adt0.MakeEmptyArray(store).Root() + if err != nil { + return nil, err + } + + em, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *market0.ConstructState(ea, em, em) + + return &out, nil +} + type state0 struct { market0.State store adt.Store @@ -207,3 +225,7 @@ func (s *dealProposals0) array() adt.Array { func fromV0DealProposal(v0 market0.DealProposal) DealProposal { return (DealProposal)(v0) } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/market/v2.go b/chain/actors/builtin/market/v2.go index dafae8feb..fdedcce85 100644 --- a/chain/actors/builtin/market/v2.go +++ b/chain/actors/builtin/market/v2.go @@ -26,6 +26,24 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store) (State, error) { + out := state2{store: store} + + ea, err := adt2.MakeEmptyArray(store).Root() + if err != nil { + return nil, err + } + + em, err := adt2.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *market2.ConstructState(ea, em, em) + + return &out, nil +} + type state2 struct { market2.State store adt.Store @@ -207,3 +225,7 @@ func (s *dealProposals2) array() adt.Array { func fromV2DealProposal(v2 market2.DealProposal) DealProposal { return (DealProposal)(v2) } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/market/v3.go b/chain/actors/builtin/market/v3.go index dec8d6e25..53d266443 100644 --- a/chain/actors/builtin/market/v3.go +++ b/chain/actors/builtin/market/v3.go @@ -26,6 +26,19 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store) (State, error) { + out := state3{store: store} + + s, err := market3.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state3 struct { market3.State store adt.Store @@ -207,3 +220,7 @@ func (s *dealProposals3) array() adt.Array { func fromV3DealProposal(v3 market3.DealProposal) DealProposal { return (DealProposal)(v3) } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/market/v4.go b/chain/actors/builtin/market/v4.go index 22514395c..30aa26920 100644 --- a/chain/actors/builtin/market/v4.go +++ b/chain/actors/builtin/market/v4.go @@ -26,6 +26,19 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store) (State, error) { + out := state4{store: store} + + s, err := market4.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state4 struct { market4.State store adt.Store @@ -207,3 +220,7 @@ func (s *dealProposals4) array() adt.Array { func fromV4DealProposal(v4 market4.DealProposal) DealProposal { return (DealProposal)(v4) } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/miner/actor.go.template b/chain/actors/builtin/miner/actor.go.template index 4b3d8db5e..c7755ef71 100644 --- a/chain/actors/builtin/miner/actor.go.template +++ b/chain/actors/builtin/miner/actor.go.template @@ -3,6 +3,7 @@ package miner import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" cbg "github.com/whyrusleeping/cbor-gen" @@ -60,6 +61,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.StorageMinerActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -79,6 +101,11 @@ type State interface { NumLiveSectors() (uint64, error) IsAllocated(abi.SectorNumber) (bool, error) + // Note that ProvingPeriodStart is deprecated and will be renamed / removed in a future version of actors + GetProvingPeriodStart() (abi.ChainEpoch, error) + // Testing only + EraseAllUnproven() error + LoadDeadline(idx uint64) (Deadline, error) ForEachDeadline(cb func(idx uint64, dl Deadline) error) error NumDeadlines() (uint64, error) @@ -95,6 +122,7 @@ type State interface { decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error) precommits() (adt.Map, error) decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error) + GetState() interface{} } type Deadline interface { @@ -115,26 +143,26 @@ type Partition interface { } type SectorOnChainInfo struct { - SectorNumber abi.SectorNumber - SealProof abi.RegisteredSealProof - SealedCID cid.Cid - DealIDs []abi.DealID - Activation abi.ChainEpoch - Expiration abi.ChainEpoch - DealWeight abi.DealWeight - VerifiedDealWeight abi.DealWeight - InitialPledge abi.TokenAmount - ExpectedDayReward abi.TokenAmount + SectorNumber abi.SectorNumber + SealProof abi.RegisteredSealProof + SealedCID cid.Cid + DealIDs []abi.DealID + Activation abi.ChainEpoch + Expiration abi.ChainEpoch + DealWeight abi.DealWeight + VerifiedDealWeight abi.DealWeight + InitialPledge abi.TokenAmount + ExpectedDayReward abi.TokenAmount ExpectedStoragePledge abi.TokenAmount } type SectorPreCommitInfo = miner0.SectorPreCommitInfo type SectorPreCommitOnChainInfo struct { - Info SectorPreCommitInfo + Info SectorPreCommitInfo PreCommitDeposit abi.TokenAmount - PreCommitEpoch abi.ChainEpoch - DealWeight abi.DealWeight + PreCommitEpoch abi.ChainEpoch + DealWeight abi.DealWeight VerifiedDealWeight abi.DealWeight } @@ -203,17 +231,17 @@ func WinningPoStProofTypeFromWindowPoStProofType(nver network.Version, proof abi } type MinerInfo struct { - Owner address.Address // Must be an ID-address. - Worker address.Address // Must be an ID-address. - NewWorker address.Address // Must be an ID-address. - ControlAddresses []address.Address // Must be an ID-addresses. - WorkerChangeEpoch abi.ChainEpoch - PeerId *peer.ID - Multiaddrs []abi.Multiaddrs - WindowPoStProofType abi.RegisteredPoStProof - SectorSize abi.SectorSize + Owner address.Address // Must be an ID-address. + Worker address.Address // Must be an ID-address. + NewWorker address.Address // Must be an ID-address. + ControlAddresses []address.Address // Must be an ID-addresses. + WorkerChangeEpoch abi.ChainEpoch + PeerId *peer.ID + Multiaddrs []abi.Multiaddrs + WindowPoStProofType abi.RegisteredPoStProof + SectorSize abi.SectorSize WindowPoStPartitionSectors uint64 - ConsensusFaultElapsed abi.ChainEpoch + ConsensusFaultElapsed abi.ChainEpoch } func (mi MinerInfo) IsController(addr address.Address) bool { @@ -244,25 +272,25 @@ type SectorLocation struct { } type SectorChanges struct { - Added []SectorOnChainInfo + Added []SectorOnChainInfo Extended []SectorExtensions - Removed []SectorOnChainInfo + Removed []SectorOnChainInfo } type SectorExtensions struct { From SectorOnChainInfo - To SectorOnChainInfo + To SectorOnChainInfo } type PreCommitChanges struct { - Added []SectorPreCommitOnChainInfo + Added []SectorPreCommitOnChainInfo Removed []SectorPreCommitOnChainInfo } type LockedFunds struct { - VestingFunds abi.TokenAmount + VestingFunds abi.TokenAmount InitialPledgeRequirement abi.TokenAmount - PreCommitDeposits abi.TokenAmount + PreCommitDeposits abi.TokenAmount } func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount { diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index a426e063b..d9b872e3f 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -3,6 +3,7 @@ package miner import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" cbg "github.com/whyrusleeping/cbor-gen" @@ -86,6 +87,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.StorageMinerActorCodeID, nil + + case actors.Version2: + return builtin2.StorageMinerActorCodeID, nil + + case actors.Version3: + return builtin3.StorageMinerActorCodeID, nil + + case actors.Version4: + return builtin4.StorageMinerActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -105,6 +145,11 @@ type State interface { NumLiveSectors() (uint64, error) IsAllocated(abi.SectorNumber) (bool, error) + // Note that ProvingPeriodStart is deprecated and will be renamed / removed in a future version of actors + GetProvingPeriodStart() (abi.ChainEpoch, error) + // Testing only + EraseAllUnproven() error + LoadDeadline(idx uint64) (Deadline, error) ForEachDeadline(cb func(idx uint64, dl Deadline) error) error NumDeadlines() (uint64, error) @@ -121,6 +166,7 @@ type State interface { decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error) precommits() (adt.Map, error) decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error) + GetState() interface{} } type Deadline interface { diff --git a/chain/actors/builtin/miner/state.go.template b/chain/actors/builtin/miner/state.go.template index 0769eea10..270510a8c 100644 --- a/chain/actors/builtin/miner/state.go.template +++ b/chain/actors/builtin/miner/state.go.template @@ -35,6 +35,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + out.State = miner{{.v}}.State{} + return &out, nil +} + type state{{.v}} struct { miner{{.v}}.State store adt.Store @@ -68,9 +74,9 @@ func (s *state{{.v}}) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) func (s *state{{.v}}) LockedFunds() (LockedFunds, error) { return LockedFunds{ - VestingFunds: s.State.LockedFunds, + VestingFunds: s.State.LockedFunds, InitialPledgeRequirement: s.State.InitialPledge{{if (le .v 1)}}Requirement{{end}}, - PreCommitDeposits: s.State.PreCommitDeposits, + PreCommitDeposits: s.State.PreCommitDeposits, }, nil } @@ -245,6 +251,10 @@ func (s *state{{.v}}) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } +func (s *state{{.v}}) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + func (s *state{{.v}}) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -307,19 +317,19 @@ func (s *state{{.v}}) Info() (MinerInfo, error) { } {{end}} mi := MinerInfo{ - Owner: info.Owner, - Worker: info.Worker, + Owner: info.Owner, + Worker: info.Worker, ControlAddresses: info.ControlAddresses, - NewWorker: address.Undef, + NewWorker: address.Undef, WorkerChangeEpoch: -1, - PeerId: pid, - Multiaddrs: info.Multiaddrs, - WindowPoStProofType: {{if (ge .v 3)}}info.WindowPoStProofType{{else}}wpp{{end}}, - SectorSize: info.SectorSize, + PeerId: pid, + Multiaddrs: info.Multiaddrs, + WindowPoStProofType: {{if (ge .v 3)}}info.WindowPoStProofType{{else}}wpp{{end}}, + SectorSize: info.SectorSize, WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, - ConsensusFaultElapsed: {{if (ge .v 2)}}info.ConsensusFaultElapsed{{else}}-1{{end}}, + ConsensusFaultElapsed: {{if (ge .v 2)}}info.ConsensusFaultElapsed{{else}}-1{{end}}, } if info.PendingWorkerKey != nil { @@ -366,6 +376,45 @@ func (s *state{{.v}}) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (Secto return fromV{{.v}}SectorPreCommitOnChainInfo(sp), nil } +func (s *state{{.v}}) EraseAllUnproven() error { + {{if (ge .v 2)}} + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner{{.v}}.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner{{.v}}.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + + return s.State.SaveDeadlines(s.store, dls) + {{else}} + // field doesn't exist until v2 + {{end}} + return nil +} + func (d *deadline{{.v}}) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -428,16 +477,16 @@ func (p *partition{{.v}}) RecoveringSectors() (bitfield.BitField, error) { func fromV{{.v}}SectorOnChainInfo(v{{.v}} miner{{.v}}.SectorOnChainInfo) SectorOnChainInfo { {{if (ge .v 2)}} return SectorOnChainInfo{ - SectorNumber: v{{.v}}.SectorNumber, - SealProof: v{{.v}}.SealProof, - SealedCID: v{{.v}}.SealedCID, - DealIDs: v{{.v}}.DealIDs, - Activation: v{{.v}}.Activation, - Expiration: v{{.v}}.Expiration, - DealWeight: v{{.v}}.DealWeight, - VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, - InitialPledge: v{{.v}}.InitialPledge, - ExpectedDayReward: v{{.v}}.ExpectedDayReward, + SectorNumber: v{{.v}}.SectorNumber, + SealProof: v{{.v}}.SealProof, + SealedCID: v{{.v}}.SealedCID, + DealIDs: v{{.v}}.DealIDs, + Activation: v{{.v}}.Activation, + Expiration: v{{.v}}.Expiration, + DealWeight: v{{.v}}.DealWeight, + VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, + InitialPledge: v{{.v}}.InitialPledge, + ExpectedDayReward: v{{.v}}.ExpectedDayReward, ExpectedStoragePledge: v{{.v}}.ExpectedStoragePledge, } {{else}} @@ -448,13 +497,17 @@ func fromV{{.v}}SectorOnChainInfo(v{{.v}} miner{{.v}}.SectorOnChainInfo) SectorO func fromV{{.v}}SectorPreCommitOnChainInfo(v{{.v}} miner{{.v}}.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { {{if (ge .v 2)}} return SectorPreCommitOnChainInfo{ - Info: (SectorPreCommitInfo)(v{{.v}}.Info), - PreCommitDeposit: v{{.v}}.PreCommitDeposit, - PreCommitEpoch: v{{.v}}.PreCommitEpoch, - DealWeight: v{{.v}}.DealWeight, + Info: (SectorPreCommitInfo)(v{{.v}}.Info), + PreCommitDeposit: v{{.v}}.PreCommitDeposit, + PreCommitEpoch: v{{.v}}.PreCommitEpoch, + DealWeight: v{{.v}}.DealWeight, VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, } {{else}} return (SectorPreCommitOnChainInfo)(v0) {{end}} } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/miner/temp b/chain/actors/builtin/miner/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/miner/v0.go b/chain/actors/builtin/miner/v0.go index 2dc8ae23e..344be1993 100644 --- a/chain/actors/builtin/miner/v0.go +++ b/chain/actors/builtin/miner/v0.go @@ -32,6 +32,12 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store) (State, error) { + out := state0{store: store} + out.State = miner0.State{} + return &out, nil +} + type state0 struct { miner0.State store adt.Store @@ -242,6 +248,10 @@ func (s *state0) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } +func (s *state0) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + func (s *state0) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -363,6 +373,13 @@ func (s *state0) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV0SectorPreCommitOnChainInfo(sp), nil } +func (s *state0) EraseAllUnproven() error { + + // field doesn't exist until v2 + + return nil +} + func (d *deadline0) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -426,3 +443,7 @@ func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) Sect return (SectorPreCommitOnChainInfo)(v0) } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/miner/v2.go b/chain/actors/builtin/miner/v2.go index 7564dd8b8..3e76d0b69 100644 --- a/chain/actors/builtin/miner/v2.go +++ b/chain/actors/builtin/miner/v2.go @@ -30,6 +30,12 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store) (State, error) { + out := state2{store: store} + out.State = miner2.State{} + return &out, nil +} + type state2 struct { miner2.State store adt.Store @@ -240,6 +246,10 @@ func (s *state2) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } +func (s *state2) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + func (s *state2) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -361,6 +371,43 @@ func (s *state2) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV2SectorPreCommitOnChainInfo(sp), nil } +func (s *state2) EraseAllUnproven() error { + + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner2.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner2.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + + return s.State.SaveDeadlines(s.store, dls) + + return nil +} + func (d *deadline2) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -442,3 +489,7 @@ func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) Sect } } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/miner/v3.go b/chain/actors/builtin/miner/v3.go index 72a080f73..72986233d 100644 --- a/chain/actors/builtin/miner/v3.go +++ b/chain/actors/builtin/miner/v3.go @@ -32,6 +32,12 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store) (State, error) { + out := state3{store: store} + out.State = miner3.State{} + return &out, nil +} + type state3 struct { miner3.State store adt.Store @@ -242,6 +248,10 @@ func (s *state3) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } +func (s *state3) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + func (s *state3) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -358,6 +368,43 @@ func (s *state3) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV3SectorPreCommitOnChainInfo(sp), nil } +func (s *state3) EraseAllUnproven() error { + + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner3.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner3.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + + return s.State.SaveDeadlines(s.store, dls) + + return nil +} + func (d *deadline3) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -443,3 +490,7 @@ func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) Sect } } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/miner/v4.go b/chain/actors/builtin/miner/v4.go index 698bdf2f5..96ed21f04 100644 --- a/chain/actors/builtin/miner/v4.go +++ b/chain/actors/builtin/miner/v4.go @@ -32,6 +32,12 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store) (State, error) { + out := state4{store: store} + out.State = miner4.State{} + return &out, nil +} + type state4 struct { miner4.State store adt.Store @@ -242,6 +248,10 @@ func (s *state4) IsAllocated(num abi.SectorNumber) (bool, error) { return allocatedSectors.IsSet(uint64(num)) } +func (s *state4) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + func (s *state4) LoadDeadline(idx uint64) (Deadline, error) { dls, err := s.State.LoadDeadlines(s.store) if err != nil { @@ -358,6 +368,43 @@ func (s *state4) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreC return fromV4SectorPreCommitOnChainInfo(sp), nil } +func (s *state4) EraseAllUnproven() error { + + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner4.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner4.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + + return s.State.SaveDeadlines(s.store, dls) + + return nil +} + func (d *deadline4) LoadPartition(idx uint64) (Partition, error) { p, err := d.Deadline.LoadPartition(d.store, idx) if err != nil { @@ -443,3 +490,7 @@ func fromV4SectorPreCommitOnChainInfo(v4 miner4.SectorPreCommitOnChainInfo) Sect } } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/multisig/actor.go.template b/chain/actors/builtin/multisig/actor.go.template index 19d99dcb7..3af270c60 100644 --- a/chain/actors/builtin/multisig/actor.go.template +++ b/chain/actors/builtin/multisig/actor.go.template @@ -40,6 +40,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store, signers, threshold, startEpoch, unlockDuration, initialBalance) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.MultisigActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -55,6 +76,7 @@ type State interface { transactions() (adt.Map, error) decodeTransaction(val *cbg.Deferred) (Transaction, error) + GetState() interface{} } type Transaction = msig{{.latestVersion}}.Transaction @@ -66,7 +88,7 @@ func Message(version actors.Version, from address.Address) MessageBuilder { {{range .versions}} case actors.Version{{.}}: return message{{.}}{{"{"}}{{if (ge . 2)}}message0{from}{{else}}from{{end}}} -{{end}} default: +{{end}} default: panic(fmt.Sprintf("unsupported actors version: %d", version)) } } diff --git a/chain/actors/builtin/multisig/message.go.template b/chain/actors/builtin/multisig/message.go.template index 6bff8983a..917e6944b 100644 --- a/chain/actors/builtin/multisig/message.go.template +++ b/chain/actors/builtin/multisig/message.go.template @@ -43,10 +43,10 @@ func (m message{{.v}}) Create( {{end}} // Set up constructor parameters for multisig msigParams := &multisig{{.v}}.ConstructorParams{ - Signers: signers, + Signers: signers, NumApprovalsThreshold: threshold, - UnlockDuration: unlockDuration,{{if (ge .v 2)}} - StartEpoch: unlockStart,{{end}} + UnlockDuration: unlockDuration,{{if (ge .v 2)}} + StartEpoch: unlockStart,{{end}} } enc, actErr := actors.SerializeParams(msigParams) @@ -56,7 +56,7 @@ func (m message{{.v}}) Create( // new actors are created by invoking 'exec' on the init actor with the constructor params execParams := &init{{.v}}.ExecParams{ - CodeCID: builtin{{.v}}.MultisigActorCodeID, + CodeCID: builtin{{.v}}.MultisigActorCodeID, ConstructorParams: enc, } @@ -66,11 +66,11 @@ func (m message{{.v}}) Create( } return &types.Message{ - To: init_.Address, - From: m.from, + To: init_.Address, + From: m.from, Method: builtin{{.v}}.MethodsInit.Exec, Params: enc, - Value: initialAmount, + Value: initialAmount, }, nil } @@ -96,8 +96,8 @@ func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount, } enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{ - To: to, - Value: amt, + To: to, + Value: amt, Method: method, Params: params, }) @@ -106,9 +106,9 @@ func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount, } return &types.Message{ - To: msig, - From: m.from, - Value: abi.NewTokenAmount(0), + To: msig, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin0.MethodsMultisig.Propose, Params: enc, }, nil @@ -121,9 +121,9 @@ func (m message0) Approve(msig address.Address, txID uint64, hashData *ProposalH } return &types.Message{ - To: msig, - From: m.from, - Value: types.NewInt(0), + To: msig, + From: m.from, + Value: types.NewInt(0), Method: builtin0.MethodsMultisig.Approve, Params: enc, }, nil @@ -136,9 +136,9 @@ func (m message0) Cancel(msig address.Address, txID uint64, hashData *ProposalHa } return &types.Message{ - To: msig, - From: m.from, - Value: types.NewInt(0), + To: msig, + From: m.from, + Value: types.NewInt(0), Method: builtin0.MethodsMultisig.Cancel, Params: enc, }, nil diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go index d8f6fabae..fd773f398 100644 --- a/chain/actors/builtin/multisig/multisig.go +++ b/chain/actors/builtin/multisig/multisig.go @@ -66,6 +66,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + switch av { + + case actors.Version0: + return make0(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + + case actors.Version2: + return make2(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + + case actors.Version3: + return make3(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + + case actors.Version4: + return make4(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.MultisigActorCodeID, nil + + case actors.Version2: + return builtin2.MultisigActorCodeID, nil + + case actors.Version3: + return builtin3.MultisigActorCodeID, nil + + case actors.Version4: + return builtin4.MultisigActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -81,6 +120,7 @@ type State interface { transactions() (adt.Map, error) decodeTransaction(val *cbg.Deferred) (Transaction, error) + GetState() interface{} } type Transaction = msig4.Transaction diff --git a/chain/actors/builtin/multisig/state.go.template b/chain/actors/builtin/multisig/state.go.template index 2316aadba..067415533 100644 --- a/chain/actors/builtin/multisig/state.go.template +++ b/chain/actors/builtin/multisig/state.go.template @@ -31,6 +31,32 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state{{.v}}{store: store} + out.State = msig{{.v}}.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + {{if (le .v 2)}} + em, err := adt{{.v}}.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + {{else}} + em, err := adt{{.v}}.StoreEmptyMap(store, builtin{{.v}}.DefaultHamtBitwidth) + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + {{end}} + return &out, nil +} + type state{{.v}} struct { msig{{.v}}.State store adt.Store @@ -95,3 +121,7 @@ func (s *state{{.v}}) decodeTransaction(val *cbg.Deferred) (Transaction, error) } return tx, nil } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/multisig/temp b/chain/actors/builtin/multisig/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/multisig/v0.go b/chain/actors/builtin/multisig/v0.go index 20c1557b0..973ac9209 100644 --- a/chain/actors/builtin/multisig/v0.go +++ b/chain/actors/builtin/multisig/v0.go @@ -28,6 +28,25 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state0{store: store} + out.State = msig0.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + type state0 struct { msig0.State store adt.Store @@ -92,3 +111,7 @@ func (s *state0) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/multisig/v2.go b/chain/actors/builtin/multisig/v2.go index ef317f903..5b830e695 100644 --- a/chain/actors/builtin/multisig/v2.go +++ b/chain/actors/builtin/multisig/v2.go @@ -28,6 +28,25 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state2{store: store} + out.State = msig2.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt2.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + type state2 struct { msig2.State store adt.Store @@ -92,3 +111,7 @@ func (s *state2) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/multisig/v3.go b/chain/actors/builtin/multisig/v3.go index 8834e4553..c4a2791b7 100644 --- a/chain/actors/builtin/multisig/v3.go +++ b/chain/actors/builtin/multisig/v3.go @@ -30,6 +30,25 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state3{store: store} + out.State = msig3.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt3.StoreEmptyMap(store, builtin3.DefaultHamtBitwidth) + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + type state3 struct { msig3.State store adt.Store @@ -94,3 +113,7 @@ func (s *state3) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/multisig/v4.go b/chain/actors/builtin/multisig/v4.go index 9f9dc7573..a35a890f8 100644 --- a/chain/actors/builtin/multisig/v4.go +++ b/chain/actors/builtin/multisig/v4.go @@ -30,6 +30,25 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state4{store: store} + out.State = msig4.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt4.StoreEmptyMap(store, builtin4.DefaultHamtBitwidth) + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + type state4 struct { msig4.State store adt.Store @@ -94,3 +113,7 @@ func (s *state4) decodeTransaction(val *cbg.Deferred) (Transaction, error) { } return tx, nil } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/paych/actor.go.template b/chain/actors/builtin/paych/actor.go.template index 3f68a5cfa..7699e76b6 100644 --- a/chain/actors/builtin/paych/actor.go.template +++ b/chain/actors/builtin/paych/actor.go.template @@ -42,6 +42,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.PaymentChannelActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + // State is an abstract version of payment channel state that works across // versions type State interface { @@ -62,6 +83,8 @@ type State interface { // Iterate lane states ForEachLaneState(cb func(idx uint64, dl LaneState) error) error + + GetState() interface{} } // LaneState is an abstract copy of the state of a single lane diff --git a/chain/actors/builtin/paych/message.go.template b/chain/actors/builtin/paych/message.go.template index 4a5ea2331..cb111d910 100644 --- a/chain/actors/builtin/paych/message.go.template +++ b/chain/actors/builtin/paych/message.go.template @@ -21,7 +21,7 @@ func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) return nil, aerr } enc, aerr := actors.SerializeParams(&init{{.v}}.ExecParams{ - CodeCID: builtin{{.v}}.PaymentChannelActorCodeID, + CodeCID: builtin{{.v}}.PaymentChannelActorCodeID, ConstructorParams: params, }) if aerr != nil { @@ -29,9 +29,9 @@ func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) } return &types.Message{ - To: init_.Address, - From: m.from, - Value: initialAmount, + To: init_.Address, + From: m.from, + Value: initialAmount, Method: builtin{{.v}}.MethodsInit.Exec, Params: enc, }, nil @@ -39,7 +39,7 @@ func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { params, aerr := actors.SerializeParams(&paych{{.v}}.UpdateChannelStateParams{ - Sv: *sv, + Sv: *sv, Secret: secret, }) if aerr != nil { @@ -47,9 +47,9 @@ func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret [ } return &types.Message{ - To: paych, - From: m.from, - Value: abi.NewTokenAmount(0), + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin{{.v}}.MethodsPaych.UpdateChannelState, Params: params, }, nil @@ -57,18 +57,18 @@ func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret [ func (m message{{.v}}) Settle(paych address.Address) (*types.Message, error) { return &types.Message{ - To: paych, - From: m.from, - Value: abi.NewTokenAmount(0), + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin{{.v}}.MethodsPaych.Settle, }, nil } func (m message{{.v}}) Collect(paych address.Address) (*types.Message, error) { return &types.Message{ - To: paych, - From: m.from, - Value: abi.NewTokenAmount(0), + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), Method: builtin{{.v}}.MethodsPaych.Collect, }, nil } diff --git a/chain/actors/builtin/paych/mock/mock.go b/chain/actors/builtin/paych/mock/mock.go index 3b82511ff..1ecfa1130 100644 --- a/chain/actors/builtin/paych/mock/mock.go +++ b/chain/actors/builtin/paych/mock/mock.go @@ -17,6 +17,10 @@ type mockState struct { lanes map[uint64]paych.LaneState } +func (ms *mockState) GetState() interface{} { + panic("implement me") +} + type mockLaneState struct { redeemed big.Int nonce uint64 diff --git a/chain/actors/builtin/paych/mock/temp b/chain/actors/builtin/paych/mock/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go index 30e4408d8..63638cda1 100644 --- a/chain/actors/builtin/paych/paych.go +++ b/chain/actors/builtin/paych/paych.go @@ -68,6 +68,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.PaymentChannelActorCodeID, nil + + case actors.Version2: + return builtin2.PaymentChannelActorCodeID, nil + + case actors.Version3: + return builtin3.PaymentChannelActorCodeID, nil + + case actors.Version4: + return builtin4.PaymentChannelActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + // State is an abstract version of payment channel state that works across // versions type State interface { @@ -88,6 +127,8 @@ type State interface { // Iterate lane states ForEachLaneState(cb func(idx uint64, dl LaneState) error) error + + GetState() interface{} } // LaneState is an abstract copy of the state of a single lane diff --git a/chain/actors/builtin/paych/state.go.template b/chain/actors/builtin/paych/state.go.template index b4b575a3e..3e41f5be5 100644 --- a/chain/actors/builtin/paych/state.go.template +++ b/chain/actors/builtin/paych/state.go.template @@ -24,6 +24,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + out.State = paych{{.v}}.State{} + return &out, nil +} + type state{{.v}} struct { paych{{.v}}.State store adt.Store @@ -74,6 +80,10 @@ func (s *state{{.v}}) LaneCount() (uint64, error) { return lsamt.Length(), nil } +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} + // Iterate lane states func (s *state{{.v}}) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/temp b/chain/actors/builtin/paych/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/paych/v0.go b/chain/actors/builtin/paych/v0.go index 8e0e3434e..e9bc30e3d 100644 --- a/chain/actors/builtin/paych/v0.go +++ b/chain/actors/builtin/paych/v0.go @@ -24,6 +24,12 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store) (State, error) { + out := state0{store: store} + out.State = paych0.State{} + return &out, nil +} + type state0 struct { paych0.State store adt.Store @@ -74,6 +80,10 @@ func (s *state0) LaneCount() (uint64, error) { return lsamt.Length(), nil } +func (s *state0) GetState() interface{} { + return &s.State +} + // Iterate lane states func (s *state0) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/v2.go b/chain/actors/builtin/paych/v2.go index fbf4b9fde..400305e2f 100644 --- a/chain/actors/builtin/paych/v2.go +++ b/chain/actors/builtin/paych/v2.go @@ -24,6 +24,12 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store) (State, error) { + out := state2{store: store} + out.State = paych2.State{} + return &out, nil +} + type state2 struct { paych2.State store adt.Store @@ -74,6 +80,10 @@ func (s *state2) LaneCount() (uint64, error) { return lsamt.Length(), nil } +func (s *state2) GetState() interface{} { + return &s.State +} + // Iterate lane states func (s *state2) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/v3.go b/chain/actors/builtin/paych/v3.go index 14bb4cb61..1d7c2f94b 100644 --- a/chain/actors/builtin/paych/v3.go +++ b/chain/actors/builtin/paych/v3.go @@ -24,6 +24,12 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store) (State, error) { + out := state3{store: store} + out.State = paych3.State{} + return &out, nil +} + type state3 struct { paych3.State store adt.Store @@ -74,6 +80,10 @@ func (s *state3) LaneCount() (uint64, error) { return lsamt.Length(), nil } +func (s *state3) GetState() interface{} { + return &s.State +} + // Iterate lane states func (s *state3) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/paych/v4.go b/chain/actors/builtin/paych/v4.go index cf37eea5c..b7d1e52a5 100644 --- a/chain/actors/builtin/paych/v4.go +++ b/chain/actors/builtin/paych/v4.go @@ -24,6 +24,12 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store) (State, error) { + out := state4{store: store} + out.State = paych4.State{} + return &out, nil +} + type state4 struct { paych4.State store adt.Store @@ -74,6 +80,10 @@ func (s *state4) LaneCount() (uint64, error) { return lsamt.Length(), nil } +func (s *state4) GetState() interface{} { + return &s.State +} + // Iterate lane states func (s *state4) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { // Get the lane state from the chain diff --git a/chain/actors/builtin/power/actor.go.template b/chain/actors/builtin/power/actor.go.template index 82f791e58..7ff3d0387 100644 --- a/chain/actors/builtin/power/actor.go.template +++ b/chain/actors/builtin/power/actor.go.template @@ -3,6 +3,7 @@ package power import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -40,6 +41,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.StoragePowerActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -47,6 +69,7 @@ type State interface { TotalPower() (Claim, error) TotalCommitted() (Claim, error) TotalPowerSmoothed() (builtin.FilterEstimate, error) + GetState() interface{} // MinerCounts returns the number of miners. Participating is the number // with power above the minimum miner threshold. @@ -57,6 +80,12 @@ type State interface { ForEachClaim(func(miner address.Address, claim Claim) error) error ClaimsChanged(State) (bool, error) + // Testing or genesis setup only + SetTotalQualityAdjPower(abi.StoragePower) error + SetTotalRawBytePower(abi.StoragePower) error + SetThisEpochQualityAdjPower(abi.StoragePower) error + SetThisEpochRawBytePower(abi.StoragePower) error + // Diff helpers. Used by Diff* functions internally. claims() (adt.Map, error) decodeClaim(*cbg.Deferred) (Claim, error) @@ -72,7 +101,7 @@ type Claim struct { func AddClaims(a Claim, b Claim) Claim { return Claim{ - RawBytePower: big.Add(a.RawBytePower, b.RawBytePower), + RawBytePower: big.Add(a.RawBytePower, b.RawBytePower), QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower), } } diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index bf530a21a..69ed6cf89 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -3,6 +3,7 @@ package power import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/chain/actors" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -66,6 +67,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.StoragePowerActorCodeID, nil + + case actors.Version2: + return builtin2.StoragePowerActorCodeID, nil + + case actors.Version3: + return builtin3.StoragePowerActorCodeID, nil + + case actors.Version4: + return builtin4.StoragePowerActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -73,6 +113,7 @@ type State interface { TotalPower() (Claim, error) TotalCommitted() (Claim, error) TotalPowerSmoothed() (builtin.FilterEstimate, error) + GetState() interface{} // MinerCounts returns the number of miners. Participating is the number // with power above the minimum miner threshold. @@ -83,6 +124,12 @@ type State interface { ForEachClaim(func(miner address.Address, claim Claim) error) error ClaimsChanged(State) (bool, error) + // Testing or genesis setup only + SetTotalQualityAdjPower(abi.StoragePower) error + SetTotalRawBytePower(abi.StoragePower) error + SetThisEpochQualityAdjPower(abi.StoragePower) error + SetThisEpochRawBytePower(abi.StoragePower) error + // Diff helpers. Used by Diff* functions internally. claims() (adt.Map, error) decodeClaim(*cbg.Deferred) (Claim, error) diff --git a/chain/actors/builtin/power/state.go.template b/chain/actors/builtin/power/state.go.template index 4cb904a1d..d0abba3fa 100644 --- a/chain/actors/builtin/power/state.go.template +++ b/chain/actors/builtin/power/state.go.template @@ -29,6 +29,32 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + {{if (le .v 2)}} + em, err := adt{{.v}}.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + emm, err := adt{{.v}}.MakeEmptyMultimap(store).Root() + if err != nil { + return nil, err + } + + out.State = *power{{.v}}.ConstructState(em, emm) + {{else}} + s, err := power{{.v}}.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + {{end}} + + return &out, nil +} + type state{{.v}} struct { power{{.v}}.State store adt.Store @@ -40,7 +66,7 @@ func (s *state{{.v}}) TotalLocked() (abi.TokenAmount, error) { func (s *state{{.v}}) TotalPower() (Claim, error) { return Claim{ - RawBytePower: s.TotalRawBytePower, + RawBytePower: s.TotalRawBytePower, QualityAdjPower: s.TotalQualityAdjPower, }, nil } @@ -48,7 +74,7 @@ func (s *state{{.v}}) TotalPower() (Claim, error) { // Committed power to the network. Includes miners below the minimum threshold. func (s *state{{.v}}) TotalCommitted() (Claim, error) { return Claim{ - RawBytePower: s.TotalBytesCommitted, + RawBytePower: s.TotalBytesCommitted, QualityAdjPower: s.TotalQABytesCommitted, }, nil } @@ -64,7 +90,7 @@ func (s *state{{.v}}) MinerPower(addr address.Address) (Claim, bool, error) { return Claim{}, false, err } return Claim{ - RawBytePower: claim.RawBytePower, + RawBytePower: claim.RawBytePower, QualityAdjPower: claim.QualityAdjPower, }, ok, nil } @@ -116,7 +142,7 @@ func (s *state{{.v}}) ForEachClaim(cb func(miner address.Address, claim Claim) e return err } return cb(a, Claim{ - RawBytePower: claim.RawBytePower, + RawBytePower: claim.RawBytePower, QualityAdjPower: claim.QualityAdjPower, }) }) @@ -131,6 +157,30 @@ func (s *state{{.v}}) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other{{.v}}.State.Claims), nil } +func (s *state{{.v}}) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state{{.v}}) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state{{.v}}) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state{{.v}}) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} + func (s *state{{.v}}) claims() (adt.Map, error) { return adt{{.v}}.AsMap(s.store, s.Claims{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) } @@ -145,7 +195,7 @@ func (s *state{{.v}}) decodeClaim(val *cbg.Deferred) (Claim, error) { func fromV{{.v}}Claim(v{{.v}} power{{.v}}.Claim) Claim { return Claim{ - RawBytePower: v{{.v}}.RawBytePower, + RawBytePower: v{{.v}}.RawBytePower, QualityAdjPower: v{{.v}}.QualityAdjPower, } } diff --git a/chain/actors/builtin/power/temp b/chain/actors/builtin/power/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/power/v0.go b/chain/actors/builtin/power/v0.go index 91fad8c57..465d16c5c 100644 --- a/chain/actors/builtin/power/v0.go +++ b/chain/actors/builtin/power/v0.go @@ -26,6 +26,24 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store) (State, error) { + out := state0{store: store} + + em, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + emm, err := adt0.MakeEmptyMultimap(store).Root() + if err != nil { + return nil, err + } + + out.State = *power0.ConstructState(em, emm) + + return &out, nil +} + type state0 struct { power0.State store adt.Store @@ -128,6 +146,30 @@ func (s *state0) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other0.State.Claims), nil } +func (s *state0) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state0) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state0) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state0) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state0) GetState() interface{} { + return &s.State +} + func (s *state0) claims() (adt.Map, error) { return adt0.AsMap(s.store, s.Claims) } diff --git a/chain/actors/builtin/power/v2.go b/chain/actors/builtin/power/v2.go index 313160a78..606534cef 100644 --- a/chain/actors/builtin/power/v2.go +++ b/chain/actors/builtin/power/v2.go @@ -26,6 +26,24 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store) (State, error) { + out := state2{store: store} + + em, err := adt2.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + emm, err := adt2.MakeEmptyMultimap(store).Root() + if err != nil { + return nil, err + } + + out.State = *power2.ConstructState(em, emm) + + return &out, nil +} + type state2 struct { power2.State store adt.Store @@ -128,6 +146,30 @@ func (s *state2) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other2.State.Claims), nil } +func (s *state2) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state2) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state2) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state2) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state2) GetState() interface{} { + return &s.State +} + func (s *state2) claims() (adt.Map, error) { return adt2.AsMap(s.store, s.Claims) } diff --git a/chain/actors/builtin/power/v3.go b/chain/actors/builtin/power/v3.go index 2ef1e2808..3dec3c63e 100644 --- a/chain/actors/builtin/power/v3.go +++ b/chain/actors/builtin/power/v3.go @@ -28,6 +28,19 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store) (State, error) { + out := state3{store: store} + + s, err := power3.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state3 struct { power3.State store adt.Store @@ -130,6 +143,30 @@ func (s *state3) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other3.State.Claims), nil } +func (s *state3) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state3) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state3) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state3) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state3) GetState() interface{} { + return &s.State +} + func (s *state3) claims() (adt.Map, error) { return adt3.AsMap(s.store, s.Claims, builtin3.DefaultHamtBitwidth) } diff --git a/chain/actors/builtin/power/v4.go b/chain/actors/builtin/power/v4.go index 686550456..b73eedf5a 100644 --- a/chain/actors/builtin/power/v4.go +++ b/chain/actors/builtin/power/v4.go @@ -28,6 +28,19 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store) (State, error) { + out := state4{store: store} + + s, err := power4.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state4 struct { power4.State store adt.Store @@ -130,6 +143,30 @@ func (s *state4) ClaimsChanged(other State) (bool, error) { return !s.State.Claims.Equals(other4.State.Claims), nil } +func (s *state4) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state4) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state4) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state4) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state4) GetState() interface{} { + return &s.State +} + func (s *state4) claims() (adt.Map, error) { return adt4.AsMap(s.store, s.Claims, builtin4.DefaultHamtBitwidth) } diff --git a/chain/actors/builtin/reward/actor.go.template b/chain/actors/builtin/reward/actor.go.template index 81437d26f..89cdddaec 100644 --- a/chain/actors/builtin/reward/actor.go.template +++ b/chain/actors/builtin/reward/actor.go.template @@ -4,6 +4,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" "github.com/ipfs/go-cid" + "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/cbor" @@ -38,6 +39,27 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, currRealizedPower abi.StoragePower) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store, currRealizedPower) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.RewardActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -55,6 +77,7 @@ type State interface { InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error) PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error) + GetState() interface{} } type AwardBlockRewardParams = reward0.AwardBlockRewardParams diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index 1037cf741..c325cc7b6 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -2,6 +2,7 @@ package reward import ( "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors" reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -64,6 +65,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, currRealizedPower abi.StoragePower) (State, error) { + switch av { + + case actors.Version0: + return make0(store, currRealizedPower) + + case actors.Version2: + return make2(store, currRealizedPower) + + case actors.Version3: + return make3(store, currRealizedPower) + + case actors.Version4: + return make4(store, currRealizedPower) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.RewardActorCodeID, nil + + case actors.Version2: + return builtin2.RewardActorCodeID, nil + + case actors.Version3: + return builtin3.RewardActorCodeID, nil + + case actors.Version4: + return builtin4.RewardActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -81,6 +121,7 @@ type State interface { InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error) PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error) + GetState() interface{} } type AwardBlockRewardParams = reward0.AwardBlockRewardParams diff --git a/chain/actors/builtin/reward/state.go.template b/chain/actors/builtin/reward/state.go.template index 1758d1413..67bfd5c85 100644 --- a/chain/actors/builtin/reward/state.go.template +++ b/chain/actors/builtin/reward/state.go.template @@ -23,6 +23,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state{{.v}}{store: store} + out.State = *reward{{.v}}.ConstructState(currRealizedPower) + return &out, nil +} + type state{{.v}} struct { reward{{.v}}.State store adt.Store @@ -101,3 +107,7 @@ func (s *state{{.v}}) PreCommitDepositForPower(networkQAPower builtin.FilterEsti }, sectorWeight), nil } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/reward/temp b/chain/actors/builtin/reward/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/reward/v0.go b/chain/actors/builtin/reward/v0.go index fe053cc16..cd098c151 100644 --- a/chain/actors/builtin/reward/v0.go +++ b/chain/actors/builtin/reward/v0.go @@ -23,6 +23,12 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state0{store: store} + out.State = *reward0.ConstructState(currRealizedPower) + return &out, nil +} + type state0 struct { reward0.State store adt.Store @@ -83,3 +89,7 @@ func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/reward/v2.go b/chain/actors/builtin/reward/v2.go index 90621e467..08e9a7bc3 100644 --- a/chain/actors/builtin/reward/v2.go +++ b/chain/actors/builtin/reward/v2.go @@ -23,6 +23,12 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state2{store: store} + out.State = *reward2.ConstructState(currRealizedPower) + return &out, nil +} + type state2 struct { reward2.State store adt.Store @@ -86,3 +92,7 @@ func (s *state2) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/reward/v3.go b/chain/actors/builtin/reward/v3.go index 926cc085b..fd9fa56e2 100644 --- a/chain/actors/builtin/reward/v3.go +++ b/chain/actors/builtin/reward/v3.go @@ -23,6 +23,12 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state3{store: store} + out.State = *reward3.ConstructState(currRealizedPower) + return &out, nil +} + type state3 struct { reward3.State store adt.Store @@ -86,3 +92,7 @@ func (s *state3) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/reward/v4.go b/chain/actors/builtin/reward/v4.go index f034b0018..310ca04e8 100644 --- a/chain/actors/builtin/reward/v4.go +++ b/chain/actors/builtin/reward/v4.go @@ -23,6 +23,12 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state4{store: store} + out.State = *reward4.ConstructState(currRealizedPower) + return &out, nil +} + type state4 struct { reward4.State store adt.Store @@ -86,3 +92,7 @@ func (s *state4) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, }, sectorWeight), nil } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/system/actor.go.template b/chain/actors/builtin/system/actor.go.template new file mode 100644 index 000000000..925319970 --- /dev/null +++ b/chain/actors/builtin/system/actor.go.template @@ -0,0 +1,41 @@ +package system + +import ( + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" + "golang.org/x/xerrors" + "github.com/ipfs/go-cid" + +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} +) + +var ( + Address = builtin{{.latestVersion}}.SystemActorAddr +) + +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.SystemActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + +type State interface { + GetState() interface{} +} diff --git a/chain/actors/builtin/system/state.go.template b/chain/actors/builtin/system/state.go.template new file mode 100644 index 000000000..fa644f8c7 --- /dev/null +++ b/chain/actors/builtin/system/state.go.template @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/system" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make{{.v}}(store adt.Store) (State, error) { + out := state{{.v}}{store: store} + out.State = system{{.v}}.State{} + return &out, nil +} + +type state{{.v}} struct { + system{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/system/system.go b/chain/actors/builtin/system/system.go new file mode 100644 index 000000000..b4ced850f --- /dev/null +++ b/chain/actors/builtin/system/system.go @@ -0,0 +1,63 @@ +package system + +import ( + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" +) + +var ( + Address = builtin4.SystemActorAddr +) + +func MakeState(store adt.Store, av actors.Version) (State, error) { + switch av { + + case actors.Version0: + return make0(store) + + case actors.Version2: + return make2(store) + + case actors.Version3: + return make3(store) + + case actors.Version4: + return make4(store) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.SystemActorCodeID, nil + + case actors.Version2: + return builtin2.SystemActorCodeID, nil + + case actors.Version3: + return builtin3.SystemActorCodeID, nil + + case actors.Version4: + return builtin4.SystemActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + +type State interface { + GetState() interface{} +} diff --git a/chain/actors/builtin/system/temp b/chain/actors/builtin/system/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/system/v0.go b/chain/actors/builtin/system/v0.go new file mode 100644 index 000000000..64c6f53d3 --- /dev/null +++ b/chain/actors/builtin/system/v0.go @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system0 "github.com/filecoin-project/specs-actors/actors/builtin/system" +) + +var _ State = (*state0)(nil) + +func load0(store adt.Store, root cid.Cid) (State, error) { + out := state0{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make0(store adt.Store) (State, error) { + out := state0{store: store} + out.State = system0.State{} + return &out, nil +} + +type state0 struct { + system0.State + store adt.Store +} + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/system/v2.go b/chain/actors/builtin/system/v2.go new file mode 100644 index 000000000..eb540891c --- /dev/null +++ b/chain/actors/builtin/system/v2.go @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/system" +) + +var _ State = (*state2)(nil) + +func load2(store adt.Store, root cid.Cid) (State, error) { + out := state2{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make2(store adt.Store) (State, error) { + out := state2{store: store} + out.State = system2.State{} + return &out, nil +} + +type state2 struct { + system2.State + store adt.Store +} + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/system/v3.go b/chain/actors/builtin/system/v3.go new file mode 100644 index 000000000..5b04e189e --- /dev/null +++ b/chain/actors/builtin/system/v3.go @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/system" +) + +var _ State = (*state3)(nil) + +func load3(store adt.Store, root cid.Cid) (State, error) { + out := state3{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make3(store adt.Store) (State, error) { + out := state3{store: store} + out.State = system3.State{} + return &out, nil +} + +type state3 struct { + system3.State + store adt.Store +} + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/system/v4.go b/chain/actors/builtin/system/v4.go new file mode 100644 index 000000000..b6c924978 --- /dev/null +++ b/chain/actors/builtin/system/v4.go @@ -0,0 +1,35 @@ +package system + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + system4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/system" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make4(store adt.Store) (State, error) { + out := state4{store: store} + out.State = system4.State{} + return &out, nil +} + +type state4 struct { + system4.State + store adt.Store +} + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/temp b/chain/actors/builtin/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/verifreg/actor.go.template b/chain/actors/builtin/verifreg/actor.go.template index 22e809ccf..9ea8e155a 100644 --- a/chain/actors/builtin/verifreg/actor.go.template +++ b/chain/actors/builtin/verifreg/actor.go.template @@ -14,6 +14,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) @@ -40,6 +41,28 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, rootKeyAddress address.Address) (State, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return make{{.}}(store, rootKeyAddress) +{{end}} +} + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { +{{range .versions}} + case actors.Version{{.}}: + return builtin{{.}}.VerifiedRegistryActorCodeID, nil +{{end}} + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + + type State interface { cbor.Marshaler @@ -48,4 +71,5 @@ type State interface { VerifierDataCap(address.Address) (bool, abi.StoragePower, error) ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error + GetState() interface{} } diff --git a/chain/actors/builtin/verifreg/state.go.template b/chain/actors/builtin/verifreg/state.go.template index 244d20932..96bebe25f 100644 --- a/chain/actors/builtin/verifreg/state.go.template +++ b/chain/actors/builtin/verifreg/state.go.template @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" {{if (ge .v 3)}} builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin" -{{end}} verifreg{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/verifreg" +{{end}} verifreg{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/verifreg" adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt" ) @@ -24,6 +24,26 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make{{.v}}(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state{{.v}}{store: store} + {{if (le .v 2)}} + em, err := adt{{.v}}.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *verifreg{{.v}}.ConstructState(em, rootKeyAddress) + {{else}} + s, err := verifreg{{.v}}.ConstructState(store, rootKeyAddress) + if err != nil { + return nil, err + } + + out.State = *s + {{end}} + return &out, nil +} + type state{{.v}} struct { verifreg{{.v}}.State store adt.Store @@ -56,3 +76,7 @@ func (s *state{{.v}}) verifiedClients() (adt.Map, error) { func (s *state{{.v}}) verifiers() (adt.Map, error) { return adt{{.v}}.AsMap(s.store, s.Verifiers{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) } + +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} \ No newline at end of file diff --git a/chain/actors/builtin/verifreg/temp b/chain/actors/builtin/verifreg/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/builtin/verifreg/v0.go b/chain/actors/builtin/verifreg/v0.go index 0dc4696f4..e70b0e3c9 100644 --- a/chain/actors/builtin/verifreg/v0.go +++ b/chain/actors/builtin/verifreg/v0.go @@ -23,6 +23,19 @@ func load0(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make0(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state0{store: store} + + em, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *verifreg0.ConstructState(em, rootKeyAddress) + + return &out, nil +} + type state0 struct { verifreg0.State store adt.Store @@ -55,3 +68,7 @@ func (s *state0) verifiedClients() (adt.Map, error) { func (s *state0) verifiers() (adt.Map, error) { return adt0.AsMap(s.store, s.Verifiers) } + +func (s *state0) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/verifreg/v2.go b/chain/actors/builtin/verifreg/v2.go index a5ef84532..0bcbe0212 100644 --- a/chain/actors/builtin/verifreg/v2.go +++ b/chain/actors/builtin/verifreg/v2.go @@ -23,6 +23,19 @@ func load2(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make2(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state2{store: store} + + em, err := adt2.MakeEmptyMap(store).Root() + if err != nil { + return nil, err + } + + out.State = *verifreg2.ConstructState(em, rootKeyAddress) + + return &out, nil +} + type state2 struct { verifreg2.State store adt.Store @@ -55,3 +68,7 @@ func (s *state2) verifiedClients() (adt.Map, error) { func (s *state2) verifiers() (adt.Map, error) { return adt2.AsMap(s.store, s.Verifiers) } + +func (s *state2) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/verifreg/v3.go b/chain/actors/builtin/verifreg/v3.go index fb0c46d0c..32003ca3a 100644 --- a/chain/actors/builtin/verifreg/v3.go +++ b/chain/actors/builtin/verifreg/v3.go @@ -24,6 +24,19 @@ func load3(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make3(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state3{store: store} + + s, err := verifreg3.ConstructState(store, rootKeyAddress) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state3 struct { verifreg3.State store adt.Store @@ -56,3 +69,7 @@ func (s *state3) verifiedClients() (adt.Map, error) { func (s *state3) verifiers() (adt.Map, error) { return adt3.AsMap(s.store, s.Verifiers, builtin3.DefaultHamtBitwidth) } + +func (s *state3) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/verifreg/v4.go b/chain/actors/builtin/verifreg/v4.go index 2419ef758..b752e747b 100644 --- a/chain/actors/builtin/verifreg/v4.go +++ b/chain/actors/builtin/verifreg/v4.go @@ -24,6 +24,19 @@ func load4(store adt.Store, root cid.Cid) (State, error) { return &out, nil } +func make4(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state4{store: store} + + s, err := verifreg4.ConstructState(store, rootKeyAddress) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + type state4 struct { verifreg4.State store adt.Store @@ -56,3 +69,7 @@ func (s *state4) verifiedClients() (adt.Map, error) { func (s *state4) verifiers() (adt.Map, error) { return adt4.AsMap(s.store, s.Verifiers, builtin4.DefaultHamtBitwidth) } + +func (s *state4) GetState() interface{} { + return &s.State +} diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index 32f50a4ae..618907554 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -17,6 +17,7 @@ import ( builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" @@ -66,6 +67,45 @@ func Load(store adt.Store, act *types.Actor) (State, error) { return nil, xerrors.Errorf("unknown actor code %s", act.Code) } +func MakeState(store adt.Store, av actors.Version, rootKeyAddress address.Address) (State, error) { + switch av { + + case actors.Version0: + return make0(store, rootKeyAddress) + + case actors.Version2: + return make2(store, rootKeyAddress) + + case actors.Version3: + return make3(store, rootKeyAddress) + + case actors.Version4: + return make4(store, rootKeyAddress) + + } + return nil, xerrors.Errorf("unknown actor version %d", av) +} + +func GetActorCodeID(av actors.Version) (cid.Cid, error) { + switch av { + + case actors.Version0: + return builtin0.VerifiedRegistryActorCodeID, nil + + case actors.Version2: + return builtin2.VerifiedRegistryActorCodeID, nil + + case actors.Version3: + return builtin3.VerifiedRegistryActorCodeID, nil + + case actors.Version4: + return builtin4.VerifiedRegistryActorCodeID, nil + + } + + return cid.Undef, xerrors.Errorf("unknown actor version %d", av) +} + type State interface { cbor.Marshaler @@ -74,4 +114,5 @@ type State interface { VerifierDataCap(address.Address) (bool, abi.StoragePower, error) ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error + GetState() interface{} } diff --git a/chain/actors/policy/policy.go.template b/chain/actors/policy/policy.go.template index d395d7132..a1a47852b 100644 --- a/chain/actors/policy/policy.go.template +++ b/chain/actors/policy/policy.go.template @@ -8,20 +8,20 @@ import ( "github.com/filecoin-project/lotus/chain/actors" {{range .versions}} - {{if (ge . 2)}} builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" {{end}} + {{if (ge . 2)}} builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" {{end}} market{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/market" miner{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/miner" verifreg{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/verifreg" {{if (eq . 0)}} power{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/power" {{end}} - {{end}} + {{end}} - paych{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/paych" + paych{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/paych" ) const ( - ChainFinality = miner{{.latestVersion}}.ChainFinality - SealRandomnessLookback = ChainFinality - PaychSettleDelay = paych{{.latestVersion}}.SettleDelay + ChainFinality = miner{{.latestVersion}}.ChainFinality + SealRandomnessLookback = ChainFinality + PaychSettleDelay = paych{{.latestVersion}}.SettleDelay MaxPreCommitRandomnessLookback = builtin{{.latestVersion}}.EpochsInDay + SealRandomnessLookback ) @@ -29,13 +29,13 @@ const ( // This should only be used for testing. func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { {{range .versions}} - {{if (eq . 0)}} - miner{{.}}.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types)) - {{else}} - miner{{.}}.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types)) - miner{{.}}.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2) - miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) - {{end}} + {{if (eq . 0)}} + miner{{.}}.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types)) + {{else}} + miner{{.}}.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + miner{{.}}.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2) + miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + {{end}} {{end}} AddSupportedProofTypes(types...) @@ -51,15 +51,15 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { // Set for all miner versions. {{range .versions}} - {{if (eq . 0)}} - miner{{.}}.SupportedProofTypes[t] = struct{}{} - {{else}} - miner{{.}}.PreCommitSealProofTypesV0[t] = struct{}{} - miner{{.}}.PreCommitSealProofTypesV7[t] = struct{}{} - miner{{.}}.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} - miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} - {{end}} - {{end}} + {{if (eq . 0)}} + miner{{.}}.SupportedProofTypes[t] = struct{}{} + {{else}} + miner{{.}}.PreCommitSealProofTypesV0[t] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV7[t] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + {{end}} + {{end}} } } @@ -67,9 +67,9 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { // actors versions. Use for testing. func SetPreCommitChallengeDelay(delay abi.ChainEpoch) { // Set for all miner versions. - {{range .versions}} - miner{{.}}.PreCommitChallengeDelay = delay - {{end}} + {{range .versions}} + miner{{.}}.PreCommitChallengeDelay = delay + {{end}} } // TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay. @@ -81,42 +81,42 @@ func GetPreCommitChallengeDelay() abi.ChainEpoch { // meet for leader election, across all actor versions. This should only be used // for testing. func SetConsensusMinerMinPower(p abi.StoragePower) { - {{range .versions}} - {{if (eq . 0)}} - power{{.}}.ConsensusMinerMinPower = p - {{else if (eq . 2)}} - for _, policy := range builtin{{.}}.SealProofPolicies { - policy.ConsensusMinerMinPower = p - } - {{else}} - for _, policy := range builtin{{.}}.PoStProofPolicies { - policy.ConsensusMinerMinPower = p - } - {{end}} - {{end}} + {{range .versions}} + {{if (eq . 0)}} + power{{.}}.ConsensusMinerMinPower = p + {{else if (eq . 2)}} + for _, policy := range builtin{{.}}.SealProofPolicies { + policy.ConsensusMinerMinPower = p + } + {{else}} + for _, policy := range builtin{{.}}.PoStProofPolicies { + policy.ConsensusMinerMinPower = p + } + {{end}} + {{end}} } // SetMinVerifiedDealSize sets the minimum size of a verified deal. This should // only be used for testing. func SetMinVerifiedDealSize(size abi.StoragePower) { - {{range .versions}} - verifreg{{.}}.MinVerifiedDealSize = size - {{end}} + {{range .versions}} + verifreg{{.}}.MinVerifiedDealSize = size + {{end}} } func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch { switch ver { {{range .versions}} - case actors.Version{{.}}: - {{if (eq . 0)}} - return miner{{.}}.MaxSealDuration[t] - {{else}} - return miner{{.}}.MaxProveCommitDuration[t] - {{end}} - {{end}} - default: - panic("unsupported actors version") - } + case actors.Version{{.}}: + {{if (eq . 0)}} + return miner{{.}}.MaxSealDuration[t] + {{else}} + return miner{{.}}.MaxProveCommitDuration[t] + {{end}} + {{end}} + default: + panic("unsupported actors version") + } } func DealProviderCollateralBounds( @@ -125,14 +125,14 @@ func DealProviderCollateralBounds( circulatingFil abi.TokenAmount, nwVer network.Version, ) (min, max abi.TokenAmount) { switch actors.VersionForNetwork(nwVer) { - {{range .versions}} - case actors.Version{{.}}: - {{if (eq . 0)}} - return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) - {{else}} - return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) - {{end}} - {{end}} + {{range .versions}} + case actors.Version{{.}}: + {{if (eq . 0)}} + return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) + {{else}} + return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + {{end}} + {{end}} default: panic("unsupported actors version") } @@ -145,15 +145,15 @@ func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) // Sets the challenge window and scales the proving period to match (such that // there are always 48 challenge windows in a proving period). func SetWPoStChallengeWindow(period abi.ChainEpoch) { - {{range .versions}} - miner{{.}}.WPoStChallengeWindow = period - miner{{.}}.WPoStProvingPeriod = period * abi.ChainEpoch(miner{{.}}.WPoStPeriodDeadlines) - {{if (ge . 3)}} - // by default, this is 2x finality which is 30 periods. - // scale it if we're scaling the challenge period. - miner{{.}}.WPoStDisputeWindow = period * 30 - {{end}} - {{end}} + {{range .versions}} + miner{{.}}.WPoStChallengeWindow = period + miner{{.}}.WPoStProvingPeriod = period * abi.ChainEpoch(miner{{.}}.WPoStPeriodDeadlines) + {{if (ge . 3)}} + // by default, this is 2x finality which is 30 periods. + // scale it if we're scaling the challenge period. + miner{{.}}.WPoStDisputeWindow = period * 30 + {{end}} + {{end}} } func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { @@ -161,7 +161,7 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { return 10 } - // NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well + // NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well return ChainFinality } @@ -207,10 +207,10 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) func GetAddressedSectorsMax(nwVer network.Version) int { switch actors.VersionForNetwork(nwVer) { - {{range .versions}} - case actors.Version{{.}}: - return miner{{.}}.AddressedSectorsMax - {{end}} + {{range .versions}} + case actors.Version{{.}}: + return miner{{.}}.AddressedSectorsMax + {{end}} default: panic("unsupported network version") } @@ -218,15 +218,15 @@ func GetAddressedSectorsMax(nwVer network.Version) int { func GetDeclarationsMax(nwVer network.Version) int { switch actors.VersionForNetwork(nwVer) { - {{range .versions}} - case actors.Version{{.}}: - {{if (eq . 0)}} - // TODO: Should we instead panic here since the concept doesn't exist yet? - return miner{{.}}.AddressedPartitionsMax - {{else}} - return miner{{.}}.DeclarationsMax - {{end}} - {{end}} + {{range .versions}} + case actors.Version{{.}}: + {{if (eq . 0)}} + // TODO: Should we instead panic here since the concept doesn't exist yet? + return miner{{.}}.AddressedPartitionsMax + {{else}} + return miner{{.}}.DeclarationsMax + {{end}} + {{end}} default: panic("unsupported network version") } diff --git a/chain/actors/policy/temp b/chain/actors/policy/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/temp b/chain/actors/temp new file mode 100644 index 000000000..e69de29bb diff --git a/chain/actors/version.go b/chain/actors/version.go index bd7b708bd..a8b4c62b2 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -8,6 +8,10 @@ import ( type Version int +var LatestVersion = 4 + +var Versions = []int{0, 2, 3, LatestVersion} + const ( Version0 Version = 0 Version2 Version = 2 diff --git a/chain/gen/gen.go b/chain/gen/gen.go index d06c755fa..5c33ac4d7 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -9,6 +9,8 @@ import ( "sync/atomic" "time" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" @@ -197,6 +199,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { sys := vm.Syscalls(&genFakeVerifier{}) tpl := genesis.Template{ + NetworkVersion: network.Version0, Accounts: []genesis.Actor{ { Type: genesis.TAccount, diff --git a/chain/gen/genesis/f00_system.go b/chain/gen/genesis/f00_system.go index 015dfac4a..d1dd203b6 100644 --- a/chain/gen/genesis/f00_system.go +++ b/chain/gen/genesis/f00_system.go @@ -3,27 +3,36 @@ package genesis import ( "context" - "github.com/filecoin-project/specs-actors/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/system" - "github.com/filecoin-project/specs-actors/actors/builtin" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupSystemActor(bs bstore.Blockstore) (*types.Actor, error) { - var st system.State +func SetupSystemActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { cst := cbor.NewCborStore(bs) + st, err := system.MakeState(adt.WrapStore(ctx, cst), av) + if err != nil { + return nil, err + } - statecid, err := cst.Put(context.TODO(), &st) + statecid, err := cst.Put(ctx, st.GetState()) + if err != nil { + return nil, err + } + + actcid, err := system.GetActorCodeID(av) if err != nil { return nil, err } act := &types.Actor{ - Code: builtin.SystemActorCodeID, + Code: actcid, Head: statecid, } diff --git a/chain/gen/genesis/f01_init.go b/chain/gen/genesis/f01_init.go index 718eb4480..88d409221 100644 --- a/chain/gen/genesis/f01_init.go +++ b/chain/gen/genesis/f01_init.go @@ -5,13 +5,15 @@ import ( "encoding/json" "fmt" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/util/adt" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" cbor "github.com/ipfs/go-ipld-cbor" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -21,17 +23,25 @@ import ( "github.com/filecoin-project/lotus/genesis" ) -func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesis.Actor, rootVerifier genesis.Actor, remainder genesis.Actor) (int64, *types.Actor, map[address.Address]address.Address, error) { +func SetupInitActor(ctx context.Context, bs bstore.Blockstore, netname string, initialActors []genesis.Actor, rootVerifier genesis.Actor, remainder genesis.Actor, av actors.Version) (int64, *types.Actor, map[address.Address]address.Address, error) { if len(initialActors) > MaxAccounts { return 0, nil, nil, xerrors.New("too many initial actors") } - var ias init_.State - ias.NextID = MinerStart - ias.NetworkName = netname + cst := cbor.NewCborStore(bs) + ist, err := init_.MakeState(adt.WrapStore(ctx, cst), av, netname) + if err != nil { + return 0, nil, nil, err + } - store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) - amap := adt.MakeEmptyMap(store) + if err = ist.SetNextID(MinerStart); err != nil { + return 0, nil, nil, err + } + + amap, err := ist.AddressMap() + if err != nil { + return 0, nil, nil, err + } keyToId := map[address.Address]address.Address{} counter := int64(AccountStart) @@ -155,15 +165,23 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi if err != nil { return 0, nil, nil, err } - ias.AddressMap = amapaddr - statecid, err := store.Put(store.Context(), &ias) + if err = ist.SetAddressMap(amapaddr); err != nil { + return 0, nil, nil, err + } + + statecid, err := cst.Put(ctx, ist.GetState()) + if err != nil { + return 0, nil, nil, err + } + + actcid, err := init_.GetActorCodeID(av) if err != nil { return 0, nil, nil, err } act := &types.Actor{ - Code: builtin.InitActorCodeID, + Code: actcid, Head: statecid, } diff --git a/chain/gen/genesis/f02_reward.go b/chain/gen/genesis/f02_reward.go index e218da6fe..c8f479722 100644 --- a/chain/gen/genesis/f02_reward.go +++ b/chain/gen/genesis/f02_reward.go @@ -3,10 +3,12 @@ package genesis import ( "context" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/reward" + "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" @@ -14,19 +16,28 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func SetupRewardActor(bs bstore.Blockstore, qaPower big.Int) (*types.Actor, error) { +func SetupRewardActor(ctx context.Context, bs bstore.Blockstore, qaPower big.Int, av actors.Version) (*types.Actor, error) { cst := cbor.NewCborStore(bs) - - st := reward0.ConstructState(qaPower) - - hcid, err := cst.Put(context.TODO(), st) + rst, err := reward.MakeState(adt.WrapStore(ctx, cst), av, qaPower) if err != nil { return nil, err } - return &types.Actor{ - Code: builtin.RewardActorCodeID, + statecid, err := cst.Put(ctx, rst.GetState()) + if err != nil { + return nil, err + } + + actcid, err := reward.GetActorCodeID(av) + if err != nil { + return nil, err + } + + act := &types.Actor{ + Code: actcid, Balance: types.BigInt{Int: build.InitialRewardBalance}, - Head: hcid, - }, nil + Head: statecid, + } + + return act, nil } diff --git a/chain/gen/genesis/f03_cron.go b/chain/gen/genesis/f03_cron.go index dd43a59a4..c6fd2422a 100644 --- a/chain/gen/genesis/f03_cron.go +++ b/chain/gen/genesis/f03_cron.go @@ -3,27 +3,37 @@ package genesis import ( "context" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/cron" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/cron" + cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupCronActor(bs bstore.Blockstore) (*types.Actor, error) { +func SetupCronActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { cst := cbor.NewCborStore(bs) - cas := cron.ConstructState(cron.BuiltInEntries()) - - stcid, err := cst.Put(context.TODO(), cas) + st, err := cron.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av) if err != nil { return nil, err } - return &types.Actor{ - Code: builtin.CronActorCodeID, - Head: stcid, - Nonce: 0, - Balance: types.NewInt(0), - }, nil + statecid, err := cst.Put(ctx, st.GetState()) + if err != nil { + return nil, err + } + + actcid, err := cron.GetActorCodeID(av) + if err != nil { + return nil, err + } + + act := &types.Actor{ + Code: actcid, + Head: statecid, + } + + return act, nil } diff --git a/chain/gen/genesis/f04_power.go b/chain/gen/genesis/f04_power.go index ed349c18b..6fe4d75c0 100644 --- a/chain/gen/genesis/f04_power.go +++ b/chain/gen/genesis/f04_power.go @@ -3,44 +3,39 @@ package genesis import ( "context" - "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/power" + + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/specs-actors/actors/util/adt" - power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) { - store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) - emptyMap, err := adt.MakeEmptyMap(store).Root() +func SetupStoragePowerActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { + + cst := cbor.NewCborStore(bs) + pst, err := power.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av) if err != nil { return nil, err } - multiMap, err := adt.AsMultimap(store, emptyMap) + statecid, err := cst.Put(ctx, pst.GetState()) if err != nil { return nil, err } - emptyMultiMap, err := multiMap.Root() + actcid, err := power.GetActorCodeID(av) if err != nil { return nil, err } - sms := power0.ConstructState(emptyMap, emptyMultiMap) - - stcid, err := store.Put(store.Context(), sms) - if err != nil { - return nil, err + act := &types.Actor{ + Code: actcid, + Head: statecid, } - return &types.Actor{ - Code: builtin.StoragePowerActorCodeID, - Head: stcid, - Nonce: 0, - Balance: types.NewInt(0), - }, nil + return act, nil } diff --git a/chain/gen/genesis/f05_market.go b/chain/gen/genesis/f05_market.go index f7ac26f43..5c39ef38f 100644 --- a/chain/gen/genesis/f05_market.go +++ b/chain/gen/genesis/f05_market.go @@ -3,38 +3,36 @@ package genesis import ( "context" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/market" - "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" + cbor "github.com/ipfs/go-ipld-cbor" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" ) -func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) { - store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) - - a, err := adt.MakeEmptyArray(store).Root() - if err != nil { - return nil, err - } - h, err := adt.MakeEmptyMap(store).Root() +func SetupStorageMarketActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { + cst := cbor.NewCborStore(bs) + mst, err := market.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av) if err != nil { return nil, err } - sms := market.ConstructState(a, h, h) + statecid, err := cst.Put(ctx, mst.GetState()) + if err != nil { + return nil, err + } - stcid, err := store.Put(store.Context(), sms) + actcid, err := market.GetActorCodeID(av) if err != nil { return nil, err } act := &types.Actor{ - Code: builtin.StorageMarketActorCodeID, - Head: stcid, - Balance: types.NewInt(0), + Code: actcid, + Head: statecid, } return act, nil diff --git a/chain/gen/genesis/f06_vreg.go b/chain/gen/genesis/f06_vreg.go index 1ba8abede..d8f5ee2a0 100644 --- a/chain/gen/genesis/f06_vreg.go +++ b/chain/gen/genesis/f06_vreg.go @@ -3,11 +3,13 @@ package genesis import ( "context" + "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/go-address" cbor "github.com/ipfs/go-ipld-cbor" - "github.com/filecoin-project/specs-actors/actors/builtin" - verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" "github.com/filecoin-project/specs-actors/actors/util/adt" bstore "github.com/filecoin-project/lotus/blockstore" @@ -26,25 +28,26 @@ func init() { RootVerifierID = idk } -func SetupVerifiedRegistryActor(bs bstore.Blockstore) (*types.Actor, error) { - store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs)) - - h, err := adt.MakeEmptyMap(store).Root() +func SetupVerifiedRegistryActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) { + cst := cbor.NewCborStore(bs) + vst, err := verifreg.MakeState(adt.WrapStore(ctx, cbor.NewCborStore(bs)), av, RootVerifierID) if err != nil { return nil, err } - sms := verifreg0.ConstructState(h, RootVerifierID) + statecid, err := cst.Put(ctx, vst.GetState()) + if err != nil { + return nil, err + } - stcid, err := store.Put(store.Context(), sms) + actcid, err := verifreg.GetActorCodeID(av) if err != nil { return nil, err } act := &types.Actor{ - Code: builtin.VerifiedRegistryActorCodeID, - Head: stcid, - Balance: types.NewInt(0), + Code: actcid, + Head: statecid, } return act, nil diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index 4b86db550..94badbbfb 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -6,6 +6,32 @@ import ( "encoding/json" "fmt" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + + "github.com/filecoin-project/go-state-types/network" + + "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/account" + + "github.com/filecoin-project/lotus/chain/actors" + + "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" + + "github.com/filecoin-project/lotus/chain/actors/builtin/market" + + "github.com/filecoin-project/lotus/chain/actors/builtin/power" + + "github.com/filecoin-project/lotus/chain/actors/builtin/cron" + + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/actors/builtin/reward" + + "github.com/filecoin-project/lotus/chain/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/journal" @@ -21,11 +47,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - account0 "github.com/filecoin-project/specs-actors/actors/builtin/account" - multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" @@ -118,94 +139,92 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return nil, nil, xerrors.Errorf("putting empty object: %w", err) } - state, err := state.NewStateTree(cst, types.StateTreeVersion0) + sv, err := state.VersionForNetwork(template.NetworkVersion) + if err != nil { + return nil, nil, xerrors.Errorf("getting state tree version: %w", err) + } + + state, err := state.NewStateTree(cst, sv) if err != nil { return nil, nil, xerrors.Errorf("making new state tree: %w", err) } + av := actors.VersionForNetwork(template.NetworkVersion) + // Create system actor - sysact, err := SetupSystemActor(bs) + sysact, err := SetupSystemActor(ctx, bs, av) if err != nil { - return nil, nil, xerrors.Errorf("setup init actor: %w", err) + return nil, nil, xerrors.Errorf("setup system actor: %w", err) } - if err := state.SetActor(builtin0.SystemActorAddr, sysact); err != nil { - return nil, nil, xerrors.Errorf("set init actor: %w", err) + if err := state.SetActor(system.Address, sysact); err != nil { + return nil, nil, xerrors.Errorf("set system actor: %w", err) } // Create init actor - idStart, initact, keyIDs, err := SetupInitActor(bs, template.NetworkName, template.Accounts, template.VerifregRootKey, template.RemainderAccount) + idStart, initact, keyIDs, err := SetupInitActor(ctx, bs, template.NetworkName, template.Accounts, template.VerifregRootKey, template.RemainderAccount, av) if err != nil { return nil, nil, xerrors.Errorf("setup init actor: %w", err) } - if err := state.SetActor(builtin0.InitActorAddr, initact); err != nil { + if err := state.SetActor(init_.Address, initact); err != nil { return nil, nil, xerrors.Errorf("set init actor: %w", err) } // Setup reward - // RewardActor's state is overrwritten by SetupStorageMiners - rewact, err := SetupRewardActor(bs, big.Zero()) + // RewardActor's state is overwritten by SetupStorageMiners, but needs to exist for miner creation messages + rewact, err := SetupRewardActor(ctx, bs, big.Zero(), av) if err != nil { - return nil, nil, xerrors.Errorf("setup init actor: %w", err) + return nil, nil, xerrors.Errorf("setup reward actor: %w", err) } - err = state.SetActor(builtin0.RewardActorAddr, rewact) + err = state.SetActor(reward.Address, rewact) if err != nil { - return nil, nil, xerrors.Errorf("set network account actor: %w", err) + return nil, nil, xerrors.Errorf("set reward actor: %w", err) } // Setup cron - cronact, err := SetupCronActor(bs) + cronact, err := SetupCronActor(ctx, bs, av) if err != nil { return nil, nil, xerrors.Errorf("setup cron actor: %w", err) } - if err := state.SetActor(builtin0.CronActorAddr, cronact); err != nil { + if err := state.SetActor(cron.Address, cronact); err != nil { return nil, nil, xerrors.Errorf("set cron actor: %w", err) } // Create empty power actor - spact, err := SetupStoragePowerActor(bs) + spact, err := SetupStoragePowerActor(ctx, bs, av) if err != nil { - return nil, nil, xerrors.Errorf("setup storage market actor: %w", err) + return nil, nil, xerrors.Errorf("setup storage power actor: %w", err) } - if err := state.SetActor(builtin0.StoragePowerActorAddr, spact); err != nil { - return nil, nil, xerrors.Errorf("set storage market actor: %w", err) + if err := state.SetActor(power.Address, spact); err != nil { + return nil, nil, xerrors.Errorf("set storage power actor: %w", err) } // Create empty market actor - marketact, err := SetupStorageMarketActor(bs) + marketact, err := SetupStorageMarketActor(ctx, bs, av) if err != nil { return nil, nil, xerrors.Errorf("setup storage market actor: %w", err) } - if err := state.SetActor(builtin0.StorageMarketActorAddr, marketact); err != nil { - return nil, nil, xerrors.Errorf("set market actor: %w", err) + if err := state.SetActor(market.Address, marketact); err != nil { + return nil, nil, xerrors.Errorf("set storage market actor: %w", err) } // Create verified registry - verifact, err := SetupVerifiedRegistryActor(bs) + verifact, err := SetupVerifiedRegistryActor(ctx, bs, av) if err != nil { - return nil, nil, xerrors.Errorf("setup storage market actor: %w", err) + return nil, nil, xerrors.Errorf("setup verified registry market actor: %w", err) } - if err := state.SetActor(builtin0.VerifiedRegistryActorAddr, verifact); err != nil { - return nil, nil, xerrors.Errorf("set market actor: %w", err) + if err := state.SetActor(verifreg.Address, verifact); err != nil { + return nil, nil, xerrors.Errorf("set verified registry actor: %w", err) } - burntRoot, err := cst.Put(ctx, &account0.State{ - Address: builtin0.BurntFundsActorAddr, - }) + bact, err := makeAccountActor(ctx, cst, av, builtin.BurntFundsActorAddr, big.Zero()) if err != nil { - return nil, nil, xerrors.Errorf("failed to setup burnt funds actor state: %w", err) + return nil, nil, xerrors.Errorf("setup burnt funds actor state: %w", err) } - - // Setup burnt-funds - err = state.SetActor(builtin0.BurntFundsActorAddr, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: types.NewInt(0), - Head: burntRoot, - }) - if err != nil { - return nil, nil, xerrors.Errorf("set burnt funds account actor: %w", err) + if err := state.SetActor(builtin.BurntFundsActorAddr, bact); err != nil { + return nil, nil, xerrors.Errorf("set burnt funds actor: %w", err) } // Create accounts @@ -213,7 +232,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge switch info.Type { case genesis.TAccount: - if err := createAccountActor(ctx, cst, state, info, keyIDs); err != nil { + if err := createAccountActor(ctx, cst, state, info, keyIDs, av); err != nil { return nil, nil, xerrors.Errorf("failed to create account actor: %w", err) } @@ -225,7 +244,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge } idStart++ - if err := createMultisigAccount(ctx, bs, cst, state, ida, info, keyIDs); err != nil { + if err := createMultisigAccount(ctx, cst, state, ida, info, keyIDs, av); err != nil { return nil, nil, err } default: @@ -240,26 +259,21 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge if err := json.Unmarshal(template.VerifregRootKey.Meta, &ainfo); err != nil { return nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err) } - st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner}) - if err != nil { - return nil, nil, err - } _, ok := keyIDs[ainfo.Owner] if ok { return nil, nil, fmt.Errorf("rootkey account has already been declared, cannot be assigned 80: %s", ainfo.Owner) } - err = state.SetActor(builtin.RootVerifierAddress, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: template.VerifregRootKey.Balance, - Head: st, - }) + vact, err := makeAccountActor(ctx, cst, av, ainfo.Owner, template.VerifregRootKey.Balance) if err != nil { - return nil, nil, xerrors.Errorf("setting verifreg rootkey account: %w", err) + return nil, nil, xerrors.Errorf("setup verifreg rootkey account state: %w", err) + } + if err = state.SetActor(builtin.RootVerifierAddress, vact); err != nil { + return nil, nil, xerrors.Errorf("set verifreg rootkey account actor: %w", err) } case genesis.TMultisig: - if err = createMultisigAccount(ctx, bs, cst, state, builtin.RootVerifierAddress, template.VerifregRootKey, keyIDs); err != nil { + if err = createMultisigAccount(ctx, cst, state, builtin.RootVerifierAddress, template.VerifregRootKey, keyIDs, av); err != nil { return nil, nil, xerrors.Errorf("failed to set up verified registry signer: %w", err) } default: @@ -288,18 +302,13 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return nil, nil, err } - verifierState, err := cst.Put(ctx, &account0.State{Address: verifierAd}) + verifierAct, err := makeAccountActor(ctx, cst, av, verifierAd, big.Zero()) if err != nil { - return nil, nil, err + return nil, nil, xerrors.Errorf("setup first verifier state: %w", err) } - err = state.SetActor(verifierId, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: types.NewInt(0), - Head: verifierState, - }) - if err != nil { - return nil, nil, xerrors.Errorf("setting account from actmap: %w", err) + if err = state.SetActor(verifierId, verifierAct); err != nil { + return nil, nil, xerrors.Errorf("set first verifier actor: %w", err) } totalFilAllocated := big.Zero() @@ -337,13 +346,13 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge } keyIDs[ainfo.Owner] = builtin.ReserveAddress - err = createAccountActor(ctx, cst, state, template.RemainderAccount, keyIDs) + err = createAccountActor(ctx, cst, state, template.RemainderAccount, keyIDs, av) if err != nil { return nil, nil, xerrors.Errorf("creating remainder acct: %w", err) } case genesis.TMultisig: - if err = createMultisigAccount(ctx, bs, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs); err != nil { + if err = createMultisigAccount(ctx, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs, av); err != nil { return nil, nil, xerrors.Errorf("failed to set up remainder: %w", err) } default: @@ -353,12 +362,38 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return state, keyIDs, nil } -func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.StateTree, info genesis.Actor, keyIDs map[address.Address]address.Address) error { +func makeAccountActor(ctx context.Context, cst cbor.IpldStore, av actors.Version, addr address.Address, bal types.BigInt) (*types.Actor, error) { + ast, err := account.MakeState(adt.WrapStore(ctx, cst), av, addr) + if err != nil { + return nil, err + } + + statecid, err := cst.Put(ctx, ast.GetState()) + if err != nil { + return nil, err + } + + actcid, err := account.GetActorCodeID(av) + if err != nil { + return nil, err + } + + act := &types.Actor{ + Code: actcid, + Head: statecid, + Balance: bal, + } + + return act, nil +} + +func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.StateTree, info genesis.Actor, keyIDs map[address.Address]address.Address, av actors.Version) error { var ainfo genesis.AccountMeta if err := json.Unmarshal(info.Meta, &ainfo); err != nil { return xerrors.Errorf("unmarshaling account meta: %w", err) } - st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner}) + + aa, err := makeAccountActor(ctx, cst, av, ainfo.Owner, info.Balance) if err != nil { return err } @@ -368,18 +403,14 @@ func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.St return fmt.Errorf("no registered ID for account actor: %s", ainfo.Owner) } - err = state.SetActor(ida, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: info.Balance, - Head: st, - }) + err = state.SetActor(ida, aa) if err != nil { return xerrors.Errorf("setting account from actmap: %w", err) } return nil } -func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.IpldStore, state *state.StateTree, ida address.Address, info genesis.Actor, keyIDs map[address.Address]address.Address) error { +func createMultisigAccount(ctx context.Context, cst cbor.IpldStore, state *state.StateTree, ida address.Address, info genesis.Actor, keyIDs map[address.Address]address.Address, av actors.Version) error { if info.Type != genesis.TMultisig { return fmt.Errorf("can only call createMultisigAccount with multisig Actor info") } @@ -387,10 +418,6 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I if err := json.Unmarshal(info.Meta, &ainfo); err != nil { return xerrors.Errorf("unmarshaling account meta: %w", err) } - pending, err := adt0.MakeEmptyMap(adt0.WrapStore(ctx, cst)).Root() - if err != nil { - return xerrors.Errorf("failed to create empty map: %v", err) - } var signers []address.Address @@ -407,44 +434,45 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I continue } - st, err := cst.Put(ctx, &account0.State{Address: e}) + aa, err := makeAccountActor(ctx, cst, av, e, big.Zero()) if err != nil { return err } - err = state.SetActor(idAddress, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: types.NewInt(0), - Head: st, - }) - if err != nil { + + if err = state.SetActor(idAddress, aa); err != nil { return xerrors.Errorf("setting account from actmap: %w", err) } signers = append(signers, idAddress) } - st, err := cst.Put(ctx, &multisig0.State{ - Signers: signers, - NumApprovalsThreshold: uint64(ainfo.Threshold), - StartEpoch: abi.ChainEpoch(ainfo.VestingStart), - UnlockDuration: abi.ChainEpoch(ainfo.VestingDuration), - PendingTxns: pending, - InitialBalance: info.Balance, - }) + mst, err := multisig.MakeState(adt.WrapStore(ctx, cst), av, signers, uint64(ainfo.Threshold), abi.ChainEpoch(ainfo.VestingStart), abi.ChainEpoch(ainfo.VestingDuration), info.Balance) if err != nil { return err } + + statecid, err := cst.Put(ctx, mst.GetState()) + if err != nil { + return err + } + + actcid, err := multisig.GetActorCodeID(av) + if err != nil { + return err + } + err = state.SetActor(ida, &types.Actor{ - Code: builtin0.MultisigActorCodeID, + Code: actcid, Balance: info.Balance, - Head: st, + Head: statecid, }) if err != nil { return xerrors.Errorf("setting account from actmap: %w", err) } + return nil } -func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot cid.Cid, template genesis.Template, keyIDs map[address.Address]address.Address) (cid.Cid, error) { +func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot cid.Cid, template genesis.Template, keyIDs map[address.Address]address.Address, nv network.Version) (cid.Cid, error) { verifNeeds := make(map[address.Address]abi.PaddedPieceSize) var sum abi.PaddedPieceSize @@ -455,8 +483,10 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci Bstore: cs.StateBlockstore(), Syscalls: mkFakedSigSyscalls(cs.VMSys()), CircSupplyCalc: nil, - NtwkVersion: genesisNetworkVersion, - BaseFee: types.NewInt(0), + NtwkVersion: func(_ context.Context, _ abi.ChainEpoch) network.Version { + return nv + }, + BaseFee: types.NewInt(0), } vm, err := vm.NewVM(ctx, &vmopt) if err != nil { @@ -485,7 +515,8 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci return cid.Undef, err } - _, err = doExecValue(ctx, vm, builtin0.VerifiedRegistryActorAddr, verifregRoot, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg0.AddVerifierParams{ + // Note: This is brittle, if the methodNum / param changes, it could break things + _, err = doExecValue(ctx, vm, verifreg.Address, verifregRoot, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg0.AddVerifierParams{ Address: verifier, Allowance: abi.NewStoragePower(int64(sum)), // eh, close enough @@ -496,7 +527,8 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci } for c, amt := range verifNeeds { - _, err := doExecValue(ctx, vm, builtin0.VerifiedRegistryActorAddr, verifier, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifiedClient, mustEnc(&verifreg0.AddVerifiedClientParams{ + // Note: This is brittle, if the methodNum / param changes, it could break things + _, err := doExecValue(ctx, vm, verifreg.Address, verifier, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifiedClient, mustEnc(&verifreg0.AddVerifiedClientParams{ Address: c, Allowance: abi.NewStoragePower(int64(amt)), })) @@ -531,17 +563,17 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto cs := store.NewChainStore(bs, bs, datastore.NewMapDatastore(), sys, j) // Verify PreSealed Data - stateroot, err = VerifyPreSealedData(ctx, cs, stateroot, template, keyIDs) + stateroot, err = VerifyPreSealedData(ctx, cs, stateroot, template, keyIDs, template.NetworkVersion) if err != nil { return nil, xerrors.Errorf("failed to verify presealed data: %w", err) } - stateroot, err = SetupStorageMiners(ctx, cs, stateroot, template.Miners) + stateroot, err = SetupStorageMiners(ctx, cs, stateroot, template.Miners, template.NetworkVersion) if err != nil { return nil, xerrors.Errorf("setup miners failed: %w", err) } - store := adt0.WrapStore(ctx, cbor.NewCborStore(bs)) + store := adt.WrapStore(ctx, cbor.NewCborStore(bs)) emptyroot, err := adt0.MakeEmptyArray(store).Root() if err != nil { return nil, xerrors.Errorf("amt build failed: %w", err) @@ -590,7 +622,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto } b := &types.BlockHeader{ - Miner: builtin0.SystemActorAddr, + Miner: system.Address, Ticket: genesisticket, Parents: []cid.Cid{filecoinGenesisCid}, Height: 0, diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index 297543886..17349b270 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -6,6 +6,22 @@ import ( "fmt" "math/rand" + power4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/power" + + reward4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/reward" + + market4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/market" + + "github.com/filecoin-project/lotus/chain/actors" + + "github.com/filecoin-project/lotus/chain/actors/builtin" + + "github.com/filecoin-project/lotus/chain/actors/policy" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + "github.com/filecoin-project/go-state-types/network" + market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/power" @@ -61,7 +77,12 @@ func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder { } } -func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner) (cid.Cid, error) { +// Note: Much of this is brittle, if the methodNum / param / return changes, it will break things +func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner, nv network.Version) (cid.Cid, error) { + + cst := cbor.NewCborStore(cs.StateBlockstore()) + av := actors.VersionForNetwork(nv) + csc := func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) { return big.Zero(), nil } @@ -73,8 +94,10 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid Bstore: cs.StateBlockstore(), Syscalls: mkFakedSigSyscalls(cs.VMSys()), CircSupplyCalc: csc, - NtwkVersion: genesisNetworkVersion, - BaseFee: types.NewInt(0), + NtwkVersion: func(_ context.Context, _ abi.ChainEpoch) network.Version { + return nv + }, + BaseFee: types.NewInt(0), } vm, err := vm.NewVM(ctx, vmopt) @@ -94,12 +117,13 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid dealIDs []abi.DealID }, len(miners)) + maxPeriods := policy.GetMaxSectorExpirationExtension() / miner.WPoStProvingPeriod for i, m := range miners { // Create miner through power actor i := i m := m - spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, GenesisNetworkVersion) + spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, nv) if err != nil { return cid.Undef, err } @@ -113,7 +137,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid } params := mustEnc(constructorParams) - rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, builtin0.MethodsPower.CreateMiner, params) + rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, power.Methods.CreateMiner, params) if err != nil { return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err) } @@ -129,23 +153,34 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid } minerInfos[i].maddr = ma.IDAddress - // TODO: ActorUpgrade - err = vm.MutateState(ctx, minerInfos[i].maddr, func(cst cbor.IpldStore, st *miner0.State) error { - maxPeriods := miner0.MaxSectorExpirationExtension / miner0.WPoStProvingPeriod - minerInfos[i].presealExp = (maxPeriods-1)*miner0.WPoStProvingPeriod + st.ProvingPeriodStart - 1 - - return nil - }) + _, err = vm.Flush(ctx) if err != nil { - return cid.Undef, xerrors.Errorf("mutating state: %w", err) + return cid.Undef, xerrors.Errorf("flushing vm: %w", err) } + + mact, err := vm.StateTree().GetActor(minerInfos[i].maddr) + if err != nil { + return cid.Undef, xerrors.Errorf("getting newly created miner actor: %w", err) + } + + mst, err := miner.Load(adt.WrapStore(ctx, cst), mact) + if err != nil { + return cid.Undef, xerrors.Errorf("getting newly created miner state: %w", err) + } + + pps, err := mst.GetProvingPeriodStart() + if err != nil { + return cid.Undef, xerrors.Errorf("getting newly created miner proving period start: %w", err) + } + + minerInfos[i].presealExp = (maxPeriods-1)*miner0.WPoStProvingPeriod + pps - 1 } // Add market funds if m.MarketBalance.GreaterThan(big.Zero()) { params := mustEnc(&minerInfos[i].maddr) - _, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin0.MethodsMarket.AddBalance, params) + _, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, market.Methods.AddBalance, params) if err != nil { return cid.Undef, xerrors.Errorf("failed to create genesis miner (add balance): %w", err) } @@ -203,35 +238,66 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid for pi := range m.Sectors { rawPow = types.BigAdd(rawPow, types.NewInt(uint64(m.SectorSize))) - dweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, []abi.DealID{minerInfos[i].dealIDs[pi]}, 0, minerInfos[i].presealExp) + dweight, vdweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, []abi.DealID{minerInfos[i].dealIDs[pi]}, 0, minerInfos[i].presealExp, av) if err != nil { return cid.Undef, xerrors.Errorf("getting deal weight: %w", err) } - sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight) + sectorWeight := builtin.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight, vdweight) qaPow = types.BigAdd(qaPow, sectorWeight) } } - err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error { - st.TotalQualityAdjPower = qaPow - st.TotalRawBytePower = rawPow - - st.ThisEpochQualityAdjPower = qaPow - st.ThisEpochRawBytePower = rawPow - return nil - }) + _, err = vm.Flush(ctx) if err != nil { - return cid.Undef, xerrors.Errorf("mutating state: %w", err) + return cid.Undef, xerrors.Errorf("flushing vm: %w", err) } - err = vm.MutateState(ctx, reward.Address, func(sct cbor.IpldStore, st *reward0.State) error { - *st = *reward0.ConstructState(qaPow) - return nil - }) + pact, err := vm.StateTree().GetActor(power.Address) if err != nil { - return cid.Undef, xerrors.Errorf("mutating state: %w", err) + return cid.Undef, xerrors.Errorf("getting power actor: %w", err) + } + + pst, err := power.Load(adt.WrapStore(ctx, cst), pact) + if err != nil { + return cid.Undef, xerrors.Errorf("getting power state: %w", err) + } + + if err = pst.SetTotalQualityAdjPower(qaPow); err != nil { + return cid.Undef, xerrors.Errorf("setting TotalQualityAdjPower in power state: %w", err) + } + + if err = pst.SetTotalRawBytePower(rawPow); err != nil { + return cid.Undef, xerrors.Errorf("setting TotalRawBytePower in power state: %w", err) + } + + if err = pst.SetThisEpochQualityAdjPower(qaPow); err != nil { + return cid.Undef, xerrors.Errorf("setting ThisEpochQualityAdjPower in power state: %w", err) + } + + if err = pst.SetThisEpochRawBytePower(rawPow); err != nil { + return cid.Undef, xerrors.Errorf("setting ThisEpochRawBytePower in power state: %w", err) + } + + pcid, err := cst.Put(ctx, pst.GetState()) + if err != nil { + return cid.Undef, xerrors.Errorf("putting power state: %w", err) + } + + pact.Head = pcid + + if err = vm.StateTree().SetActor(power.Address, pact); err != nil { + return cid.Undef, xerrors.Errorf("setting power state: %w", err) + } + + rewact, err := SetupRewardActor(ctx, cs.StateBlockstore(), big.Zero(), actors.VersionForNetwork(nv)) + if err != nil { + return cid.Undef, xerrors.Errorf("setup reward actor: %w", err) + } + + if err = vm.StateTree().SetActor(reward.Address, rewact); err != nil { + return cid.Undef, xerrors.Errorf("set reward actor: %w", err) } } @@ -248,24 +314,55 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid Expiration: minerInfos[i].presealExp, // TODO: Allow setting externally! } - dweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, params.DealIDs, 0, minerInfos[i].presealExp) + dweight, vdweight, err := dealWeight(ctx, vm, minerInfos[i].maddr, params.DealIDs, 0, minerInfos[i].presealExp, av) if err != nil { return cid.Undef, xerrors.Errorf("getting deal weight: %w", err) } - sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight) + sectorWeight := builtin.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight, vdweight) // we've added fake power for this sector above, remove it now - err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error { - st.TotalQualityAdjPower = types.BigSub(st.TotalQualityAdjPower, sectorWeight) //nolint:scopelint - st.TotalRawBytePower = types.BigSub(st.TotalRawBytePower, types.NewInt(uint64(m.SectorSize))) - return nil - }) + + _, err = vm.Flush(ctx) if err != nil { - return cid.Undef, xerrors.Errorf("removing fake power: %w", err) + return cid.Undef, xerrors.Errorf("flushing vm: %w", err) } - epochReward, err := currentEpochBlockReward(ctx, vm, minerInfos[i].maddr) + pact, err := vm.StateTree().GetActor(power.Address) + if err != nil { + return cid.Undef, xerrors.Errorf("getting power actor: %w", err) + } + + pst, err := power.Load(adt.WrapStore(ctx, cst), pact) + if err != nil { + return cid.Undef, xerrors.Errorf("getting power state: %w", err) + } + + pc, err := pst.TotalPower() + if err != nil { + return cid.Undef, xerrors.Errorf("getting total power: %w", err) + } + + if err = pst.SetTotalRawBytePower(types.BigSub(pc.RawBytePower, types.NewInt(uint64(m.SectorSize)))); err != nil { + return cid.Undef, xerrors.Errorf("setting TotalRawBytePower in power state: %w", err) + } + + if err = pst.SetTotalQualityAdjPower(types.BigSub(pc.QualityAdjPower, sectorWeight)); err != nil { + return cid.Undef, xerrors.Errorf("setting TotalQualityAdjPower in power state: %w", err) + } + + pcid, err := cst.Put(ctx, pst.GetState()) + if err != nil { + return cid.Undef, xerrors.Errorf("putting power state: %w", err) + } + + pact.Head = pcid + + if err = vm.StateTree().SetActor(power.Address, pact); err != nil { + return cid.Undef, xerrors.Errorf("setting power state: %w", err) + } + + baselinePower, rewardSmoothed, err := currentEpochBlockReward(ctx, vm, minerInfos[i].maddr, av) if err != nil { return cid.Undef, xerrors.Errorf("getting current epoch reward: %w", err) } @@ -275,13 +372,13 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid return cid.Undef, xerrors.Errorf("getting current total power: %w", err) } - pcd := miner0.PreCommitDepositForPower(epochReward.ThisEpochRewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight) + pcd := miner0.PreCommitDepositForPower(&rewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight) pledge := miner0.InitialPledgeForPower( sectorWeight, - epochReward.ThisEpochBaselinePower, + baselinePower, tpow.PledgeCollateral, - epochReward.ThisEpochRewardSmoothed, + &rewardSmoothed, tpow.QualityAdjPowerSmoothed, circSupply(ctx, vm, minerInfos[i].maddr), ) @@ -289,7 +386,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid pledge = big.Add(pcd, pledge) fmt.Println(types.FIL(pledge)) - _, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, builtin0.MethodsMiner.PreCommitSector, mustEnc(params)) + _, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, miner.Methods.PreCommitSector, mustEnc(params)) if err != nil { return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) } @@ -299,28 +396,84 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid Sectors: []abi.SectorNumber{preseal.SectorID}, } - _, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin0.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams)) + _, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), miner.Methods.ConfirmSectorProofsValid, mustEnc(confirmParams)) if err != nil { return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) } + + if av > actors.Version2 { + // post v2, we need to explicitly Claim this power since ConfirmSectorProofsValid doesn't do it anymore + claimParams := &power4.UpdateClaimedPowerParams{ + RawByteDelta: types.NewInt(uint64(m.SectorSize)), + QualityAdjustedDelta: sectorWeight, + } + + _, err = doExecValue(ctx, vm, power.Address, minerInfos[i].maddr, big.Zero(), power.Methods.UpdateClaimedPower, mustEnc(claimParams)) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) + } + + _, err = vm.Flush(ctx) + if err != nil { + return cid.Undef, xerrors.Errorf("flushing vm: %w", err) + } + + mact, err := vm.StateTree().GetActor(minerInfos[i].maddr) + if err != nil { + return cid.Undef, xerrors.Errorf("getting miner actor: %w", err) + } + + mst, err := miner.Load(adt.WrapStore(ctx, cst), mact) + if err != nil { + return cid.Undef, xerrors.Errorf("getting miner state: %w", err) + } + + if err = mst.EraseAllUnproven(); err != nil { + return cid.Undef, xerrors.Errorf("failed to erase unproven sectors: %w", err) + } + + mcid, err := cst.Put(ctx, mst.GetState()) + if err != nil { + return cid.Undef, xerrors.Errorf("putting miner state: %w", err) + } + + mact.Head = mcid + + if err = vm.StateTree().SetActor(minerInfos[i].maddr, mact); err != nil { + return cid.Undef, xerrors.Errorf("setting miner state: %w", err) + } + } } } } // Sanity-check total network power - err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error { - if !st.TotalRawBytePower.Equals(rawPow) { - return xerrors.Errorf("st.TotalRawBytePower doesn't match previously calculated rawPow") - } - - if !st.TotalQualityAdjPower.Equals(qaPow) { - return xerrors.Errorf("st.TotalQualityAdjPower doesn't match previously calculated qaPow") - } - - return nil - }) + _, err = vm.Flush(ctx) if err != nil { - return cid.Undef, xerrors.Errorf("mutating state: %w", err) + return cid.Undef, xerrors.Errorf("flushing vm: %w", err) + } + + pact, err := vm.StateTree().GetActor(power.Address) + if err != nil { + return cid.Undef, xerrors.Errorf("getting power actor: %w", err) + } + + pst, err := power.Load(adt.WrapStore(ctx, cst), pact) + if err != nil { + return cid.Undef, xerrors.Errorf("getting power state: %w", err) + } + + pc, err := pst.TotalPower() + if err != nil { + return cid.Undef, xerrors.Errorf("getting total power: %w", err) + } + + if !pc.RawBytePower.Equals(rawPow) { + return cid.Undef, xerrors.Errorf("TotalRawBytePower (%s) doesn't match previously calculated rawPow (%s)", pc.RawBytePower, rawPow) + } + + if !pc.QualityAdjPower.Equals(qaPow) { + return cid.Undef, xerrors.Errorf("QualityAdjPower (%s) doesn't match previously calculated qaPow (%s)", pc.QualityAdjPower, qaPow) } // TODO: Should we re-ConstructState for the reward actor using rawPow as currRealizedPower here? @@ -360,43 +513,79 @@ func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (* return &pwr, nil } -func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch) (market0.VerifyDealsForActivationReturn, error) { - params := &market.VerifyDealsForActivationParams{ - DealIDs: dealIDs, - SectorStart: sectorStart, - SectorExpiry: sectorExpiry, - } +func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch, av actors.Version) (abi.DealWeight, abi.DealWeight, error) { + // TODO: This hack should move to market actor wrapper + if av <= actors.Version2 { + params := &market0.VerifyDealsForActivationParams{ + DealIDs: dealIDs, + SectorStart: sectorStart, + SectorExpiry: sectorExpiry, + } - var dealWeights market0.VerifyDealsForActivationReturn + var dealWeights market0.VerifyDealsForActivationReturn + ret, err := doExecValue(ctx, vm, + market.Address, + maddr, + abi.NewTokenAmount(0), + builtin0.MethodsMarket.VerifyDealsForActivation, + mustEnc(params), + ) + if err != nil { + return big.Zero(), big.Zero(), err + } + if err := dealWeights.UnmarshalCBOR(bytes.NewReader(ret)); err != nil { + return big.Zero(), big.Zero(), err + } + + return dealWeights.DealWeight, dealWeights.VerifiedDealWeight, nil + } + params := &market4.VerifyDealsForActivationParams{Sectors: []market4.SectorDeals{{ + SectorExpiry: sectorExpiry, + DealIDs: dealIDs, + }}} + + var dealWeights market4.VerifyDealsForActivationReturn ret, err := doExecValue(ctx, vm, market.Address, maddr, abi.NewTokenAmount(0), - builtin0.MethodsMarket.VerifyDealsForActivation, + market.Methods.VerifyDealsForActivation, mustEnc(params), ) if err != nil { - return market0.VerifyDealsForActivationReturn{}, err + return big.Zero(), big.Zero(), err } if err := dealWeights.UnmarshalCBOR(bytes.NewReader(ret)); err != nil { - return market0.VerifyDealsForActivationReturn{}, err + return big.Zero(), big.Zero(), err } - return dealWeights, nil + return dealWeights.Sectors[0].DealWeight, dealWeights.Sectors[0].VerifiedDealWeight, nil } -func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward0.ThisEpochRewardReturn, error) { - rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin0.MethodsReward.ThisEpochReward, nil) +func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address, av actors.Version) (abi.StoragePower, builtin.FilterEstimate, error) { + rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), reward.Methods.ThisEpochReward, nil) if err != nil { - return nil, err + return big.Zero(), builtin.FilterEstimate{}, err } - var epochReward reward0.ThisEpochRewardReturn + // TODO: This hack should move to reward actor wrapper + if av <= actors.Version2 { + var epochReward reward0.ThisEpochRewardReturn + + if err := epochReward.UnmarshalCBOR(bytes.NewReader(rwret)); err != nil { + return big.Zero(), builtin.FilterEstimate{}, err + } + + return epochReward.ThisEpochBaselinePower, *epochReward.ThisEpochRewardSmoothed, nil + } + + var epochReward reward4.ThisEpochRewardReturn + if err := epochReward.UnmarshalCBOR(bytes.NewReader(rwret)); err != nil { - return nil, err + return big.Zero(), builtin.FilterEstimate{}, err } - return &epochReward, nil + return epochReward.ThisEpochBaselinePower, builtin.FilterEstimate(epochReward.ThisEpochRewardSmoothed), nil } func circSupply(ctx context.Context, vmi *vm.VM, maddr address.Address) abi.TokenAmount { diff --git a/chain/gen/genesis/util.go b/chain/gen/genesis/util.go index 54cc30cc1..67a4e9579 100644 --- a/chain/gen/genesis/util.go +++ b/chain/gen/genesis/util.go @@ -3,9 +3,6 @@ package genesis import ( "context" - "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" cbg "github.com/whyrusleeping/cbor-gen" @@ -49,29 +46,3 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value return ret.Return, nil } - -// TODO: Get from build -// TODO: make a list/schedule of these. -var GenesisNetworkVersion = func() network.Version { - // returns the version _before_ the first upgrade. - if build.UpgradeBreezeHeight >= 0 { - return network.Version0 - } - if build.UpgradeSmokeHeight >= 0 { - return network.Version1 - } - if build.UpgradeIgnitionHeight >= 0 { - return network.Version2 - } - if build.UpgradeActorsV2Height >= 0 { - return network.Version3 - } - if build.UpgradeLiftoffHeight >= 0 { - return network.Version3 - } - return build.ActorUpgradeNetworkVersion - 1 // genesis requires actors v0. -}() - -func genesisNetworkVersion(context.Context, abi.ChainEpoch) network.Version { // TODO: Get from build/ - return GenesisNetworkVersion // TODO: Get from build/ -} // TODO: Get from build/ diff --git a/chain/state/statetree.go b/chain/state/statetree.go index 2a7b436b8..a31ec2396 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -14,7 +14,6 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/chain/actors" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" cbg "github.com/whyrusleeping/cbor-gen" @@ -142,11 +141,19 @@ func (ss *stateSnaps) deleteActor(addr address.Address) { // VersionForNetwork returns the state tree version for the given network // version. -func VersionForNetwork(ver network.Version) types.StateTreeVersion { - if actors.VersionForNetwork(ver) == actors.Version0 { - return types.StateTreeVersion0 +func VersionForNetwork(ver network.Version) (types.StateTreeVersion, error) { + switch ver { + case network.Version0, network.Version1, network.Version2, network.Version3: + return types.StateTreeVersion0, nil + case network.Version4, network.Version5, network.Version6, network.Version7, network.Version8, network.Version9: + return types.StateTreeVersion1, nil + case network.Version10, network.Version11: + return types.StateTreeVersion2, nil + case network.Version12: + return types.StateTreeVersion3, nil + default: + panic(fmt.Sprintf("unsupported network version %d", ver)) } - return types.StateTreeVersion1 } func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, error) { diff --git a/chain/state/statetree_test.go b/chain/state/statetree_test.go index 91674337b..9177af312 100644 --- a/chain/state/statetree_test.go +++ b/chain/state/statetree_test.go @@ -5,11 +5,12 @@ import ( "fmt" "testing" + "github.com/filecoin-project/go-state-types/network" + "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" address "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-state-types/network" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/build" @@ -45,7 +46,12 @@ func BenchmarkStateTreeSet(b *testing.B) { func BenchmarkStateTreeSetFlush(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + sv, err := VersionForNetwork(build.NewestNetworkVersion) + if err != nil { + b.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { b.Fatal(err) } @@ -75,7 +81,12 @@ func BenchmarkStateTreeSetFlush(b *testing.B) { func TestResolveCache(t *testing.T) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + sv, err := VersionForNetwork(build.NewestNetworkVersion) + if err != nil { + t.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { t.Fatal(err) } @@ -172,7 +183,12 @@ func TestResolveCache(t *testing.T) { func BenchmarkStateTree10kGetActor(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + sv, err := VersionForNetwork(build.NewestNetworkVersion) + if err != nil { + b.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { b.Fatal(err) } @@ -214,7 +230,12 @@ func BenchmarkStateTree10kGetActor(b *testing.B) { func TestSetCache(t *testing.T) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + sv, err := VersionForNetwork(build.NewestNetworkVersion) + if err != nil { + t.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { t.Fatal(err) } @@ -251,7 +272,13 @@ func TestSetCache(t *testing.T) { func TestSnapshots(t *testing.T) { ctx := context.Background() cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + + sv, err := VersionForNetwork(build.NewestNetworkVersion) + if err != nil { + t.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { t.Fatal(err) } @@ -334,8 +361,15 @@ func assertNotHas(t *testing.T, st *StateTree, addr address.Address) { func TestStateTreeConsistency(t *testing.T) { cst := cbor.NewMemCborStore() + // TODO: ActorUpgrade: this test tests pre actors v2 - st, err := NewStateTree(cst, VersionForNetwork(network.Version3)) + + sv, err := VersionForNetwork(network.Version3) + if err != nil { + t.Fatal(err) + } + + st, err := NewStateTree(cst, sv) if err != nil { t.Fatal(err) } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index afc74e744..f488c7864 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "fmt" - "reflect" "sync/atomic" "time" @@ -203,7 +202,8 @@ type ( ) type VM struct { - cstate *state.StateTree + cstate *state.StateTree + // TODO: Is base actually used? Can we delete it? base cid.Cid cst *cbor.BasicIpldStore buf *blockstore.BufferedBlockstore @@ -662,37 +662,6 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) { return root, nil } -// MutateState usage: MutateState(ctx, idAddr, func(cst cbor.IpldStore, st *ActorStateType) error {...}) -func (vm *VM) MutateState(ctx context.Context, addr address.Address, fn interface{}) error { - act, err := vm.cstate.GetActor(addr) - if err != nil { - return xerrors.Errorf("actor not found: %w", err) - } - - st := reflect.New(reflect.TypeOf(fn).In(1).Elem()) - if err := vm.cst.Get(ctx, act.Head, st.Interface()); err != nil { - return xerrors.Errorf("read actor head: %w", err) - } - - out := reflect.ValueOf(fn).Call([]reflect.Value{reflect.ValueOf(vm.cst), st}) - if !out[0].IsNil() && out[0].Interface().(error) != nil { - return out[0].Interface().(error) - } - - head, err := vm.cst.Put(ctx, st.Interface()) - if err != nil { - return xerrors.Errorf("put new actor head: %w", err) - } - - act.Head = head - - if err := vm.cstate.SetActor(addr, act); err != nil { - return xerrors.Errorf("set actor: %w", err) - } - - return nil -} - func linksForObj(blk block.Block, cb func(cid.Cid)) error { switch blk.Cid().Prefix().Codec { case cid.DagCBOR: diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go index d5f1d5ad6..87493c58a 100644 --- a/cmd/lotus-seed/genesis.go +++ b/cmd/lotus-seed/genesis.go @@ -9,6 +9,8 @@ import ( "strconv" "strings" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" @@ -39,6 +41,7 @@ var genesisCmd = &cli.Command{ genesisAddMsigsCmd, genesisSetVRKCmd, genesisSetRemainderCmd, + genesisSetActorVersionCmd, genesisCarCmd, }, } @@ -56,6 +59,7 @@ var genesisNewCmd = &cli.Command{ return xerrors.New("seed genesis new [genesis.json]") } out := genesis.Template{ + NetworkVersion: network.Version0, Accounts: []genesis.Actor{}, Miners: []genesis.Miner{}, VerifregRootKey: gen.DefaultVerifregRootkeyActor, @@ -503,6 +507,53 @@ var genesisSetRemainderCmd = &cli.Command{ }, } +var genesisSetActorVersionCmd = &cli.Command{ + Name: "set-network-version", + Usage: "Set the version that this network will start from", + ArgsUsage: " ", + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() != 2 { + return fmt.Errorf("must specify genesis file and network version (e.g. '0'") + } + + genf, err := homedir.Expand(cctx.Args().First()) + if err != nil { + return err + } + + var template genesis.Template + b, err := ioutil.ReadFile(genf) + if err != nil { + return xerrors.Errorf("read genesis template: %w", err) + } + + if err := json.Unmarshal(b, &template); err != nil { + return xerrors.Errorf("unmarshal genesis template: %w", err) + } + + nv, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64) + if err != nil { + return xerrors.Errorf("parsing network version: %w", err) + } + + if nv > uint64(build.NewestNetworkVersion) { + return xerrors.Errorf("invalid network version: %d", nv) + } + + template.NetworkVersion = network.Version(nv) + + b, err = json.MarshalIndent(&template, "", " ") + if err != nil { + return err + } + + if err := ioutil.WriteFile(genf, b, 0644); err != nil { + return err + } + return nil + }, +} + var genesisCarCmd = &cli.Command{ Name: "car", Description: "write genesis car file", diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index c4e62b419..c92397125 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -94,6 +94,11 @@ var preSealCmd = &cli.Command{ Name: "fake-sectors", Value: false, }, + &cli.IntFlag{ + Name: "network-version", + Value: 0, + Usage: "specify network version", + }, }, Action: func(c *cli.Context) error { sdir := c.String("sector-dir") @@ -129,7 +134,7 @@ var preSealCmd = &cli.Command{ } sectorSize := abi.SectorSize(sectorSizeInt) - spt, err := miner.SealProofTypeFromSectorSize(sectorSize, network.Version0) + spt, err := miner.SealProofTypeFromSectorSize(sectorSize, network.Version(c.Uint64("network-version"))) if err != nil { return err } diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index 0372c0dab..a8b760f8a 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -4551,7 +4551,7 @@ Inputs: ] ``` -Response: `11` +Response: `12` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index bf282745a..be326b3e8 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -4772,7 +4772,7 @@ Inputs: ] ``` -Response: `11` +Response: `12` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/genesis/types.go b/genesis/types.go index db8d32a3b..d4c04113a 100644 --- a/genesis/types.go +++ b/genesis/types.go @@ -3,6 +3,8 @@ package genesis import ( "encoding/json" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" @@ -75,8 +77,9 @@ type Actor struct { } type Template struct { - Accounts []Actor - Miners []Miner + NetworkVersion network.Version + Accounts []Actor + Miners []Miner NetworkName string Timestamp uint64 `json:",omitempty"` diff --git a/node/test/builder.go b/node/test/builder.go index 7e26966a8..bd180ee41 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -12,6 +12,8 @@ import ( "testing" "time" + "github.com/filecoin-project/go-state-types/network" + "github.com/gorilla/mux" "golang.org/x/xerrors" @@ -277,6 +279,7 @@ func mockBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []test. genms = append(genms, *genm) } templ := &genesis.Template{ + NetworkVersion: network.Version0, Accounts: genaccs, Miners: genms, NetworkName: "test", @@ -440,6 +443,7 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes genms = append(genms, *genm) } templ := &genesis.Template{ + NetworkVersion: network.Version0, Accounts: genaccs, Miners: genms, NetworkName: "test", From 1ad2c4dab0be604c42f0744f04c986c0ed831cf1 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Wed, 26 May 2021 12:40:13 -0400 Subject: [PATCH 76/80] Make devnets work again --- cmd/lotus-seed/genesis.go | 2 +- cmd/lotus-seed/main.go | 8 ++++++-- lotuspond/spawn.go | 11 ++++++++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go index 87493c58a..66de93888 100644 --- a/cmd/lotus-seed/genesis.go +++ b/cmd/lotus-seed/genesis.go @@ -59,7 +59,7 @@ var genesisNewCmd = &cli.Command{ return xerrors.New("seed genesis new [genesis.json]") } out := genesis.Template{ - NetworkVersion: network.Version0, + NetworkVersion: build.NewestNetworkVersion, Accounts: []genesis.Actor{}, Miners: []genesis.Miner{}, VerifregRootKey: gen.DefaultVerifregRootkeyActor, diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index c92397125..42f4b74e4 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -96,7 +96,6 @@ var preSealCmd = &cli.Command{ }, &cli.IntFlag{ Name: "network-version", - Value: 0, Usage: "specify network version", }, }, @@ -134,7 +133,12 @@ var preSealCmd = &cli.Command{ } sectorSize := abi.SectorSize(sectorSizeInt) - spt, err := miner.SealProofTypeFromSectorSize(sectorSize, network.Version(c.Uint64("network-version"))) + nv := build.NewestNetworkVersion + if c.IsSet("network-version") { + nv = network.Version(c.Uint64("network-version")) + } + + spt, err := miner.SealProofTypeFromSectorSize(sectorSize, nv) if err != nil { return err } diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index 9085bc24a..900c372b1 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -11,6 +11,9 @@ import ( "sync/atomic" "time" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/google/uuid" "golang.org/x/xerrors" @@ -48,7 +51,12 @@ func (api *api) Spawn() (nodeInfo, error) { } sbroot := filepath.Join(dir, "preseal") - genm, ki, err := seed.PreSeal(genMiner, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, 2, sbroot, []byte("8"), nil, false) + spt, err := miner.SealProofTypeFromSectorSize(2<<10, build.NewestNetworkVersion) + if err != nil { + return nodeInfo{}, err + } + + genm, ki, err := seed.PreSeal(genMiner, spt, 0, 2, sbroot, []byte("8"), nil, false) if err != nil { return nodeInfo{}, xerrors.Errorf("preseal failed: %w", err) } @@ -71,6 +79,7 @@ func (api *api) Spawn() (nodeInfo, error) { template.VerifregRootKey = gen.DefaultVerifregRootkeyActor template.RemainderAccount = gen.DefaultRemainderAccountActor template.NetworkName = "pond-" + uuid.New().String() + template.NetworkVersion = build.NewestNetworkVersion tb, err := json.Marshal(&template) if err != nil { From e24f24bc71d20f80520d73b05e126a8de89cfb77 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Wed, 26 May 2021 10:45:04 -0700 Subject: [PATCH 77/80] Remove log line when tracing is not configured --- lib/tracing/setup.go | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/tracing/setup.go b/lib/tracing/setup.go index 1ace962e5..b8c0399ad 100644 --- a/lib/tracing/setup.go +++ b/lib/tracing/setup.go @@ -56,7 +56,6 @@ func jaegerOptsFromEnv(opts *jaeger.Options) bool { log.Infof("jaeger traces will be sent to agent %s", opts.AgentEndpoint) return true } - log.Infof("jaeger tracing is not configured.") return false } From d9e86afa24c558ebb78160f2615b5555da361b1d Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Wed, 26 May 2021 21:46:37 -0400 Subject: [PATCH 78/80] Tweak client calcDealExpiration to consider genesis miners --- node/impl/client/client.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index fa87446c9..370cde5da 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -96,7 +96,13 @@ func calcDealExpiration(minDuration uint64, md *dline.Info, startEpoch abi.Chain minExp := startEpoch + abi.ChainEpoch(minDuration) // Align on miners ProvingPeriodBoundary - return minExp + md.WPoStProvingPeriod - (minExp % md.WPoStProvingPeriod) + (md.PeriodStart % md.WPoStProvingPeriod) - 1 + exp := minExp + md.WPoStProvingPeriod - (minExp % md.WPoStProvingPeriod) + (md.PeriodStart % md.WPoStProvingPeriod) - 1 + // Should only be possible for miners created around genesis + for exp < minExp { + exp += md.WPoStProvingPeriod + } + + return exp } func (a *API) imgr() *importmgr.Mgr { From d04e7d98ceb0988a1c8171efccdfbd8cd673c6da Mon Sep 17 00:00:00 2001 From: yaohcn Date: Thu, 27 May 2021 11:53:33 +0800 Subject: [PATCH 79/80] Get current seal proof when necessary --- extern/storage-sealing/fsm.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/extern/storage-sealing/fsm.go b/extern/storage-sealing/fsm.go index d14d363e5..8726fe2f8 100644 --- a/extern/storage-sealing/fsm.go +++ b/extern/storage-sealing/fsm.go @@ -410,15 +410,16 @@ func (m *Sealing) onUpdateSector(ctx context.Context, state *SectorInfo) error { if err != nil { return xerrors.Errorf("getting config: %w", err) } - sp, err := m.currentSealProof(ctx) - if err != nil { - return xerrors.Errorf("getting seal proof type: %w", err) - } shouldUpdateInput := m.stats.updateSector(cfg, m.minerSectorID(state.SectorNumber), state.State) // trigger more input processing when we've dipped below max sealing limits if shouldUpdateInput { + sp, err := m.currentSealProof(ctx) + if err != nil { + return xerrors.Errorf("getting seal proof type: %w", err) + } + go func() { m.inputLk.Lock() defer m.inputLk.Unlock() From 3ea39f76e1b7aacf23da103290bce689d8359f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 30 May 2021 17:20:14 +0200 Subject: [PATCH 80/80] events: Fix handling of multiple matched events per epoch --- chain/events/events_called.go | 12 ++++--- chain/events/events_test.go | 59 +++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/chain/events/events_called.go b/chain/events/events_called.go index 1a619c195..2fe6853eb 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -144,8 +144,10 @@ func (e *hcEvents) processHeadChangeEvent(rev, app []*types.TipSet) error { // Queue up calls until there have been enough blocks to reach // confidence on the message calls - for tid, data := range newCalls { - e.queueForConfidence(tid, data, nil, ts) + for tid, calls := range newCalls { + for _, data := range calls { + e.queueForConfidence(tid, data, nil, ts) + } } for at := e.lastTs.Height(); at <= ts.Height(); at++ { @@ -474,7 +476,7 @@ func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs EventAPI) mes } // Check if there are any new actor calls -func (me *messageEvents) checkNewCalls(ts *types.TipSet) (map[triggerID]eventData, error) { +func (me *messageEvents) checkNewCalls(ts *types.TipSet) (map[triggerID][]eventData, error) { pts, err := me.cs.ChainGetTipSet(me.ctx, ts.Parents()) // we actually care about messages in the parent tipset here if err != nil { log.Errorf("getting parent tipset in checkNewCalls: %s", err) @@ -485,7 +487,7 @@ func (me *messageEvents) checkNewCalls(ts *types.TipSet) (map[triggerID]eventDat defer me.lk.RUnlock() // For each message in the tipset - res := make(map[triggerID]eventData) + res := make(map[triggerID][]eventData) me.messagesForTs(pts, func(msg *types.Message) { // TODO: provide receipts @@ -500,7 +502,7 @@ func (me *messageEvents) checkNewCalls(ts *types.TipSet) (map[triggerID]eventDat // If there was a match, include the message in the results for the // trigger if matched { - res[tid] = msg + res[tid] = append(res[tid], msg) } } }) diff --git a/chain/events/events_test.go b/chain/events/events_test.go index 0aab626dd..e18d5ba7c 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -1323,3 +1323,62 @@ func TestStateChangedTimeout(t *testing.T) { fcs.advance(0, 5, nil) require.False(t, called) } + +func TestCalledMultiplePerEpoch(t *testing.T) { + fcs := &fakeCS{ + t: t, + h: 1, + + msgs: map[cid.Cid]fakeMsg{}, + blkMsgs: map[cid.Cid]cid.Cid{}, + tsc: newTSCache(2*build.ForkLengthThreshold, nil), + } + require.NoError(t, fcs.tsc.add(fcs.makeTs(t, nil, 1, dummyCid))) + + events := NewEvents(context.Background(), fcs) + + t0123, err := address.NewFromString("t0123") + require.NoError(t, err) + + at := 0 + + err = events.Called(func(ts *types.TipSet) (d bool, m bool, e error) { + return false, true, nil + }, func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (bool, error) { + switch at { + case 0: + require.Equal(t, uint64(1), msg.Nonce) + require.Equal(t, abi.ChainEpoch(4), ts.Height()) + case 1: + require.Equal(t, uint64(2), msg.Nonce) + require.Equal(t, abi.ChainEpoch(4), ts.Height()) + default: + t.Fatal("apply should only get called twice, at: ", at) + } + at++ + return true, nil + }, func(_ context.Context, ts *types.TipSet) error { + switch at { + case 2: + require.Equal(t, abi.ChainEpoch(4), ts.Height()) + case 3: + require.Equal(t, abi.ChainEpoch(4), ts.Height()) + default: + t.Fatal("revert should only get called twice, at: ", at) + } + at++ + return nil + }, 3, 20, matchAddrMethod(t0123, 5)) + require.NoError(t, err) + + fcs.advance(0, 10, map[int]cid.Cid{ + 1: fcs.fakeMsgs(fakeMsg{ + bmsgs: []*types.Message{ + {To: t0123, From: t0123, Method: 5, Nonce: 1}, + {To: t0123, From: t0123, Method: 5, Nonce: 2}, + }, + }), + }) + + fcs.advance(9, 1, nil) +}