diff --git a/.circleci/config.yml b/.circleci/config.yml index acd447f69..f82008e9b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -188,6 +188,14 @@ jobs: command: | bash <(curl -s https://codecov.io/bash) + test-chain: + <<: *test + test-node: + <<: *test + test-storage: + <<: *test + test-cli: + <<: *test test-short: <<: *test test-window-post: @@ -428,6 +436,22 @@ workflows: - test: codecov-upload: true test-suite-name: full + - test-chain: + codecov-upload: true + test-suite-name: chain + packages: "./chain/..." + - test-node: + codecov-upload: true + test-suite-name: node + packages: "./node/..." + - test-storage: + codecov-upload: true + test-suite-name: storage + packages: "./storage/... ./extern/..." + - test-cli: + codecov-upload: true + test-suite-name: cli + packages: "./cli/... ./cmd/... ./api/..." - test-window-post: go-test-flags: "-run=TestWindowedPost" winpost-test: "1" diff --git a/CHANGELOG.md b/CHANGELOG.md index 701f221b0..c21ffb685 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,49 @@ # Lotus changelog +# 1.1.0 / 2020-10-20 + +This is a mandatory release that introduces the first post-liftoff upgrade to the Filecoin network. The changes that break consensus are an upgrade to specs-actors v2.2.0 at epoch 170000. + +## Changes + +- Introduce Network version 6 (https://github.com/filecoin-project/lotus/pull/4506) +- Update markets v1.0.0 (https://github.com/filecoin-project/lotus/pull/4505) +- Add some extra logging to try and debug sync issues (https://github.com/filecoin-project/lotus/pull/4486) +- Circle: Run tests for some subsystems separately (https://github.com/filecoin-project/lotus/pull/4496) +- Add a terminate sectors command to lotus-shed (https://github.com/filecoin-project/lotus/pull/4507) +- Add a comment to BlockMessages to address #4446 (https://github.com/filecoin-project/lotus/pull/4491) + +# 1.0.0 / 2020-10-19 + +It's 1.0.0! This is an optional release of Lotus that introduces some UX improvements to the 0.10 series. + +This very small release is largely cosmetic, and intended to flag the code that the Filecoin mainnet was launched with. + +## API changes + +- `StateMsgGasCost` has been removed. The equivalent information can be gained by calling `StateReplay`. +- A `GasCost` field has been added to the `InvocResult` type, meaning detailed gas costs will be returned when calling `StateReplay`, `StateCompute`, and `StateCall`. +- The behaviour of `StateReplay` in response to an empty tipset key has been changed. Instead of simply using the heaviest tipset (which is almost guaranteed to be an unsuccessful replay), we search now search the chain for the tipset that included the message, and replay the message in that tipset (we fail if no such tipset is found). + +## Changes + +- Increase code coverage! (https://github.com/filecoin-project/lotus/pull/4410) +- Mpool: Don't block node startup loading messages (https://github.com/filecoin-project/lotus/pull/4411) +- Improve the UX of multisig approves (https://github.com/filecoin-project/lotus/pull/4398) +- Use build.BlockDelaySecs for deal start buffer (https://github.com/filecoin-project/lotus/pull/4415) +- Conformance: support multiple protocol versions (https://github.com/filecoin-project/lotus/pull/4393) +- Ensure msig inspect cli works with lotus-lite (https://github.com/filecoin-project/lotus/pull/4421) +- Add command to (slowly) prune lotus chain datastore (https://github.com/filecoin-project/lotus/pull/3876) +- Add WalletVerify to lotus-gateway (https://github.com/filecoin-project/lotus/pull/4373) +- Improve StateMsg APIs (https://github.com/filecoin-project/lotus/pull/4429) +- Add endpoints needed by spacegap (https://github.com/filecoin-project/lotus/pull/4426) +- Make audit balances capable of printing robust addresses (https://github.com/filecoin-project/lotus/pull/4423) +- Custom filters for retrieval deals (https://github.com/filecoin-project/lotus/pull/4424) +- Fix message list api (https://github.com/filecoin-project/lotus/pull/4422) +- Replace bootstrap peers (https://github.com/filecoin-project/lotus/pull/4447) +- Don't overwrite previously-configured maxPieceSize for a persisted ask (https://github.com/filecoin-project/lotus/pull/4480) +- State: optimize state snapshot address cache (https://github.com/filecoin-project/lotus/pull/4481) + # 0.10.2 / 2020-10-14 This is an optional release of Lotus that updates markets to 0.9.1, which fixes an issue affecting deals that were mid-transfer when the node was upgraded to 0.9.0. This release also includes some tweaks to default gas values and minor performance improvements. diff --git a/Makefile b/Makefile index 79f7fa81e..093f62ef6 100644 --- a/Makefile +++ b/Makefile @@ -133,18 +133,30 @@ benchmarks: lotus-pond: 2k go build -o lotus-pond ./lotuspond - (cd lotuspond/front && npm i && CI=false npm run build) .PHONY: lotus-pond BINS+=lotus-pond +lotus-pond-front: + (cd lotuspond/front && npm i && CI=false npm run build) +.PHONY: lotus-pond-front + +lotus-pond-app: lotus-pond-front lotus-pond +.PHONY: lotus-pond-app + lotus-townhall: rm -f lotus-townhall go build -o lotus-townhall ./cmd/lotus-townhall - (cd ./cmd/lotus-townhall/townhall && npm i && npm run build) - go run github.com/GeertJohan/go.rice/rice append --exec lotus-townhall -i ./cmd/lotus-townhall -i ./build .PHONY: lotus-townhall BINS+=lotus-townhall +lotus-townhall-front: + (cd ./cmd/lotus-townhall/townhall && npm i && npm run build) +.PHONY: lotus-townhall-front + +lotus-townhall-app: lotus-touch lotus-townhall-front + go run github.com/GeertJohan/go.rice/rice append --exec lotus-townhall -i ./cmd/lotus-townhall -i ./build +.PHONY: lotus-townhall-app + lotus-fountain: rm -f lotus-fountain go build -o lotus-fountain ./cmd/lotus-fountain diff --git a/api/api_full.go b/api/api_full.go index c9662c73f..f4948ccb9 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -207,6 +207,15 @@ type FullNode interface { // based on current chain conditions MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error) + // MpoolBatchPush batch pushes a signed message to mempool. + MpoolBatchPush(context.Context, []*types.SignedMessage) ([]cid.Cid, error) + + // MpoolBatchPushUntrusted batch pushes a signed message to mempool from untrusted sources. + MpoolBatchPushUntrusted(context.Context, []*types.SignedMessage) ([]cid.Cid, error) + + // MpoolBatchPushMessage batch pushes a unsigned message to mempool. + MpoolBatchPushMessage(context.Context, []*types.Message, *MessageSendSpec) ([]*types.SignedMessage, error) + // MpoolGetNonce gets next nonce for the specified sender. // Note that this method may not be atomic. Use MpoolPushMessage instead. MpoolGetNonce(context.Context, address.Address) (uint64, error) @@ -277,6 +286,8 @@ type FullNode interface { ClientListDeals(ctx context.Context) ([]DealInfo, error) // ClientGetDealUpdates returns the status of updated deals ClientGetDealUpdates(ctx context.Context) (<-chan DealInfo, error) + // ClientGetDealStatus returns status given a code + ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error) // ClientHasLocal indicates whether a certain CID is locally stored. ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) // ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer). @@ -593,6 +604,8 @@ type MsgGasCost struct { TotalCost abi.TokenAmount } +// BlsMessages[x].cid = Cids[x] +// SecpkMessages[y].cid = Cids[BlsMessages.length + y] type BlockMessages struct { BlsMessages []*types.Message SecpkMessages []*types.SignedMessage diff --git a/api/api_gateway.go b/api/api_gateway.go index c99ff8408..07fb5deb3 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -3,24 +3,42 @@ package api import ( "context" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/go-state-types/network" + + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/types" - "github.com/ipfs/go-cid" ) type GatewayAPI interface { ChainHasObj(context.Context, cid.Cid) (bool, error) ChainHead(ctx context.Context) (*types.TipSet, error) + ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error) + ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) + ChainNotify(context.Context) (<-chan []*HeadChange, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) MpoolPush(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) 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) (DealCollateralBounds, error) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) + StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) + StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) + StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (MarketBalance, error) + StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*MarketDeal, error) + StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) + StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) + StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error) + StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error) + StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*MsgLookup, error) } diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 70eb518e4..8d9216ef4 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -132,6 +132,10 @@ type FullNodeStruct struct { MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"` MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"` + MpoolBatchPush func(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` + MpoolBatchPushUntrusted func(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` + MpoolBatchPushMessage func(ctx context.Context, msgs []*types.Message, spec *api.MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"` + MinerGetBaseInfo func(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"` MinerCreateBlock func(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"` @@ -157,6 +161,7 @@ type FullNodeStruct struct { 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"` 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"` ClientGetDealUpdates func(ctx context.Context) (<-chan api.DealInfo, error) `perm:"read"` ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"` @@ -314,18 +319,18 @@ type StorageMinerStruct struct { SealingSchedDiag func(context.Context) (interface{}, error) `perm:"admin"` - StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"` - StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"` - StorageStat func(context.Context, stores.ID) (fsutil.FsStat, error) `perm:"admin"` - StorageAttach func(context.Context, stores.StorageInfo, fsutil.FsStat) error `perm:"admin" retry:"true"` - StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, storiface.SectorFileType, bool) error `perm:"admin"` - StorageDropSector func(context.Context, stores.ID, abi.SectorID, storiface.SectorFileType) error `perm:"admin"` - StorageFindSector func(context.Context, abi.SectorID, storiface.SectorFileType, abi.RegisteredSealProof, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"` - StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"` - StorageBestAlloc func(ctx context.Context, allocate storiface.SectorFileType, spt abi.RegisteredSealProof, sealing storiface.PathType) ([]stores.StorageInfo, error) `perm:"admin"` - StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"` - StorageLock func(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error `perm:"admin"` - StorageTryLock func(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) `perm:"admin"` + StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"` + StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"` + StorageStat func(context.Context, stores.ID) (fsutil.FsStat, error) `perm:"admin"` + StorageAttach func(context.Context, stores.StorageInfo, fsutil.FsStat) error `perm:"admin"` + StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, storiface.SectorFileType, bool) error `perm:"admin"` + StorageDropSector func(context.Context, stores.ID, abi.SectorID, storiface.SectorFileType) error `perm:"admin"` + StorageFindSector func(context.Context, abi.SectorID, storiface.SectorFileType, abi.SectorSize, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"` + StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"` + StorageBestAlloc func(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, sealing storiface.PathType) ([]stores.StorageInfo, error) `perm:"admin"` + StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"` + StorageLock func(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error `perm:"admin"` + StorageTryLock func(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) `perm:"admin"` DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"` DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"` @@ -382,20 +387,32 @@ type WorkerStruct struct { type GatewayStruct struct { Internal struct { - // TODO: does the gateway need perms? - ChainHasObj func(context.Context, cid.Cid) (bool, error) - ChainGetTipSet func(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) - ChainGetTipSetByHeight func(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) - ChainHead func(ctx context.Context) (*types.TipSet, error) - ChainReadObj func(context.Context, cid.Cid) ([]byte, error) - GasEstimateMessageGas func(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) - MpoolPush func(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) - MsigGetAvailableBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) - MsigGetVested func(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) - StateAccountKey func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) - StateGetActor func(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) - StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) - StateWaitMsg func(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) + ChainGetBlockMessages func(ctx context.Context, c cid.Cid) (*api.BlockMessages, error) + ChainGetMessage func(ctx context.Context, mc cid.Cid) (*types.Message, error) + ChainGetTipSet func(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) + ChainGetTipSetByHeight func(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) + ChainHasObj func(context.Context, cid.Cid) (bool, error) + ChainHead func(ctx context.Context) (*types.TipSet, error) + ChainNotify func(ctx context.Context) (<-chan []*api.HeadChange, error) + ChainReadObj func(context.Context, cid.Cid) ([]byte, error) + GasEstimateMessageGas func(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) + MpoolPush func(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) + MsigGetAvailableBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) + MsigGetVested func(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) + StateAccountKey func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) + StateDealProviderCollateralBounds func(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) + StateGetActor func(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) + StateGetReceipt func(ctx context.Context, c cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) + StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) + StateListMiners func(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) + StateMinerInfo func(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) + StateMinerProvingDeadline func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) + StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) + StateMarketBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) + StateMarketStorageDeal func(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) + StateNetworkVersion func(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error) + StateVerifiedClientStatus func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) + StateWaitMsg func(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) } } @@ -533,6 +550,10 @@ func (c *FullNodeStruct) ClientGetDealInfo(ctx context.Context, deal cid.Cid) (* return c.Internal.ClientGetDealInfo(ctx, deal) } +func (c *FullNodeStruct) ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error) { + return c.Internal.ClientGetDealStatus(ctx, statusCode) +} + func (c *FullNodeStruct) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) { return c.Internal.ClientListDeals(ctx) } @@ -628,6 +649,18 @@ func (c *FullNodeStruct) MpoolPushMessage(ctx context.Context, msg *types.Messag return c.Internal.MpoolPushMessage(ctx, msg, spec) } +func (c *FullNodeStruct) MpoolBatchPush(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) { + return c.Internal.MpoolBatchPush(ctx, smsgs) +} + +func (c *FullNodeStruct) MpoolBatchPushUntrusted(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) { + return c.Internal.MpoolBatchPushUntrusted(ctx, smsgs) +} + +func (c *FullNodeStruct) MpoolBatchPushMessage(ctx context.Context, msgs []*types.Message, spec *api.MessageSendSpec) ([]*types.SignedMessage, error) { + return c.Internal.MpoolBatchPushMessage(ctx, msgs, spec) +} + func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate, error) { return c.Internal.MpoolSub(ctx) } @@ -1268,8 +1301,8 @@ func (c *StorageMinerStruct) StorageDropSector(ctx context.Context, storageId st return c.Internal.StorageDropSector(ctx, storageId, s, ft) } -func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types storiface.SectorFileType, spt abi.RegisteredSealProof, allowFetch bool) ([]stores.SectorStorageInfo, error) { - return c.Internal.StorageFindSector(ctx, si, types, spt, allowFetch) +func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types storiface.SectorFileType, ssize abi.SectorSize, allowFetch bool) ([]stores.SectorStorageInfo, error) { + return c.Internal.StorageFindSector(ctx, si, types, ssize, allowFetch) } func (c *StorageMinerStruct) StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) { @@ -1288,8 +1321,8 @@ func (c *StorageMinerStruct) StorageInfo(ctx context.Context, id stores.ID) (sto return c.Internal.StorageInfo(ctx, id) } -func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, spt abi.RegisteredSealProof, pt storiface.PathType) ([]stores.StorageInfo, error) { - return c.Internal.StorageBestAlloc(ctx, allocate, spt, pt) +func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pt storiface.PathType) ([]stores.StorageInfo, error) { + return c.Internal.StorageBestAlloc(ctx, allocate, ssize, pt) } func (c *StorageMinerStruct) StorageReportHealth(ctx context.Context, id stores.ID, report stores.HealthReport) error { @@ -1494,12 +1527,12 @@ func (w *WorkerStruct) Session(ctx context.Context) (uuid.UUID, error) { return w.Internal.Session(ctx) } -func (g GatewayStruct) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) { - return g.Internal.ChainHasObj(ctx, c) +func (g GatewayStruct) ChainGetBlockMessages(ctx context.Context, c cid.Cid) (*api.BlockMessages, error) { + return g.Internal.ChainGetBlockMessages(ctx, c) } -func (g GatewayStruct) ChainHead(ctx context.Context) (*types.TipSet, error) { - return g.Internal.ChainHead(ctx) +func (g GatewayStruct) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) { + return g.Internal.ChainGetMessage(ctx, mc) } func (g GatewayStruct) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) { @@ -1510,6 +1543,18 @@ func (g GatewayStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEp return g.Internal.ChainGetTipSetByHeight(ctx, h, tsk) } +func (g GatewayStruct) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) { + return g.Internal.ChainHasObj(ctx, c) +} + +func (g GatewayStruct) ChainHead(ctx context.Context) (*types.TipSet, error) { + return g.Internal.ChainHead(ctx) +} + +func (g GatewayStruct) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, error) { + return g.Internal.ChainNotify(ctx) +} + func (g GatewayStruct) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { return g.Internal.ChainReadObj(ctx, c) } @@ -1534,14 +1579,54 @@ func (g GatewayStruct) StateAccountKey(ctx context.Context, addr address.Address return g.Internal.StateAccountKey(ctx, addr, tsk) } +func (g GatewayStruct) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) { + return g.Internal.StateDealProviderCollateralBounds(ctx, size, verified, tsk) +} + func (g GatewayStruct) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) { return g.Internal.StateGetActor(ctx, actor, ts) } +func (g GatewayStruct) StateGetReceipt(ctx context.Context, c cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) { + return g.Internal.StateGetReceipt(ctx, c, tsk) +} + func (g GatewayStruct) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { return g.Internal.StateLookupID(ctx, addr, tsk) } +func (g GatewayStruct) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { + return g.Internal.StateListMiners(ctx, tsk) +} + +func (g GatewayStruct) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) { + return g.Internal.StateMarketBalance(ctx, addr, tsk) +} + +func (g GatewayStruct) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) { + return g.Internal.StateMarketStorageDeal(ctx, dealId, tsk) +} + +func (g GatewayStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) { + return g.Internal.StateMinerInfo(ctx, actor, tsk) +} + +func (g GatewayStruct) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) { + return g.Internal.StateMinerProvingDeadline(ctx, addr, tsk) +} + +func (g GatewayStruct) StateMinerPower(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*api.MinerPower, error) { + return g.Internal.StateMinerPower(ctx, addr, tsk) +} + +func (g GatewayStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error) { + return g.Internal.StateNetworkVersion(ctx, tsk) +} + +func (g GatewayStruct) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) { + return g.Internal.StateVerifiedClientStatus(ctx, addr, tsk) +} + func (g GatewayStruct) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) { return g.Internal.StateWaitMsg(ctx, msg, confidence) } diff --git a/api/test/ccupgrade.go b/api/test/ccupgrade.go index 4a860c661..75f72d861 100644 --- a/api/test/ccupgrade.go +++ b/api/test/ccupgrade.go @@ -3,7 +3,6 @@ package test import ( "context" "fmt" - "os" "sync/atomic" "testing" "time" @@ -17,8 +16,6 @@ import ( ) func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) { - _ = os.Setenv("BELLMAN_NO_GPU", "1") - for _, height := range []abi.ChainEpoch{ 1, // before 162, // while sealing @@ -92,7 +89,7 @@ func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeH t.Fatal(err) } - makeDeal(t, ctx, 6, client, miner, false, false) + MakeDeal(t, ctx, 6, client, miner, false, false) // Validate upgrade diff --git a/api/test/deals.go b/api/test/deals.go index 8b4a7fe8b..b81099d90 100644 --- a/api/test/deals.go +++ b/api/test/deals.go @@ -16,15 +16,12 @@ import ( "github.com/ipfs/go-cid" files "github.com/ipfs/go-ipfs-files" - logging "github.com/ipfs/go-log/v2" "github.com/ipld/go-car" "github.com/filecoin-project/go-fil-markets/storagemarket" - "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" sealing "github.com/filecoin-project/lotus/extern/storage-sealing" - "github.com/filecoin-project/lotus/miner" dag "github.com/ipfs/go-merkledag" dstest "github.com/ipfs/go-merkledag/test" unixfile "github.com/ipfs/go-unixfs/file" @@ -34,18 +31,7 @@ import ( ipld "github.com/ipfs/go-ipld-format" ) -var MineNext = miner.MineReq{ - InjectNulls: 0, - Done: func(bool, abi.ChainEpoch, error) {}, -} - -func init() { - logging.SetAllLoggers(logging.LevelInfo) - build.InsecurePoStValidation = true -} - func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool) { - _ = os.Setenv("BELLMAN_NO_GPU", "1") ctx := context.Background() n, sn := b(t, OneFull, OneMiner) @@ -74,7 +60,7 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport } }() - makeDeal(t, ctx, 6, client, miner, carExport, fastRet) + MakeDeal(t, ctx, 6, client, miner, carExport, fastRet) atomic.AddInt64(&mine, -1) fmt.Println("shutting down mining") @@ -82,7 +68,6 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport } func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) { - _ = os.Setenv("BELLMAN_NO_GPU", "1") ctx := context.Background() n, sn := b(t, OneFull, OneMiner) @@ -112,24 +97,21 @@ func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) { } }() - makeDeal(t, ctx, 6, client, miner, false, false) - makeDeal(t, ctx, 7, client, miner, false, false) + MakeDeal(t, ctx, 6, client, miner, false, false) + MakeDeal(t, ctx, 7, client, miner, false, false) atomic.AddInt64(&mine, -1) fmt.Println("shutting down mining") <-done } -func makeDeal(t *testing.T, ctx context.Context, rseed int, client *impl.FullNodeAPI, miner TestStorageNode, carExport, fastRet bool) { - data := make([]byte, 1600) - rand.New(rand.NewSource(int64(rseed))).Read(data) - - r := bytes.NewReader(data) - fcid, err := client.ClientImportLocal(ctx, r) +func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestStorageNode, carExport, fastRet bool) { + res, data, err := CreateClientFile(ctx, client, rseed) if err != nil { t.Fatal(err) } + fcid := res.Root fmt.Println("FILE CID: ", fcid) deal := startDeal(t, ctx, miner, client, fcid, fastRet) @@ -145,8 +127,29 @@ func makeDeal(t *testing.T, ctx context.Context, rseed int, client *impl.FullNod testRetrieval(t, ctx, client, fcid, &info.PieceCID, carExport, data) } +func CreateClientFile(ctx context.Context, client api.FullNode, rseed int) (*api.ImportRes, []byte, error) { + data := make([]byte, 1600) + rand.New(rand.NewSource(int64(rseed))).Read(data) + + dir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-") + if err != nil { + return nil, nil, err + } + + path := filepath.Join(dir, "sourcefile.dat") + err = ioutil.WriteFile(path, data, 0644) + if err != nil { + return nil, nil, err + } + + res, err := client.ClientImport(ctx, api.FileRef{Path: path}) + if err != nil { + return nil, nil, err + } + return res, data, nil +} + func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) { - _ = os.Setenv("BELLMAN_NO_GPU", "1") ctx := context.Background() n, sn := b(t, OneFull, OneMiner) @@ -201,7 +204,6 @@ func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Durati } func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) { - _ = os.Setenv("BELLMAN_NO_GPU", "1") ctx := context.Background() n, sn := b(t, OneFull, OneMiner) @@ -276,7 +278,7 @@ func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration <-done } -func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client *impl.FullNodeAPI, fcid cid.Cid, fastRet bool) *cid.Cid { +func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, fcid cid.Cid, fastRet bool) *cid.Cid { maddr, err := miner.ActorAddress(ctx) if err != nil { t.Fatal(err) @@ -303,7 +305,7 @@ func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client return deal } -func waitDealSealed(t *testing.T, ctx context.Context, miner TestStorageNode, client *impl.FullNodeAPI, deal *cid.Cid, noseal bool) { +func waitDealSealed(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, deal *cid.Cid, noseal bool) { loop: for { di, err := client.ClientGetDealInfo(ctx, *deal) @@ -376,7 +378,7 @@ func startSealingWaiting(t *testing.T, ctx context.Context, miner TestStorageNod } } -func testRetrieval(t *testing.T, ctx context.Context, client *impl.FullNodeAPI, fcid cid.Cid, piece *cid.Cid, carExport bool, data []byte) { +func testRetrieval(t *testing.T, ctx context.Context, client api.FullNode, fcid cid.Cid, piece *cid.Cid, carExport bool, data []byte) { offers, err := client.ClientFindData(ctx, fcid, piece) if err != nil { t.Fatal(err) diff --git a/api/test/mining.go b/api/test/mining.go index 8147c224b..90e8e8a45 100644 --- a/api/test/mining.go +++ b/api/test/mining.go @@ -5,7 +5,6 @@ import ( "context" "fmt" "math/rand" - "os" "sync/atomic" "testing" "time" @@ -88,8 +87,6 @@ func (ts *testSuite) testMiningReal(t *testing.T) { } func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) { - _ = os.Setenv("BELLMAN_NO_GPU", "1") - // test making a deal with a fresh miner, and see if it starts to mine ctx := context.Background() diff --git a/api/test/paych.go b/api/test/paych.go index 43401554d..2bcea4369 100644 --- a/api/test/paych.go +++ b/api/test/paych.go @@ -3,14 +3,10 @@ package test import ( "context" "fmt" - "os" "sync/atomic" "testing" "time" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" - "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/ipfs/go-cid" @@ -22,15 +18,15 @@ import ( "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/events/state" "github.com/filecoin-project/lotus/chain/types" ) func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { - _ = os.Setenv("BELLMAN_NO_GPU", "1") - ctx := context.Background() n, sn := b(t, TwoFull, OneMiner) @@ -227,7 +223,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { } // wait for the settlement period to pass before collecting - waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, paych0.SettleDelay) + waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, policy.PaychSettleDelay) creatorPreCollectBalance, err := paymentCreator.WalletBalance(ctx, createrAddr) if err != nil { @@ -283,7 +279,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentRec // Add a real block m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{ - To: builtin0.BurntFundsActorAddr, + To: builtin.BurntFundsActorAddr, From: receiverAddr, Value: types.NewInt(0), }, nil) diff --git a/api/test/test.go b/api/test/test.go index 4074ce4a6..bae3d520e 100644 --- a/api/test/test.go +++ b/api/test/test.go @@ -2,12 +2,15 @@ package test import ( "context" + "fmt" + "os" "testing" "time" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" + logging "github.com/ipfs/go-log/v2" "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/assert" @@ -22,6 +25,15 @@ import ( "github.com/filecoin-project/lotus/node" ) +func init() { + logging.SetAllLoggers(logging.LevelInfo) + err := os.Setenv("BELLMAN_NO_GPU", "1") + if err != nil { + panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err)) + } + build.InsecurePoStValidation = true +} + type TestNode struct { api.FullNode // ListenAddr is the address on which an API server is listening, if an @@ -110,6 +122,11 @@ var FullNodeWithUpgradeAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts { } } +var MineNext = miner.MineReq{ + InjectNulls: 0, + Done: func(bool, abi.ChainEpoch, error) {}, +} + func (ts *testSuite) testVersion(t *testing.T) { build.RunningNodeType = build.NodeFull diff --git a/api/test/window_post.go b/api/test/window_post.go index 28639cda8..55fc4ad70 100644 --- a/api/test/window_post.go +++ b/api/test/window_post.go @@ -5,7 +5,6 @@ import ( "fmt" "sync/atomic" - "os" "strings" "testing" "time" @@ -24,13 +23,6 @@ import ( "github.com/filecoin-project/lotus/node/impl" ) -func init() { - err := os.Setenv("BELLMAN_NO_GPU", "1") - if err != nil { - panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err)) - } -} - func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/build/params_2k.go b/build/params_2k.go index b09b60fae..5a0e8fd61 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -22,6 +22,8 @@ const UpgradeTapeHeight = -4 var UpgradeActorsV2Height = abi.ChainEpoch(10) var UpgradeLiftoffHeight = abi.ChainEpoch(-5) +const UpgradeKumquatHeight = -6 + var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, } diff --git a/build/params_mainnet.go b/build/params_mainnet.go index 54f50ac6e..94deedfec 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -12,7 +12,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/chain/actors/policy" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ @@ -37,6 +37,8 @@ const UpgradeTapeHeight = 140760 // We still have upgrades and state changes to do, but can happen after signaling timing here. const UpgradeLiftoffHeight = 148888 +const UpgradeKumquatHeight = 170000 + func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40)) policy.SetSupportedProofTypes( @@ -55,6 +57,6 @@ func init() { Devnet = false } -const BlockDelaySecs = uint64(builtin0.EpochDurationSeconds) +const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds) const PropagationDelaySecs = uint64(6) diff --git a/build/params_shared_funcs.go b/build/params_shared_funcs.go index 40ccca50b..77fd9256d 100644 --- a/build/params_shared_funcs.go +++ b/build/params_shared_funcs.go @@ -1,36 +1,13 @@ package build import ( - "sort" - "github.com/filecoin-project/go-address" "github.com/libp2p/go-libp2p-core/protocol" - "github.com/filecoin-project/go-state-types/abi" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - "github.com/filecoin-project/lotus/node/modules/dtypes" ) -func DefaultSectorSize() abi.SectorSize { - szs := make([]abi.SectorSize, 0, len(miner0.SupportedProofTypes)) - for spt := range miner0.SupportedProofTypes { - ss, err := spt.SectorSize() - if err != nil { - panic(err) - } - - szs = append(szs, ss) - } - - sort.Slice(szs, func(i, j int) bool { - return szs[i] < szs[j] - }) - - return szs[0] -} - // Core network constants func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) } @@ -39,14 +16,6 @@ func DhtProtocolName(netName dtypes.NetworkName) protocol.ID { return protocol.ID("/fil/kad/" + string(netName)) } -func UseNewestNetwork() bool { - // TODO: Put these in a container we can iterate over - if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 && UpgradeActorsV2Height <= 0 { - return true - } - return false -} - func SetAddressNetwork(n address.Network) { address.CurrentNetwork = n } diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index ede40c0e3..5070777bd 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -7,12 +7,12 @@ import ( "os" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/actors/policy" - + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + "github.com/filecoin-project/lotus/chain/actors/policy" ) // ///// @@ -25,14 +25,14 @@ const UnixfsLinksPerLevel = 1024 // Consensus / Network const AllowableClockDriftSecs = uint64(1) -const NewestNetworkVersion = network.Version5 +const NewestNetworkVersion = network.Version6 const ActorUpgradeNetworkVersion = network.Version4 // Epochs const ForkLengthThreshold = Finality // Blocks (e) -var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) +var BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch) // Epochs const Finality = policy.ChainFinality @@ -116,4 +116,4 @@ const PackingEfficiencyDenom = 5 // Actor consts // TODO: Pull from actors when its made not private -var MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay) +var MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay) diff --git a/build/params_testground.go b/build/params_testground.go index 7ef034234..d9893a5f5 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -12,7 +12,8 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/specs-actors/actors/builtin" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/policy" ) @@ -21,14 +22,14 @@ var ( UnixfsChunkSize = uint64(1 << 20) UnixfsLinksPerLevel = 1024 - BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) + BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch) BlockMessageLimit = 512 BlockGasLimit = int64(100_000_000_000) BlockGasTarget = int64(BlockGasLimit / 2) BaseFeeMaxChangeDenom = int64(8) // 12.5% InitialBaseFee = int64(100e6) MinimumBaseFee = int64(100) - BlockDelaySecs = uint64(builtin.EpochDurationSeconds) + BlockDelaySecs = uint64(builtin2.EpochDurationSeconds) PropagationDelaySecs = uint64(6) AllowableClockDriftSecs = uint64(1) @@ -72,7 +73,7 @@ var ( // Actor consts // TODO: Pull from actors when its made not private - MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay) + MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay) PackingEfficiencyNum int64 = 4 PackingEfficiencyDenom int64 = 5 @@ -86,6 +87,7 @@ var ( UpgradeTapeHeight abi.ChainEpoch = -4 UpgradeActorsV2Height abi.ChainEpoch = 10 UpgradeLiftoffHeight abi.ChainEpoch = -5 + UpgradeKumquatHeight abi.ChainEpoch = -6 DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/version.go b/build/version.go index cb61ff8fb..e1f730026 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 = "0.10.2" +const BuildVersion = "1.1.0" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit @@ -84,7 +84,7 @@ func VersionForType(nodeType NodeType) (Version, error) { // semver versions of the rpc api exposed var ( FullAPIVersion = newVer(0, 17, 0) - MinerAPIVersion = newVer(0, 16, 0) + MinerAPIVersion = newVer(0, 17, 0) WorkerAPIVersion = newVer(0, 16, 0) ) diff --git a/chain/actors/adt/diff_adt_test.go b/chain/actors/adt/diff_adt_test.go index 1c0726003..a187c9f35 100644 --- a/chain/actors/adt/diff_adt_test.go +++ b/chain/actors/adt/diff_adt_test.go @@ -12,8 +12,9 @@ import ( typegen "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/runtime" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" bstore "github.com/filecoin-project/lotus/lib/blockstore" ) @@ -22,24 +23,24 @@ func TestDiffAdtArray(t *testing.T) { ctxstoreA := newContextStore() ctxstoreB := newContextStore() - arrA := adt0.MakeEmptyArray(ctxstoreA) - arrB := adt0.MakeEmptyArray(ctxstoreB) + arrA := adt2.MakeEmptyArray(ctxstoreA) + arrB := adt2.MakeEmptyArray(ctxstoreB) - require.NoError(t, arrA.Set(0, runtime.CBORBytes([]byte{0}))) // delete + require.NoError(t, arrA.Set(0, builtin2.CBORBytes([]byte{0}))) // delete - require.NoError(t, arrA.Set(1, runtime.CBORBytes([]byte{0}))) // modify - require.NoError(t, arrB.Set(1, runtime.CBORBytes([]byte{1}))) + require.NoError(t, arrA.Set(1, builtin2.CBORBytes([]byte{0}))) // modify + require.NoError(t, arrB.Set(1, builtin2.CBORBytes([]byte{1}))) - require.NoError(t, arrA.Set(2, runtime.CBORBytes([]byte{1}))) // delete + require.NoError(t, arrA.Set(2, builtin2.CBORBytes([]byte{1}))) // delete - require.NoError(t, arrA.Set(3, runtime.CBORBytes([]byte{0}))) // noop - require.NoError(t, arrB.Set(3, runtime.CBORBytes([]byte{0}))) + require.NoError(t, arrA.Set(3, builtin2.CBORBytes([]byte{0}))) // noop + require.NoError(t, arrB.Set(3, builtin2.CBORBytes([]byte{0}))) - require.NoError(t, arrA.Set(4, runtime.CBORBytes([]byte{0}))) // modify - require.NoError(t, arrB.Set(4, runtime.CBORBytes([]byte{6}))) + require.NoError(t, arrA.Set(4, builtin2.CBORBytes([]byte{0}))) // modify + require.NoError(t, arrB.Set(4, builtin2.CBORBytes([]byte{6}))) - require.NoError(t, arrB.Set(5, runtime.CBORBytes{8})) // add - require.NoError(t, arrB.Set(6, runtime.CBORBytes{9})) // add + require.NoError(t, arrB.Set(5, builtin2.CBORBytes{8})) // add + require.NoError(t, arrB.Set(6, builtin2.CBORBytes{9})) // add changes := new(TestDiffArray) @@ -76,24 +77,24 @@ func TestDiffAdtMap(t *testing.T) { ctxstoreA := newContextStore() ctxstoreB := newContextStore() - mapA := adt0.MakeEmptyMap(ctxstoreA) - mapB := adt0.MakeEmptyMap(ctxstoreB) + mapA := adt2.MakeEmptyMap(ctxstoreA) + mapB := adt2.MakeEmptyMap(ctxstoreB) - require.NoError(t, mapA.Put(abi.UIntKey(0), runtime.CBORBytes([]byte{0}))) // delete + require.NoError(t, mapA.Put(abi.UIntKey(0), builtin2.CBORBytes([]byte{0}))) // delete - require.NoError(t, mapA.Put(abi.UIntKey(1), runtime.CBORBytes([]byte{0}))) // modify - require.NoError(t, mapB.Put(abi.UIntKey(1), runtime.CBORBytes([]byte{1}))) + require.NoError(t, mapA.Put(abi.UIntKey(1), builtin2.CBORBytes([]byte{0}))) // modify + require.NoError(t, mapB.Put(abi.UIntKey(1), builtin2.CBORBytes([]byte{1}))) - require.NoError(t, mapA.Put(abi.UIntKey(2), runtime.CBORBytes([]byte{1}))) // delete + require.NoError(t, mapA.Put(abi.UIntKey(2), builtin2.CBORBytes([]byte{1}))) // delete - require.NoError(t, mapA.Put(abi.UIntKey(3), runtime.CBORBytes([]byte{0}))) // noop - require.NoError(t, mapB.Put(abi.UIntKey(3), runtime.CBORBytes([]byte{0}))) + require.NoError(t, mapA.Put(abi.UIntKey(3), builtin2.CBORBytes([]byte{0}))) // noop + require.NoError(t, mapB.Put(abi.UIntKey(3), builtin2.CBORBytes([]byte{0}))) - require.NoError(t, mapA.Put(abi.UIntKey(4), runtime.CBORBytes([]byte{0}))) // modify - require.NoError(t, mapB.Put(abi.UIntKey(4), runtime.CBORBytes([]byte{6}))) + require.NoError(t, mapA.Put(abi.UIntKey(4), builtin2.CBORBytes([]byte{0}))) // modify + require.NoError(t, mapB.Put(abi.UIntKey(4), builtin2.CBORBytes([]byte{6}))) - require.NoError(t, mapB.Put(abi.UIntKey(5), runtime.CBORBytes{8})) // add - require.NoError(t, mapB.Put(abi.UIntKey(6), runtime.CBORBytes{9})) // add + require.NoError(t, mapB.Put(abi.UIntKey(5), builtin2.CBORBytes{8})) // add + require.NoError(t, mapB.Put(abi.UIntKey(6), builtin2.CBORBytes{9})) // add changes := new(TestDiffMap) @@ -144,7 +145,7 @@ func (t *TestDiffMap) AsKey(key string) (abi.Keyer, error) { } func (t *TestDiffMap) Add(key string, val *typegen.Deferred) error { - v := new(runtime.CBORBytes) + v := new(builtin2.CBORBytes) err := v.UnmarshalCBOR(bytes.NewReader(val.Raw)) if err != nil { return err @@ -161,13 +162,13 @@ func (t *TestDiffMap) Add(key string, val *typegen.Deferred) error { } func (t *TestDiffMap) Modify(key string, from, to *typegen.Deferred) error { - vFrom := new(runtime.CBORBytes) + vFrom := new(builtin2.CBORBytes) err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw)) if err != nil { return err } - vTo := new(runtime.CBORBytes) + vTo := new(builtin2.CBORBytes) err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw)) if err != nil { return err @@ -194,7 +195,7 @@ func (t *TestDiffMap) Modify(key string, from, to *typegen.Deferred) error { } func (t *TestDiffMap) Remove(key string, val *typegen.Deferred) error { - v := new(runtime.CBORBytes) + v := new(builtin2.CBORBytes) err := v.UnmarshalCBOR(bytes.NewReader(val.Raw)) if err != nil { return err @@ -212,7 +213,7 @@ func (t *TestDiffMap) Remove(key string, val *typegen.Deferred) error { type adtMapDiffResult struct { key uint64 - val runtime.CBORBytes + val builtin2.CBORBytes } type TestAdtMapDiffModified struct { @@ -222,7 +223,7 @@ type TestAdtMapDiffModified struct { type adtArrayDiffResult struct { key uint64 - val runtime.CBORBytes + val builtin2.CBORBytes } type TestDiffArray struct { @@ -239,7 +240,7 @@ type TestAdtArrayDiffModified struct { } func (t *TestDiffArray) Add(key uint64, val *typegen.Deferred) error { - v := new(runtime.CBORBytes) + v := new(builtin2.CBORBytes) err := v.UnmarshalCBOR(bytes.NewReader(val.Raw)) if err != nil { return err @@ -252,13 +253,13 @@ func (t *TestDiffArray) Add(key uint64, val *typegen.Deferred) error { } func (t *TestDiffArray) Modify(key uint64, from, to *typegen.Deferred) error { - vFrom := new(runtime.CBORBytes) + vFrom := new(builtin2.CBORBytes) err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw)) if err != nil { return err } - vTo := new(runtime.CBORBytes) + vTo := new(builtin2.CBORBytes) err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw)) if err != nil { return err @@ -280,7 +281,7 @@ func (t *TestDiffArray) Modify(key uint64, from, to *typegen.Deferred) error { } func (t *TestDiffArray) Remove(key uint64, val *typegen.Deferred) error { - v := new(runtime.CBORBytes) + v := new(builtin2.CBORBytes) err := v.UnmarshalCBOR(bytes.NewReader(val.Raw)) if err != nil { return err diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go index 7b1b2a792..38ed2654b 100644 --- a/chain/actors/builtin/account/account.go +++ b/chain/actors/builtin/account/account.go @@ -24,6 +24,8 @@ func init() { }) } +var Methods = builtin2.MethodsAccount + func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { case builtin0.AccountActorCodeID: diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index 350b3a9a6..afba8efe8 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -27,6 +27,21 @@ var SaftAddress = makeAddress("t0122") var ReserveAddress = makeAddress("t090") var RootVerifierAddress = makeAddress("t080") +var ( + ExpectedLeadersPerEpoch = builtin0.ExpectedLeadersPerEpoch +) + +const ( + EpochDurationSeconds = builtin0.EpochDurationSeconds + EpochsInDay = builtin0.EpochsInDay + SecondsInDay = builtin0.SecondsInDay +) + +const ( + MethodSend = builtin2.MethodSend + MethodConstructor = builtin2.MethodConstructor +) + // TODO: Why does actors have 2 different versions of this? type SectorInfo = proof0.SectorInfo type PoStProof = proof0.PoStProof diff --git a/chain/actors/builtin/cron/cron.go b/chain/actors/builtin/cron/cron.go new file mode 100644 index 000000000..65bfd992f --- /dev/null +++ b/chain/actors/builtin/cron/cron.go @@ -0,0 +1,10 @@ +package cron + +import ( + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" +) + +var ( + Address = builtin2.CronActorAddr + Methods = builtin2.MethodsCron +) diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index 5777bb890..60dbdf4fe 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -26,7 +26,10 @@ func init() { }) } -var Address = builtin0.InitActorAddr +var ( + Address = builtin2.InitActorAddr + Methods = builtin2.MethodsInit +) func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index fd08a0119..195ca40b9 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -27,7 +27,10 @@ func init() { }) } -var Address = builtin0.StorageMarketActorAddr +var ( + Address = builtin2.StorageMarketActorAddr + Methods = builtin2.MethodsMarket +) func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 3cca39326..aad41e8a9 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -31,6 +31,8 @@ func init() { }) } +var Methods = builtin2.MethodsMiner + // Unchanged between v0 and v2 actors var WPoStProvingPeriod = miner0.WPoStProvingPeriod var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines diff --git a/chain/actors/builtin/multisig/message.go b/chain/actors/builtin/multisig/message.go index 5beb5319d..3d2c66e6b 100644 --- a/chain/actors/builtin/multisig/message.go +++ b/chain/actors/builtin/multisig/message.go @@ -9,12 +9,15 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) +var Methods = builtin2.MethodsMultisig + func Message(version actors.Version, from address.Address) MessageBuilder { switch version { case actors.Version0: diff --git a/chain/actors/builtin/paych/message.go b/chain/actors/builtin/paych/message.go index 23b360394..5709d4b23 100644 --- a/chain/actors/builtin/paych/message.go +++ b/chain/actors/builtin/paych/message.go @@ -7,8 +7,12 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) +var Methods = builtin2.MethodsPaych + func Message(version actors.Version, from address.Address) MessageBuilder { switch version { case actors.Version0: diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index bafb14de0..f941ce93e 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -2,6 +2,7 @@ package power import ( "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -25,7 +26,10 @@ func init() { }) } -var Address = builtin0.StoragePowerActorAddr +var ( + Address = builtin2.StoragePowerActorAddr + Methods = builtin2.MethodsPower +) func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { @@ -61,3 +65,10 @@ type Claim struct { // Sum of quality adjusted power for a miner's sectors. QualityAdjPower abi.StoragePower } + +func AddClaims(a Claim, b Claim) Claim { + return Claim{ + RawBytePower: big.Add(a.RawBytePower, b.RawBytePower), + QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower), + } +} diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index 065f242e2..952ca270b 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -24,7 +24,10 @@ func init() { }) } -var Address = builtin0.RewardActorAddr +var ( + Address = builtin2.RewardActorAddr + Methods = builtin2.MethodsReward +) func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index 204cdae95..a4468d8a0 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -24,7 +24,10 @@ func init() { }) } -var Address = builtin0.VerifiedRegistryActorAddr +var ( + Address = builtin2.VerifiedRegistryActorAddr + Methods = builtin2.MethodsVerifiedRegistry +) func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index ba09e4424..c1a971db5 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -1,6 +1,8 @@ package policy import ( + "sort" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/chain/actors" @@ -11,12 +13,14 @@ import ( builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" ) const ( ChainFinality = miner0.ChainFinality SealRandomnessLookback = ChainFinality + PaychSettleDelay = paych2.SettleDelay ) // SetSupportedProofTypes sets supported proof types, across all actor versions. @@ -114,3 +118,35 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { return ChainFinality } + +func GetMaxSectorExpirationExtension() abi.ChainEpoch { + return miner0.MaxSectorExpirationExtension +} + +// TODO: we'll probably need to abstract over this better in the future. +func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) { + sectorsPerPart, err := builtin2.PoStProofWindowPoStPartitionSectors(p) + if err != nil { + return 0, err + } + return int(miner2.AddressedSectorsMax / sectorsPerPart), nil +} + +func GetDefaultSectorSize() abi.SectorSize { + // supported proof types are the same across versions. + szs := make([]abi.SectorSize, 0, len(miner2.SupportedProofTypes)) + for spt := range miner2.SupportedProofTypes { + ss, err := spt.SectorSize() + if err != nil { + panic(err) + } + + szs = append(szs, ss) + } + + sort.Slice(szs, func(i, j int) bool { + return szs[i] < szs[j] + }) + + return szs[0] +} diff --git a/chain/actors/policy/policy_test.go b/chain/actors/policy/policy_test.go index 62e7f8964..af600cc75 100644 --- a/chain/actors/policy/policy_test.go +++ b/chain/actors/policy/policy_test.go @@ -6,9 +6,13 @@ import ( "github.com/stretchr/testify/require" "github.com/filecoin-project/go-state-types/abi" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" ) @@ -42,9 +46,25 @@ func TestSupportedProofTypes(t *testing.T) { func TestAssumptions(t *testing.T) { require.EqualValues(t, miner0.SupportedProofTypes, miner2.SupportedProofTypes) require.Equal(t, miner0.PreCommitChallengeDelay, miner2.PreCommitChallengeDelay) + require.Equal(t, miner0.MaxSectorExpirationExtension, miner2.MaxSectorExpirationExtension) require.Equal(t, miner0.ChainFinality, miner2.ChainFinality) require.Equal(t, miner0.WPoStChallengeWindow, miner2.WPoStChallengeWindow) require.Equal(t, miner0.WPoStProvingPeriod, miner2.WPoStProvingPeriod) require.Equal(t, miner0.WPoStPeriodDeadlines, miner2.WPoStPeriodDeadlines) + require.Equal(t, miner0.AddressedSectorsMax, miner2.AddressedSectorsMax) + require.Equal(t, paych0.SettleDelay, paych2.SettleDelay) require.True(t, verifreg0.MinVerifiedDealSize.Equals(verifreg2.MinVerifiedDealSize)) } + +func TestPartitionSizes(t *testing.T) { + for p := range abi.PoStSealProofTypes { + sizeNew, err := builtin2.PoStProofWindowPoStPartitionSectors(p) + require.NoError(t, err) + sizeOld, err := builtin0.PoStProofWindowPoStPartitionSectors(p) + if err != nil { + // new proof type. + continue + } + require.Equal(t, sizeOld, sizeNew) + } +} diff --git a/chain/actors/version.go b/chain/actors/version.go index 2efd903bb..fe16d521e 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -18,7 +18,7 @@ func VersionForNetwork(version network.Version) Version { switch version { case network.Version0, network.Version1, network.Version2, network.Version3: return Version0 - case network.Version4, network.Version5: + case network.Version4, network.Version5, network.Version6: return Version2 default: panic(fmt.Sprintf("unsupported network version %d", version)) diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 6e8e83a20..4abc12d29 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -65,6 +65,11 @@ type DrandBeacon struct { localCache map[uint64]types.BeaconEntry } +// DrandHTTPClient interface overrides the user agent used by drand +type DrandHTTPClient interface { + SetUserAgent(string) +} + func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes.DrandConfig) (*DrandBeacon, error) { if genesisTs == 0 { panic("what are you doing this cant be zero") @@ -84,6 +89,7 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes if err != nil { return nil, xerrors.Errorf("could not create http drand client: %w", err) } + hc.(DrandHTTPClient).SetUserAgent("drand-client-lotus/" + build.BuildVersion) clients = append(clients, hc) } @@ -92,7 +98,6 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes dclient.WithChainInfo(drandChain), dclient.WithCacheSize(1024), dclient.WithLogger(dlogger), - dclient.WithAutoWatch(), } if ps != nil { diff --git a/chain/events/state/predicates_test.go b/chain/events/state/predicates_test.go index 461ac4997..9b393f6e4 100644 --- a/chain/events/state/predicates_test.go +++ b/chain/events/state/predicates_test.go @@ -18,14 +18,14 @@ 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" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + tutils "github.com/filecoin-project/specs-actors/v2/support/testing" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" - - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - "github.com/filecoin-project/specs-actors/actors/util/adt" - tutils "github.com/filecoin-project/specs-actors/support/testing" - "github.com/filecoin-project/lotus/chain/types" bstore "github.com/filecoin-project/lotus/lib/blockstore" ) @@ -72,24 +72,24 @@ func (m mockAPI) setActor(tsk types.TipSetKey, act *types.Actor) { func TestMarketPredicates(t *testing.T) { ctx := context.Background() bs := bstore.NewTemporarySync() - store := adt.WrapStore(ctx, cbornode.NewCborStore(bs)) + store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs)) - oldDeal1 := &market0.DealState{ + oldDeal1 := &market2.DealState{ SectorStartEpoch: 1, LastUpdatedEpoch: 2, SlashEpoch: 0, } - oldDeal2 := &market0.DealState{ + oldDeal2 := &market2.DealState{ SectorStartEpoch: 4, LastUpdatedEpoch: 5, SlashEpoch: 0, } - oldDeals := map[abi.DealID]*market0.DealState{ + oldDeals := map[abi.DealID]*market2.DealState{ abi.DealID(1): oldDeal1, abi.DealID(2): oldDeal2, } - oldProp1 := &market0.DealProposal{ + oldProp1 := &market2.DealProposal{ PieceCID: dummyCid, PieceSize: 0, VerifiedDeal: false, @@ -101,7 +101,7 @@ func TestMarketPredicates(t *testing.T) { ProviderCollateral: big.Zero(), ClientCollateral: big.Zero(), } - oldProp2 := &market0.DealProposal{ + oldProp2 := &market2.DealProposal{ PieceCID: dummyCid, PieceSize: 0, VerifiedDeal: false, @@ -113,7 +113,7 @@ func TestMarketPredicates(t *testing.T) { ProviderCollateral: big.Zero(), ClientCollateral: big.Zero(), } - oldProps := map[abi.DealID]*market0.DealProposal{ + oldProps := map[abi.DealID]*market2.DealProposal{ abi.DealID(1): oldProp1, abi.DealID(2): oldProp2, } @@ -127,7 +127,7 @@ func TestMarketPredicates(t *testing.T) { oldStateC := createMarketState(ctx, t, store, oldDeals, oldProps, oldBalances) - newDeal1 := &market0.DealState{ + newDeal1 := &market2.DealState{ SectorStartEpoch: 1, LastUpdatedEpoch: 3, SlashEpoch: 0, @@ -136,19 +136,19 @@ func TestMarketPredicates(t *testing.T) { // deal 2 removed // added - newDeal3 := &market0.DealState{ + newDeal3 := &market2.DealState{ SectorStartEpoch: 1, LastUpdatedEpoch: 2, SlashEpoch: 3, } - newDeals := map[abi.DealID]*market0.DealState{ + newDeals := map[abi.DealID]*market2.DealState{ abi.DealID(1): newDeal1, // deal 2 was removed abi.DealID(3): newDeal3, } // added - newProp3 := &market0.DealProposal{ + newProp3 := &market2.DealProposal{ PieceCID: dummyCid, PieceSize: 0, VerifiedDeal: false, @@ -160,7 +160,7 @@ func TestMarketPredicates(t *testing.T) { ProviderCollateral: big.Zero(), ClientCollateral: big.Zero(), } - newProps := map[abi.DealID]*market0.DealProposal{ + newProps := map[abi.DealID]*market2.DealProposal{ abi.DealID(1): oldProp1, // 1 was persisted // prop 2 was removed abi.DealID(3): newProp3, // new @@ -183,8 +183,8 @@ func TestMarketPredicates(t *testing.T) { require.NoError(t, err) api := newMockAPI(bs) - api.setActor(oldState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: oldStateC}) - api.setActor(newState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: newStateC}) + api.setActor(oldState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: oldStateC}) + api.setActor(newState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: newStateC}) t.Run("deal ID predicate", func(t *testing.T) { preds := NewStatePredicates(api) @@ -243,7 +243,7 @@ func TestMarketPredicates(t *testing.T) { marketCid, err := store.Put(ctx, marketState0) require.NoError(t, err) marketState, err := market.Load(store, &types.Actor{ - Code: builtin0.StorageMarketActorCodeID, + Code: builtin2.StorageMarketActorCodeID, Head: marketCid, }) require.NoError(t, err) @@ -356,7 +356,7 @@ func TestMarketPredicates(t *testing.T) { marketCid, err := store.Put(ctx, marketState0) require.NoError(t, err) marketState, err := market.Load(store, &types.Actor{ - Code: builtin0.StorageMarketActorCodeID, + Code: builtin2.StorageMarketActorCodeID, Head: marketCid, }) require.NoError(t, err) @@ -370,7 +370,7 @@ func TestMarketPredicates(t *testing.T) { func TestMinerSectorChange(t *testing.T) { ctx := context.Background() bs := bstore.NewTemporarySync() - store := adt.WrapStore(ctx, cbornode.NewCborStore(bs)) + store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs)) nextID := uint64(0) nextIDAddrF := func() address.Address { @@ -379,12 +379,12 @@ func TestMinerSectorChange(t *testing.T) { } owner, worker := nextIDAddrF(), nextIDAddrF() - si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner0.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10)) - si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner0.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11)) - si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner0.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11)) + si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner2.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10)) + si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner2.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11)) + si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner2.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11)) oldMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si0, si1, si2}) - si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner0.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12)) + si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner2.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12)) // 0 delete // 1 extend // 2 same @@ -400,8 +400,8 @@ func TestMinerSectorChange(t *testing.T) { require.NoError(t, err) api := newMockAPI(bs) - api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin0.StorageMinerActorCodeID}) - api.setActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin0.StorageMinerActorCodeID}) + api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin2.StorageMinerActorCodeID}) + api.setActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin2.StorageMinerActorCodeID}) preds := NewStatePredicates(api) @@ -467,7 +467,7 @@ type balance struct { locked abi.TokenAmount } -func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market0.DealState, props map[abi.DealID]*market0.DealProposal, balances map[address.Address]balance) cid.Cid { +func createMarketState(ctx context.Context, t *testing.T, store adt2.Store, deals map[abi.DealID]*market2.DealState, props map[abi.DealID]*market2.DealProposal, balances map[address.Address]balance) cid.Cid { dealRootCid := createDealAMT(ctx, t, store, deals) propRootCid := createProposalAMT(ctx, t, store, props) balancesCids := createBalanceTable(ctx, t, store, balances) @@ -482,16 +482,16 @@ func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals return stateC } -func createEmptyMarketState(t *testing.T, store adt.Store) *market0.State { - emptyArrayCid, err := adt.MakeEmptyArray(store).Root() +func createEmptyMarketState(t *testing.T, store adt2.Store) *market2.State { + emptyArrayCid, err := adt2.MakeEmptyArray(store).Root() require.NoError(t, err) - emptyMap, err := adt.MakeEmptyMap(store).Root() + emptyMap, err := adt2.MakeEmptyMap(store).Root() require.NoError(t, err) - return market0.ConstructState(emptyArrayCid, emptyMap, emptyMap) + return market2.ConstructState(emptyArrayCid, emptyMap, emptyMap) } -func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market0.DealState) cid.Cid { - root := adt.MakeEmptyArray(store) +func createDealAMT(ctx context.Context, t *testing.T, store adt2.Store, deals map[abi.DealID]*market2.DealState) cid.Cid { + root := adt2.MakeEmptyArray(store) for dealID, dealState := range deals { err := root.Set(uint64(dealID), dealState) require.NoError(t, err) @@ -501,8 +501,8 @@ func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map return rootCid } -func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props map[abi.DealID]*market0.DealProposal) cid.Cid { - root := adt.MakeEmptyArray(store) +func createProposalAMT(ctx context.Context, t *testing.T, store adt2.Store, props map[abi.DealID]*market2.DealProposal) cid.Cid { + root := adt2.MakeEmptyArray(store) for dealID, prop := range props { err := root.Set(uint64(dealID), prop) require.NoError(t, err) @@ -512,16 +512,16 @@ func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props return rootCid } -func createBalanceTable(ctx context.Context, t *testing.T, store adt.Store, balances map[address.Address]balance) [2]cid.Cid { - escrowMapRoot := adt.MakeEmptyMap(store) +func createBalanceTable(ctx context.Context, t *testing.T, store adt2.Store, balances map[address.Address]balance) [2]cid.Cid { + escrowMapRoot := adt2.MakeEmptyMap(store) escrowMapRootCid, err := escrowMapRoot.Root() require.NoError(t, err) - escrowRoot, err := adt.AsBalanceTable(store, escrowMapRootCid) + escrowRoot, err := adt2.AsBalanceTable(store, escrowMapRootCid) require.NoError(t, err) - lockedMapRoot := adt.MakeEmptyMap(store) + lockedMapRoot := adt2.MakeEmptyMap(store) lockedMapRootCid, err := lockedMapRoot.Root() require.NoError(t, err) - lockedRoot, err := adt.AsBalanceTable(store, lockedMapRootCid) + lockedRoot, err := adt2.AsBalanceTable(store, lockedMapRootCid) require.NoError(t, err) for addr, balance := range balances { @@ -538,7 +538,7 @@ func createBalanceTable(ctx context.Context, t *testing.T, store adt.Store, bala return [2]cid.Cid{escrowRootCid, lockedRootCid} } -func createMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address, sectors []miner.SectorOnChainInfo) cid.Cid { +func createMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner, worker address.Address, sectors []miner.SectorOnChainInfo) cid.Cid { rootCid := createSectorsAMT(ctx, t, store, sectors) state := createEmptyMinerState(ctx, t, store, owner, worker) @@ -549,20 +549,20 @@ func createMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, return stateC } -func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address) *miner0.State { - emptyArrayCid, err := adt.MakeEmptyArray(store).Root() +func createEmptyMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner, worker address.Address) *miner2.State { + emptyArrayCid, err := adt2.MakeEmptyArray(store).Root() require.NoError(t, err) - emptyMap, err := adt.MakeEmptyMap(store).Root() + emptyMap, err := adt2.MakeEmptyMap(store).Root() require.NoError(t, err) - emptyDeadline, err := store.Put(store.Context(), miner0.ConstructDeadline(emptyArrayCid)) + emptyDeadline, err := store.Put(store.Context(), miner2.ConstructDeadline(emptyArrayCid)) require.NoError(t, err) - emptyVestingFunds := miner0.ConstructVestingFunds() + emptyVestingFunds := miner2.ConstructVestingFunds() emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds) require.NoError(t, err) - emptyDeadlines := miner0.ConstructDeadlines(emptyDeadline) + emptyDeadlines := miner2.ConstructDeadlines(emptyDeadline) emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines) require.NoError(t, err) @@ -572,16 +572,30 @@ func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, o emptyBitfieldCid, err := store.Put(store.Context(), emptyBitfield) require.NoError(t, err) - state, err := miner0.ConstructState(minerInfo, 123, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid) + state, err := miner2.ConstructState(minerInfo, 123, 4, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid) require.NoError(t, err) return state } -func createSectorsAMT(ctx context.Context, t *testing.T, store adt.Store, sectors []miner.SectorOnChainInfo) cid.Cid { - root := adt.MakeEmptyArray(store) +func createSectorsAMT(ctx context.Context, t *testing.T, store adt2.Store, sectors []miner.SectorOnChainInfo) cid.Cid { + root := adt2.MakeEmptyArray(store) for _, sector := range sectors { - sector := (miner0.SectorOnChainInfo)(sector) + sector := miner2.SectorOnChainInfo{ + SectorNumber: sector.SectorNumber, + SealProof: sector.SealProof, + SealedCID: sector.SealedCID, + DealIDs: sector.DealIDs, + Activation: sector.Activation, + Expiration: sector.Expiration, + DealWeight: sector.DealWeight, + VerifiedDealWeight: sector.VerifiedDealWeight, + InitialPledge: sector.InitialPledge, + ExpectedDayReward: sector.ExpectedDayReward, + ExpectedStoragePledge: sector.ExpectedStoragePledge, + ReplacedSectorAge: 0, + ReplacedDayReward: big.NewInt(0), + } err := root.Set(uint64(sector.SectorNumber), §or) require.NoError(t, err) } @@ -614,8 +628,8 @@ const ( ) // returns a unique SectorPreCommitInfo with each invocation with SectorNumber set to `sectorNo`. -func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner0.SectorPreCommitInfo { - return &miner0.SectorPreCommitInfo{ +func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner2.SectorPreCommitInfo { + return &miner2.SectorPreCommitInfo{ SealProof: abi.RegisteredSealProof_StackedDrg32GiBV1, SectorNumber: sectorNo, SealedCID: sealed, @@ -625,7 +639,7 @@ func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiratio } } -func dealEquality(expected market0.DealState, actual market.DealState) bool { +func dealEquality(expected market2.DealState, actual market.DealState) bool { return expected.LastUpdatedEpoch == actual.LastUpdatedEpoch && expected.SectorStartEpoch == actual.SectorStartEpoch && expected.SlashEpoch == actual.SlashEpoch diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 288c84219..d56f285a0 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -8,13 +8,11 @@ import ( "sync/atomic" "time" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" - "github.com/google/uuid" - "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" + "github.com/google/uuid" block "github.com/ipfs/go-block-format" "github.com/ipfs/go-blockservice" "github.com/ipfs/go-cid" @@ -26,6 +24,8 @@ import ( "go.opencensus.io/trace" "golang.org/x/xerrors" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/policy" @@ -50,7 +50,7 @@ const msgsPerBlock = 20 //nolint:deadcode,varcheck var log = logging.Logger("gen") -var ValidWpostForTesting = []proof.PoStProof{{ +var ValidWpostForTesting = []proof2.PoStProof{{ ProofBytes: []byte("valid proof"), }} @@ -467,7 +467,7 @@ func (cg *ChainGen) NextTipSetFromMinersWithMessages(base *types.TipSet, miners func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticket *types.Ticket, eticket *types.ElectionProof, bvals []types.BeaconEntry, height abi.ChainEpoch, - wpost []proof.PoStProof, msgs []*types.SignedMessage) (*types.FullBlock, error) { + wpost []proof2.PoStProof, msgs []*types.SignedMessage) (*types.FullBlock, error) { var ts uint64 if cg.Timestamper != nil { @@ -605,7 +605,7 @@ func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*cr type WinningPoStProver interface { GenerateCandidates(context.Context, abi.PoStRandomness, uint64) ([]uint64, error) - ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error) + ComputeProof(context.Context, []proof2.SectorInfo, abi.PoStRandomness) ([]proof2.PoStProof, error) } type wppProvider struct{} @@ -614,7 +614,7 @@ func (wpp *wppProvider) GenerateCandidates(ctx context.Context, _ abi.PoStRandom return []uint64{0}, nil } -func (wpp *wppProvider) ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error) { +func (wpp *wppProvider) ComputeProof(context.Context, []proof2.SectorInfo, abi.PoStRandomness) ([]proof2.PoStProof, error) { return ValidWpostForTesting, nil } @@ -681,15 +681,15 @@ type genFakeVerifier struct{} var _ ffiwrapper.Verifier = (*genFakeVerifier)(nil) -func (m genFakeVerifier) VerifySeal(svi proof.SealVerifyInfo) (bool, error) { +func (m genFakeVerifier) VerifySeal(svi proof2.SealVerifyInfo) (bool, error) { return true, nil } -func (m genFakeVerifier) VerifyWinningPoSt(ctx context.Context, info proof.WinningPoStVerifyInfo) (bool, error) { +func (m genFakeVerifier) VerifyWinningPoSt(ctx context.Context, info proof2.WinningPoStVerifyInfo) (bool, error) { panic("not supported") } -func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info proof.WindowPoStVerifyInfo) (bool, error) { +func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info proof2.WindowPoStVerifyInfo) (bool, error) { panic("not supported") } diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index 1023e5efa..49e09d792 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -24,11 +24,12 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" - "github.com/filecoin-project/specs-actors/actors/builtin" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" - "github.com/filecoin-project/specs-actors/actors/runtime" + runtime2 "github.com/filecoin-project/specs-actors/v2/actors/runtime" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/store" @@ -47,7 +48,7 @@ func MinerAddress(genesisIndex uint64) address.Address { } type fakedSigSyscalls struct { - runtime.Syscalls + runtime2.Syscalls } func (fss *fakedSigSyscalls) VerifySignature(signature crypto.Signature, signer address.Address, plaintext []byte) error { @@ -55,7 +56,7 @@ func (fss *fakedSigSyscalls) VerifySignature(signature crypto.Signature, signer } func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder { - return func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls { + return func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime2.Syscalls { return &fakedSigSyscalls{ base(ctx, cstate, cst), } @@ -114,7 +115,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, builtin.MethodsPower.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) } @@ -146,7 +147,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid if m.MarketBalance.GreaterThan(big.Zero()) { params := mustEnc(&minerInfos[i].maddr) - _, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin.MethodsMarket.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) } @@ -158,7 +159,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid publish := func(params *market.PublishStorageDealsParams) error { fmt.Printf("publishing %d storage deals on miner %s with worker %s\n", len(params.Deals), params.Deals[0].Proposal.Provider, m.Worker) - ret, err := doExecValue(ctx, vm, market.Address, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params)) + ret, err := doExecValue(ctx, vm, market.Address, m.Worker, big.Zero(), builtin0.MethodsMarket.PublishStorageDeals, mustEnc(params)) if err != nil { return xerrors.Errorf("failed to create genesis miner (publish deals): %w", err) } @@ -290,17 +291,17 @@ 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, builtin.MethodsMiner.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) } // Commit one-by-one, otherwise pledge math tends to explode - confirmParams := &builtin.ConfirmSectorProofsParams{ + confirmParams := &builtin0.ConfirmSectorProofsParams{ Sectors: []abi.SectorNumber{preseal.SectorID}, } - _, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin.MethodsMiner.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) } @@ -349,7 +350,7 @@ func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization cry } func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) { - pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin.MethodsPower.CurrentTotalPower, nil) + pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin0.MethodsPower.CurrentTotalPower, nil) if err != nil { return nil, err } @@ -373,7 +374,7 @@ func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs [ market.Address, maddr, abi.NewTokenAmount(0), - builtin.MethodsMarket.VerifyDealsForActivation, + builtin0.MethodsMarket.VerifyDealsForActivation, mustEnc(params), ) if err != nil { @@ -387,7 +388,7 @@ func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs [ } func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward0.ThisEpochRewardReturn, error) { - rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin.MethodsReward.ThisEpochReward, nil) + rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin0.MethodsReward.ThisEpochReward, nil) if err != nil { return nil, err } @@ -405,7 +406,7 @@ func circSupply(ctx context.Context, vmi *vm.VM, maddr address.Address) abi.Toke rt := unsafeVM.MakeRuntime(ctx, &types.Message{ GasLimit: 1_000_000_000, From: maddr, - }, maddr, 0, 0, 0) + }) return rt.TotalFilCircSupply() } diff --git a/chain/gen/genesis/util.go b/chain/gen/genesis/util.go index bcafb007e..54cc30cc1 100644 --- a/chain/gen/genesis/util.go +++ b/chain/gen/genesis/util.go @@ -50,12 +50,27 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value return ret.Return, nil } -var GenesisNetworkVersion = func() network.Version { // TODO: Get from build/ - if build.UseNewestNetwork() { // TODO: Get from build/ - return build.NewestNetworkVersion // TODO: Get from build/ - } // TODO: Get from build/ - return network.Version1 // TODO: Get from build/ -}() // TODO: Get from build/ +// 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/ diff --git a/chain/gen/mining.go b/chain/gen/mining.go index 45a089452..5fc56e8b2 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -4,17 +4,14 @@ import ( "context" "github.com/filecoin-project/go-state-types/crypto" - "github.com/filecoin-project/specs-actors/actors/util/adt" + blockadt "github.com/filecoin-project/specs-actors/actors/util/adt" cid "github.com/ipfs/go-cid" - cbor "github.com/ipfs/go-ipld-cbor" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/lib/sigs/bls" ) @@ -30,7 +27,17 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletA return nil, xerrors.Errorf("failed to load tipset state: %w", err) } - worker, err := stmgr.GetMinerWorkerRaw(ctx, sm, st, bt.Miner) + lbts, err := stmgr.GetLookbackTipSetForRound(ctx, sm, pts, bt.Epoch) + if err != nil { + return nil, xerrors.Errorf("getting lookback miner actor state: %w", err) + } + + lbst, _, err := sm.TipSetState(ctx, lbts) + if err != nil { + return nil, err + } + + worker, err := stmgr.GetMinerWorkerRaw(ctx, sm, lbst, bt.Miner) if err != nil { return nil, xerrors.Errorf("failed to get miner worker: %w", err) } @@ -114,23 +121,12 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletA } next.ParentBaseFee = baseFee - cst := cbor.NewCborStore(sm.ChainStore().Blockstore()) - tree, err := state.LoadStateTree(cst, st) - if err != nil { - return nil, xerrors.Errorf("failed to load state tree: %w", err) - } - - waddr, err := vm.ResolveToKeyAddr(tree, cst, worker) - if err != nil { - return nil, xerrors.Errorf("failed to resolve miner address to key address: %w", err) - } - nosigbytes, err := next.SigningBytes() if err != nil { return nil, xerrors.Errorf("failed to get signing bytes for block: %w", err) } - sig, err := w.WalletSign(ctx, waddr, nosigbytes, api.MsgMeta{ + sig, err := w.WalletSign(ctx, worker, nosigbytes, api.MsgMeta{ Type: api.MTBlock, }) if err != nil { @@ -181,8 +177,8 @@ func aggregateSignatures(sigs []crypto.Signature) (*crypto.Signature, error) { }, nil } -func toArray(store adt.Store, cids []cid.Cid) (cid.Cid, error) { - arr := adt.MakeEmptyArray(store) +func toArray(store blockadt.Store, cids []cid.Cid) (cid.Cid, error) { + arr := blockadt.MakeEmptyArray(store) for i, c := range cids { oc := cbg.CborCid(c) if err := arr.Set(uint64(i), &oc); err != nil { diff --git a/chain/market/fundmgr.go b/chain/market/fundmgr.go index 8b5f85a12..50467a6e1 100644 --- a/chain/market/fundmgr.go +++ b/chain/market/fundmgr.go @@ -4,15 +4,13 @@ import ( "context" "sync" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - "go.uber.org/fx" - - "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log" + "go.uber.org/fx" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin/market" @@ -156,7 +154,7 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Add To: market.Address, From: wallet, Value: toAdd, - Method: builtin.MethodsMarket.AddBalance, + Method: market.Methods.AddBalance, Params: params, }, nil) if err != nil { diff --git a/chain/market/fundmgr_test.go b/chain/market/fundmgr_test.go index f5936f73d..88ca2e16f 100644 --- a/chain/market/fundmgr_test.go +++ b/chain/market/fundmgr_test.go @@ -12,8 +12,8 @@ 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/specs-actors/actors/builtin" - tutils "github.com/filecoin-project/specs-actors/support/testing" + + tutils "github.com/filecoin-project/specs-actors/v2/support/testing" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" @@ -51,7 +51,7 @@ func addFundsMsg(toAdd abi.TokenAmount, addr address.Address, wallet address.Add To: market.Address, From: wallet, Value: toAdd, - Method: builtin.MethodsMarket.AddBalance, + Method: market.Methods.AddBalance, Params: params, } } diff --git a/chain/messagepool/gasguess/guessgas.go b/chain/messagepool/gasguess/guessgas.go index 607c7824a..76ab39078 100644 --- a/chain/messagepool/gasguess/guessgas.go +++ b/chain/messagepool/gasguess/guessgas.go @@ -6,6 +6,7 @@ import ( "github.com/ipfs/go-cid" "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/go-address" @@ -68,7 +69,7 @@ func failedGuess(msg *types.SignedMessage) int64 { func GuessGasUsed(ctx context.Context, tsk types.TipSetKey, msg *types.SignedMessage, al ActorLookup) (int64, error) { // MethodSend is the same in all versions. - if msg.Message.Method == builtin0.MethodSend { + if msg.Message.Method == builtin.MethodSend { switch msg.Message.From.Protocol() { case address.BLS: return 1298450, nil diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index cc26be0b5..79ab572ba 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -432,9 +432,14 @@ func (mp *MessagePool) runLoop() { } } -func (mp *MessagePool) addLocal(m *types.SignedMessage, msgb []byte) error { +func (mp *MessagePool) addLocal(m *types.SignedMessage) error { mp.localAddrs[m.Message.From] = struct{}{} + msgb, err := m.Serialize() + if err != nil { + return xerrors.Errorf("error serializing message: %w", err) + } + if err := mp.localMsgs.Put(datastore.NewKey(string(m.Cid().Bytes())), msgb); err != nil { return xerrors.Errorf("persisting local message: %w", err) } @@ -507,11 +512,6 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) { <-mp.addSema }() - msgb, err := m.Serialize() - if err != nil { - return cid.Undef, err - } - mp.curTsLk.Lock() publish, err := mp.addTs(m, mp.curTs, true, false) if err != nil { @@ -520,18 +520,19 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) { } mp.curTsLk.Unlock() - mp.lk.Lock() - if err := mp.addLocal(m, msgb); err != nil { - mp.lk.Unlock() - return cid.Undef, err - } - mp.lk.Unlock() - if publish { + msgb, err := m.Serialize() + if err != nil { + return cid.Undef, xerrors.Errorf("error serializing message: %w", err) + } + err = mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb) + if err != nil { + return cid.Undef, xerrors.Errorf("error publishing message: %w", err) + } } - return m.Cid(), err + return m.Cid(), nil } func (mp *MessagePool) checkMessage(m *types.SignedMessage) error { @@ -670,7 +671,19 @@ func (mp *MessagePool) addTs(m *types.SignedMessage, curTs *types.TipSet, local, return false, err } - return publish, mp.addLocked(m, !local, untrusted) + err = mp.addLocked(m, !local, untrusted) + if err != nil { + return false, err + } + + if local { + err = mp.addLocal(m) + if err != nil { + return false, xerrors.Errorf("error persisting local message: %w", err) + } + } + + return publish, nil } func (mp *MessagePool) addLoaded(m *types.SignedMessage) error { @@ -837,11 +850,6 @@ func (mp *MessagePool) PushUntrusted(m *types.SignedMessage) (cid.Cid, error) { <-mp.addSema }() - msgb, err := m.Serialize() - if err != nil { - return cid.Undef, err - } - mp.curTsLk.Lock() publish, err := mp.addTs(m, mp.curTs, false, true) if err != nil { @@ -850,18 +858,19 @@ func (mp *MessagePool) PushUntrusted(m *types.SignedMessage) (cid.Cid, error) { } mp.curTsLk.Unlock() - mp.lk.Lock() - if err := mp.addLocal(m, msgb); err != nil { - mp.lk.Unlock() - return cid.Undef, err - } - mp.lk.Unlock() - if publish { + msgb, err := m.Serialize() + if err != nil { + return cid.Undef, xerrors.Errorf("error serializing message: %w", err) + } + err = mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb) + if err != nil { + return cid.Undef, xerrors.Errorf("error publishing message: %w", err) + } } - return m.Cid(), err + return m.Cid(), nil } func (mp *MessagePool) Remove(from address.Address, nonce uint64, applied bool) { diff --git a/chain/messagepool/messagepool_test.go b/chain/messagepool/messagepool_test.go index 8f6613cad..e31df936c 100644 --- a/chain/messagepool/messagepool_test.go +++ b/chain/messagepool/messagepool_test.go @@ -8,16 +8,18 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + logging "github.com/ipfs/go-log/v2" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/filecoin-project/lotus/chain/messagepool/gasguess" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/mock" "github.com/filecoin-project/lotus/chain/wallet" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/ipfs/go-cid" - "github.com/ipfs/go-datastore" - logging "github.com/ipfs/go-log/v2" ) func init() { @@ -142,7 +144,7 @@ func (tma *testMpoolAPI) GetActorAfter(addr address.Address, ts *types.TipSet) ( } return &types.Actor{ - Code: builtin.StorageMarketActorCodeID, + Code: builtin2.StorageMarketActorCodeID, Nonce: nonce, Balance: balance, }, nil @@ -449,7 +451,7 @@ func TestLoadLocal(t *testing.T) { tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] msgs := make(map[cid.Cid]struct{}) for i := 0; i < 10; i++ { m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) @@ -521,7 +523,7 @@ func TestClearAll(t *testing.T) { tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] for i := 0; i < 10; i++ { m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) _, err := mp.Push(m) @@ -576,7 +578,7 @@ func TestClearNonLocal(t *testing.T) { tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] for i := 0; i < 10; i++ { m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) _, err := mp.Push(m) @@ -642,7 +644,7 @@ func TestUpdates(t *testing.T) { t.Fatal(err) } - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL diff --git a/chain/messagepool/repub_test.go b/chain/messagepool/repub_test.go index 9cadf24c7..8da64f974 100644 --- a/chain/messagepool/repub_test.go +++ b/chain/messagepool/repub_test.go @@ -5,11 +5,13 @@ import ( "testing" "time" + "github.com/ipfs/go-datastore" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/filecoin-project/lotus/chain/messagepool/gasguess" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/ipfs/go-datastore" ) func TestRepubMessages(t *testing.T) { @@ -48,7 +50,7 @@ func TestRepubMessages(t *testing.T) { t.Fatal(err) } - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] tma.setBalance(a1, 1) // in FIL diff --git a/chain/messagepool/selection_test.go b/chain/messagepool/selection_test.go index 37c2f2dc0..08cf286c8 100644 --- a/chain/messagepool/selection_test.go +++ b/chain/messagepool/selection_test.go @@ -13,17 +13,18 @@ import ( "sort" "testing" + "github.com/filecoin-project/go-address" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" logging "github.com/ipfs/go-log" - "github.com/filecoin-project/go-address" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/messagepool/gasguess" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/mock" "github.com/filecoin-project/lotus/chain/wallet" - "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/lotus/api" _ "github.com/filecoin-project/lotus/lib/sigs/bls" @@ -94,7 +95,7 @@ func TestMessageChains(t *testing.T) { block := tma.nextBlock() ts := mock.TipSet(block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] tma.setBalance(a1, 1) // in FIL @@ -332,7 +333,7 @@ func TestMessageChainSkipping(t *testing.T) { block := tma.nextBlock() ts := mock.TipSet(block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] baseFee := types.NewInt(0) tma.setBalance(a1, 1) // in FIL @@ -409,7 +410,7 @@ func TestBasicMessageSelection(t *testing.T) { ts := mock.TipSet(block) tma.applyBlock(t, block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL @@ -553,7 +554,7 @@ func TestMessageSelectionTrimming(t *testing.T) { ts := mock.TipSet(block) tma.applyBlock(t, block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL @@ -616,7 +617,7 @@ func TestPriorityMessageSelection(t *testing.T) { ts := mock.TipSet(block) tma.applyBlock(t, block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL @@ -695,7 +696,7 @@ func TestPriorityMessageSelection2(t *testing.T) { ts := mock.TipSet(block) tma.applyBlock(t, block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL @@ -764,7 +765,7 @@ func TestPriorityMessageSelection3(t *testing.T) { ts := mock.TipSet(block) tma.applyBlock(t, block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL @@ -861,7 +862,7 @@ func TestOptimalMessageSelection1(t *testing.T) { ts := mock.TipSet(block) tma.applyBlock(t, block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL @@ -928,7 +929,7 @@ func TestOptimalMessageSelection2(t *testing.T) { ts := mock.TipSet(block) tma.applyBlock(t, block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] tma.setBalance(a1, 1) // in FIL tma.setBalance(a2, 1) // in FIL @@ -1006,7 +1007,7 @@ func TestOptimalMessageSelection3(t *testing.T) { ts := mock.TipSet(block) tma.applyBlock(t, block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] for _, a := range actors { tma.setBalance(a, 1) // in FIL @@ -1086,7 +1087,7 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu ts := mock.TipSet(block) tma.applyBlock(t, block) - gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}] + gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] baseFee := types.NewInt(0) for _, a := range actors { diff --git a/chain/state/statetree.go b/chain/state/statetree.go index e9b76ea77..7fa55b31c 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -26,16 +26,18 @@ var log = logging.Logger("statetree") // StateTree stores actors state by their ID. type StateTree struct { - root adt.Map - version types.StateTreeVersion - info cid.Cid - Store cbor.IpldStore + root adt.Map + version types.StateTreeVersion + info cid.Cid + Store cbor.IpldStore + lookupIDFun func(address.Address) (address.Address, error) snaps *stateSnaps } type stateSnaps struct { - layers []*stateSnapLayer + layers []*stateSnapLayer + lastMaybeNonEmptyResolveCache int } type stateSnapLayer struct { @@ -67,7 +69,12 @@ func (ss *stateSnaps) addLayer() { func (ss *stateSnaps) dropLayer() { ss.layers[len(ss.layers)-1] = nil // allow it to be GCed + ss.layers = ss.layers[:len(ss.layers)-1] + + if ss.lastMaybeNonEmptyResolveCache == len(ss.layers) { + ss.lastMaybeNonEmptyResolveCache = len(ss.layers) - 1 + } } func (ss *stateSnaps) mergeLastLayer() { @@ -86,7 +93,13 @@ func (ss *stateSnaps) mergeLastLayer() { } func (ss *stateSnaps) resolveAddress(addr address.Address) (address.Address, bool) { - for i := len(ss.layers) - 1; i >= 0; i-- { + for i := ss.lastMaybeNonEmptyResolveCache; i >= 0; i-- { + if len(ss.layers[i].resolveCache) == 0 { + if ss.lastMaybeNonEmptyResolveCache == i { + ss.lastMaybeNonEmptyResolveCache = i - 1 + } + continue + } resa, ok := ss.layers[i].resolveCache[addr] if ok { return resa, true @@ -97,6 +110,7 @@ func (ss *stateSnaps) resolveAddress(addr address.Address) (address.Address, boo func (ss *stateSnaps) cacheResolveAddress(addr, resa address.Address) { ss.layers[len(ss.layers)-1].resolveCache[addr] = resa + ss.lastMaybeNonEmptyResolveCache = len(ss.layers) - 1 } func (ss *stateSnaps) getActor(addr address.Address) (*types.Actor, error) { @@ -160,13 +174,15 @@ func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, e return nil, err } - return &StateTree{ + s := &StateTree{ root: root, info: info, version: ver, Store: cst, snaps: newStateSnaps(), - }, nil + } + s.lookupIDFun = s.lookupIDinternal + return s, nil } func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { @@ -190,13 +206,15 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { return nil, err } - return &StateTree{ + s := &StateTree{ root: nd, info: root.Info, version: root.Version, Store: cst, snaps: newStateSnaps(), - }, nil + } + s.lookupIDFun = s.lookupIDinternal + return s, nil default: return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version) } @@ -213,17 +231,7 @@ func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error { return nil } -// LookupID gets the ID address of this actor's `addr` stored in the `InitActor`. -func (st *StateTree) LookupID(addr address.Address) (address.Address, error) { - if addr.Protocol() == address.ID { - return addr, nil - } - - resa, ok := st.snaps.resolveAddress(addr) - if ok { - return resa, nil - } - +func (st *StateTree) lookupIDinternal(addr address.Address) (address.Address, error) { act, err := st.GetActor(init_.Address) if err != nil { return address.Undef, xerrors.Errorf("getting init actor: %w", err) @@ -241,6 +249,23 @@ func (st *StateTree) LookupID(addr address.Address) (address.Address, error) { if err != nil { return address.Undef, xerrors.Errorf("resolve address %s: %w", addr, err) } + return a, err +} + +// LookupID gets the ID address of this actor's `addr` stored in the `InitActor`. +func (st *StateTree) LookupID(addr address.Address) (address.Address, error) { + if addr.Protocol() == address.ID { + return addr, nil + } + + resa, ok := st.snaps.resolveAddress(addr) + if ok { + return resa, nil + } + a, err := st.lookupIDFun(addr) + if err != nil { + return a, err + } st.snaps.cacheResolveAddress(addr, a) diff --git a/chain/state/statetree_test.go b/chain/state/statetree_test.go index ed1fb1889..91674337b 100644 --- a/chain/state/statetree_test.go +++ b/chain/state/statetree_test.go @@ -10,7 +10,7 @@ import ( address "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" @@ -18,7 +18,7 @@ import ( func BenchmarkStateTreeSet(b *testing.B) { cst := cbor.NewMemCborStore() - st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + st, err := NewStateTree(cst, types.StateTreeVersion1) if err != nil { b.Fatal(err) } @@ -33,8 +33,8 @@ func BenchmarkStateTreeSet(b *testing.B) { } err = st.SetActor(a, &types.Actor{ Balance: types.NewInt(1258812523), - Code: builtin.StorageMinerActorCodeID, - Head: builtin.AccountActorCodeID, + Code: builtin2.StorageMinerActorCodeID, + Head: builtin2.AccountActorCodeID, Nonce: uint64(i), }) if err != nil { @@ -60,8 +60,8 @@ func BenchmarkStateTreeSetFlush(b *testing.B) { } err = st.SetActor(a, &types.Actor{ Balance: types.NewInt(1258812523), - Code: builtin.StorageMinerActorCodeID, - Head: builtin.AccountActorCodeID, + Code: builtin2.StorageMinerActorCodeID, + Head: builtin2.AccountActorCodeID, Nonce: uint64(i), }) if err != nil { @@ -73,6 +73,103 @@ func BenchmarkStateTreeSetFlush(b *testing.B) { } } +func TestResolveCache(t *testing.T) { + cst := cbor.NewMemCborStore() + st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) + if err != nil { + t.Fatal(err) + } + nonId := address.NewForTestGetter()() + id, _ := address.NewIDAddress(1000) + + st.lookupIDFun = func(a address.Address) (address.Address, error) { + if a == nonId { + return id, nil + } + return address.Undef, types.ErrActorNotFound + } + + err = st.SetActor(nonId, &types.Actor{Nonce: 1}) + if err != nil { + t.Fatal(err) + } + + { + err = st.Snapshot(context.TODO()) + if err != nil { + t.Fatal(err) + } + act, err := st.GetActor(nonId) + if err != nil { + t.Fatal(err) + } + if act.Nonce != 1 { + t.Fatalf("expected nonce 1, got %d", act.Nonce) + } + err = st.SetActor(nonId, &types.Actor{Nonce: 2}) + if err != nil { + t.Fatal(err) + } + + act, err = st.GetActor(nonId) + if err != nil { + t.Fatal(err) + } + if act.Nonce != 2 { + t.Fatalf("expected nonce 2, got %d", act.Nonce) + } + + if err := st.Revert(); err != nil { + t.Fatal(err) + } + st.ClearSnapshot() + } + + act, err := st.GetActor(nonId) + if err != nil { + t.Fatal(err) + } + if act.Nonce != 1 { + t.Fatalf("expected nonce 1, got %d", act.Nonce) + } + + { + err = st.Snapshot(context.TODO()) + if err != nil { + t.Fatal(err) + } + act, err := st.GetActor(nonId) + if err != nil { + t.Fatal(err) + } + if act.Nonce != 1 { + t.Fatalf("expected nonce 1, got %d", act.Nonce) + } + err = st.SetActor(nonId, &types.Actor{Nonce: 2}) + if err != nil { + t.Fatal(err) + } + + act, err = st.GetActor(nonId) + if err != nil { + t.Fatal(err) + } + if act.Nonce != 2 { + t.Fatalf("expected nonce 2, got %d", act.Nonce) + } + st.ClearSnapshot() + } + + act, err = st.GetActor(nonId) + if err != nil { + t.Fatal(err) + } + if act.Nonce != 2 { + t.Fatalf("expected nonce 2, got %d", act.Nonce) + } + +} + func BenchmarkStateTree10kGetActor(b *testing.B) { cst := cbor.NewMemCborStore() st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) @@ -86,8 +183,8 @@ func BenchmarkStateTree10kGetActor(b *testing.B) { } err = st.SetActor(a, &types.Actor{ Balance: types.NewInt(1258812523 + uint64(i)), - Code: builtin.StorageMinerActorCodeID, - Head: builtin.AccountActorCodeID, + Code: builtin2.StorageMinerActorCodeID, + Head: builtin2.AccountActorCodeID, Nonce: uint64(i), }) if err != nil { @@ -129,8 +226,8 @@ func TestSetCache(t *testing.T) { act := &types.Actor{ Balance: types.NewInt(0), - Code: builtin.StorageMinerActorCodeID, - Head: builtin.AccountActorCodeID, + Code: builtin2.StorageMinerActorCodeID, + Head: builtin2.AccountActorCodeID, Nonce: 0, } @@ -173,7 +270,7 @@ func TestSnapshots(t *testing.T) { t.Fatal(err) } - if err := st.SetActor(addrs[0], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(55)}); err != nil { + if err := st.SetActor(addrs[0], &types.Actor{Code: builtin2.AccountActorCodeID, Head: builtin2.AccountActorCodeID, Balance: types.NewInt(55)}); err != nil { t.Fatal(err) } @@ -182,7 +279,7 @@ func TestSnapshots(t *testing.T) { t.Fatal(err) } - if err := st.SetActor(addrs[1], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(77)}); err != nil { + if err := st.SetActor(addrs[1], &types.Actor{Code: builtin2.AccountActorCodeID, Head: builtin2.AccountActorCodeID, Balance: types.NewInt(77)}); err != nil { t.Fatal(err) } @@ -193,7 +290,7 @@ func TestSnapshots(t *testing.T) { } // more operations in top level call... - if err := st.SetActor(addrs[2], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(123)}); err != nil { + if err := st.SetActor(addrs[2], &types.Actor{Code: builtin2.AccountActorCodeID, Head: builtin2.AccountActorCodeID, Balance: types.NewInt(123)}); err != nil { t.Fatal(err) } @@ -202,7 +299,7 @@ func TestSnapshots(t *testing.T) { t.Fatal(err) } - if err := st.SetActor(addrs[3], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(5)}); err != nil { + if err := st.SetActor(addrs[3], &types.Actor{Code: builtin2.AccountActorCodeID, Head: builtin2.AccountActorCodeID, Balance: types.NewInt(5)}); err != nil { t.Fatal(err) } diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 488f84167..e089a1084 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -86,6 +86,10 @@ func DefaultUpgradeSchedule() UpgradeSchedule { Height: build.UpgradeLiftoffHeight, Network: network.Version5, Migration: UpgradeLiftoff, + }, { + Height: build.UpgradeKumquatHeight, + Network: network.Version6, + Migration: nil, }} if build.UpgradeActorsV2Height == math.MaxInt64 { // disable actors upgrade @@ -539,17 +543,17 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo return cid.Undef, xerrors.Errorf("second split address: %w", err) } - err = resetGenesisMsigs(ctx, sm, store, tree, build.UpgradeLiftoffHeight) + err = resetGenesisMsigs0(ctx, sm, store, tree, build.UpgradeLiftoffHeight) if err != nil { return cid.Undef, xerrors.Errorf("resetting genesis msig start epochs: %w", err) } - err = splitGenesisMultisig(ctx, cb, split1, store, tree, 50, epoch) + err = splitGenesisMultisig0(ctx, cb, split1, store, tree, 50, epoch) if err != nil { return cid.Undef, xerrors.Errorf("splitting first msig: %w", err) } - err = splitGenesisMultisig(ctx, cb, split2, store, tree, 50, epoch) + err = splitGenesisMultisig0(ctx, cb, split2, store, tree, 50, epoch) if err != nil { return cid.Undef, xerrors.Errorf("splitting second msig: %w", err) } @@ -570,17 +574,17 @@ func UpgradeRefuel(ctx context.Context, sm *StateManager, cb ExecCallback, root return cid.Undef, xerrors.Errorf("getting state tree: %w", err) } - err = resetMultisigVesting(ctx, store, tree, builtin.SaftAddress, 0, 0, big.Zero()) + err = resetMultisigVesting0(ctx, store, tree, builtin.SaftAddress, 0, 0, big.Zero()) if err != nil { return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) } - err = resetMultisigVesting(ctx, store, tree, builtin.ReserveAddress, 0, 0, big.Zero()) + err = resetMultisigVesting0(ctx, store, tree, builtin.ReserveAddress, 0, 0, big.Zero()) if err != nil { return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) } - err = resetMultisigVesting(ctx, store, tree, builtin.RootVerifierAddress, 0, 0, big.Zero()) + err = resetMultisigVesting0(ctx, store, tree, builtin.RootVerifierAddress, 0, 0, big.Zero()) if err != nil { return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) } @@ -675,7 +679,7 @@ func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree, return nil } -func splitGenesisMultisig(ctx context.Context, cb ExecCallback, addr address.Address, store adt0.Store, tree *state.StateTree, portions uint64, epoch abi.ChainEpoch) error { +func splitGenesisMultisig0(ctx context.Context, cb ExecCallback, addr address.Address, store adt0.Store, tree *state.StateTree, portions uint64, epoch abi.ChainEpoch) error { if portions < 1 { return xerrors.Errorf("cannot split into 0 portions") } @@ -831,7 +835,7 @@ func makeKeyAddr(splitAddr address.Address, count uint64) (address.Address, erro } // TODO: After the Liftoff epoch, refactor this to use resetMultisigVesting -func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree, startEpoch abi.ChainEpoch) error { +func resetGenesisMsigs0(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree, startEpoch abi.ChainEpoch) error { gb, err := sm.cs.GetGenesis() if err != nil { return xerrors.Errorf("getting genesis block: %w", err) @@ -881,7 +885,7 @@ func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, return nil } -func resetMultisigVesting(ctx context.Context, store adt0.Store, tree *state.StateTree, addr address.Address, startEpoch abi.ChainEpoch, duration abi.ChainEpoch, balance abi.TokenAmount) error { +func resetMultisigVesting0(ctx context.Context, store adt0.Store, tree *state.StateTree, addr address.Address, startEpoch abi.ChainEpoch, duration abi.ChainEpoch, balance abi.TokenAmount) error { act, err := tree.GetActor(addr) if err != nil { return xerrors.Errorf("getting actor: %w", err) diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index 0388af6ad..a2b7a179f 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -16,14 +16,15 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" - "github.com/filecoin-project/specs-actors/actors/builtin" - init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" - "github.com/filecoin-project/specs-actors/actors/runtime" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + rt2 "github.com/filecoin-project/specs-actors/v2/actors/runtime" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" - lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init" + _init "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/gen" . "github.com/filecoin-project/lotus/chain/stmgr" @@ -45,7 +46,7 @@ type testActor struct { } // must use existing actor that an account is allowed to exec. -func (testActor) Code() cid.Cid { return builtin.PaymentChannelActorCodeID } +func (testActor) Code() cid.Cid { return builtin0.PaymentChannelActorCodeID } func (testActor) State() cbor.Er { return new(testActorState) } type testActorState struct { @@ -75,7 +76,7 @@ func (ta testActor) Exports() []interface{} { } } -func (ta *testActor) Constructor(rt runtime.Runtime, params *abi.EmptyValue) *abi.EmptyValue { +func (ta *testActor) Constructor(rt rt2.Runtime, params *abi.EmptyValue) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() rt.StateCreate(&testActorState{11}) //fmt.Println("NEW ACTOR ADDRESS IS: ", rt.Receiver()) @@ -83,7 +84,7 @@ func (ta *testActor) Constructor(rt runtime.Runtime, params *abi.EmptyValue) *ab return abi.Empty } -func (ta *testActor) TestMethod(rt runtime.Runtime, params *abi.EmptyValue) *abi.EmptyValue { +func (ta *testActor) TestMethod(rt rt2.Runtime, params *abi.EmptyValue) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() var st testActorState rt.StateReadonly(&st) @@ -175,15 +176,15 @@ func TestForkHeightTriggers(t *testing.T) { var msgs []*types.SignedMessage - enc, err := actors.SerializeParams(&init0.ExecParams{CodeCID: (testActor{}).Code()}) + enc, err := actors.SerializeParams(&init2.ExecParams{CodeCID: (testActor{}).Code()}) if err != nil { t.Fatal(err) } m := &types.Message{ From: cg.Banker(), - To: lotusinit.Address, - Method: builtin.MethodsInit.Exec, + To: _init.Address, + Method: _init.Methods.Exec, Params: enc, GasLimit: types.TestGasLimit, } @@ -273,15 +274,15 @@ func TestForkRefuseCall(t *testing.T) { cg.SetStateManager(sm) - enc, err := actors.SerializeParams(&init0.ExecParams{CodeCID: (testActor{}).Code()}) + enc, err := actors.SerializeParams(&init2.ExecParams{CodeCID: (testActor{}).Code()}) if err != nil { t.Fatal(err) } m := &types.Message{ From: cg.Banker(), - To: lotusinit.Address, - Method: builtin.MethodsInit.Exec, + To: _init.Address, + Method: _init.Methods.Exec, Params: enc, GasLimit: types.TestGasLimit, Value: types.NewInt(0), diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index be14797d9..2822344b0 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -6,16 +6,6 @@ import ( "fmt" "sync" - "github.com/filecoin-project/lotus/chain/actors/builtin" - "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" - - _init "github.com/filecoin-project/lotus/chain/actors/builtin/init" - - "github.com/filecoin-project/lotus/chain/actors/builtin/miner" - - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" logging "github.com/ipfs/go-log/v2" @@ -28,15 +18,23 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" + // Used for genesis. + msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + "github.com/filecoin-project/lotus/api" "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" + "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/market" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/actors/builtin/reward" + "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -48,6 +46,8 @@ const LookbackNoLimit = abi.ChainEpoch(-1) var log = logging.Logger("statemgr") type StateManagerAPI interface { + Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) + GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error) LoadActorTsk(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) LookupID(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) @@ -254,14 +254,14 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp runCron := func(epoch abi.ChainEpoch) error { cronMsg := &types.Message{ - To: builtin0.CronActorAddr, - From: builtin0.SystemActorAddr, + To: cron.Address, + From: builtin.SystemActorAddr, Nonce: uint64(epoch), Value: types.NewInt(0), GasFeeCap: types.NewInt(0), GasPremium: types.NewInt(0), GasLimit: build.BlockGasLimit * 10000, // Make super sure this is never too little - Method: builtin0.MethodsCron.EpochTick, + Method: cron.Methods.EpochTick, Params: nil, } ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg) @@ -350,14 +350,14 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp } rwMsg := &types.Message{ - From: builtin0.SystemActorAddr, + From: builtin.SystemActorAddr, To: reward.Address, Nonce: uint64(epoch), Value: types.NewInt(0), GasFeeCap: types.NewInt(0), GasPremium: types.NewInt(0), GasLimit: 1 << 30, - Method: builtin0.MethodsReward.AwardBlockReward, + Method: reward.Methods.AwardBlockReward, Params: params, } ret, actErr := vmi.ApplyImplicitMessage(ctx, rwMsg) @@ -974,7 +974,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error { } else if builtin.IsAccountActor(act.Code) { // should exclude burnt funds actor and "remainder account actor" // should only ever be "faucet" accounts in testnets - if kaddr == builtin0.BurntFundsActorAddr { + if kaddr == builtin.BurntFundsActorAddr { return nil } @@ -1052,24 +1052,24 @@ func (sm *StateManager) setupPreIgnitionGenesisActorsTestnet(ctx context.Context totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount) // 6 months - sixMonths := abi.ChainEpoch(183 * builtin0.EpochsInDay) + sixMonths := abi.ChainEpoch(183 * builtin.EpochsInDay) totalsByEpoch[sixMonths] = big.NewInt(49_929_341) totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700)) // 1 year - oneYear := abi.ChainEpoch(365 * builtin0.EpochsInDay) + oneYear := abi.ChainEpoch(365 * builtin.EpochsInDay) totalsByEpoch[oneYear] = big.NewInt(22_421_712) // 2 years - twoYears := abi.ChainEpoch(2 * 365 * builtin0.EpochsInDay) + twoYears := abi.ChainEpoch(2 * 365 * builtin.EpochsInDay) totalsByEpoch[twoYears] = big.NewInt(7_223_364) // 3 years - threeYears := abi.ChainEpoch(3 * 365 * builtin0.EpochsInDay) + threeYears := abi.ChainEpoch(3 * 365 * builtin.EpochsInDay) totalsByEpoch[threeYears] = big.NewInt(87_637_883) // 6 years - sixYears := abi.ChainEpoch(6 * 365 * builtin0.EpochsInDay) + sixYears := abi.ChainEpoch(6 * 365 * builtin.EpochsInDay) totalsByEpoch[sixYears] = big.NewInt(100_000_000) totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000)) @@ -1129,24 +1129,24 @@ func (sm *StateManager) setupPostIgnitionGenesisActors(ctx context.Context) erro totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount) // 6 months - sixMonths := abi.ChainEpoch(183 * builtin0.EpochsInDay) + sixMonths := abi.ChainEpoch(183 * builtin.EpochsInDay) totalsByEpoch[sixMonths] = big.NewInt(49_929_341) totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700)) // 1 year - oneYear := abi.ChainEpoch(365 * builtin0.EpochsInDay) + oneYear := abi.ChainEpoch(365 * builtin.EpochsInDay) totalsByEpoch[oneYear] = big.NewInt(22_421_712) // 2 years - twoYears := abi.ChainEpoch(2 * 365 * builtin0.EpochsInDay) + twoYears := abi.ChainEpoch(2 * 365 * builtin.EpochsInDay) totalsByEpoch[twoYears] = big.NewInt(7_223_364) // 3 years - threeYears := abi.ChainEpoch(3 * 365 * builtin0.EpochsInDay) + threeYears := abi.ChainEpoch(3 * 365 * builtin.EpochsInDay) totalsByEpoch[threeYears] = big.NewInt(87_637_883) // 6 years - sixYears := abi.ChainEpoch(6 * 365 * builtin0.EpochsInDay) + sixYears := abi.ChainEpoch(6 * 365 * builtin.EpochsInDay) totalsByEpoch[sixYears] = big.NewInt(100_000_000) totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000)) @@ -1280,7 +1280,7 @@ func (sm *StateManager) GetFilLocked(ctx context.Context, st *state.StateTree) ( } func GetFilBurnt(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) { - burnt, err := st.GetActor(builtin0.BurntFundsActorAddr) + burnt, err := st.GetActor(builtin.BurntFundsActorAddr) if err != nil { return big.Zero(), xerrors.Errorf("failed to load burnt actor: %w", err) } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index de4f947df..54f75c138 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -12,7 +12,6 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/chain/actors/policy" cid "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -24,16 +23,16 @@ import ( "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/rt" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported" - proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/power" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/store" @@ -159,7 +158,7 @@ func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, return mas.LoadSectors(snos) } -func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]proof0.SectorInfo, error) { +func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]builtin.SectorInfo, error) { act, err := sm.LoadActorRaw(ctx, maddr, st) if err != nil { return nil, xerrors.Errorf("failed to load miner actor: %w", err) @@ -244,9 +243,9 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S return nil, xerrors.Errorf("loading proving sectors: %w", err) } - out := make([]proof0.SectorInfo, len(sectors)) + out := make([]builtin.SectorInfo, len(sectors)) for i, sinfo := range sectors { - out[i] = proof0.SectorInfo{ + out[i] = builtin.SectorInfo{ SealProof: spt, SectorNumber: sinfo.SectorNumber, SealedCID: sinfo.SealedCID, @@ -256,25 +255,6 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S return out, nil } -func StateMinerInfo(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (*miner.MinerInfo, error) { - act, err := sm.LoadActor(ctx, maddr, ts) - if err != nil { - return nil, xerrors.Errorf("failed to load miner actor: %w", err) - } - - mas, err := miner.Load(sm.cs.Store(ctx), act) - if err != nil { - return nil, xerrors.Errorf("failed to load miner actor state: %w", err) - } - - mi, err := mas.Info() - if err != nil { - return nil, err - } - - return &mi, err -} - func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (bool, error) { act, err := sm.LoadActor(ctx, power.Address, ts) if err != nil { @@ -461,12 +441,21 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule return nil, xerrors.Errorf("getting lookback miner actor state: %w", err) } + // TODO: load the state instead of computing it? lbst, _, err := sm.TipSetState(ctx, lbts) if err != nil { return nil, err } act, err := sm.LoadActorRaw(ctx, maddr, lbst) + if xerrors.Is(err, types.ErrActorNotFound) { + _, err := sm.LoadActor(ctx, maddr, ts) + if err != nil { + return nil, xerrors.Errorf("loading miner in current state: %w", err) + } + + return nil, nil + } if err != nil { return nil, xerrors.Errorf("failed to load miner actor: %w", err) } @@ -548,8 +537,7 @@ func init() { methods := make(map[abi.MethodNum]MethodMeta, len(exports)) // Explicitly add send, it's special. - // Note that builtin2.MethodSend = builtin0.MethodSend = 0. - methods[builtin0.MethodSend] = MethodMeta{ + methods[builtin.MethodSend] = MethodMeta{ Name: "Send", Params: reflect.TypeOf(new(abi.EmptyValue)), Ret: reflect.TypeOf(new(abi.EmptyValue)), @@ -573,11 +561,9 @@ func init() { fnName = strings.TrimSuffix(fnName[strings.LastIndexByte(fnName, '.')+1:], "-fm") switch abi.MethodNum(number) { - case builtin0.MethodSend: - // Note that builtin2.MethodSend = builtin0.MethodSend = 0. + case builtin.MethodSend: panic("method 0 is reserved for Send") - case builtin0.MethodConstructor: - // Note that builtin2.MethodConstructor = builtin0.MethodConstructor = 1. + case builtin.MethodConstructor: if fnName != "Constructor" { panic("method 1 is reserved for Constructor") } diff --git a/chain/store/store.go b/chain/store/store.go index c6fc0cbef..00a78500e 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -19,12 +19,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + blockadt "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/journal" bstore "github.com/filecoin-project/lotus/lib/blockstore" @@ -815,7 +815,7 @@ func (cs *ChainStore) GetSignedMessage(c cid.Cid) (*types.SignedMessage, error) func (cs *ChainStore) readAMTCids(root cid.Cid) ([]cid.Cid, error) { ctx := context.TODO() // block headers use adt0, for now. - a, err := adt0.AsArray(cs.Store(ctx), root) + a, err := blockadt.AsArray(cs.Store(ctx), root) if err != nil { return nil, xerrors.Errorf("amt load: %w", err) } @@ -1009,7 +1009,7 @@ func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message, func (cs *ChainStore) GetParentReceipt(b *types.BlockHeader, i int) (*types.MessageReceipt, error) { ctx := context.TODO() // block headers use adt0, for now. - a, err := adt0.AsArray(cs.Store(ctx), b.ParentMessageReceipts) + a, err := blockadt.AsArray(cs.Store(ctx), b.ParentMessageReceipts) if err != nil { return nil, xerrors.Errorf("amt load: %w", err) } @@ -1312,11 +1312,13 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe var cids []cid.Cid if !skipOldMsgs || b.Height > ts.Height()-inclRecentRoots { - mcids, err := recurseLinks(cs.bs, walked, b.Messages, []cid.Cid{b.Messages}) - if err != nil { - return xerrors.Errorf("recursing messages failed: %w", err) + if walked.Visit(b.Messages) { + mcids, err := recurseLinks(cs.bs, walked, b.Messages, []cid.Cid{b.Messages}) + if err != nil { + return xerrors.Errorf("recursing messages failed: %w", err) + } + cids = mcids } - cids = mcids } if b.Height > 0 { @@ -1331,12 +1333,14 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe out := cids if b.Height == 0 || b.Height > ts.Height()-inclRecentRoots { - cids, err := recurseLinks(cs.bs, walked, b.ParentStateRoot, []cid.Cid{b.ParentStateRoot}) - if err != nil { - return xerrors.Errorf("recursing genesis state failed: %w", err) - } + if walked.Visit(b.ParentStateRoot) { + cids, err := recurseLinks(cs.bs, walked, b.ParentStateRoot, []cid.Cid{b.ParentStateRoot}) + if err != nil { + return xerrors.Errorf("recursing genesis state failed: %w", err) + } - out = append(out, cids...) + out = append(out, cids...) + } } for _, c := range out { diff --git a/chain/store/store_test.go b/chain/store/store_test.go index 326899f90..160527104 100644 --- a/chain/store/store_test.go +++ b/chain/store/store_test.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/gen" + "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/blockstore" @@ -107,3 +108,60 @@ func TestChainExportImport(t *testing.T) { t.Fatal("imported chain differed from exported chain") } } + +func TestChainExportImportFull(t *testing.T) { + cg, err := gen.NewGenerator() + if err != nil { + t.Fatal(err) + } + + var last *types.TipSet + for i := 0; i < 100; i++ { + ts, err := cg.NextTipSet() + if err != nil { + t.Fatal(err) + } + + last = ts.TipSet.TipSet() + } + + buf := new(bytes.Buffer) + if err := cg.ChainStore().Export(context.TODO(), last, last.Height(), false, buf); err != nil { + t.Fatal(err) + } + + nbs := blockstore.NewTemporary() + cs := store.NewChainStore(nbs, datastore.NewMapDatastore(), nil, nil) + root, err := cs.Import(buf) + if err != nil { + t.Fatal(err) + } + + err = cs.SetHead(last) + if err != nil { + t.Fatal(err) + } + + if !root.Equals(last) { + t.Fatal("imported chain differed from exported chain") + } + + sm := stmgr.NewStateManager(cs) + for i := 0; i < 100; i++ { + ts, err := cs.GetTipsetByHeight(context.TODO(), abi.ChainEpoch(i), nil, false) + if err != nil { + t.Fatal(err) + } + + st, err := sm.ParentState(ts) + if err != nil { + t.Fatal(err) + } + + // touches a bunch of actors + _, err = sm.GetCirculatingSupply(context.TODO(), abi.ChainEpoch(i), st) + if err != nil { + t.Fatal(err) + } + } +} diff --git a/chain/sub/incoming.go b/chain/sub/incoming.go index 99ca2fc65..625c8d1e2 100644 --- a/chain/sub/incoming.go +++ b/chain/sub/incoming.go @@ -23,7 +23,7 @@ import ( "go.opencensus.io/stats" "go.opencensus.io/tag" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + blockadt "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain" @@ -391,9 +391,9 @@ func (bv *BlockValidator) isChainNearSynced() bool { func (bv *BlockValidator) validateMsgMeta(ctx context.Context, msg *types.BlockMsg) error { // TODO there has to be a simpler way to do this without the blockstore dance // block headers use adt0 - store := adt0.WrapStore(ctx, cbor.NewCborStore(blockstore.NewTemporary())) - bmArr := adt0.MakeEmptyArray(store) - smArr := adt0.MakeEmptyArray(store) + store := blockadt.WrapStore(ctx, cbor.NewCborStore(blockstore.NewTemporary())) + bmArr := blockadt.MakeEmptyArray(store) + smArr := blockadt.MakeEmptyArray(store) for i, m := range msg.BlsMessages { c := cbg.CborCid(m) diff --git a/chain/sync.go b/chain/sync.go index 97915d8df..8da093cb6 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -15,8 +15,6 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" - "github.com/Gurpartap/async" "github.com/hashicorp/go-multierror" blocks "github.com/ipfs/go-block-format" @@ -37,7 +35,11 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" blst "github.com/supranational/blst/bindings/go" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + // named msgarray here to make it clear that these are the types used by + // messages, regardless of specs-actors version. + blockadt "github.com/filecoin-project/specs-actors/actors/util/adt" + + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" @@ -268,14 +270,15 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool { syncer.Exchange.AddPeer(from) - bestPweight := syncer.store.GetHeaviestTipSet().ParentWeight() + hts := syncer.store.GetHeaviestTipSet() + bestPweight := hts.ParentWeight() targetWeight := fts.TipSet().ParentWeight() if targetWeight.LessThan(bestPweight) { var miners []string for _, blk := range fts.TipSet().Blocks() { miners = append(miners, blk.Miner.String()) } - log.Infof("incoming tipset from %s does not appear to be better than our best chain, ignoring for now", miners) + log.Infow("incoming tipset does not appear to be better than our best chain, ignoring for now", "miners", miners, "bestPweight", bestPweight, "bestTS", hts.Cids(), "incomingWeight", targetWeight, "incomingTS", fts.TipSet().Cids()) return false } @@ -462,9 +465,9 @@ func zipTipSetAndMessages(bs cbor.IpldStore, ts *types.TipSet, allbmsgs []*types // of both types (BLS and Secpk). func computeMsgMeta(bs cbor.IpldStore, bmsgCids, smsgCids []cid.Cid) (cid.Cid, error) { // block headers use adt0 - store := adt0.WrapStore(context.TODO(), bs) - bmArr := adt0.MakeEmptyArray(store) - smArr := adt0.MakeEmptyArray(store) + store := blockadt.WrapStore(context.TODO(), bs) + bmArr := blockadt.MakeEmptyArray(store) + smArr := blockadt.MakeEmptyArray(store) for i, m := range bmsgCids { c := cbg.CborCid(m) @@ -1014,7 +1017,7 @@ func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.Block return xerrors.Errorf("getting winning post sector set: %w", err) } - ok, err := ffiwrapper.ProofVerifier.VerifyWinningPoSt(ctx, proof.WinningPoStVerifyInfo{ + ok, err := ffiwrapper.ProofVerifier.VerifyWinningPoSt(ctx, proof2.WinningPoStVerifyInfo{ Randomness: rand, Proofs: h.WinPoStProof, ChallengedSectors: sectors, @@ -1109,9 +1112,9 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock // Validate message arrays in a temporary blockstore. tmpbs := bstore.NewTemporary() - tmpstore := adt0.WrapStore(ctx, cbor.NewCborStore(tmpbs)) + tmpstore := blockadt.WrapStore(ctx, cbor.NewCborStore(tmpbs)) - bmArr := adt0.MakeEmptyArray(tmpstore) + bmArr := blockadt.MakeEmptyArray(tmpstore) for i, m := range b.BlsMessages { if err := checkMsg(m); err != nil { return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err) @@ -1128,7 +1131,7 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock } } - smArr := adt0.MakeEmptyArray(tmpstore) + smArr := blockadt.MakeEmptyArray(tmpstore) for i, m := range b.SecpkMessages { if err := checkMsg(m); err != nil { return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err) @@ -1393,6 +1396,11 @@ loop: } base := blockSet[len(blockSet)-1] + if base.Equals(known) { + blockSet = blockSet[:len(blockSet)-1] + base = blockSet[len(blockSet)-1] + } + if base.IsChildOf(known) { // common case: receiving blocks that are building on top of our best tipset return blockSet, nil @@ -1728,9 +1736,6 @@ func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet) error } func VerifyElectionPoStVRF(ctx context.Context, worker address.Address, rand []byte, evrf []byte) error { - if build.InsecurePoStValidation { - return nil - } return gen.VerifyVRF(ctx, worker, rand, evrf) } diff --git a/chain/sync_manager.go b/chain/sync_manager.go index c7fdea726..c25068f60 100644 --- a/chain/sync_manager.go +++ b/chain/sync_manager.go @@ -2,7 +2,9 @@ package chain import ( "context" + "os" "sort" + "strings" "sync" "github.com/filecoin-project/lotus/chain/types" @@ -11,6 +13,14 @@ import ( const BootstrapPeerThreshold = 2 +var coalesceForksParents = false + +func init() { + if os.Getenv("LOTUS_SYNC_REL_PARENT") == "yes" { + coalesceForksParents = true + } +} + const ( BSStateInit = 0 BSStateSelected = 1 @@ -152,6 +162,19 @@ func newSyncTargetBucket(tipsets ...*types.TipSet) *syncTargetBucket { return &stb } +func (sbs *syncBucketSet) String() string { + var bStrings []string + for _, b := range sbs.buckets { + var tsStrings []string + for _, t := range b.tips { + tsStrings = append(tsStrings, t.String()) + } + bStrings = append(bStrings, "["+strings.Join(tsStrings, ",")+"]") + } + + return "{" + strings.Join(bStrings, ";") + "}" +} + func (sbs *syncBucketSet) RelatedToAny(ts *types.TipSet) bool { for _, b := range sbs.buckets { if b.sameChainAs(ts) { @@ -198,13 +221,17 @@ func (sbs *syncBucketSet) removeBucket(toremove *syncTargetBucket) { } func (sbs *syncBucketSet) PopRelated(ts *types.TipSet) *syncTargetBucket { + var bOut *syncTargetBucket for _, b := range sbs.buckets { if b.sameChainAs(ts) { sbs.removeBucket(b) - return b + if bOut == nil { + bOut = &syncTargetBucket{} + } + bOut.tips = append(bOut.tips, b.tips...) } } - return nil + return bOut } func (sbs *syncBucketSet) Heaviest() *types.TipSet { @@ -224,8 +251,7 @@ func (sbs *syncBucketSet) Empty() bool { } type syncTargetBucket struct { - tips []*types.TipSet - count int + tips []*types.TipSet } func (stb *syncTargetBucket) sameChainAs(ts *types.TipSet) bool { @@ -239,12 +265,14 @@ func (stb *syncTargetBucket) sameChainAs(ts *types.TipSet) bool { if ts.Parents() == t.Key() { return true } + if coalesceForksParents && ts.Parents() == t.Parents() { + return true + } } return false } func (stb *syncTargetBucket) add(ts *types.TipSet) { - stb.count++ for _, t := range stb.tips { if t.Equals(ts) { @@ -294,7 +322,6 @@ func (sm *syncManager) selectSyncTarget() (*types.TipSet, error) { } func (sm *syncManager) syncScheduler() { - for { select { case ts, ok := <-sm.incomingTipSets: @@ -326,7 +353,8 @@ func (sm *syncManager) scheduleIncoming(ts *types.TipSet) { var relatedToActiveSync bool for _, acts := range sm.activeSyncs { if ts.Equals(acts) { - break + // ignore, we are already syncing it + return } if ts.Parents() == acts.Key() { @@ -376,7 +404,9 @@ func (sm *syncManager) scheduleProcessResult(res *syncResult) { sm.nextSyncTarget = relbucket sm.workerChan = sm.syncTargets } else { - sm.syncQueue.buckets = append(sm.syncQueue.buckets, relbucket) + for _, t := range relbucket.tips { + sm.syncQueue.Insert(t) + } } return } diff --git a/chain/sync_manager_test.go b/chain/sync_manager_test.go index 269b3a62e..709e03a41 100644 --- a/chain/sync_manager_test.go +++ b/chain/sync_manager_test.go @@ -67,6 +67,69 @@ func assertGetSyncOp(t *testing.T, c chan *syncOp, ts *types.TipSet) { } } +func TestSyncManagerEdgeCase(t *testing.T) { + ctx := context.Background() + + a := mock.TipSet(mock.MkBlock(genTs, 1, 1)) + t.Logf("a: %s", a) + b1 := mock.TipSet(mock.MkBlock(a, 1, 2)) + t.Logf("b1: %s", b1) + b2 := mock.TipSet(mock.MkBlock(a, 2, 3)) + t.Logf("b2: %s", b2) + c1 := mock.TipSet(mock.MkBlock(b1, 2, 4)) + t.Logf("c1: %s", c1) + c2 := mock.TipSet(mock.MkBlock(b2, 1, 5)) + t.Logf("c2: %s", c2) + d1 := mock.TipSet(mock.MkBlock(c1, 1, 6)) + t.Logf("d1: %s", d1) + e1 := mock.TipSet(mock.MkBlock(d1, 1, 7)) + t.Logf("e1: %s", e1) + + runSyncMgrTest(t, "edgeCase", 1, func(t *testing.T, sm *syncManager, stc chan *syncOp) { + sm.SetPeerHead(ctx, "peer1", a) + assertGetSyncOp(t, stc, a) + + sm.SetPeerHead(ctx, "peer1", b1) + sm.SetPeerHead(ctx, "peer1", b2) + // b1 and b2 are being processed + + b1op := <-stc + b2op := <-stc + if !b1op.ts.Equals(b1) { + b1op, b2op = b2op, b1op + } + + sm.SetPeerHead(ctx, "peer2", c2) // c2 is put into activeSyncTips at index 0 + sm.SetPeerHead(ctx, "peer2", c1) // c1 is put into activeSyncTips at index 1 + sm.SetPeerHead(ctx, "peer3", b2) // b2 is related to c2 and even though it is actively synced it is put into activeSyncTips index 0 + sm.SetPeerHead(ctx, "peer1", a) // a is related to b2 and is put into activeSyncTips index 0 + + b1op.done() // b1 completes first, is related to a, so it pops activeSyncTips index 0 + // even though correct one is index 1 + + b2op.done() + // b2 completes and is not related to c1, so it leaves activeSyncTips as it is + + waitUntilAllWorkersAreDone(stc) + + if len(sm.activeSyncTips.buckets) != 0 { + t.Errorf("activeSyncTips expected empty but got: %s", sm.activeSyncTips.String()) + } + }) +} + +func waitUntilAllWorkersAreDone(stc chan *syncOp) { + for i := 0; i < 10; { + select { + case so := <-stc: + so.done() + default: + i++ + time.Sleep(10 * time.Millisecond) + } + } +} + func TestSyncManager(t *testing.T) { ctx := context.Background() diff --git a/chain/sync_test.go b/chain/sync_test.go index 0a8174c41..559a73bf5 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -7,8 +7,6 @@ import ( "testing" "time" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" - "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" @@ -20,6 +18,8 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/policy" @@ -469,8 +469,8 @@ func (wpp badWpp) GenerateCandidates(context.Context, abi.PoStRandomness, uint64 return []uint64{1}, nil } -func (wpp badWpp) ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error) { - return []proof.PoStProof{ +func (wpp badWpp) ComputeProof(context.Context, []proof2.SectorInfo, abi.PoStRandomness) ([]proof2.PoStProof, error) { + return []proof2.PoStProof{ { PoStProof: abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, ProofBytes: []byte("evil"), diff --git a/chain/types/blockheader.go b/chain/types/blockheader.go index 0ec33fe42..4db6788e1 100644 --- a/chain/types/blockheader.go +++ b/chain/types/blockheader.go @@ -4,7 +4,7 @@ import ( "bytes" "math/big" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/minio/blake2b-simd" @@ -55,7 +55,7 @@ type BlockHeader struct { BeaconEntries []BeaconEntry // 3 - WinPoStProof []proof.PoStProof // 4 + WinPoStProof []proof2.PoStProof // 4 Parents []cid.Cid // 5 diff --git a/chain/types/blockheader_test.go b/chain/types/blockheader_test.go index f5faac3b3..6674f1205 100644 --- a/chain/types/blockheader_test.go +++ b/chain/types/blockheader_test.go @@ -7,7 +7,7 @@ import ( "reflect" "testing" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" cid "github.com/ipfs/go-cid" "github.com/stretchr/testify/require" @@ -82,7 +82,7 @@ func TestInteropBH(t *testing.T) { t.Fatal(err) } - posts := []proof.PoStProof{ + posts := []proof2.PoStProof{ {PoStProof: abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, ProofBytes: []byte{0x07}}, } diff --git a/chain/types/execresult.go b/chain/types/execresult.go index 6fc93fac6..917b84a92 100644 --- a/chain/types/execresult.go +++ b/chain/types/execresult.go @@ -3,6 +3,7 @@ package types import ( "encoding/json" "fmt" + "regexp" "runtime" "strings" "time" @@ -68,11 +69,10 @@ func (l Loc) String() string { return fmt.Sprintf("%s@%s:%d", fnpkg, file[len(file)-1], l.Line) } +var importantRegex = regexp.MustCompile(`github.com/filecoin-project/specs-actors/(v\d+/)?actors/builtin`) + func (l Loc) Important() bool { - if strings.HasPrefix(l.Function, "github.com/filecoin-project/specs-actors/actors/builtin") { - return true - } - return false + return importantRegex.MatchString(l.Function) } func (gt *GasTrace) MarshalJSON() ([]byte, error) { diff --git a/chain/types/message_test.go b/chain/types/message_test.go index dab8e0939..a5a00f66b 100644 --- a/chain/types/message_test.go +++ b/chain/types/message_test.go @@ -9,13 +9,15 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" - "github.com/filecoin-project/specs-actors/actors/builtin" + + // we can't import the actors shims from this package due to cyclic imports. + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) func TestEqualCall(t *testing.T) { m1 := &Message{ - To: builtin.StoragePowerActorAddr, - From: builtin.SystemActorAddr, + To: builtin2.StoragePowerActorAddr, + From: builtin2.SystemActorAddr, Nonce: 34, Value: big.Zero(), @@ -28,8 +30,8 @@ func TestEqualCall(t *testing.T) { } m2 := &Message{ - To: builtin.StoragePowerActorAddr, - From: builtin.SystemActorAddr, + To: builtin2.StoragePowerActorAddr, + From: builtin2.SystemActorAddr, Nonce: 34, Value: big.Zero(), @@ -42,8 +44,8 @@ func TestEqualCall(t *testing.T) { } m3 := &Message{ - To: builtin.StoragePowerActorAddr, - From: builtin.SystemActorAddr, + To: builtin2.StoragePowerActorAddr, + From: builtin2.SystemActorAddr, Nonce: 34, Value: big.Zero(), @@ -56,8 +58,8 @@ func TestEqualCall(t *testing.T) { } m4 := &Message{ - To: builtin.StoragePowerActorAddr, - From: builtin.SystemActorAddr, + To: builtin2.StoragePowerActorAddr, + From: builtin2.SystemActorAddr, Nonce: 34, Value: big.Zero(), @@ -76,8 +78,8 @@ func TestEqualCall(t *testing.T) { func TestMessageJson(t *testing.T) { m := &Message{ - To: builtin.StoragePowerActorAddr, - From: builtin.SystemActorAddr, + To: builtin2.StoragePowerActorAddr, + From: builtin2.SystemActorAddr, Nonce: 34, Value: big.Zero(), @@ -105,8 +107,8 @@ func TestMessageJson(t *testing.T) { func TestSignedMessageJson(t *testing.T) { m := Message{ - To: builtin.StoragePowerActorAddr, - From: builtin.SystemActorAddr, + To: builtin2.StoragePowerActorAddr, + From: builtin2.SystemActorAddr, Nonce: 34, Value: big.Zero(), diff --git a/chain/vm/gas.go b/chain/vm/gas.go index 6802013e5..cbe5bab13 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -3,13 +3,13 @@ package vm import ( "fmt" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" + vmr2 "github.com/filecoin-project/specs-actors/v2/actors/runtime" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/filecoin-project/go-address" addr "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" - vmr "github.com/filecoin-project/specs-actors/actors/runtime" "github.com/ipfs/go-cid" ) @@ -78,8 +78,8 @@ type Pricelist interface { OnVerifySignature(sigType crypto.SigType, planTextSize int) (GasCharge, error) OnHashing(dataSize int) GasCharge OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge - OnVerifySeal(info proof.SealVerifyInfo) GasCharge - OnVerifyPost(info proof.WindowPoStVerifyInfo) GasCharge + OnVerifySeal(info proof2.SealVerifyInfo) GasCharge + OnVerifyPost(info proof2.WindowPoStVerifyInfo) GasCharge OnVerifyConsensusFault() GasCharge } @@ -150,7 +150,7 @@ func PricelistByEpoch(epoch abi.ChainEpoch) Pricelist { } type pricedSyscalls struct { - under vmr.Syscalls + under vmr2.Syscalls pl Pricelist chargeGas func(GasCharge) } @@ -184,7 +184,7 @@ func (ps pricedSyscalls) ComputeUnsealedSectorCID(reg abi.RegisteredSealProof, p } // Verifies a sector seal proof. -func (ps pricedSyscalls) VerifySeal(vi proof.SealVerifyInfo) error { +func (ps pricedSyscalls) VerifySeal(vi proof2.SealVerifyInfo) error { ps.chargeGas(ps.pl.OnVerifySeal(vi)) defer ps.chargeGas(gasOnActorExec) @@ -192,7 +192,7 @@ func (ps pricedSyscalls) VerifySeal(vi proof.SealVerifyInfo) error { } // Verifies a proof of spacetime. -func (ps pricedSyscalls) VerifyPoSt(vi proof.WindowPoStVerifyInfo) error { +func (ps pricedSyscalls) VerifyPoSt(vi proof2.WindowPoStVerifyInfo) error { ps.chargeGas(ps.pl.OnVerifyPost(vi)) defer ps.chargeGas(gasOnActorExec) @@ -209,14 +209,14 @@ func (ps pricedSyscalls) VerifyPoSt(vi proof.WindowPoStVerifyInfo) error { // the "parent grinding fault", in which case it must be the sibling of h1 (same parent tipset) and one of the // blocks in the parent of h2 (i.e. h2's grandparent). // Returns nil and an error if the headers don't prove a fault. -func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte) (*vmr.ConsensusFault, error) { +func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte) (*vmr2.ConsensusFault, error) { ps.chargeGas(ps.pl.OnVerifyConsensusFault()) defer ps.chargeGas(gasOnActorExec) return ps.under.VerifyConsensusFault(h1, h2, extra) } -func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]proof.SealVerifyInfo) (map[address.Address][]bool, error) { +func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]proof2.SealVerifyInfo) (map[address.Address][]bool, error) { count := int64(0) for _, svis := range inp { count += int64(len(svis)) diff --git a/chain/vm/gas_v0.go b/chain/vm/gas_v0.go index bfb49c345..7a7fb364d 100644 --- a/chain/vm/gas_v0.go +++ b/chain/vm/gas_v0.go @@ -3,12 +3,13 @@ package vm import ( "fmt" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "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" + + "github.com/filecoin-project/lotus/chain/actors/builtin" ) type scalingCost struct { @@ -112,14 +113,14 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M if big.Cmp(value, abi.NewTokenAmount(0)) != 0 { ret += pl.sendTransferFunds - if methodNum == builtin0.MethodSend { + if methodNum == builtin.MethodSend { // transfer only ret += pl.sendTransferOnlyPremium } extra += "t" } - if methodNum != builtin0.MethodSend { + if methodNum != builtin.MethodSend { extra += "i" // running actors is cheaper becase we hand over to actors ret += pl.sendInvokeMethod @@ -175,14 +176,14 @@ func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredSealPr } // OnVerifySeal -func (pl *pricelistV0) OnVerifySeal(info proof.SealVerifyInfo) GasCharge { +func (pl *pricelistV0) OnVerifySeal(info proof2.SealVerifyInfo) GasCharge { // TODO: this needs more cost tunning, check with @lotus // this is not used return newGasCharge("OnVerifySeal", pl.verifySealBase, 0) } // OnVerifyPost -func (pl *pricelistV0) OnVerifyPost(info proof.WindowPoStVerifyInfo) GasCharge { +func (pl *pricelistV0) OnVerifyPost(info proof2.WindowPoStVerifyInfo) GasCharge { sectorSize := "unknown" var proofType abi.RegisteredPoStProof diff --git a/chain/vm/invoker_test.go b/chain/vm/invoker_test.go index 4005dd42f..bce385b02 100644 --- a/chain/vm/invoker_test.go +++ b/chain/vm/invoker_test.go @@ -5,16 +5,17 @@ import ( "io" "testing" - "github.com/filecoin-project/go-state-types/abi" - cbor "github.com/ipfs/go-ipld-cbor" "github.com/stretchr/testify/assert" cbg "github.com/whyrusleeping/cbor-gen" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/exitcode" + + runtime2 "github.com/filecoin-project/specs-actors/v2/actors/runtime" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" - "github.com/filecoin-project/specs-actors/actors/runtime" ) type basicContract struct{} @@ -61,17 +62,17 @@ func (b basicContract) Exports() []interface{} { } } -func (basicContract) InvokeSomething0(rt runtime.Runtime, params *basicParams) *abi.EmptyValue { +func (basicContract) InvokeSomething0(rt runtime2.Runtime, params *basicParams) *abi.EmptyValue { rt.Abortf(exitcode.ExitCode(params.B), "params.B") return nil } -func (basicContract) BadParam(rt runtime.Runtime, params *basicParams) *abi.EmptyValue { +func (basicContract) BadParam(rt runtime2.Runtime, params *basicParams) *abi.EmptyValue { rt.Abortf(255, "bad params") return nil } -func (basicContract) InvokeSomething10(rt runtime.Runtime, params *basicParams) *abi.EmptyValue { +func (basicContract) InvokeSomething10(rt runtime2.Runtime, params *basicParams) *abi.EmptyValue { rt.Abortf(exitcode.ExitCode(params.B+10), "params.B") return nil } diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 22a2acb8b..885d3c0db 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -15,6 +15,8 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/chain/actors/aerrors" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/account" "github.com/filecoin-project/lotus/chain/types" ) @@ -56,7 +58,7 @@ func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, add } // call constructor on account - _, aerr = rt.internalSend(builtin0.SystemActorAddr, addrID, builtin0.MethodsAccount.Constructor, big.Zero(), p) + _, aerr = rt.internalSend(builtin.SystemActorAddr, addrID, account.Methods.Constructor, big.Zero(), p) if aerr != nil { return nil, address.Undef, aerrors.Wrap(aerr, "failed to invoke account constructor") } diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 8f124247c..6e36e8e87 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -53,8 +53,8 @@ func (m *Message) ValueReceived() abi.TokenAmount { var EnableGasTracing = false type Runtime struct { - rt0.Message - rt0.Syscalls + rt2.Message + rt2.Syscalls ctx context.Context @@ -72,6 +72,7 @@ type Runtime struct { originNonce uint64 executionTrace types.ExecutionTrace + depth uint64 numActorsCreated uint64 allowInternal bool callerValidated bool diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index a7f5dab0c..347c3409c 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -7,8 +7,6 @@ import ( goruntime "runtime" "sync" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" - "github.com/filecoin-project/go-address" "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" @@ -23,7 +21,9 @@ import ( "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sigs" - "github.com/filecoin-project/specs-actors/actors/runtime" + + runtime2 "github.com/filecoin-project/specs-actors/v2/actors/runtime" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" ) @@ -34,10 +34,10 @@ func init() { // Actual type is defined in chain/types/vmcontext.go because the VMContext interface is there -type SyscallBuilder func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls +type SyscallBuilder func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime2.Syscalls func Syscalls(verifier ffiwrapper.Verifier) SyscallBuilder { - return func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls { + return func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime2.Syscalls { return &syscallShim{ ctx: ctx, @@ -79,7 +79,7 @@ func (ss *syscallShim) HashBlake2b(data []byte) [32]byte { // Checks validity of the submitted consensus fault with the two block headers needed to prove the fault // and an optional extra one to check common ancestry (as needed). // Note that the blocks are ordered: the method requires a.Epoch() <= b.Epoch(). -func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime.ConsensusFault, error) { +func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime2.ConsensusFault, error) { // Note that block syntax is not validated. Any validly signed block will be accepted pursuant to the below conditions. // Whether or not it could ever have been accepted in a chain is not checked/does not matter here. // for that reason when checking block parent relationships, rather than instantiating a Tipset to do so @@ -115,14 +115,14 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime.Consen } // (2) check for the consensus faults themselves - var consensusFault *runtime.ConsensusFault + var consensusFault *runtime2.ConsensusFault // (a) double-fork mining fault if blockA.Height == blockB.Height { - consensusFault = &runtime.ConsensusFault{ + consensusFault = &runtime2.ConsensusFault{ Target: blockA.Miner, Epoch: blockB.Height, - Type: runtime.ConsensusFaultDoubleForkMining, + Type: runtime2.ConsensusFaultDoubleForkMining, } } @@ -130,10 +130,10 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime.Consen // strictly speaking no need to compare heights based on double fork mining check above, // but at same height this would be a different fault. if types.CidArrsEqual(blockA.Parents, blockB.Parents) && blockA.Height != blockB.Height { - consensusFault = &runtime.ConsensusFault{ + consensusFault = &runtime2.ConsensusFault{ Target: blockA.Miner, Epoch: blockB.Height, - Type: runtime.ConsensusFaultTimeOffsetMining, + Type: runtime2.ConsensusFaultTimeOffsetMining, } } @@ -153,10 +153,10 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime.Consen if types.CidArrsEqual(blockA.Parents, blockC.Parents) && blockA.Height == blockC.Height && types.CidArrsContains(blockB.Parents, blockC.Cid()) && !types.CidArrsContains(blockB.Parents, blockA.Cid()) { - consensusFault = &runtime.ConsensusFault{ + consensusFault = &runtime2.ConsensusFault{ Target: blockA.Miner, Epoch: blockB.Height, - Type: runtime.ConsensusFaultParentGrinding, + Type: runtime2.ConsensusFaultParentGrinding, } } } @@ -215,7 +215,7 @@ func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error { return nil } -func (ss *syscallShim) VerifyPoSt(proof proof.WindowPoStVerifyInfo) error { +func (ss *syscallShim) VerifyPoSt(proof proof2.WindowPoStVerifyInfo) error { ok, err := ss.verifier.VerifyWindowPoSt(context.TODO(), proof) if err != nil { return err @@ -226,7 +226,7 @@ func (ss *syscallShim) VerifyPoSt(proof proof.WindowPoStVerifyInfo) error { return nil } -func (ss *syscallShim) VerifySeal(info proof.SealVerifyInfo) error { +func (ss *syscallShim) VerifySeal(info proof2.SealVerifyInfo) error { //_, span := trace.StartSpan(ctx, "ValidatePoRep") //defer span.End() @@ -266,7 +266,7 @@ func (ss *syscallShim) VerifySignature(sig crypto.Signature, addr address.Addres var BatchSealVerifyParallelism = goruntime.NumCPU() -func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]proof.SealVerifyInfo) (map[address.Address][]bool, error) { +func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]proof2.SealVerifyInfo) (map[address.Address][]bool, error) { out := make(map[address.Address][]bool) sema := make(chan struct{}, BatchSealVerifyParallelism) @@ -278,7 +278,7 @@ func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]proof.SealVeri for i, s := range seals { wg.Add(1) - go func(ma address.Address, ix int, svi proof.SealVerifyInfo, res []bool) { + go func(ma address.Address, ix int, svi proof2.SealVerifyInfo, res []bool) { defer wg.Done() sema <- struct{}{} diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 72ad731aa..a7aa05719 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -38,6 +38,8 @@ import ( "github.com/filecoin-project/lotus/lib/bufbstore" ) +const MaxCallDepth = 4096 + var log = logging.Logger("vm") var actorLog = logging.Logger("actors") var gasOnActorExec = newGasCharge("OnActorExec", 0, 0) @@ -97,24 +99,37 @@ func (bs *gasChargingBlocks) Put(blk block.Block) error { return nil } -func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin address.Address, originNonce uint64, usedGas int64, nac uint64) *Runtime { +func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runtime) *Runtime { rt := &Runtime{ ctx: ctx, vm: vm, state: vm.cstate, - origin: origin, - originNonce: originNonce, + origin: msg.From, + originNonce: msg.Nonce, height: vm.blockHeight, - gasUsed: usedGas, + gasUsed: 0, gasAvailable: msg.GasLimit, - numActorsCreated: nac, + depth: 0, + numActorsCreated: 0, pricelist: PricelistByEpoch(vm.blockHeight), allowInternal: true, callerValidated: false, executionTrace: types.ExecutionTrace{Msg: msg}, } + if parent != nil { + rt.gasUsed = parent.gasUsed + rt.origin = parent.origin + rt.originNonce = parent.originNonce + rt.numActorsCreated = parent.numActorsCreated + rt.depth = parent.depth + 1 + } + + if rt.depth > MaxCallDepth && rt.NetworkVersion() >= network.Version6 { + rt.Abortf(exitcode.SysErrForbidden, "message execution exceeds call depth") + } + rt.cst = &cbor.BasicIpldStore{ Blocks: &gasChargingBlocks{rt.chargeGasFunc(2), rt.pricelist, vm.cst.Blocks}, Atlas: vm.cst.Atlas, @@ -148,8 +163,8 @@ type UnsafeVM struct { VM *VM } -func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message, origin address.Address, originNonce uint64, usedGas int64, nac uint64) *Runtime { - return vm.VM.makeRuntime(ctx, msg, origin, originNonce, usedGas, nac) +func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message) *Runtime { + return vm.VM.makeRuntime(ctx, msg, nil) } type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) @@ -224,18 +239,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime, st := vm.cstate - origin := msg.From - on := msg.Nonce - var nac uint64 = 0 - var gasUsed int64 - if parent != nil { - gasUsed = parent.gasUsed - origin = parent.origin - on = parent.originNonce - nac = parent.numActorsCreated - } - - rt := vm.makeRuntime(ctx, msg, origin, on, gasUsed, nac) + rt := vm.makeRuntime(ctx, msg, parent) if EnableGasTracing { rt.lastGasChargeTime = start if parent != nil { diff --git a/chain/wallet/wallet.go b/chain/wallet/wallet.go index 925547ea8..1f3329498 100644 --- a/chain/wallet/wallet.go +++ b/chain/wallet/wallet.go @@ -272,6 +272,7 @@ func (w *LocalWallet) WalletHas(ctx context.Context, addr address.Address) (bool func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) error { k, err := w.findKey(addr) + if err != nil { return xerrors.Errorf("failed to delete key %s : %w", addr, err) } @@ -279,6 +280,9 @@ func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) er return nil // already not there } + w.lk.Lock() + defer w.lk.Unlock() + if err := w.keystore.Put(KTrashPrefix+k.Address.String(), k.KeyInfo); err != nil { return xerrors.Errorf("failed to mark key %s as trashed: %w", addr, err) } @@ -295,6 +299,8 @@ func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) er // TODO: Does this always error in the not-found case? Just ignoring an error return for now. _ = w.keystore.Delete(KNamePrefix + tAddr) + delete(w.keys, addr) + return nil } diff --git a/cli/chain.go b/cli/chain.go index b1351549f..e2d0ebb4a 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -1291,7 +1291,7 @@ var chainDecodeParamsCmd = &cli.Command{ return xerrors.Errorf("getting actor: %w", err) } - pstr, err := jsonParams(act.Code, abi.MethodNum(method), params) + pstr, err := JsonParams(act.Code, abi.MethodNum(method), params) if err != nil { return err } diff --git a/cli/client.go b/cli/client.go index 7035fb64b..c3479a725 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1,24 +1,29 @@ package cli import ( + "bufio" "context" "encoding/json" "errors" "fmt" "io" + "math/rand" "os" "path/filepath" "sort" "strconv" + "strings" + "sync" + "sync/atomic" "text/tabwriter" "time" tm "github.com/buger/goterm" + "github.com/chzyer/readline" "github.com/docker/go-units" "github.com/fatih/color" datatransfer "github.com/filecoin-project/go-data-transfer" "github.com/filecoin-project/go-fil-markets/retrievalmarket" - "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/ipfs/go-cid" "github.com/ipfs/go-cidutil/cidenc" "github.com/libp2p/go-libp2p-core/peer" @@ -35,6 +40,7 @@ import ( "github.com/filecoin-project/lotus/api" lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/tablewriter" @@ -74,6 +80,7 @@ var clientCmd = &cli.Command{ WithCategory("storage", clientQueryAskCmd), WithCategory("storage", clientListDeals), WithCategory("storage", clientGetDealCmd), + WithCategory("storage", clientListAsksCmd), WithCategory("data", clientImportCmd), WithCategory("data", clientDropCmd), WithCategory("data", clientLocalCmd), @@ -336,6 +343,7 @@ var clientDealCmd = &cli.Command{ } defer closer() ctx := ReqContext(cctx) + afmt := NewAppFmt(cctx.App) if cctx.NArg() != 4 { return xerrors.New("expected 4 args: dataCid, miner, price, duration") @@ -455,7 +463,7 @@ var clientDealCmd = &cli.Command{ return err } - fmt.Println(encoder.Encode(*proposal)) + afmt.Println(encoder.Encode(*proposal)) return nil }, @@ -468,16 +476,27 @@ func interactiveDeal(cctx *cli.Context) error { } defer closer() ctx := ReqContext(cctx) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + afmt := NewAppFmt(cctx.App) state := "import" + gib := types.NewInt(1 << 30) var data cid.Cid var days int - var maddr address.Address - var ask storagemarket.StorageAsk - var epochPrice big.Int + var maddrs []address.Address + var ask []storagemarket.StorageAsk + var epochPrices []big.Int + var dur time.Duration var epochs abi.ChainEpoch var verified bool + var ds lapi.DataSize + + // find + var candidateAsks []*storagemarket.StorageAsk + var budget types.FIL + var dealCount int64 var a address.Address if from := cctx.String("from"); from != "" { @@ -494,10 +513,24 @@ func interactiveDeal(cctx *cli.Context) error { a = def } - printErr := func(err error) { - fmt.Printf("%s %s\n", color.RedString("Error:"), err.Error()) + fromBal, err := api.WalletBalance(ctx, a) + if err != nil { + return xerrors.Errorf("checking from address balance: %w", err) } + printErr := func(err error) { + afmt.Printf("%s %s\n", color.RedString("Error:"), err.Error()) + } + + cs := readline.NewCancelableStdin(afmt.Stdin) + go func() { + <-ctx.Done() + cs.Close() // nolint:errcheck + }() + + rl := bufio.NewReader(cs) + +uiLoop: for { // TODO: better exit handling if err := ctx.Err(); err != nil { @@ -506,10 +539,10 @@ func interactiveDeal(cctx *cli.Context) error { switch state { case "import": - fmt.Print("Data CID (from " + color.YellowString("lotus client import") + "): ") + afmt.Print("Data CID (from " + color.YellowString("lotus client import") + "): ") - var cidStr string - _, err := fmt.Scan(&cidStr) + _cidStr, _, err := rl.ReadLine() + cidStr := string(_cidStr) if err != nil { printErr(xerrors.Errorf("reading cid string: %w", err)) continue @@ -521,11 +554,23 @@ func interactiveDeal(cctx *cli.Context) error { continue } + color.Blue(".. calculating data size\n") + ds, err = api.ClientDealSize(ctx, data) + if err != nil { + return err + } + state = "duration" case "duration": - fmt.Print("Deal duration (days): ") + afmt.Print("Deal duration (days): ") - _, err := fmt.Scan(&days) + _daystr, _, err := rl.ReadLine() + daystr := string(_daystr) + if err != nil { + return err + } + + _, err = fmt.Sscan(daystr, &days) if err != nil { printErr(xerrors.Errorf("parsing duration: %w", err)) continue @@ -536,44 +581,9 @@ func interactiveDeal(cctx *cli.Context) error { continue } - state = "miner" - case "miner": - fmt.Print("Miner Address (f0..): ") - var maddrStr string + dur = 24 * time.Hour * time.Duration(days) + epochs = abi.ChainEpoch(dur / (time.Duration(build.BlockDelaySecs) * time.Second)) - _, err := fmt.Scan(&maddrStr) - if err != nil { - printErr(xerrors.Errorf("reading miner address: %w", err)) - continue - } - - maddr, err = address.NewFromString(maddrStr) - if err != nil { - printErr(xerrors.Errorf("parsing miner address: %w", err)) - continue - } - - state = "query" - case "query": - color.Blue(".. querying miner ask") - - mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) - if err != nil { - printErr(xerrors.Errorf("failed to get peerID for miner: %w", err)) - state = "miner" - continue - } - - a, err := api.ClientQueryAsk(ctx, *mi.PeerId, maddr) - if err != nil { - printErr(xerrors.Errorf("failed to query ask: %w", err)) - state = "miner" - continue - } - - ask = *a - - // TODO: run more validation state = "verified" case "verified": ts, err := api.ChainHead(ctx) @@ -587,26 +597,20 @@ func interactiveDeal(cctx *cli.Context) error { } if dcap == nil { - state = "confirm" + state = "miner" continue } - color.Blue(".. checking verified deal eligibility\n") - ds, err := api.ClientDealSize(ctx, data) - if err != nil { - return err - } - if dcap.Uint64() < uint64(ds.PieceSize) { color.Yellow(".. not enough DataCap available for a verified deal\n") - state = "confirm" + state = "miner" continue } - fmt.Print("\nMake this a verified deal? (yes/no): ") + afmt.Print("\nMake this a verified deal? (yes/no): ") - var yn string - _, err = fmt.Scan(&yn) + _yn, _, err := rl.ReadLine() + yn := string(_yn) if err != nil { return err } @@ -617,54 +621,208 @@ func interactiveDeal(cctx *cli.Context) error { case "no": verified = false default: - fmt.Println("Type in full 'yes' or 'no'") + afmt.Println("Type in full 'yes' or 'no'") continue } - state = "confirm" - case "confirm": - fromBal, err := api.WalletBalance(ctx, a) + state = "miner" + case "miner": + afmt.Print("Miner Addresses (f0.. f0..), none to find: ") + + _maddrsStr, _, err := rl.ReadLine() + maddrsStr := string(_maddrsStr) if err != nil { - return xerrors.Errorf("checking from address balance: %w", err) + printErr(xerrors.Errorf("reading miner address: %w", err)) + continue } - color.Blue(".. calculating data size\n") - ds, err := api.ClientDealSize(ctx, data) + for _, s := range strings.Fields(maddrsStr) { + maddr, err := address.NewFromString(strings.TrimSpace(s)) + if err != nil { + printErr(xerrors.Errorf("parsing miner address: %w", err)) + continue uiLoop + } + + maddrs = append(maddrs, maddr) + } + + state = "query" + if len(maddrs) == 0 { + state = "find" + } + case "find": + asks, err := getAsks(ctx, api) if err != nil { return err } - dur := 24 * time.Hour * time.Duration(days) - - epochs = abi.ChainEpoch(dur / (time.Duration(build.BlockDelaySecs) * time.Second)) - // TODO: do some more or epochs math (round to miner PP, deal start buffer) - - pricePerGib := ask.Price - if verified { - pricePerGib = ask.VerifiedPrice + for _, ask := range asks { + if ask.MinPieceSize > ds.PieceSize { + continue + } + if ask.MaxPieceSize < ds.PieceSize { + continue + } + candidateAsks = append(candidateAsks, ask) } - gib := types.NewInt(1 << 30) + afmt.Printf("Found %d candidate asks\n", len(candidateAsks)) + state = "find-budget" + case "find-budget": + afmt.Printf("Proposing from %s, Current Balance: %s\n", a, types.FIL(fromBal)) + afmt.Print("Maximum budget (FIL): ") // TODO: Propose some default somehow? + + _budgetStr, _, err := rl.ReadLine() + budgetStr := string(_budgetStr) + if err != nil { + printErr(xerrors.Errorf("reading miner address: %w", err)) + continue + } + + budget, err = types.ParseFIL(budgetStr) + if err != nil { + printErr(xerrors.Errorf("parsing FIL: %w", err)) + continue uiLoop + } + + var goodAsks []*storagemarket.StorageAsk + for _, ask := range candidateAsks { + p := ask.Price + if verified { + p = ask.VerifiedPrice + } + + epochPrice := types.BigDiv(types.BigMul(p, types.NewInt(uint64(ds.PieceSize))), gib) + totalPrice := types.BigMul(epochPrice, types.NewInt(uint64(epochs))) + + if totalPrice.LessThan(abi.TokenAmount(budget)) { + goodAsks = append(goodAsks, ask) + } + } + candidateAsks = goodAsks + afmt.Printf("%d asks within budget\n", len(candidateAsks)) + state = "find-count" + case "find-count": + afmt.Print("Deals to make (1): ") + dealcStr, _, err := rl.ReadLine() + if err != nil { + printErr(xerrors.Errorf("reading deal count: %w", err)) + continue + } + + dealCount, err = strconv.ParseInt(string(dealcStr), 10, 64) + if err != nil { + return err + } + + color.Blue(".. Picking miners") + + // TODO: some better strategy (this tries to pick randomly) + var pickedAsks []*storagemarket.StorageAsk + pickLoop: + for i := 0; i < 64; i++ { + rand.Shuffle(len(candidateAsks), func(i, j int) { + candidateAsks[i], candidateAsks[j] = candidateAsks[j], candidateAsks[i] + }) + + remainingBudget := abi.TokenAmount(budget) + pickedAsks = []*storagemarket.StorageAsk{} + + for _, ask := range candidateAsks { + p := ask.Price + if verified { + p = ask.VerifiedPrice + } + + epochPrice := types.BigDiv(types.BigMul(p, types.NewInt(uint64(ds.PieceSize))), gib) + totalPrice := types.BigMul(epochPrice, types.NewInt(uint64(epochs))) + + if totalPrice.GreaterThan(remainingBudget) { + continue + } + + pickedAsks = append(pickedAsks, ask) + remainingBudget = big.Sub(remainingBudget, totalPrice) + + if len(pickedAsks) == int(dealCount) { + break pickLoop + } + } + } + + for _, pickedAsk := range pickedAsks { + maddrs = append(maddrs, pickedAsk.Miner) + ask = append(ask, *pickedAsk) + } + + state = "confirm" + case "query": + color.Blue(".. querying miner asks") + + for _, maddr := range maddrs { + mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + printErr(xerrors.Errorf("failed to get peerID for miner: %w", err)) + state = "miner" + continue uiLoop + } + + a, err := api.ClientQueryAsk(ctx, *mi.PeerId, maddr) + if err != nil { + printErr(xerrors.Errorf("failed to query ask: %w", err)) + state = "miner" + continue uiLoop + } + + ask = append(ask, *a) + } + + // TODO: run more validation + state = "confirm" + case "confirm": + // TODO: do some more or epochs math (round to miner PP, deal start buffer) + + afmt.Printf("-----\n") + afmt.Printf("Proposing from %s\n", a) + afmt.Printf("\tBalance: %s\n", types.FIL(fromBal)) + afmt.Printf("\n") + afmt.Printf("Piece size: %s (Payload size: %s)\n", units.BytesSize(float64(ds.PieceSize)), units.BytesSize(float64(ds.PayloadSize))) + afmt.Printf("Duration: %s\n", dur) + + pricePerGib := big.Zero() + for _, a := range ask { + p := a.Price + if verified { + p = a.VerifiedPrice + } + pricePerGib = big.Add(pricePerGib, p) + epochPrice := types.BigDiv(types.BigMul(p, types.NewInt(uint64(ds.PieceSize))), gib) + epochPrices = append(epochPrices, epochPrice) + + mpow, err := api.StateMinerPower(ctx, a.Miner, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting power (%s): %w", a.Miner, err) + } + + if len(ask) > 1 { + totalPrice := types.BigMul(epochPrice, types.NewInt(uint64(epochs))) + afmt.Printf("Miner %s (Power:%s) price: ~%s (%s per epoch)\n", color.YellowString(a.Miner.String()), color.GreenString(types.SizeStr(mpow.MinerPower.QualityAdjPower)), color.BlueString(types.FIL(totalPrice).String()), types.FIL(epochPrice)) + } + } // TODO: price is based on PaddedPieceSize, right? - epochPrice = types.BigDiv(types.BigMul(pricePerGib, types.NewInt(uint64(ds.PieceSize))), gib) + epochPrice := types.BigDiv(types.BigMul(pricePerGib, types.NewInt(uint64(ds.PieceSize))), gib) totalPrice := types.BigMul(epochPrice, types.NewInt(uint64(epochs))) - fmt.Printf("-----\n") - fmt.Printf("Proposing from %s\n", a) - fmt.Printf("\tBalance: %s\n", types.FIL(fromBal)) - fmt.Printf("\n") - fmt.Printf("Piece size: %s (Payload size: %s)\n", units.BytesSize(float64(ds.PieceSize)), units.BytesSize(float64(ds.PayloadSize))) - fmt.Printf("Duration: %s\n", dur) - fmt.Printf("Total price: ~%s (%s per epoch)\n", types.FIL(totalPrice), types.FIL(epochPrice)) - fmt.Printf("Verified: %v\n", verified) + afmt.Printf("Total price: ~%s (%s per epoch)\n", color.CyanString(types.FIL(totalPrice).String()), types.FIL(epochPrice)) + afmt.Printf("Verified: %v\n", verified) state = "accept" case "accept": - fmt.Print("\nAccept (yes/no): ") + afmt.Print("\nAccept (yes/no): ") - var yn string - _, err := fmt.Scan(&yn) + _yn, _, err := rl.ReadLine() + yn := string(_yn) if err != nil { return err } @@ -674,36 +832,40 @@ func interactiveDeal(cctx *cli.Context) error { } if yn != "yes" { - fmt.Println("Type in full 'yes' or 'no'") + afmt.Println("Type in full 'yes' or 'no'") continue } state = "execute" case "execute": - color.Blue(".. executing") - proposal, err := api.ClientStartDeal(ctx, &lapi.StartDealParams{ - Data: &storagemarket.DataRef{ - TransferType: storagemarket.TTGraphsync, - Root: data, - }, - Wallet: a, - Miner: maddr, - EpochPrice: epochPrice, - MinBlocksDuration: uint64(epochs), - DealStartEpoch: abi.ChainEpoch(cctx.Int64("start-epoch")), - FastRetrieval: cctx.Bool("fast-retrieval"), - VerifiedDeal: verified, - }) - if err != nil { - return err + color.Blue(".. executing\n") + + for i, maddr := range maddrs { + proposal, err := api.ClientStartDeal(ctx, &lapi.StartDealParams{ + Data: &storagemarket.DataRef{ + TransferType: storagemarket.TTGraphsync, + Root: data, + }, + Wallet: a, + Miner: maddr, + EpochPrice: epochPrices[i], + MinBlocksDuration: uint64(epochs), + DealStartEpoch: abi.ChainEpoch(cctx.Int64("start-epoch")), + FastRetrieval: cctx.Bool("fast-retrieval"), + VerifiedDeal: verified, + }) + if err != nil { + return err + } + + encoder, err := GetCidEncoder(cctx) + if err != nil { + return err + } + + afmt.Printf("Deal (%s) CID: %s\n", maddr, color.GreenString(encoder.Encode(*proposal))) } - encoder, err := GetCidEncoder(cctx) - if err != nil { - return err - } - - fmt.Println("\nDeal CID:", color.GreenString(encoder.Encode(*proposal))) return nil default: return xerrors.Errorf("unknown state: %s", state) @@ -815,6 +977,7 @@ var clientRetrieveCmd = &cli.Command{ } defer closer() ctx := ReqContext(cctx) + afmt := NewAppFmt(cctx.App) var payer address.Address if cctx.String("from") != "" { @@ -923,14 +1086,14 @@ var clientRetrieveCmd = &cli.Command{ select { case evt, ok := <-updates: if ok { - fmt.Printf("> Recv: %s, Paid %s, %s (%s)\n", + afmt.Printf("> Recv: %s, Paid %s, %s (%s)\n", types.SizeStr(types.NewInt(evt.BytesReceived)), types.FIL(evt.FundsSpent), retrievalmarket.ClientEvents[evt.Event], retrievalmarket.DealStatuses[evt.Status], ) } else { - fmt.Println("Success") + afmt.Println("Success") return nil } @@ -944,6 +1107,152 @@ var clientRetrieveCmd = &cli.Command{ }, } +var clientListAsksCmd = &cli.Command{ + Name: "list-asks", + Usage: "List asks for top miners", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + asks, err := getAsks(ctx, api) + if err != nil { + return err + } + + for _, ask := range asks { + fmt.Printf("%s: min:%s max:%s price:%s/GiB/Epoch verifiedPrice:%s/GiB/Epoch\n", ask.Miner, + types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), + types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), + types.FIL(ask.Price), + types.FIL(ask.VerifiedPrice), + ) + } + + return nil + }, +} + +func getAsks(ctx context.Context, api lapi.FullNode) ([]*storagemarket.StorageAsk, error) { + color.Blue(".. getting miner list") + miners, err := api.StateListMiners(ctx, types.EmptyTSK) + if err != nil { + return nil, xerrors.Errorf("getting miner list: %w", err) + } + + var lk sync.Mutex + var found int64 + var withMinPower []address.Address + done := make(chan struct{}) + + go func() { + defer close(done) + + var wg sync.WaitGroup + wg.Add(len(miners)) + + throttle := make(chan struct{}, 50) + for _, miner := range miners { + throttle <- struct{}{} + go func(miner address.Address) { + defer wg.Done() + defer func() { + <-throttle + }() + + power, err := api.StateMinerPower(ctx, miner, types.EmptyTSK) + if err != nil { + return + } + + if power.HasMinPower { // TODO: Lower threshold + atomic.AddInt64(&found, 1) + lk.Lock() + withMinPower = append(withMinPower, miner) + lk.Unlock() + } + }(miner) + } + }() + +loop: + for { + select { + case <-time.After(150 * time.Millisecond): + fmt.Printf("\r* Found %d miners with power", atomic.LoadInt64(&found)) + case <-done: + break loop + } + } + fmt.Printf("\r* Found %d miners with power\n", atomic.LoadInt64(&found)) + + color.Blue(".. querying asks") + + var asks []*storagemarket.StorageAsk + var queried, got int64 + + done = make(chan struct{}) + go func() { + defer close(done) + + var wg sync.WaitGroup + wg.Add(len(withMinPower)) + + throttle := make(chan struct{}, 50) + for _, miner := range withMinPower { + throttle <- struct{}{} + go func(miner address.Address) { + defer wg.Done() + defer func() { + <-throttle + atomic.AddInt64(&queried, 1) + }() + + ctx, cancel := context.WithTimeout(ctx, 4*time.Second) + defer cancel() + + mi, err := api.StateMinerInfo(ctx, miner, types.EmptyTSK) + if err != nil { + return + } + if mi.PeerId == nil { + return + } + + ask, err := api.ClientQueryAsk(ctx, *mi.PeerId, miner) + if err != nil { + return + } + + atomic.AddInt64(&got, 1) + lk.Lock() + asks = append(asks, ask) + lk.Unlock() + }(miner) + } + }() + +loop2: + for { + select { + case <-time.After(150 * time.Millisecond): + fmt.Printf("\r* Queried %d asks, got %d responses", atomic.LoadInt64(&queried), atomic.LoadInt64(&got)) + case <-done: + break loop2 + } + } + fmt.Printf("\r* Queried %d asks, got %d responses\n", atomic.LoadInt64(&queried), atomic.LoadInt64(&got)) + + sort.Slice(asks, func(i, j int) bool { + return asks[i].Price.LessThan(asks[j].Price) + }) + + return asks, nil +} + var clientQueryAskCmd = &cli.Command{ Name: "query-ask", Usage: "Find a miners ask", @@ -963,8 +1272,9 @@ var clientQueryAskCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { + afmt := NewAppFmt(cctx.App) if cctx.NArg() != 1 { - fmt.Println("Usage: query-ask [minerAddress]") + afmt.Println("Usage: query-ask [minerAddress]") return nil } @@ -1005,23 +1315,23 @@ var clientQueryAskCmd = &cli.Command{ return err } - fmt.Printf("Ask: %s\n", maddr) - fmt.Printf("Price per GiB: %s\n", types.FIL(ask.Price)) - fmt.Printf("Verified Price per GiB: %s\n", types.FIL(ask.VerifiedPrice)) - fmt.Printf("Max Piece size: %s\n", types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize)))) + afmt.Printf("Ask: %s\n", maddr) + afmt.Printf("Price per GiB: %s\n", types.FIL(ask.Price)) + afmt.Printf("Verified Price per GiB: %s\n", types.FIL(ask.VerifiedPrice)) + afmt.Printf("Max Piece size: %s\n", types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize)))) size := cctx.Int64("size") if size == 0 { return nil } perEpoch := types.BigDiv(types.BigMul(ask.Price, types.NewInt(uint64(size))), types.NewInt(1<<30)) - fmt.Printf("Price per Block: %s\n", types.FIL(perEpoch)) + afmt.Printf("Price per Block: %s\n", types.FIL(perEpoch)) duration := cctx.Int64("duration") if duration == 0 { return nil } - fmt.Printf("Total Price: %s\n", types.FIL(types.BigMul(perEpoch, types.NewInt(uint64(duration))))) + afmt.Printf("Total Price: %s\n", types.FIL(types.BigMul(perEpoch, types.NewInt(uint64(duration))))) return nil }, @@ -1104,7 +1414,7 @@ var clientListDeals = &cli.Command{ } } - return outputStorageDeals(ctx, os.Stdout, api, localDeals, cctx.Bool("verbose"), cctx.Bool("color"), showFailed) + return outputStorageDeals(ctx, cctx.App.Writer, api, localDeals, cctx.Bool("verbose"), cctx.Bool("color"), showFailed) }, } diff --git a/cli/client_test.go b/cli/client_test.go new file mode 100644 index 000000000..f0e8efda8 --- /dev/null +++ b/cli/client_test.go @@ -0,0 +1,22 @@ +package cli + +import ( + "context" + "os" + "testing" + "time" + + clitest "github.com/filecoin-project/lotus/cli/test" +) + +// TestClient does a basic test to exercise the client CLI +// commands +func TestClient(t *testing.T) { + _ = os.Setenv("BELLMAN_NO_GPU", "1") + clitest.QuietMiningLogs() + + blocktime := 5 * time.Millisecond + ctx := context.Background() + clientNode, _ := clitest.StartOneNodeOneMiner(ctx, t, blocktime) + clitest.RunClientTest(t, Commands, clientNode) +} diff --git a/cli/helper.go b/cli/helper.go index 9398ead71..da236bcae 100644 --- a/cli/helper.go +++ b/cli/helper.go @@ -2,15 +2,16 @@ package cli import ( "fmt" + "io" "os" - "github.com/urfave/cli/v2" + ufcli "github.com/urfave/cli/v2" "golang.org/x/xerrors" ) type PrintHelpErr struct { Err error - Ctx *cli.Context + Ctx *ufcli.Context } func (e *PrintHelpErr) Error() string { @@ -26,11 +27,11 @@ func (e *PrintHelpErr) Is(o error) bool { return ok } -func ShowHelp(cctx *cli.Context, err error) error { +func ShowHelp(cctx *ufcli.Context, err error) error { return &PrintHelpErr{Err: err, Ctx: cctx} } -func RunApp(app *cli.App) { +func RunApp(app *ufcli.App) { if err := app.Run(os.Args); err != nil { if os.Getenv("LOTUS_DEV") != "" { log.Warnf("%+v", err) @@ -39,8 +40,40 @@ func RunApp(app *cli.App) { } var phe *PrintHelpErr if xerrors.As(err, &phe) { - _ = cli.ShowCommandHelp(phe.Ctx, phe.Ctx.Command.Name) + _ = ufcli.ShowCommandHelp(phe.Ctx, phe.Ctx.Command.Name) } os.Exit(1) } } + +type AppFmt struct { + app *ufcli.App + Stdin io.Reader +} + +func NewAppFmt(a *ufcli.App) *AppFmt { + var stdin io.Reader + istdin, ok := a.Metadata["stdin"] + if ok { + stdin = istdin.(io.Reader) + } else { + stdin = os.Stdin + } + return &AppFmt{app: a, Stdin: stdin} +} + +func (a *AppFmt) Print(args ...interface{}) { + fmt.Fprint(a.app.Writer, args...) +} + +func (a *AppFmt) Println(args ...interface{}) { + fmt.Fprintln(a.app.Writer, args...) +} + +func (a *AppFmt) Printf(fmtstr string, args ...interface{}) { + fmt.Fprintf(a.app.Writer, fmtstr, args...) +} + +func (a *AppFmt) Scan(args ...interface{}) (int, error) { + return fmt.Fscan(a.Stdin, args...) +} diff --git a/cli/multisig.go b/cli/multisig.go index 7cf7ed750..a50032cda 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -10,8 +10,6 @@ import ( "strconv" "text/tabwriter" - builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" - "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors" @@ -28,8 +26,8 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" - init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" - msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + msig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/build" @@ -167,7 +165,7 @@ var msigCreateCmd = &cli.Command{ // get address of newly created miner - var execreturn init0.ExecReturn + var execreturn init2.ExecReturn if err := execreturn.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil { return err } @@ -427,7 +425,7 @@ var msigProposeCmd = &cli.Command{ return fmt.Errorf("proposal returned exit %d", wait.Receipt.ExitCode) } - var retval msig0.ProposeReturn + var retval msig2.ProposeReturn if err := retval.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil { return fmt.Errorf("failed to unmarshal propose return value: %w", err) } @@ -1160,7 +1158,7 @@ var msigLockProposeCmd = &cli.Command{ from = defaddr } - params, actErr := actors.SerializeParams(&msig0.LockBalanceParams{ + params, actErr := actors.SerializeParams(&msig2.LockBalanceParams{ StartEpoch: abi.ChainEpoch(start), UnlockDuration: abi.ChainEpoch(duration), Amount: abi.NewTokenAmount(amount.Int64()), @@ -1170,7 +1168,7 @@ var msigLockProposeCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigPropose(ctx, msig, msig, big.Zero(), from, uint64(builtin2.MethodsMultisig.LockBalance), params) + msgCid, err := api.MsigPropose(ctx, msig, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params) if err != nil { return err } @@ -1257,7 +1255,7 @@ var msigLockApproveCmd = &cli.Command{ from = defaddr } - params, actErr := actors.SerializeParams(&msig0.LockBalanceParams{ + params, actErr := actors.SerializeParams(&msig2.LockBalanceParams{ StartEpoch: abi.ChainEpoch(start), UnlockDuration: abi.ChainEpoch(duration), Amount: abi.NewTokenAmount(amount.Int64()), @@ -1267,7 +1265,7 @@ var msigLockApproveCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigApproveTxnHash(ctx, msig, txid, prop, msig, big.Zero(), from, uint64(builtin2.MethodsMultisig.LockBalance), params) + msgCid, err := api.MsigApproveTxnHash(ctx, msig, txid, prop, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params) if err != nil { return err } @@ -1349,7 +1347,7 @@ var msigLockCancelCmd = &cli.Command{ from = defaddr } - params, actErr := actors.SerializeParams(&msig0.LockBalanceParams{ + params, actErr := actors.SerializeParams(&msig2.LockBalanceParams{ StartEpoch: abi.ChainEpoch(start), UnlockDuration: abi.ChainEpoch(duration), Amount: abi.NewTokenAmount(amount.Int64()), @@ -1359,7 +1357,7 @@ var msigLockCancelCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigCancel(ctx, msig, txid, msig, big.Zero(), from, uint64(builtin2.MethodsMultisig.LockBalance), params) + msgCid, err := api.MsigCancel(ctx, msig, txid, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params) if err != nil { return err } @@ -1488,7 +1486,7 @@ var msigProposeThresholdCmd = &cli.Command{ from = defaddr } - params, actErr := actors.SerializeParams(&msig0.ChangeNumApprovalsThresholdParams{ + params, actErr := actors.SerializeParams(&msig2.ChangeNumApprovalsThresholdParams{ NewThreshold: newM, }) @@ -1496,7 +1494,7 @@ var msigProposeThresholdCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigPropose(ctx, msig, msig, types.NewInt(0), from, uint64(builtin2.MethodsMultisig.ChangeNumApprovalsThreshold), params) + msgCid, err := api.MsigPropose(ctx, msig, msig, types.NewInt(0), from, uint64(multisig.Methods.ChangeNumApprovalsThreshold), params) if err != nil { return fmt.Errorf("failed to propose change of threshold: %w", err) } diff --git a/cli/multisig_test.go b/cli/multisig_test.go index 09cdbe056..82472cd62 100644 --- a/cli/multisig_test.go +++ b/cli/multisig_test.go @@ -6,50 +6,17 @@ import ( "testing" "time" - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/api/test" clitest "github.com/filecoin-project/lotus/cli/test" - builder "github.com/filecoin-project/lotus/node/test" ) // TestMultisig does a basic test to exercise the multisig CLI // commands func TestMultisig(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") + clitest.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() - nodes, _ := startNodes(ctx, t, blocktime) - clientNode := nodes[0] + clientNode, _ := clitest.StartOneNodeOneMiner(ctx, t, blocktime) clitest.RunMultisigTest(t, Commands, clientNode) } - -func startNodes(ctx context.Context, t *testing.T, blocktime time.Duration) ([]test.TestNode, []address.Address) { - n, sn := builder.RPCMockSbBuilder(t, test.OneFull, test.OneMiner) - - full := n[0] - miner := sn[0] - - // Get everyone connected - addrs, err := full.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrs); err != nil { - t.Fatal(err) - } - - // Start mining blocks - bm := test.NewBlockMiner(ctx, t, miner, blocktime) - bm.MineBlocks() - - // Get the creator's address - creatorAddr, err := full.WalletDefaultAddress(ctx) - if err != nil { - t.Fatal(err) - } - - // Create mock CLI - return n, []address.Address{creatorAddr} -} diff --git a/cli/state.go b/cli/state.go index d0fcc4f95..13aa5c39b 100644 --- a/cli/state.go +++ b/cli/state.go @@ -1211,7 +1211,7 @@ func ComputeStateHTMLTempl(w io.Writer, ts *types.TipSet, o *api.ComputeStateOut "GetCode": getCode, "GetMethod": getMethod, "ToFil": toFil, - "JsonParams": jsonParams, + "JsonParams": JsonParams, "JsonReturn": jsonReturn, "IsSlow": isSlow, "IsVerySlow": isVerySlow, @@ -1298,7 +1298,7 @@ func sumGas(changes []*types.GasTrace) types.GasTrace { return out } -func jsonParams(code cid.Cid, method abi.MethodNum, params []byte) (string, error) { +func JsonParams(code cid.Cid, method abi.MethodNum, params []byte) (string, error) { methodMeta, found := stmgr.MethodsMap[code][method] if !found { return "", fmt.Errorf("method %d not found on actor %s", method, code) diff --git a/cli/test/client.go b/cli/test/client.go new file mode 100644 index 000000000..3a5146219 --- /dev/null +++ b/cli/test/client.go @@ -0,0 +1,115 @@ +package test + +import ( + "context" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "regexp" + "strings" + "testing" + "time" + + "github.com/filecoin-project/lotus/api/test" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/stretchr/testify/require" + lcli "github.com/urfave/cli/v2" +) + +// RunClientTest exercises some of the client CLI commands +func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + // Create mock CLI + mockCLI := newMockCLI(t, cmds) + clientCLI := mockCLI.client(clientNode.ListenAddr) + + // Get the miner address + addrs, err := clientNode.StateListMiners(ctx, types.EmptyTSK) + require.NoError(t, err) + require.Len(t, addrs, 1) + + minerAddr := addrs[0] + fmt.Println("Miner:", minerAddr) + + // client query-ask + cmd := []string{ + "client", "query-ask", minerAddr.String(), + } + out := clientCLI.runCmd(cmd) + require.Regexp(t, regexp.MustCompile("Ask:"), out) + + // Create a deal (non-interactive) + // client deal 1000000attofil + res, _, err := test.CreateClientFile(ctx, clientNode, 1) + require.NoError(t, err) + dataCid := res.Root + price := "1000000attofil" + duration := fmt.Sprintf("%d", build.MinDealDuration) + cmd = []string{ + "client", "deal", dataCid.String(), minerAddr.String(), price, duration, + } + out = clientCLI.runCmd(cmd) + fmt.Println("client deal", out) + + // Create a deal (interactive) + // client deal + // + // (in days) + // + // "no" (verified client) + // "yes" (confirm deal) + res, _, err = test.CreateClientFile(ctx, clientNode, 2) + require.NoError(t, err) + dataCid2 := res.Root + duration = fmt.Sprintf("%d", build.MinDealDuration/builtin.EpochsInDay) + cmd = []string{ + "client", "deal", + } + interactiveCmds := []string{ + dataCid2.String(), + duration, + minerAddr.String(), + "no", + "yes", + } + out = clientCLI.runInteractiveCmd(cmd, interactiveCmds) + fmt.Println("client deal:\n", out) + + // Wait for provider to start sealing deal + dealStatus := "" + for dealStatus != "StorageDealSealing" { + // client list-deals + cmd = []string{"client", "list-deals"} + out = clientCLI.runCmd(cmd) + fmt.Println("list-deals:\n", out) + + lines := strings.Split(out, "\n") + require.Len(t, lines, 2) + re := regexp.MustCompile(`\s+`) + parts := re.Split(lines[1], -1) + if len(parts) < 4 { + require.Fail(t, "bad list-deals output format") + } + dealStatus = parts[3] + fmt.Println(" Deal status:", dealStatus) + + time.Sleep(time.Second) + } + + // Retrieve the first file from the miner + // client retrieve + tmpdir, err := ioutil.TempDir(os.TempDir(), "test-cli-client") + require.NoError(t, err) + path := filepath.Join(tmpdir, "outfile.dat") + cmd = []string{ + "client", "retrieve", dataCid.String(), path, + } + out = clientCLI.runCmd(cmd) + fmt.Println("retrieve:\n", out) + require.Regexp(t, regexp.MustCompile("Success"), out) +} diff --git a/cli/test/mockcli.go b/cli/test/mockcli.go index f5d5cfcba..c7eb70092 100644 --- a/cli/test/mockcli.go +++ b/cli/test/mockcli.go @@ -122,3 +122,12 @@ func (c *mockCLIClient) flagSet(cmd *lcli.Command) *flag.FlagSet { } return fs } + +func (c *mockCLIClient) runInteractiveCmd(cmd []string, interactive []string) string { + c.toStdin(strings.Join(interactive, "\n") + "\n") + return c.runCmd(cmd) +} + +func (c *mockCLIClient) toStdin(s string) { + c.cctx.App.Metadata["stdin"] = bytes.NewBufferString(s) +} diff --git a/cli/test/multisig.go b/cli/test/multisig.go index e77879346..d2c0238d2 100644 --- a/cli/test/multisig.go +++ b/cli/test/multisig.go @@ -10,19 +10,10 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/api/test" "github.com/filecoin-project/lotus/chain/types" - logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" lcli "github.com/urfave/cli/v2" ) -func QuietMiningLogs() { - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") -} - func RunMultisigTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode) { ctx := context.Background() diff --git a/cli/test/net.go b/cli/test/net.go new file mode 100644 index 000000000..d13993d16 --- /dev/null +++ b/cli/test/net.go @@ -0,0 +1,41 @@ +package test + +import ( + "context" + "testing" + "time" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api/test" + test2 "github.com/filecoin-project/lotus/node/test" +) + +func StartOneNodeOneMiner(ctx context.Context, t *testing.T, blocktime time.Duration) (test.TestNode, address.Address) { + n, sn := test2.RPCMockSbBuilder(t, test.OneFull, test.OneMiner) + + full := n[0] + miner := sn[0] + + // Get everyone connected + addrs, err := full.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := miner.NetConnect(ctx, addrs); err != nil { + t.Fatal(err) + } + + // Start mining blocks + bm := test.NewBlockMiner(ctx, t, miner, blocktime) + bm.MineBlocks() + + // Get the full node's wallet address + fullAddr, err := full.WalletDefaultAddress(ctx) + if err != nil { + t.Fatal(err) + } + + // Create mock CLI + return full, fullAddr +} diff --git a/cli/test/util.go b/cli/test/util.go new file mode 100644 index 000000000..e3930dc83 --- /dev/null +++ b/cli/test/util.go @@ -0,0 +1,12 @@ +package test + +import "github.com/ipfs/go-log/v2" + +func QuietMiningLogs() { + _ = log.SetLogLevel("miner", "ERROR") + _ = log.SetLogLevel("chainstore", "ERROR") + _ = log.SetLogLevel("chain", "ERROR") + _ = log.SetLogLevel("sub", "ERROR") + _ = log.SetLogLevel("storageminer", "ERROR") + _ = log.SetLogLevel("pubsub", "ERROR") +} diff --git a/cli/wallet.go b/cli/wallet.go index 3d6abc357..f6368cbfa 100644 --- a/cli/wallet.go +++ b/cli/wallet.go @@ -13,9 +13,13 @@ import ( "golang.org/x/xerrors" "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" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors" types "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/tablewriter" ) @@ -34,6 +38,7 @@ var walletCmd = &cli.Command{ walletSign, walletVerify, walletDelete, + walletMarket, }, } @@ -74,6 +79,16 @@ var walletList = &cli.Command{ Usage: "Only print addresses", Aliases: []string{"a"}, }, + &cli.BoolFlag{ + Name: "id", + Usage: "Output ID addresses", + Aliases: []string{"i"}, + }, + &cli.BoolFlag{ + Name: "market", + Usage: "Output market balances", + Aliases: []string{"m"}, + }, }, Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) @@ -93,7 +108,10 @@ var walletList = &cli.Command{ tw := tablewriter.New( tablewriter.Col("Address"), + tablewriter.Col("ID"), tablewriter.Col("Balance"), + tablewriter.Col("Market(Avail)"), + tablewriter.Col("Market(Locked)"), tablewriter.Col("Nonce"), tablewriter.Col("Default"), tablewriter.NewLineCol("Error")) @@ -126,6 +144,23 @@ var walletList = &cli.Command{ row["Default"] = "X" } + if cctx.Bool("id") { + id, err := api.StateLookupID(ctx, addr, types.EmptyTSK) + if err != nil { + row["ID"] = "n/a" + } else { + row["ID"] = id + } + } + + if cctx.Bool("market") { + mbal, err := api.StateMarketBalance(ctx, addr, types.EmptyTSK) + if err == nil { + row["Market(Avail)"] = types.FIL(types.BigSub(mbal.Escrow, mbal.Locked)) + row["Market(Locked)"] = types.FIL(mbal.Locked) + } + } + tw.Write(row) } } @@ -471,3 +506,107 @@ var walletDelete = &cli.Command{ return api.WalletDelete(ctx, addr) }, } + +var walletMarket = &cli.Command{ + Name: "market", + Usage: "Interact with market balances", + Subcommands: []*cli.Command{ + walletMarketWithdraw, + }, +} + +var walletMarketWithdraw = &cli.Command{ + Name: "withdraw", + Usage: "Withdraw funds from the Storage Market Actor", + ArgsUsage: "[amount (FIL) optional, otherwise will withdraw max available]", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "from", + Usage: "Specify address to withdraw funds from, otherwise it will use the default wallet address", + Aliases: []string{"f"}, + }, + &cli.StringFlag{ + Name: "address", + Usage: "Market address to withdraw from (account or miner actor address, defaults to --from address)", + Aliases: []string{"a"}, + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return xerrors.Errorf("getting node API: %w", err) + } + defer closer() + ctx := ReqContext(cctx) + + var from address.Address + if cctx.String("from") != "" { + from, err = address.NewFromString(cctx.String("from")) + if err != nil { + return xerrors.Errorf("parsing from address: %w", err) + } + } else { + from, err = api.WalletDefaultAddress(ctx) + if err != nil { + return xerrors.Errorf("getting default wallet address: %w", err) + } + } + + addr := from + if cctx.String("address") != "" { + addr, err = address.NewFromString(cctx.String("address")) + if err != nil { + return xerrors.Errorf("parsing market address: %w", err) + } + } + + bal, err := api.StateMarketBalance(ctx, addr, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting market balance for address %s: %w", addr.String(), err) + } + + avail := big.Subtract(bal.Escrow, bal.Locked) + amt := avail + + if cctx.Args().Present() { + f, err := types.ParseFIL(cctx.Args().First()) + if err != nil { + return xerrors.Errorf("parsing 'amount' argument: %w", err) + } + + amt = abi.TokenAmount(f) + } + + if amt.GreaterThan(avail) { + return xerrors.Errorf("can't withdraw more funds than available; requested: %s; available: %s", types.FIL(amt), types.FIL(avail)) + } + + if avail.IsZero() { + return xerrors.Errorf("zero unlocked funds available to withdraw") + } + + params, err := actors.SerializeParams(&market.WithdrawBalanceParams{ + ProviderOrClientAddress: addr, + Amount: amt, + }) + if err != nil { + return xerrors.Errorf("serializing params: %w", err) + } + + fmt.Printf("Submitting WithdrawBalance message for amount %s for address %s\n", types.FIL(amt), from.String()) + smsg, err := api.MpoolPushMessage(ctx, &types.Message{ + To: builtin.StorageMarketActorAddr, + From: from, + Value: types.NewInt(0), + Method: builtin.MethodsMarket.WithdrawBalance, + Params: params, + }, nil) + if err != nil { + return xerrors.Errorf("submitting WithdrawBalance message: %w", err) + } + + fmt.Printf("WithdrawBalance message cid: %s\n", smsg.Cid()) + + return nil + }, +} diff --git a/cmd/lotus-bench/caching_verifier.go b/cmd/lotus-bench/caching_verifier.go index 51ab696f7..5b434c762 100644 --- a/cmd/lotus-bench/caching_verifier.go +++ b/cmd/lotus-bench/caching_verifier.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/ipfs/go-datastore" "github.com/minio/blake2b-simd" cbg "github.com/whyrusleeping/cbor-gen" @@ -78,15 +78,16 @@ func (cv cachingVerifier) withCache(execute func() (bool, error), param cbg.CBOR } } -func (cv *cachingVerifier) VerifySeal(svi proof.SealVerifyInfo) (bool, error) { +func (cv *cachingVerifier) VerifySeal(svi proof2.SealVerifyInfo) (bool, error) { return cv.withCache(func() (bool, error) { return cv.backend.VerifySeal(svi) }, &svi) } -func (cv *cachingVerifier) VerifyWinningPoSt(ctx context.Context, info proof.WinningPoStVerifyInfo) (bool, error) { + +func (cv *cachingVerifier) VerifyWinningPoSt(ctx context.Context, info proof2.WinningPoStVerifyInfo) (bool, error) { return cv.backend.VerifyWinningPoSt(ctx, info) } -func (cv *cachingVerifier) VerifyWindowPoSt(ctx context.Context, info proof.WindowPoStVerifyInfo) (bool, error) { +func (cv *cachingVerifier) VerifyWindowPoSt(ctx context.Context, info proof2.WindowPoStVerifyInfo) (bool, error) { return cv.withCache(func() (bool, error) { return cv.backend.VerifyWindowPoSt(ctx, info) }, &info) diff --git a/cmd/lotus-bench/import.go b/cmd/lotus-bench/import.go index 3f99d0453..acbf9ebdc 100644 --- a/cmd/lotus-bench/import.go +++ b/cmd/lotus-bench/import.go @@ -26,7 +26,9 @@ import ( "github.com/filecoin-project/lotus/lib/blockstore" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" + metricsprometheus "github.com/ipfs/go-metrics-prometheus" "github.com/ipld/go-car" + "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" @@ -34,6 +36,7 @@ import ( bdg "github.com/dgraph-io/badger/v2" "github.com/ipfs/go-datastore" badger "github.com/ipfs/go-ds-badger2" + measure "github.com/ipfs/go-ds-measure" pebbleds "github.com/ipfs/go-ds-pebble" "github.com/urfave/cli/v2" @@ -89,8 +92,12 @@ var importBenchCmd = &cli.Command{ &cli.BoolFlag{ Name: "only-import", }, + &cli.BoolFlag{ + Name: "use-pebble", + }, }, Action: func(cctx *cli.Context) error { + metricsprometheus.Inject() //nolint:errcheck vm.BatchSealVerifyParallelism = cctx.Int("batch-seal-verify-threads") if !cctx.Args().Present() { fmt.Println("must pass car file of chain to benchmark importing") @@ -104,6 +111,7 @@ var importBenchCmd = &cli.Command{ defer cfi.Close() //nolint:errcheck // read only file go func() { + http.Handle("/debug/metrics/prometheus", promhttp.Handler()) http.ListenAndServe("localhost:6060", nil) //nolint:errcheck }() @@ -126,7 +134,7 @@ var importBenchCmd = &cli.Command{ bdgOpt.Options.DetectConflicts = false var bds datastore.Batching - if false { + if cctx.Bool("use-pebble") { cache := 512 bds, err = pebbleds.NewDatastore(tdir, &pebble.Options{ // Pebble has a single combined cache area and the write @@ -155,6 +163,8 @@ var importBenchCmd = &cli.Command{ } defer bds.Close() //nolint:errcheck + bds = measure.New("dsbench", bds) + bs := blockstore.NewBlockstore(bds) cacheOpts := blockstore.DefaultCacheOpts() cacheOpts.HasBloomFilterSize = 0 @@ -310,6 +320,21 @@ var importBenchCmd = &cli.Command{ pprof.StopCPUProfile() + if true { + resp, err := http.Get("http://localhost:6060/debug/metrics/prometheus") + if err != nil { + return err + } + + metricsfi, err := os.Create("import-bench.metrics") + if err != nil { + return err + } + + io.Copy(metricsfi, resp.Body) //nolint:errcheck + metricsfi.Close() //nolint:errcheck + } + return nil }, diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 995e25737..1af5c1c62 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -11,7 +11,7 @@ import ( "path/filepath" "time" - saproof "github.com/filecoin-project/specs-actors/actors/runtime/proof" + saproof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/docker/go-units" logging "github.com/ipfs/go-log/v2" @@ -237,7 +237,7 @@ var sealBenchCmd = &cli.Command{ } var sealTimings []SealingResult - var sealedSectors []saproof.SectorInfo + var sealedSectors []saproof2.SectorInfo if robench == "" { var err error @@ -280,7 +280,7 @@ var sealBenchCmd = &cli.Command{ } for _, s := range genm.Sectors { - sealedSectors = append(sealedSectors, saproof.SectorInfo{ + sealedSectors = append(sealedSectors, saproof2.SectorInfo{ SealedCID: s.CommR, SectorNumber: s.SectorID, SealProof: s.ProofType, @@ -305,7 +305,7 @@ var sealBenchCmd = &cli.Command{ return err } - candidates := make([]saproof.SectorInfo, len(fcandidates)) + candidates := make([]saproof2.SectorInfo, len(fcandidates)) for i, fcandidate := range fcandidates { candidates[i] = sealedSectors[fcandidate] } @@ -328,7 +328,7 @@ var sealBenchCmd = &cli.Command{ winnningpost2 := time.Now() - pvi1 := saproof.WinningPoStVerifyInfo{ + pvi1 := saproof2.WinningPoStVerifyInfo{ Randomness: abi.PoStRandomness(challenge[:]), Proofs: proof1, ChallengedSectors: candidates, @@ -344,7 +344,7 @@ var sealBenchCmd = &cli.Command{ verifyWinningPost1 := time.Now() - pvi2 := saproof.WinningPoStVerifyInfo{ + pvi2 := saproof2.WinningPoStVerifyInfo{ Randomness: abi.PoStRandomness(challenge[:]), Proofs: proof2, ChallengedSectors: candidates, @@ -376,7 +376,7 @@ var sealBenchCmd = &cli.Command{ windowpost2 := time.Now() - wpvi1 := saproof.WindowPoStVerifyInfo{ + wpvi1 := saproof2.WindowPoStVerifyInfo{ Randomness: challenge[:], Proofs: wproof1, ChallengedSectors: sealedSectors, @@ -392,7 +392,7 @@ var sealBenchCmd = &cli.Command{ verifyWindowpost1 := time.Now() - wpvi2 := saproof.WindowPoStVerifyInfo{ + wpvi2 := saproof2.WindowPoStVerifyInfo{ Randomness: challenge[:], Proofs: wproof2, ChallengedSectors: sealedSectors, @@ -464,10 +464,10 @@ type ParCfg struct { Commit int } -func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par ParCfg, mid abi.ActorID, sectorSize abi.SectorSize, ticketPreimage []byte, saveC2inp string, skipc2, skipunseal bool) ([]SealingResult, []saproof.SectorInfo, error) { +func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par ParCfg, mid abi.ActorID, sectorSize abi.SectorSize, ticketPreimage []byte, saveC2inp string, skipc2, skipunseal bool) ([]SealingResult, []saproof2.SectorInfo, error) { var pieces []abi.PieceInfo sealTimings := make([]SealingResult, numSectors) - sealedSectors := make([]saproof.SectorInfo, numSectors) + sealedSectors := make([]saproof2.SectorInfo, numSectors) preCommit2Sema := make(chan struct{}, par.PreCommit2) commitSema := make(chan struct{}, par.Commit) @@ -537,7 +537,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par precommit2 := time.Now() <-preCommit2Sema - sealedSectors[ix] = saproof.SectorInfo{ + sealedSectors[ix] = saproof2.SectorInfo{ SealProof: sb.SealProofType(), SectorNumber: i, SealedCID: cids.Sealed, @@ -589,7 +589,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par <-commitSema if !skipc2 { - svi := saproof.SealVerifyInfo{ + svi := saproof2.SealVerifyInfo{ SectorID: abi.SectorID{Miner: mid, Number: i}, SealedCID: cids.Sealed, SealProof: sb.SealProofType(), diff --git a/cmd/lotus-chainwatch/processor/processor.go b/cmd/lotus-chainwatch/processor/processor.go index bce2b9fb7..1f8b246ed 100644 --- a/cmd/lotus-chainwatch/processor/processor.go +++ b/cmd/lotus-chainwatch/processor/processor.go @@ -15,7 +15,7 @@ import ( logging "github.com/ipfs/go-log/v2" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" @@ -134,10 +134,10 @@ func (p *Processor) Start(ctx context.Context) { log.Fatalw("Failed to collect actor changes", "error", err) } log.Infow("Collected Actor Changes", - "MarketChanges", len(actorChanges[builtin.StorageMarketActorCodeID]), - "MinerChanges", len(actorChanges[builtin.StorageMinerActorCodeID]), - "RewardChanges", len(actorChanges[builtin.RewardActorCodeID]), - "AccountChanges", len(actorChanges[builtin.AccountActorCodeID]), + "MarketChanges", len(actorChanges[builtin2.StorageMarketActorCodeID]), + "MinerChanges", len(actorChanges[builtin2.StorageMinerActorCodeID]), + "RewardChanges", len(actorChanges[builtin2.RewardActorCodeID]), + "AccountChanges", len(actorChanges[builtin2.AccountActorCodeID]), "nullRounds", len(nullRounds)) grp := sync.WaitGroup{} @@ -145,7 +145,7 @@ func (p *Processor) Start(ctx context.Context) { grp.Add(1) go func() { defer grp.Done() - if err := p.HandleMarketChanges(ctx, actorChanges[builtin.StorageMarketActorCodeID]); err != nil { + if err := p.HandleMarketChanges(ctx, actorChanges[builtin2.StorageMarketActorCodeID]); err != nil { log.Errorf("Failed to handle market changes: %w", err) return } @@ -154,7 +154,7 @@ func (p *Processor) Start(ctx context.Context) { grp.Add(1) go func() { defer grp.Done() - if err := p.HandleMinerChanges(ctx, actorChanges[builtin.StorageMinerActorCodeID]); err != nil { + if err := p.HandleMinerChanges(ctx, actorChanges[builtin2.StorageMinerActorCodeID]); err != nil { log.Errorf("Failed to handle miner changes: %w", err) return } @@ -163,7 +163,7 @@ func (p *Processor) Start(ctx context.Context) { grp.Add(1) go func() { defer grp.Done() - if err := p.HandleRewardChanges(ctx, actorChanges[builtin.RewardActorCodeID], nullRounds); err != nil { + if err := p.HandleRewardChanges(ctx, actorChanges[builtin2.RewardActorCodeID], nullRounds); err != nil { log.Errorf("Failed to handle reward changes: %w", err) return } @@ -172,7 +172,7 @@ func (p *Processor) Start(ctx context.Context) { grp.Add(1) go func() { defer grp.Done() - if err := p.HandlePowerChanges(ctx, actorChanges[builtin.StoragePowerActorCodeID]); err != nil { + if err := p.HandlePowerChanges(ctx, actorChanges[builtin2.StoragePowerActorCodeID]); err != nil { log.Errorf("Failed to handle power actor changes: %w", err) return } diff --git a/cmd/lotus-gateway/api.go b/cmd/lotus-gateway/api.go index 105f8881e..875eaac7d 100644 --- a/cmd/lotus-gateway/api.go +++ b/cmd/lotus-gateway/api.go @@ -10,6 +10,7 @@ import ( "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" @@ -22,8 +23,8 @@ import ( ) const ( - LookbackCap = time.Hour * 12 - stateWaitLookbackLimit = abi.ChainEpoch(20) + LookbackCap = time.Hour * 24 + StateWaitLookbackLimit = abi.ChainEpoch(20) ) var ( @@ -33,19 +34,29 @@ var ( // gatewayDepsAPI defines the API methods that the GatewayAPI depends on // (to make it easy to mock for tests) type gatewayDepsAPI interface { - ChainHasObj(context.Context, cid.Cid) (bool, error) - ChainHead(ctx context.Context) (*types.TipSet, error) + Version(context.Context) (api.Version, 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) - ChainGetNode(ctx context.Context, p string) (*api.IpldObject, 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) 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) + StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, 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) StateWaitMsgLimited(ctx context.Context, msg cid.Cid, confidence uint64, h abi.ChainEpoch) (*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) @@ -56,22 +67,24 @@ type gatewayDepsAPI interface { 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) + StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error) } type GatewayAPI struct { - api gatewayDepsAPI - lookbackCap time.Duration + 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) + return newGatewayAPI(api, LookbackCap, StateWaitLookbackLimit) } // used by the tests -func newGatewayAPI(api gatewayDepsAPI, lookbackCap time.Duration) *GatewayAPI { - return &GatewayAPI{api: api, lookbackCap: lookbackCap} +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 { @@ -114,6 +127,14 @@ func (a *GatewayAPI) checkTimestamp(at time.Time) error { return nil } +func (a *GatewayAPI) Version(ctx context.Context) (api.Version, 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) } @@ -124,6 +145,10 @@ func (a *GatewayAPI) ChainHead(ctx context.Context) (*types.TipSet, error) { 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) } @@ -157,14 +182,18 @@ func (a *GatewayAPI) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoc return a.api.ChainGetTipSetByHeight(ctx, h, tsk) } -func (a *GatewayAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { - return a.api.ChainReadObj(ctx, c) -} - 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 @@ -205,6 +234,14 @@ func (a *GatewayAPI) StateAccountKey(ctx context.Context, addr address.Address, 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 @@ -213,6 +250,22 @@ func (a *GatewayAPI) StateGetActor(ctx context.Context, actor address.Address, t return a.api.StateGetActor(ctx, actor, tsk) } +func (a *GatewayAPI) StateGetReceipt(ctx context.Context, c cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) { + if err := a.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + + return a.api.StateGetReceipt(ctx, c, 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 @@ -221,8 +274,32 @@ func (a *GatewayAPI) StateLookupID(ctx context.Context, addr address.Address, ts 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) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) { - return a.api.StateWaitMsgLimited(ctx, msg, confidence, stateWaitLookbackLimit) + return a.api.StateWaitMsgLimited(ctx, msg, confidence, a.stateWaitLookbackLimit) } func (a *GatewayAPI) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) { @@ -288,6 +365,13 @@ func (a *GatewayAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSe } +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 diff --git a/cmd/lotus-gateway/api_test.go b/cmd/lotus-gateway/api_test.go index ae161945b..23d2cbf3a 100644 --- a/cmd/lotus-gateway/api_test.go +++ b/cmd/lotus-gateway/api_test.go @@ -6,6 +6,9 @@ import ( "testing" "time" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/build" "github.com/stretchr/testify/require" @@ -116,6 +119,38 @@ func (m *mockGatewayDepsAPI) ChainHasObj(context.Context, cid.Cid) (bool, error) panic("implement me") } +func (m *mockGatewayDepsAPI) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) { + panic("implement me") +} + +func (m *mockGatewayDepsAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { + panic("implement me") +} + +func (m *mockGatewayDepsAPI) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) { + panic("implement me") +} + +func (m *mockGatewayDepsAPI) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { + panic("implement me") +} + +func (m *mockGatewayDepsAPI) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) { + panic("implement me") +} + +func (m *mockGatewayDepsAPI) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) { + panic("implement me") +} + +func (m *mockGatewayDepsAPI) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) { + panic("implement me") +} + +func (m *mockGatewayDepsAPI) StateNetworkVersion(ctx context.Context, key types.TipSetKey) (network.Version, error) { + panic("implement me") +} + func (m *mockGatewayDepsAPI) ChainHead(ctx context.Context) (*types.TipSet, error) { m.lk.RLock() defer m.lk.RUnlock() @@ -165,10 +200,6 @@ func (m *mockGatewayDepsAPI) ChainGetTipSetByHeight(ctx context.Context, h abi.C return m.tipsets[h], nil } -func (m *mockGatewayDepsAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { - panic("implement me") -} - func (m *mockGatewayDepsAPI) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) { panic("implement me") } diff --git a/cmd/lotus-gateway/endtoend_test.go b/cmd/lotus-gateway/endtoend_test.go index 379c96053..1e1e5e229 100644 --- a/cmd/lotus-gateway/endtoend_test.go +++ b/cmd/lotus-gateway/endtoend_test.go @@ -12,8 +12,8 @@ import ( "github.com/filecoin-project/lotus/cli" clitest "github.com/filecoin-project/lotus/cli/test" - init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" - "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" "github.com/stretchr/testify/require" "golang.org/x/xerrors" @@ -25,12 +25,14 @@ import ( "github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/api/test" "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 func init() { policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) @@ -38,15 +40,19 @@ func init() { policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) } -// TestEndToEndWalletMsig tests that wallet and msig API calls can be made -// on a lite node that is connected through a gateway to a full API node -func TestEndToEndWalletMsig(t *testing.T) { +// TestWalletMsig tests that API calls to wallet and msig can be made on a lite +// node that is connected through a gateway to a full API node +func TestWalletMsig(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") + clitest.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() - full, lite, closer := startNodes(ctx, t, blocktime, maxLookbackCap) - defer closer() + nodes := startNodes(ctx, t, blocktime, maxLookbackCap, maxStateWaitLookbackLimit) + defer nodes.closer() + + lite := nodes.lite + full := nodes.full // The full node starts with a wallet fullWalletAddr, err := full.WalletDefaultAddress(ctx) @@ -101,7 +107,7 @@ func TestEndToEndWalletMsig(t *testing.T) { require.NoError(t, err) require.EqualValues(t, 0, res.Receipt.ExitCode) - var execReturn init0.ExecReturn + var execReturn init2.ExecReturn err = execReturn.UnmarshalCBOR(bytes.NewReader(res.Receipt.Return)) require.NoError(t, err) @@ -121,7 +127,7 @@ func TestEndToEndWalletMsig(t *testing.T) { require.NoError(t, err) require.EqualValues(t, 0, res.Receipt.ExitCode) - var proposeReturn multisig.ProposeReturn + var proposeReturn multisig2.ProposeReturn err = proposeReturn.UnmarshalCBOR(bytes.NewReader(res.Receipt.Return)) require.NoError(t, err) @@ -135,62 +141,89 @@ func TestEndToEndWalletMsig(t *testing.T) { require.NoError(t, err) require.EqualValues(t, 0, res.Receipt.ExitCode) - var approveReturn multisig.ApproveReturn + var approveReturn multisig2.ApproveReturn err = approveReturn.UnmarshalCBOR(bytes.NewReader(res.Receipt.Return)) require.NoError(t, err) require.True(t, approveReturn.Applied) } -// TestEndToEndMsigCLI tests that msig CLI calls can be made +// TestMsigCLI tests that msig CLI calls can be made // on a lite node that is connected through a gateway to a full API node -func TestEndToEndMsigCLI(t *testing.T) { +func TestMsigCLI(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") clitest.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() - full, lite, closer := startNodes(ctx, t, blocktime, maxLookbackCap) - defer closer() - - // The full node starts with a wallet - fullWalletAddr, err := full.WalletDefaultAddress(ctx) - require.NoError(t, err) - - // Create a wallet on the lite node - liteWalletAddr, err := lite.WalletNew(ctx, types.KTSecp256k1) - require.NoError(t, err) - - // Send some funds from the full node to the lite node - err = sendFunds(ctx, full, fullWalletAddr, liteWalletAddr, types.NewInt(1e18)) - require.NoError(t, err) + nodes := startNodesWithFunds(ctx, t, blocktime, maxLookbackCap, maxStateWaitLookbackLimit) + defer nodes.closer() + lite := nodes.lite clitest.RunMultisigTest(t, cli.Commands, lite) } -func sendFunds(ctx context.Context, fromNode test.TestNode, fromAddr address.Address, toAddr address.Address, amt types.BigInt) error { - msg := &types.Message{ - From: fromAddr, - To: toAddr, - Value: amt, - } +func TestDealFlow(t *testing.T) { + _ = os.Setenv("BELLMAN_NO_GPU", "1") + clitest.QuietMiningLogs() - sm, err := fromNode.MpoolPushMessage(ctx, msg, nil) - if err != nil { - return err - } + blocktime := 5 * time.Millisecond + ctx := context.Background() + nodes := startNodesWithFunds(ctx, t, blocktime, maxLookbackCap, maxStateWaitLookbackLimit) + defer nodes.closer() - res, err := fromNode.StateWaitMsg(ctx, sm.Cid(), 1) - if err != nil { - return err - } - if res.Receipt.ExitCode != 0 { - return xerrors.Errorf("send funds failed with exit code %d", res.Receipt.ExitCode) - } - - return nil + test.MakeDeal(t, ctx, 6, nodes.lite, nodes.miner, false, false) } -func startNodes(ctx context.Context, t *testing.T, blocktime time.Duration, lookbackCap time.Duration) (test.TestNode, test.TestNode, jsonrpc.ClientCloser) { +func TestCLIDealFlow(t *testing.T) { + _ = os.Setenv("BELLMAN_NO_GPU", "1") + clitest.QuietMiningLogs() + + blocktime := 5 * time.Millisecond + ctx := context.Background() + nodes := startNodesWithFunds(ctx, t, blocktime, maxLookbackCap, maxStateWaitLookbackLimit) + defer nodes.closer() + + clitest.RunClientTest(t, cli.Commands, nodes.lite) +} + +type testNodes struct { + lite test.TestNode + full test.TestNode + miner test.TestStorageNode + closer jsonrpc.ClientCloser +} + +func startNodesWithFunds( + ctx context.Context, + t *testing.T, + blocktime time.Duration, + lookbackCap time.Duration, + stateWaitLookbackLimit abi.ChainEpoch, +) *testNodes { + nodes := startNodes(ctx, t, blocktime, lookbackCap, stateWaitLookbackLimit) + + // The full node starts with a wallet + fullWalletAddr, err := nodes.full.WalletDefaultAddress(ctx) + require.NoError(t, err) + + // Create a wallet on the lite node + liteWalletAddr, err := nodes.lite.WalletNew(ctx, types.KTSecp256k1) + require.NoError(t, err) + + // Send some funds from the full node to the lite node + err = sendFunds(ctx, nodes.full, fullWalletAddr, liteWalletAddr, types.NewInt(1e18)) + require.NoError(t, err) + + return nodes +} + +func startNodes( + ctx context.Context, + t *testing.T, + blocktime time.Duration, + lookbackCap time.Duration, + stateWaitLookbackLimit abi.ChainEpoch, +) *testNodes { var closer jsonrpc.ClientCloser // Create one miner and two full nodes. @@ -207,7 +240,8 @@ func startNodes(ctx context.Context, t *testing.T, blocktime time.Duration, look fullNode := nodes[0] // Create a gateway server in front of the full node - _, addr, err := builder.CreateRPCServer(newGatewayAPI(fullNode, lookbackCap)) + gapiImpl := newGatewayAPI(fullNode, lookbackCap, stateWaitLookbackLimit) + _, addr, err := builder.CreateRPCServer(gapiImpl) require.NoError(t, err) // Create a gateway client API that connects to the gateway server @@ -234,9 +268,39 @@ func startNodes(ctx context.Context, t *testing.T, blocktime time.Duration, look err = miner.NetConnect(ctx, fullAddr) require.NoError(t, err) + // Connect the miner and the lite node (so that the lite node can send + // data to the miner) + liteAddr, err := lite.NetAddrsListen(ctx) + require.NoError(t, err) + err = miner.NetConnect(ctx, liteAddr) + require.NoError(t, err) + // Start mining blocks bm := test.NewBlockMiner(ctx, t, miner, blocktime) bm.MineBlocks() - return full, lite, closer + return &testNodes{lite: lite, full: full, miner: miner, closer: closer} +} + +func sendFunds(ctx context.Context, fromNode test.TestNode, fromAddr address.Address, toAddr address.Address, amt types.BigInt) error { + msg := &types.Message{ + From: fromAddr, + To: toAddr, + Value: amt, + } + + sm, err := fromNode.MpoolPushMessage(ctx, msg, nil) + if err != nil { + return err + } + + res, err := fromNode.StateWaitMsg(ctx, sm.Cid(), 1) + if err != nil { + return err + } + if res.Receipt.ExitCode != 0 { + return xerrors.Errorf("send funds failed with exit code %d", res.Receipt.ExitCode) + } + + return nil } diff --git a/cmd/lotus-gateway/main.go b/cmd/lotus-gateway/main.go index 34e068ffd..3fed88468 100644 --- a/cmd/lotus-gateway/main.go +++ b/cmd/lotus-gateway/main.go @@ -7,10 +7,15 @@ import ( "os" "github.com/filecoin-project/go-jsonrpc" + "go.opencensus.io/tag" + "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/lotuslog" + "github.com/filecoin-project/lotus/metrics" + logging "github.com/ipfs/go-log" + "go.opencensus.io/stats/view" "github.com/gorilla/mux" "github.com/urfave/cli/v2" @@ -64,6 +69,13 @@ var runCmd = &cli.Command{ ctx, cancel := context.WithCancel(ctx) defer cancel() + // Register all metric views + if err := view.Register( + metrics.DefaultViews..., + ); err != nil { + log.Fatalf("Cannot register the view: %v", err) + } + api, closer, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err @@ -76,7 +88,7 @@ var runCmd = &cli.Command{ log.Info("Setting up API endpoint at " + address) rpcServer := jsonrpc.NewServer() - rpcServer.Register("Filecoin", NewGatewayAPI(api)) + rpcServer.Register("Filecoin", metrics.MetricedGatewayAPI(NewGatewayAPI(api))) mux.Handle("/rpc/v0", rpcServer) mux.PathPrefix("/").Handler(http.DefaultServeMux) @@ -89,6 +101,7 @@ var runCmd = &cli.Command{ srv := &http.Server{ Handler: mux, BaseContext: func(listener net.Listener) context.Context { + ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "lotus-gateway")) return ctx }, } diff --git a/cmd/lotus-pcr/main.go b/cmd/lotus-pcr/main.go index f88a0a9dc..8ee79b44a 100644 --- a/cmd/lotus-pcr/main.go +++ b/cmd/lotus-pcr/main.go @@ -6,19 +6,19 @@ import ( "context" "encoding/csv" "fmt" + "io" "io/ioutil" "net/http" _ "net/http/pprof" "os" "path/filepath" "strconv" + "strings" "time" "github.com/filecoin-project/lotus/chain/actors/builtin" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" "github.com/filecoin-project/go-state-types/network" @@ -251,6 +251,15 @@ var recoverMinersCmd = &cli.Command{ } defer closer() + r, err := NewRepo(cctx.String("repo")) + if err != nil { + return err + } + + if err := r.Open(); err != nil { + return err + } + from, err := address.NewFromString(cctx.String("from")) if err != nil { return xerrors.Errorf("parsing source address (provide correct --from flag!): %w", err) @@ -267,6 +276,12 @@ var recoverMinersCmd = &cli.Command{ minerRecoveryCutoff := uint64(cctx.Int("miner-recovery-cutoff")) minerRecoveryBonus := uint64(cctx.Int("miner-recovery-bonus")) + blockmap := make(map[address.Address]struct{}) + + for _, addr := range r.Blocklist() { + blockmap[addr] = struct{}{} + } + rf := &refunder{ api: api, wallet: from, @@ -274,6 +289,7 @@ var recoverMinersCmd = &cli.Command{ minerRecoveryRefundPercent: minerRecoveryRefundPercent, minerRecoveryCutoff: types.FromFil(minerRecoveryCutoff), minerRecoveryBonus: types.FromFil(minerRecoveryBonus), + blockmap: blockmap, } refundTipset, err := api.ChainHead(ctx) @@ -466,6 +482,12 @@ var runCmd = &cli.Command{ return err } + blockmap := make(map[address.Address]struct{}) + + for _, addr := range r.Blocklist() { + blockmap[addr] = struct{}{} + } + rf := &refunder{ api: api, wallet: from, @@ -480,13 +502,18 @@ var runCmd = &cli.Command{ publishStorageDealsEnabled: publishStorageDealsEnabled, preFeeCapMax: types.BigInt(preFeeCapMax), proveFeeCapMax: types.BigInt(proveFeeCapMax), + blockmap: blockmap, } - var refunds *MinersRefund = NewMinersRefund() - var rounds int = 0 + var refunds = NewMinersRefund() + var rounds = 0 nextMinerRecovery := r.MinerRecoveryHeight() + minerRecoveryPeriod for tipset := range tipsetsCh { + for k := range rf.blockmap { + fmt.Printf("%s\n", k) + } + refunds, err = rf.ProcessTipset(ctx, tipset, refunds) if err != nil { return err @@ -634,6 +661,7 @@ type refunder struct { windowedPoStEnabled bool publishStorageDealsEnabled bool threshold big.Int + blockmap map[address.Address]struct{} preFeeCapMax big.Int proveFeeCapMax big.Int @@ -738,6 +766,11 @@ func (r *refunder) EnsureMinerMinimums(ctx context.Context, tipset *types.TipSet } for _, maddr := range miners { + if _, found := r.blockmap[maddr]; found { + log.Debugw("skipping blocked miner", "height", tipset.Height(), "key", tipset.Key(), "miner", maddr) + continue + } + mact, err := r.api.StateGetActor(ctx, maddr, types.EmptyTSK) if err != nil { log.Errorw("failed", "err", err, "height", tipset.Height(), "key", tipset.Key(), "miner", maddr) @@ -871,7 +904,7 @@ func (r *refunder) processTipsetStorageMarketActor(ctx context.Context, tipset * var messageMethod string switch m.Method { - case builtin0.MethodsMarket.PublishStorageDeals: + case market.Methods.PublishStorageDeals: if !r.publishStorageDealsEnabled { return false, messageMethod, types.NewInt(0), nil } @@ -897,8 +930,13 @@ func (r *refunder) processTipsetStorageMinerActor(ctx context.Context, tipset *t refundValue := types.NewInt(0) var messageMethod string + if _, found := r.blockmap[m.To]; found { + log.Debugw("skipping blocked miner", "height", tipset.Height(), "key", tipset.Key(), "miner", m.To) + return false, messageMethod, types.NewInt(0), nil + } + switch m.Method { - case builtin0.MethodsMiner.SubmitWindowedPoSt: + case miner.Methods.SubmitWindowedPoSt: if !r.windowedPoStEnabled { return false, messageMethod, types.NewInt(0), nil } @@ -911,7 +949,7 @@ func (r *refunder) processTipsetStorageMinerActor(ctx context.Context, tipset *t } refundValue = types.BigMul(types.NewInt(uint64(recp.GasUsed)), tipset.Blocks()[0].ParentBaseFee) - case builtin0.MethodsMiner.ProveCommitSector: + case miner.Methods.ProveCommitSector: if !r.proveCommitEnabled { return false, messageMethod, types.NewInt(0), nil } @@ -928,9 +966,14 @@ func (r *refunder) processTipsetStorageMinerActor(ctx context.Context, tipset *t return false, messageMethod, types.NewInt(0), nil } + if tipset.Blocks()[0].ParentBaseFee.GreaterThan(r.proveFeeCapMax) { + log.Debugw("skipping high base fee message", "method", messageMethod, "cid", msg.Cid, "miner", m.To, "basefee", tipset.Blocks()[0].ParentBaseFee, "fee_cap_max", r.proveFeeCapMax) + return false, messageMethod, types.NewInt(0), nil + } + var sn abi.SectorNumber - var proveCommitSector miner0.ProveCommitSectorParams + var proveCommitSector miner2.ProveCommitSectorParams if err := proveCommitSector.UnmarshalCBOR(bytes.NewBuffer(m.Params)); err != nil { log.Warnw("failed to decode provecommit params", "err", err, "method", messageMethod, "cid", msg.Cid, "miner", m.To) return false, messageMethod, types.NewInt(0), nil @@ -967,7 +1010,7 @@ func (r *refunder) processTipsetStorageMinerActor(ctx context.Context, tipset *t if r.refundPercent > 0 { refundValue = types.BigMul(types.BigDiv(refundValue, types.NewInt(100)), types.NewInt(uint64(r.refundPercent))) } - case builtin0.MethodsMiner.PreCommitSector: + case miner.Methods.PreCommitSector: if !r.preCommitEnabled { return false, messageMethod, types.NewInt(0), nil } @@ -984,6 +1027,11 @@ func (r *refunder) processTipsetStorageMinerActor(ctx context.Context, tipset *t return false, messageMethod, types.NewInt(0), nil } + if tipset.Blocks()[0].ParentBaseFee.GreaterThan(r.preFeeCapMax) { + log.Debugw("skipping high base fee message", "method", messageMethod, "cid", msg.Cid, "miner", m.To, "basefee", tipset.Blocks()[0].ParentBaseFee, "fee_cap_max", r.preFeeCapMax) + return false, messageMethod, types.NewInt(0), nil + } + var precommitInfo miner.SectorPreCommitInfo if err := precommitInfo.UnmarshalCBOR(bytes.NewBuffer(m.Params)); err != nil { log.Warnw("failed to decode precommit params", "err", err, "method", messageMethod, "cid", msg.Cid, "miner", m.To) @@ -1167,6 +1215,7 @@ type Repo struct { lastHeight abi.ChainEpoch lastMinerRecoveryHeight abi.ChainEpoch path string + blocklist []address.Address } func NewRepo(path string) (*Repo, error) { @@ -1222,6 +1271,10 @@ func (r *Repo) Open() error { return err } + if err := r.loadBlockList(); err != nil { + return err + } + return nil } @@ -1247,6 +1300,51 @@ func loadChainEpoch(fn string) (abi.ChainEpoch, error) { return abi.ChainEpoch(height), nil } +func (r *Repo) loadBlockList() error { + var err error + fpath := filepath.Join(r.path, "blocklist") + f, err := os.OpenFile(fpath, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return err + } + defer func() { + err = f.Close() + }() + + blocklist := []address.Address{} + input := bufio.NewReader(f) + for { + stra, errR := input.ReadString('\n') + stra = strings.TrimSpace(stra) + + if len(stra) == 0 { + if errR == io.EOF { + break + } + continue + } + + addr, err := address.NewFromString(stra) + if err != nil { + return err + } + + blocklist = append(blocklist, addr) + + if errR != nil && errR != io.EOF { + return err + } + + if errR == io.EOF { + break + } + } + + r.blocklist = blocklist + + return nil +} + func (r *Repo) loadHeight() error { var err error r.lastHeight, err = loadChainEpoch(filepath.Join(r.path, "height")) @@ -1259,6 +1357,10 @@ func (r *Repo) loadMinerRecoveryHeight() error { return err } +func (r *Repo) Blocklist() []address.Address { + return r.blocklist +} + func (r *Repo) Height() abi.ChainEpoch { return r.lastHeight } diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index 9073c860e..36c9d5eff 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -18,6 +18,8 @@ import ( logging "github.com/ipfs/go-log/v2" manet "github.com/multiformats/go-multiaddr/net" "github.com/urfave/cli/v2" + "go.opencensus.io/stats/view" + "go.opencensus.io/tag" "golang.org/x/xerrors" "github.com/filecoin-project/go-jsonrpc" @@ -35,6 +37,7 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/stores" "github.com/filecoin-project/lotus/lib/lotuslog" "github.com/filecoin-project/lotus/lib/rpcenc" + "github.com/filecoin-project/lotus/metrics" "github.com/filecoin-project/lotus/node/modules" "github.com/filecoin-project/lotus/node/repo" ) @@ -194,6 +197,13 @@ var runCmd = &cli.Command{ ctx, cancel := context.WithCancel(ctx) defer cancel() + // Register all metric views + if err := view.Register( + metrics.DefaultViews..., + ); err != nil { + log.Fatalf("Cannot register the view: %v", err) + } + v, err := nodeApi.Version(ctx) if err != nil { return err @@ -376,7 +386,7 @@ var runCmd = &cli.Command{ readerHandler, readerServerOpt := rpcenc.ReaderParamDecoder() rpcServer := jsonrpc.NewServer(readerServerOpt) - rpcServer.Register("Filecoin", apistruct.PermissionedWorkerAPI(workerApi)) + rpcServer.Register("Filecoin", apistruct.PermissionedWorkerAPI(metrics.MetricedWorkerAPI(workerApi))) mux.Handle("/rpc/v0", rpcServer) mux.Handle("/rpc/streams/v0/push/{uuid}", readerHandler) @@ -391,6 +401,7 @@ var runCmd = &cli.Command{ srv := &http.Server{ Handler: ah, BaseContext: func(listener net.Listener) context.Context { + ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "lotus-worker")) return ctx }, } diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index 0ab7c9c65..ab8e5a52a 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -22,7 +22,8 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/lotus/extern/sector-storage/zerocomm" - "github.com/filecoin-project/specs-actors/actors/builtin/market" + + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" @@ -253,7 +254,7 @@ func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.Miner, func createDeals(m *genesis.Miner, k *wallet.Key, maddr address.Address, ssize abi.SectorSize) error { for i, sector := range m.Sectors { - proposal := &market.DealProposal{ + proposal := &market2.DealProposal{ PieceCID: sector.CommD, PieceSize: abi.PaddedPieceSize(ssize), Client: k.Address, diff --git a/cmd/lotus-shed/frozen-miners.go b/cmd/lotus-shed/frozen-miners.go new file mode 100644 index 000000000..6b843f0d6 --- /dev/null +++ b/cmd/lotus-shed/frozen-miners.go @@ -0,0 +1,85 @@ +package main + +import ( + "fmt" + + "github.com/filecoin-project/go-state-types/abi" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" +) + +var frozenMinersCmd = &cli.Command{ + Name: "frozen-miners", + Description: "information about miner actors with late or frozen deadline crons", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "tipset", + Usage: "specify tipset state to search on (pass comma separated array of cids)", + }, + &cli.BoolFlag{ + Name: "future", + Usage: "print info of miners with last deadline cron in the future (normal for v0 and early v2 actors)", + }, + }, + Action: func(c *cli.Context) error { + api, acloser, err := lcli.GetFullNodeAPI(c) + if err != nil { + return err + } + defer acloser() + ctx := lcli.ReqContext(c) + + ts, err := lcli.LoadTipSet(ctx, c, api) + if err != nil { + return err + } + if ts == nil { + ts, err = api.ChainHead(ctx) + if err != nil { + return err + } + } + + queryEpoch := ts.Height() + + mAddrs, err := api.StateListMiners(ctx, ts.Key()) + if err != nil { + return err + } + + for _, mAddr := range mAddrs { + st, err := api.StateReadState(ctx, mAddr, ts.Key()) + if err != nil { + return err + } + minerState, ok := st.State.(map[string]interface{}) + if !ok { + return xerrors.Errorf("internal error: failed to cast miner state to expected map type") + } + + ppsIface := minerState["ProvingPeriodStart"] + pps := int64(ppsIface.(float64)) + dlIdxIface := minerState["CurrentDeadline"] + dlIdx := uint64(dlIdxIface.(float64)) + latestDeadline := abi.ChainEpoch(pps) + abi.ChainEpoch(int64(dlIdx))*miner.WPoStChallengeWindow + nextDeadline := latestDeadline + miner.WPoStChallengeWindow + + // Need +1 because last epoch of the deadline queryEpoch = x + 59 cron gets run and + // state is left with latestDeadline = x + 60 + if c.Bool("future") && latestDeadline > queryEpoch+1 { + fmt.Printf("%s -- last deadline start in future epoch %d > query epoch %d + 1\n", mAddr, latestDeadline, queryEpoch) + } + + // Equality is an error because last epoch of the deadline queryEpoch = x + 59. Cron + // should get run and bump latestDeadline = x + 60 so nextDeadline = x + 120 + if queryEpoch >= nextDeadline { + fmt.Printf("%s -- next deadline start in non-future epoch %d <= query epoch %d\n", mAddr, nextDeadline, queryEpoch) + } + + } + + return nil + }, +} diff --git a/cmd/lotus-shed/ledger.go b/cmd/lotus-shed/ledger.go index f64916534..ecb13ec64 100644 --- a/cmd/lotus-shed/ledger.go +++ b/cmd/lotus-shed/ledger.go @@ -7,9 +7,9 @@ import ( "strings" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" "github.com/urfave/cli/v2" ledgerfil "github.com/whyrusleeping/ledger-filecoin-go" - "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" @@ -76,15 +76,22 @@ var ledgerListAddressesCmd = &cli.Command{ } if cctx.Bool("print-balances") && api != nil { // api check makes linter happier - b, err := api.WalletBalance(ctx, addr) + a, err := api.StateGetActor(ctx, addr, types.EmptyTSK) if err != nil { - return xerrors.Errorf("getting balance: %w", err) - } - if !b.IsZero() { - end = i + 21 // BIP32 spec, stop after 20 empty addresses + if strings.Contains(err.Error(), "actor not found") { + a = nil + } else { + return err + } } - fmt.Printf("%s %s %s\n", addr, printHDPath(p), types.FIL(b)) + balance := big.Zero() + if a != nil { + balance = a.Balance + end = i + 20 + 1 + } + + fmt.Printf("%s %s %s\n", addr, printHDPath(p), types.FIL(balance)) } else { fmt.Printf("%s %s\n", addr, printHDPath(p)) } diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index 29a105355..8201ec111 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "os" logging "github.com/ipfs/go-log/v2" @@ -18,6 +19,7 @@ func main() { base32Cmd, base16Cmd, bitFieldCmd, + frozenMinersCmd, keyinfoCmd, jwtCmd, noncefix, @@ -42,6 +44,8 @@ func main() { stateTreePruneCmd, datastoreCmd, ledgerCmd, + sectorsCmd, + msgCmd, } app := &cli.App{ @@ -56,6 +60,13 @@ func main() { Hidden: true, Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME }, + &cli.StringFlag{ + Name: "miner-repo", + Aliases: []string{"storagerepo"}, + EnvVars: []string{"LOTUS_MINER_PATH", "LOTUS_STORAGE_PATH"}, + Value: "~/.lotusminer", // TODO: Consider XDG_DATA_HOME + Usage: fmt.Sprintf("Specify miner repo path. flag storagerepo and env LOTUS_STORAGE_PATH are DEPRECATION, will REMOVE SOON"), + }, &cli.StringFlag{ Name: "log-level", Value: "info", diff --git a/cmd/lotus-shed/mempool-stats.go b/cmd/lotus-shed/mempool-stats.go index d70cd4b71..bc4a801f0 100644 --- a/cmd/lotus-shed/mempool-stats.go +++ b/cmd/lotus-shed/mempool-stats.go @@ -14,11 +14,10 @@ import ( "go.opencensus.io/stats/view" "go.opencensus.io/tag" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/go-address" lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) @@ -145,7 +144,7 @@ var mpoolStatsCmd = &cli.Command{ seen: time.Now(), } - if u.Message.Message.Method == builtin0.MethodsMiner.SubmitWindowedPoSt { + if u.Message.Message.Method == miner.Methods.SubmitWindowedPoSt { miner, err := isMiner(u.Message.Message.To) if err != nil { diff --git a/cmd/lotus-shed/msg.go b/cmd/lotus-shed/msg.go new file mode 100644 index 000000000..63cfc86b9 --- /dev/null +++ b/cmd/lotus-shed/msg.go @@ -0,0 +1,280 @@ +package main + +import ( + "bytes" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + + "github.com/fatih/color" + + "github.com/ipfs/go-cid" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" + + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/lotus/chain/types" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" +) + +var msgCmd = &cli.Command{ + Name: "msg", + Usage: "Translate message between various formats", + ArgsUsage: "Message in any form", + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() != 1 { + return xerrors.Errorf("expected 1 argument") + } + + msg, err := messageFromString(cctx, cctx.Args().First()) + if err != nil { + return err + } + + switch msg := msg.(type) { + case *types.SignedMessage: + return printSignedMessage(cctx, msg) + case *types.Message: + return printMessage(cctx, msg) + default: + return xerrors.Errorf("this error message can't be printed") + } + }, +} + +func printSignedMessage(cctx *cli.Context, smsg *types.SignedMessage) error { + color.Green("Signed:") + color.Blue("CID: %s\n", smsg.Cid()) + + b, err := smsg.Serialize() + if err != nil { + return err + } + color.Magenta("HEX: %x\n", b) + color.Blue("B64: %s\n", base64.StdEncoding.EncodeToString(b)) + jm, err := json.MarshalIndent(smsg, "", " ") + if err != nil { + return xerrors.Errorf("marshaling as json: %w", err) + } + + color.Magenta("JSON: %s\n", string(jm)) + fmt.Println() + fmt.Println("---") + color.Green("Signed Message Details:") + fmt.Printf("Signature(hex): %x\n", smsg.Signature.Data) + fmt.Printf("Signature(b64): %s\n", base64.StdEncoding.EncodeToString(smsg.Signature.Data)) + + sigtype, err := smsg.Signature.Type.Name() + if err != nil { + sigtype = err.Error() + } + fmt.Printf("Signature type: %d (%s)\n", smsg.Signature.Type, sigtype) + + fmt.Println("-------") + return printMessage(cctx, &smsg.Message) +} + +func printMessage(cctx *cli.Context, msg *types.Message) error { + if msg.Version != 0x6d736967 { + color.Green("Unsigned:") + color.Yellow("CID: %s\n", msg.Cid()) + + b, err := msg.Serialize() + if err != nil { + return err + } + color.Cyan("HEX: %x\n", b) + color.Yellow("B64: %s\n", base64.StdEncoding.EncodeToString(b)) + + jm, err := json.MarshalIndent(msg, "", " ") + if err != nil { + return xerrors.Errorf("marshaling as json: %w", err) + } + + color.Cyan("JSON: %s\n", string(jm)) + fmt.Println() + } else { + color.Green("Msig Propose:") + pp := &multisig.ProposeParams{ + To: msg.To, + Value: msg.Value, + Method: msg.Method, + Params: msg.Params, + } + var b bytes.Buffer + if err := pp.MarshalCBOR(&b); err != nil { + return err + } + + color.Cyan("HEX: %x\n", b.Bytes()) + color.Yellow("B64: %s\n", base64.StdEncoding.EncodeToString(b.Bytes())) + jm, err := json.MarshalIndent(pp, "", " ") + if err != nil { + return xerrors.Errorf("marshaling as json: %w", err) + } + + color.Cyan("JSON: %s\n", string(jm)) + fmt.Println() + } + + fmt.Println("---") + color.Green("Message Details:") + fmt.Println("Value:", types.FIL(msg.Value)) + fmt.Println("Max Fees:", types.FIL(msg.RequiredFunds())) + fmt.Println("Max Total Cost:", types.FIL(big.Add(msg.RequiredFunds(), msg.Value))) + + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + + defer closer() + ctx := lcli.ReqContext(cctx) + + toact, err := api.StateGetActor(ctx, msg.To, types.EmptyTSK) + if err != nil { + return nil + } + + fmt.Println("Method:", stmgr.MethodsMap[toact.Code][msg.Method].Name) + p, err := lcli.JsonParams(toact.Code, msg.Method, msg.Params) + if err != nil { + return err + } + + fmt.Println("Params:", p) + + return nil +} + +func messageFromString(cctx *cli.Context, smsg string) (types.ChainMsg, error) { + // a CID is least likely to just decode + if c, err := cid.Parse(smsg); err == nil { + return messageFromCID(cctx, c) + } + + // try baseX serializations next + { + // hex first, some hay strings may be decodable as b64 + if b, err := hex.DecodeString(smsg); err == nil { + return messageFromBytes(cctx, b) + } + + // b64 next + if b, err := base64.StdEncoding.DecodeString(smsg); err == nil { + return messageFromBytes(cctx, b) + } + + // b64u?? + if b, err := base64.URLEncoding.DecodeString(smsg); err == nil { + return messageFromBytes(cctx, b) + } + } + + // maybe it's json? + if _, err := messageFromJson(cctx, []byte(smsg)); err == nil { + return nil, err + } + + // declare defeat + return nil, xerrors.Errorf("couldn't decode the message") +} + +func messageFromJson(cctx *cli.Context, msgb []byte) (types.ChainMsg, error) { + // Unsigned + { + var msg types.Message + if err := json.Unmarshal(msgb, &msg); err == nil { + if msg.To != address.Undef { + return &msg, nil + } + } + } + + // Signed + { + var msg types.SignedMessage + if err := json.Unmarshal(msgb, &msg); err == nil { + if msg.Message.To != address.Undef { + return &msg, nil + } + } + } + + return nil, xerrors.New("probably not a json-serialized message") +} + +func messageFromBytes(cctx *cli.Context, msgb []byte) (types.ChainMsg, error) { + // Signed + { + var msg types.SignedMessage + if err := msg.UnmarshalCBOR(bytes.NewReader(msgb)); err == nil { + return &msg, nil + } + } + + // Unsigned + { + var msg types.Message + if err := msg.UnmarshalCBOR(bytes.NewReader(msgb)); err == nil { + return &msg, nil + } + } + + // Multisig propose? + { + var pp multisig.ProposeParams + if err := pp.UnmarshalCBOR(bytes.NewReader(msgb)); err == nil { + i, err := address.NewIDAddress(0) + if err != nil { + return nil, err + } + + return &types.Message{ + // Hack(-ish) + Version: 0x6d736967, + From: i, + + To: pp.To, + Value: pp.Value, + + Method: pp.Method, + Params: pp.Params, + + GasFeeCap: big.Zero(), + GasPremium: big.Zero(), + }, nil + } + } + + // Encoded json??? + { + if msg, err := messageFromJson(cctx, msgb); err == nil { + return msg, nil + } + } + + return nil, xerrors.New("probably not a cbor-serialized message") +} + +func messageFromCID(cctx *cli.Context, c cid.Cid) (types.ChainMsg, error) { + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return nil, err + } + + defer closer() + ctx := lcli.ReqContext(cctx) + + msgb, err := api.ChainReadObj(ctx, c) + if err != nil { + return nil, err + } + + return messageFromBytes(cctx, msgb) +} diff --git a/cmd/lotus-shed/proofs.go b/cmd/lotus-shed/proofs.go index 2379d8599..e75aeed14 100644 --- a/cmd/lotus-shed/proofs.go +++ b/cmd/lotus-shed/proofs.go @@ -4,7 +4,7 @@ import ( "encoding/hex" "fmt" - saproof "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/urfave/cli/v2" @@ -84,7 +84,7 @@ var verifySealProofCmd = &cli.Command{ snum := abi.SectorNumber(cctx.Uint64("sector-id")) - ok, err := ffi.VerifySeal(saproof.SealVerifyInfo{ + ok, err := ffi.VerifySeal(proof2.SealVerifyInfo{ SectorID: abi.SectorID{ Miner: abi.ActorID(mid), Number: snum, diff --git a/cmd/lotus-shed/sectors.go b/cmd/lotus-shed/sectors.go new file mode 100644 index 000000000..2e78469fa --- /dev/null +++ b/cmd/lotus-shed/sectors.go @@ -0,0 +1,133 @@ +package main + +import ( + "fmt" + "strconv" + + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/urfave/cli/v2" + + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" + lcli "github.com/filecoin-project/lotus/cli" +) + +var sectorsCmd = &cli.Command{ + Name: "sectors", + Usage: "Tools for interacting with sectors", + Flags: []cli.Flag{}, + Subcommands: []*cli.Command{ + terminateSectorCmd, + }, +} + +var terminateSectorCmd = &cli.Command{ + Name: "terminate", + Usage: "Forcefully terminate a sector (WARNING: This means losing power and pay a one-time termination penalty(including collateral) for the terminated sector)", + ArgsUsage: "[sectorNum1 sectorNum2 ...]", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "really-do-it", + Usage: "pass this flag if you know what you are doing", + }, + }, + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() < 1 { + return fmt.Errorf("at least one sector must be specified") + } + + if !cctx.Bool("really-do-it") { + return fmt.Errorf("this is a command for advanced users, only use it if you are sure of what you are doing") + } + + nodeApi, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + api, acloser, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer acloser() + + ctx := lcli.ReqContext(cctx) + + maddr, err := api.ActorAddress(ctx) + if err != nil { + return err + } + + mi, err := nodeApi.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } + + terminationDeclarationParams := []miner2.TerminationDeclaration{} + + for _, sn := range cctx.Args().Slice() { + sectorNum, err := strconv.ParseUint(sn, 10, 64) + if err != nil { + return fmt.Errorf("could not parse sector number: %w", err) + } + + sectorbit := bitfield.New() + sectorbit.Set(sectorNum) + + loca, err := nodeApi.StateSectorPartition(ctx, maddr, abi.SectorNumber(sectorNum), types.EmptyTSK) + if err != nil { + return fmt.Errorf("get state sector partition %s", err) + } + + para := miner2.TerminationDeclaration{ + Deadline: loca.Deadline, + Partition: loca.Partition, + Sectors: sectorbit, + } + + terminationDeclarationParams = append(terminationDeclarationParams, para) + } + + terminateSectorParams := &miner2.TerminateSectorsParams{ + Terminations: terminationDeclarationParams, + } + + sp, err := actors.SerializeParams(terminateSectorParams) + if err != nil { + return xerrors.Errorf("serializing params: %w", err) + } + + smsg, err := nodeApi.MpoolPushMessage(ctx, &types.Message{ + From: mi.Owner, + To: maddr, + Method: miner.Methods.TerminateSectors, + + Value: big.Zero(), + Params: sp, + }, nil) + if err != nil { + return xerrors.Errorf("mpool push message: %w", err) + } + + fmt.Println("sent termination message:", smsg.Cid()) + + wait, err := nodeApi.StateWaitMsg(ctx, smsg.Cid(), uint64(cctx.Int("confidence"))) + if err != nil { + return err + } + + if wait.Receipt.ExitCode != 0 { + return fmt.Errorf("terminate sectors message returned exit %d", wait.Receipt.ExitCode) + } + + return nil + }, +} diff --git a/cmd/lotus-shed/sync.go b/cmd/lotus-shed/sync.go index bfe7cc8b7..65d2b6d6f 100644 --- a/cmd/lotus-shed/sync.go +++ b/cmd/lotus-shed/sync.go @@ -2,6 +2,15 @@ package main import ( "fmt" + "strconv" + + "github.com/filecoin-project/go-state-types/big" + + "github.com/filecoin-project/lotus/chain/actors/builtin/power" + + "github.com/filecoin-project/go-address" + + "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" @@ -16,6 +25,7 @@ var syncCmd = &cli.Command{ Flags: []cli.Flag{}, Subcommands: []*cli.Command{ syncValidateCmd, + syncScrapePowerCmd, }, } @@ -62,3 +72,113 @@ var syncValidateCmd = &cli.Command{ return nil }, } + +var syncScrapePowerCmd = &cli.Command{ + Name: "scrape-power", + Usage: "given a height and a tipset, reports what percentage of mining power had a winning ticket between the tipset and height", + ArgsUsage: "[height tipsetkey]", + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() < 1 { + fmt.Println("usage: [blockCid1 blockCid2...]") + fmt.Println("Any CIDs passed after the height will be used as the tipset key") + fmt.Println("If no block CIDs are provided, chain head will be used") + return nil + } + + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + + defer closer() + ctx := lcli.ReqContext(cctx) + + if cctx.Args().Len() < 1 { + fmt.Println("usage: ...") + fmt.Println("At least one block cid must be provided") + return nil + } + + h, err := strconv.ParseInt(cctx.Args().Get(0), 10, 0) + if err != nil { + return err + } + + height := abi.ChainEpoch(h) + + var ts *types.TipSet + var startTsk types.TipSetKey + if cctx.NArg() > 1 { + var tscids []cid.Cid + args := cctx.Args().Slice() + + for _, s := range args[1:] { + c, err := cid.Decode(s) + if err != nil { + return fmt.Errorf("block cid was invalid: %s", err) + } + tscids = append(tscids, c) + } + + startTsk = types.NewTipSetKey(tscids...) + ts, err = api.ChainGetTipSet(ctx, startTsk) + if err != nil { + return err + } + } else { + ts, err = api.ChainHead(ctx) + if err != nil { + return err + } + + startTsk = ts.Key() + } + + if ts.Height() < height { + return fmt.Errorf("start tipset's height < stop height: %d < %d", ts.Height(), height) + } + + miners := make(map[address.Address]struct{}) + for ts.Height() >= height { + for _, blk := range ts.Blocks() { + _, found := miners[blk.Miner] + if !found { + // do the thing + miners[blk.Miner] = struct{}{} + } + } + + ts, err = api.ChainGetTipSet(ctx, ts.Parents()) + if err != nil { + return err + } + } + + totalWonPower := power.Claim{ + RawBytePower: big.Zero(), + QualityAdjPower: big.Zero(), + } + for miner := range miners { + mp, err := api.StateMinerPower(ctx, miner, startTsk) + if err != nil { + return err + } + + totalWonPower = power.AddClaims(totalWonPower, mp.MinerPower) + } + + totalPower, err := api.StateMinerPower(ctx, address.Undef, startTsk) + if err != nil { + return err + } + + qpercI := types.BigDiv(types.BigMul(totalWonPower.QualityAdjPower, types.NewInt(1000000)), totalPower.TotalPower.QualityAdjPower) + + fmt.Println("Number of winning miners: ", len(miners)) + fmt.Println("QAdjPower of winning miners: ", totalWonPower.QualityAdjPower) + fmt.Println("QAdjPower of all miners: ", totalPower.TotalPower.QualityAdjPower) + fmt.Println("Percentage of winning QAdjPower: ", float64(qpercI.Int64())/10000) + + return nil + }, +} diff --git a/cmd/lotus-shed/verifreg.go b/cmd/lotus-shed/verifreg.go index 860498302..df1f0d990 100644 --- a/cmd/lotus-shed/verifreg.go +++ b/cmd/lotus-shed/verifreg.go @@ -11,8 +11,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" + verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/build" @@ -63,7 +62,7 @@ var verifRegAddVerifierCmd = &cli.Command{ } // TODO: ActorUpgrade: Abstract - params, err := actors.SerializeParams(&verifreg0.AddVerifierParams{Address: verifier, Allowance: allowance}) + params, err := actors.SerializeParams(&verifreg2.AddVerifierParams{Address: verifier, Allowance: allowance}) if err != nil { return err } @@ -80,7 +79,7 @@ var verifRegAddVerifierCmd = &cli.Command{ return err } - smsg, err := api.MsigPropose(ctx, vrk, verifreg.Address, big.Zero(), sender, uint64(builtin0.MethodsVerifiedRegistry.AddVerifier), params) + smsg, err := api.MsigPropose(ctx, vrk, verifreg.Address, big.Zero(), sender, uint64(verifreg.Methods.AddVerifier), params) if err != nil { return err } @@ -136,7 +135,7 @@ var verifRegVerifyClientCmd = &cli.Command{ return err } - params, err := actors.SerializeParams(&verifreg0.AddVerifiedClientParams{Address: target, Allowance: allowance}) + params, err := actors.SerializeParams(&verifreg2.AddVerifiedClientParams{Address: target, Allowance: allowance}) if err != nil { return err } @@ -151,7 +150,7 @@ var verifRegVerifyClientCmd = &cli.Command{ msg := &types.Message{ To: verifreg.Address, From: fromk, - Method: builtin0.MethodsVerifiedRegistry.AddVerifiedClient, + Method: verifreg.Methods.AddVerifiedClient, Params: params, } diff --git a/cmd/lotus-storage-miner/actor.go b/cmd/lotus-storage-miner/actor.go index 35e2a268e..611ea8f19 100644 --- a/cmd/lotus-storage-miner/actor.go +++ b/cmd/lotus-storage-miner/actor.go @@ -5,14 +5,8 @@ import ( "os" "strings" - "github.com/filecoin-project/lotus/api/apibstore" - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors/builtin/miner" cbor "github.com/ipfs/go-ipld-cbor" - "github.com/filecoin-project/lotus/build" - builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" - "github.com/fatih/color" "github.com/libp2p/go-libp2p-core/peer" ma "github.com/multiformats/go-multiaddr" @@ -23,10 +17,13 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + "github.com/filecoin-project/lotus/api/apibstore" + "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/miner" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/tablewriter" @@ -98,7 +95,7 @@ var actorSetAddrsCmd = &cli.Command{ return err } - params, err := actors.SerializeParams(&miner0.ChangeMultiaddrsParams{NewMultiaddrs: addrs}) + params, err := actors.SerializeParams(&miner2.ChangeMultiaddrsParams{NewMultiaddrs: addrs}) if err != nil { return err } @@ -110,7 +107,7 @@ var actorSetAddrsCmd = &cli.Command{ From: minfo.Worker, Value: types.NewInt(0), GasLimit: gasLimit, - Method: builtin.MethodsMiner.ChangeMultiaddrs, + Method: miner.Methods.ChangeMultiaddrs, Params: params, }, nil) if err != nil { @@ -163,7 +160,7 @@ var actorSetPeeridCmd = &cli.Command{ return err } - params, err := actors.SerializeParams(&miner0.ChangePeerIDParams{NewID: abi.PeerID(pid)}) + params, err := actors.SerializeParams(&miner2.ChangePeerIDParams{NewID: abi.PeerID(pid)}) if err != nil { return err } @@ -175,7 +172,7 @@ var actorSetPeeridCmd = &cli.Command{ From: minfo.Worker, Value: types.NewInt(0), GasLimit: gasLimit, - Method: builtin.MethodsMiner.ChangePeerID, + Method: miner.Methods.ChangePeerID, Params: params, }, nil) if err != nil { @@ -236,7 +233,7 @@ var actorWithdrawCmd = &cli.Command{ } } - params, err := actors.SerializeParams(&miner0.WithdrawBalanceParams{ + params, err := actors.SerializeParams(&miner2.WithdrawBalanceParams{ AmountRequested: amount, // Default to attempting to withdraw all the extra funds in the miner actor }) if err != nil { @@ -247,7 +244,7 @@ var actorWithdrawCmd = &cli.Command{ To: maddr, From: mi.Owner, Value: types.NewInt(0), - Method: builtin.MethodsMiner.WithdrawBalance, + Method: miner.Methods.WithdrawBalance, Params: params, }, nil) if err != nil { @@ -346,7 +343,7 @@ var actorRepayDebtCmd = &cli.Command{ To: maddr, From: fromId, Value: amount, - Method: builtin2.MethodsMiner.RepayDebt, + Method: miner.Methods.RepayDebt, Params: nil, }, nil) if err != nil { @@ -560,7 +557,7 @@ var actorControlSet = &cli.Command{ return nil } - cwp := &miner0.ChangeWorkerAddressParams{ + cwp := &miner2.ChangeWorkerAddressParams{ NewWorker: mi.Worker, NewControlAddrs: toSet, } @@ -573,7 +570,7 @@ var actorControlSet = &cli.Command{ smsg, err := api.MpoolPushMessage(ctx, &types.Message{ From: mi.Owner, To: maddr, - Method: builtin.MethodsMiner.ChangeWorkerAddress, + Method: miner.Methods.ChangeWorkerAddress, Value: big.Zero(), Params: sp, @@ -651,7 +648,7 @@ var actorSetOwnerCmd = &cli.Command{ smsg, err := api.MpoolPushMessage(ctx, &types.Message{ From: mi.Owner, To: maddr, - Method: builtin2.MethodsMiner.ChangeOwnerAddress, + Method: miner.Methods.ChangeOwnerAddress, Value: big.Zero(), Params: sp, }, nil) @@ -676,7 +673,7 @@ var actorSetOwnerCmd = &cli.Command{ smsg, err = api.MpoolPushMessage(ctx, &types.Message{ From: newAddr, To: maddr, - Method: builtin2.MethodsMiner.ChangeOwnerAddress, + Method: miner.Methods.ChangeOwnerAddress, Value: big.Zero(), Params: sp, }, nil) diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 656dd6463..a7fcd722a 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -32,21 +32,23 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/lotus/extern/sector-storage/stores" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/builtin/power" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/gen/slashfilter" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" sealing "github.com/filecoin-project/lotus/extern/storage-sealing" "github.com/filecoin-project/lotus/genesis" "github.com/filecoin-project/lotus/journal" - "github.com/filecoin-project/lotus/miner" + storageminer "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node/modules" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/repo" @@ -83,7 +85,7 @@ var initCmd = &cli.Command{ &cli.StringFlag{ Name: "sector-size", Usage: "specify sector size to use", - Value: units.BytesSize(float64(build.DefaultSectorSize())), + Value: units.BytesSize(float64(policy.GetDefaultSectorSize())), }, &cli.StringSliceFlag{ Name: "pre-sealed-sectors", @@ -376,7 +378,7 @@ func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string, return mds.Put(datastore.NewKey(modules.StorageCounterDSPrefix), buf[:size]) } -func findMarketDealID(ctx context.Context, api lapi.FullNode, deal market0.DealProposal) (abi.DealID, error) { +func findMarketDealID(ctx context.Context, api lapi.FullNode, deal market2.DealProposal) (abi.DealID, error) { // TODO: find a better way // (this is only used by genesis miners) @@ -472,7 +474,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode, return fmt.Errorf("failed to open filesystem journal: %w", err) } - m := miner.NewMiner(api, epp, a, slashfilter.New(mds), j) + m := storageminer.NewMiner(api, epp, a, slashfilter.New(mds), j) { if err := m.Start(ctx); err != nil { return xerrors.Errorf("failed to start up genesis miner: %w", err) @@ -572,7 +574,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address. return xerrors.Errorf("getWorkerAddr returned bad address: %w", err) } - enc, err := actors.SerializeParams(&miner0.ChangePeerIDParams{NewID: abi.PeerID(peerid)}) + enc, err := actors.SerializeParams(&miner2.ChangePeerIDParams{NewID: abi.PeerID(peerid)}) if err != nil { return err } @@ -580,7 +582,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address. msg := &types.Message{ To: addr, From: mi.Worker, - Method: builtin0.MethodsMiner.ChangePeerID, + Method: miner.Methods.ChangePeerID, Params: enc, Value: types.NewInt(0), GasPremium: gasPrice, @@ -605,8 +607,6 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address. } func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, gasPrice types.BigInt, cctx *cli.Context) (address.Address, error) { - log.Info("Creating StorageMarket.CreateStorageMiner message") - var err error var owner address.Address if cctx.String("owner") != "" { @@ -629,9 +629,32 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, } else if cctx.Bool("create-worker-key") { // TODO: Do we need to force this if owner is Secpk? worker, err = api.WalletNew(ctx, types.KTBLS) } - // TODO: Transfer some initial funds to worker if err != nil { - return address.Undef, err + return address.Address{}, err + } + + // make sure the worker account exists on chain + _, err = api.StateLookupID(ctx, worker, types.EmptyTSK) + if err != nil { + signed, err := api.MpoolPushMessage(ctx, &types.Message{ + From: owner, + To: worker, + Value: types.NewInt(0), + }, nil) + if err != nil { + return address.Undef, xerrors.Errorf("push worker init: %w", err) + } + + log.Infof("Initializing worker account %s, message: %s", worker, signed.Cid()) + log.Infof("Waiting for confirmation") + + mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence) + if err != nil { + return address.Undef, xerrors.Errorf("waiting for worker init: %w", err) + } + if mw.Receipt.ExitCode != 0 { + return address.Undef, xerrors.Errorf("initializing worker account failed: exit code %d", mw.Receipt.ExitCode) + } } spt, err := ffiwrapper.SealProofTypeFromSectorSize(abi.SectorSize(ssize)) @@ -639,7 +662,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, return address.Undef, err } - params, err := actors.SerializeParams(&power0.CreateMinerParams{ + params, err := actors.SerializeParams(&power2.CreateMinerParams{ Owner: owner, Worker: worker, SealProofType: spt, @@ -659,11 +682,11 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, } createStorageMinerMsg := &types.Message{ - To: builtin0.StoragePowerActorAddr, + To: power.Address, From: sender, Value: big.Zero(), - Method: builtin0.MethodsPower.CreateMiner, + Method: power.Methods.CreateMiner, Params: params, GasLimit: 0, @@ -672,22 +695,22 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, signed, err := api.MpoolPushMessage(ctx, createStorageMinerMsg, nil) if err != nil { - return address.Undef, err + return address.Undef, xerrors.Errorf("pushing createMiner message: %w", err) } - log.Infof("Pushed StorageMarket.CreateStorageMiner, %s to Mpool", signed.Cid()) + log.Infof("Pushed CreateMiner message: %s", signed.Cid()) log.Infof("Waiting for confirmation") mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence) if err != nil { - return address.Undef, err + return address.Undef, xerrors.Errorf("waiting for createMiner message: %w", err) } if mw.Receipt.ExitCode != 0 { return address.Undef, xerrors.Errorf("create miner failed: exit code %d", mw.Receipt.ExitCode) } - var retval power0.CreateMinerReturn + var retval power2.CreateMinerReturn if err := retval.UnmarshalCBOR(bytes.NewReader(mw.Receipt.Return)); err != nil { return address.Undef, err } diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index c043bd903..0c2fba8b3 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -2,6 +2,7 @@ package main import ( "context" + "net" "net/http" _ "net/http/pprof" "os" @@ -12,6 +13,8 @@ import ( "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" "github.com/urfave/cli/v2" + "go.opencensus.io/stats/view" + "go.opencensus.io/tag" "golang.org/x/xerrors" "github.com/filecoin-project/go-jsonrpc" @@ -22,6 +25,7 @@ import ( "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/ulimit" + "github.com/filecoin-project/lotus/metrics" "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/impl" "github.com/filecoin-project/lotus/node/modules/dtypes" @@ -66,6 +70,13 @@ var runCmd = &cli.Command{ defer ncloser() ctx := lcli.DaemonContext(cctx) + // Register all metric views + if err := view.Register( + metrics.DefaultViews..., + ); err != nil { + log.Fatalf("Cannot register the view: %v", err) + } + v, err := nodeApi.Version(ctx) if err != nil { return err @@ -147,7 +158,7 @@ var runCmd = &cli.Command{ mux := mux.NewRouter() rpcServer := jsonrpc.NewServer() - rpcServer.Register("Filecoin", apistruct.PermissionedStorMinerAPI(minerapi)) + rpcServer.Register("Filecoin", apistruct.PermissionedStorMinerAPI(metrics.MetricedStorMinerAPI(minerapi))) mux.Handle("/rpc/v0", rpcServer) mux.PathPrefix("/remote").HandlerFunc(minerapi.(*impl.StorageMinerAPI).ServeRemote) @@ -158,7 +169,13 @@ var runCmd = &cli.Command{ Next: mux.ServeHTTP, } - srv := &http.Server{Handler: ah} + srv := &http.Server{ + Handler: ah, + BaseContext: func(listener net.Listener) context.Context { + ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "lotus-miner")) + return ctx + }, + } sigChan := make(chan os.Signal, 2) go func() { diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index b50f4a86d..0c3ef58d6 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -15,10 +15,9 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/tablewriter" @@ -463,7 +462,7 @@ var sectorsCapacityCollateralCmd = &cli.Command{ Expiration: abi.ChainEpoch(cctx.Uint64("expiration")), } if pci.Expiration == 0 { - pci.Expiration = miner0.MaxSectorExpirationExtension + pci.Expiration = policy.GetMaxSectorExpirationExtension() } pc, err := nApi.StateMinerInitialPledgeCollateral(ctx, maddr, pci, types.EmptyTSK) if err != nil { diff --git a/cmd/lotus-wallet/main.go b/cmd/lotus-wallet/main.go index 3285b13e7..25b89eb9d 100644 --- a/cmd/lotus-wallet/main.go +++ b/cmd/lotus-wallet/main.go @@ -9,6 +9,8 @@ import ( "github.com/gorilla/mux" logging "github.com/ipfs/go-log/v2" "github.com/urfave/cli/v2" + "go.opencensus.io/stats/view" + "go.opencensus.io/tag" "github.com/filecoin-project/go-jsonrpc" @@ -18,6 +20,7 @@ import ( ledgerwallet "github.com/filecoin-project/lotus/chain/wallet/ledger" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/lotuslog" + "github.com/filecoin-project/lotus/metrics" "github.com/filecoin-project/lotus/node/repo" ) @@ -75,6 +78,13 @@ var runCmd = &cli.Command{ ctx, cancel := context.WithCancel(ctx) defer cancel() + // Register all metric views + if err := view.Register( + metrics.DefaultViews..., + ); err != nil { + log.Fatalf("Cannot register the view: %v", err) + } + repoPath := cctx.String(FlagWalletRepo) r, err := repo.NewFS(repoPath) if err != nil { @@ -125,7 +135,7 @@ var runCmd = &cli.Command{ log.Info("Setting up API endpoint at " + address) rpcServer := jsonrpc.NewServer() - rpcServer.Register("Filecoin", &LoggedWallet{under: w}) + rpcServer.Register("Filecoin", &LoggedWallet{under: metrics.MetricedWalletAPI(w)}) mux.Handle("/rpc/v0", rpcServer) mux.PathPrefix("/").Handler(http.DefaultServeMux) // pprof @@ -138,6 +148,7 @@ var runCmd = &cli.Command{ srv := &http.Server{ Handler: mux, BaseContext: func(listener net.Listener) context.Context { + ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "lotus-wallet")) return ctx }, } diff --git a/cmd/lotus/rpc.go b/cmd/lotus/rpc.go index 9718deb3a..4f68ac85a 100644 --- a/cmd/lotus/rpc.go +++ b/cmd/lotus/rpc.go @@ -3,6 +3,7 @@ package main import ( "context" "encoding/json" + "net" "net/http" _ "net/http/pprof" "os" @@ -13,6 +14,7 @@ import ( logging "github.com/ipfs/go-log/v2" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" + "go.opencensus.io/tag" "golang.org/x/xerrors" "contrib.go.opencensus.io/exporter/prometheus" @@ -22,6 +24,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/metrics" "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/impl" ) @@ -30,7 +33,7 @@ var log = logging.Logger("main") func serveRPC(a api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, shutdownCh <-chan struct{}) error { rpcServer := jsonrpc.NewServer() - rpcServer.Register("Filecoin", apistruct.PermissionedFullAPI(a)) + rpcServer.Register("Filecoin", apistruct.PermissionedFullAPI(metrics.MetricedFullAPI(a))) ah := &auth.Handler{ Verify: a.AuthVerify, @@ -60,7 +63,13 @@ func serveRPC(a api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, shut return xerrors.Errorf("could not listen: %w", err) } - srv := &http.Server{Handler: http.DefaultServeMux} + srv := &http.Server{ + Handler: http.DefaultServeMux, + BaseContext: func(listener net.Listener) context.Context { + ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "lotus-daemon")) + return ctx + }, + } sigCh := make(chan os.Signal, 2) shutdownDone := make(chan struct{}) diff --git a/cmd/tvx/codenames.go b/cmd/tvx/codenames.go index 851e9d841..b9f590914 100644 --- a/cmd/tvx/codenames.go +++ b/cmd/tvx/codenames.go @@ -23,6 +23,7 @@ var ProtocolCodenames = []struct { {build.UpgradeActorsV2Height + 1, "actorsv2"}, {build.UpgradeTapeHeight + 1, "tape"}, {build.UpgradeLiftoffHeight + 1, "liftoff"}, + {build.UpgradeKumquatHeight + 1, "postliftoff"}, } // GetProtocolCodename gets the protocol codename associated with a height. diff --git a/cmd/tvx/extract.go b/cmd/tvx/extract.go index 4a8dd162c..3dfec37d8 100644 --- a/cmd/tvx/extract.go +++ b/cmd/tvx/extract.go @@ -14,15 +14,13 @@ import ( "github.com/fatih/color" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin" 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/types" "github.com/filecoin-project/lotus/chain/vm" - lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/conformance" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/test-vectors/schema" "github.com/ipfs/go-cid" @@ -35,13 +33,14 @@ const ( ) type extractOpts struct { - id string - block string - class string - cid string - file string - retain string - precursor string + id string + block string + class string + cid string + file string + retain string + precursor string + ignoreSanityChecks bool } var extractFlags extractOpts @@ -50,6 +49,8 @@ var extractCmd = &cli.Command{ Name: "extract", Description: "generate a test vector by extracting it from a live chain", Action: runExtract, + Before: initialize, + After: destroy, Flags: []cli.Flag{ &repoFlag, &cli.StringFlag{ @@ -89,53 +90,42 @@ var extractCmd = &cli.Command{ }, &cli.StringFlag{ Name: "precursor-select", - Usage: "precursors to apply; values: 'all', 'sender'; 'all' selects all preceding" + - "messages in the canonicalised tipset, 'sender' selects only preceding messages from the same" + - "sender. Usually, 'sender' is a good tradeoff and gives you sufficient accuracy. If the receipt sanity" + - "check fails due to gas reasons, switch to 'all', as previous messages in the tipset may have" + + Usage: "precursors to apply; values: 'all', 'sender'; 'all' selects all preceding " + + "messages in the canonicalised tipset, 'sender' selects only preceding messages from the same " + + "sender. Usually, 'sender' is a good tradeoff and gives you sufficient accuracy. If the receipt sanity " + + "check fails due to gas reasons, switch to 'all', as previous messages in the tipset may have " + "affected state in a disruptive way", Value: "sender", Destination: &extractFlags.precursor, }, + &cli.BoolFlag{ + Name: "ignore-sanity-checks", + Usage: "generate vector even if sanity checks fail", + Value: false, + Destination: &extractFlags.ignoreSanityChecks, + }, }, } -func runExtract(c *cli.Context) error { - // LOTUS_DISABLE_VM_BUF disables what's called "VM state tree buffering", - // which stashes write operations in a BufferedBlockstore - // (https://github.com/filecoin-project/lotus/blob/b7a4dbb07fd8332b4492313a617e3458f8003b2a/lib/bufbstore/buf_bstore.go#L21) - // such that they're not written until the VM is actually flushed. - // - // For some reason, the standard behaviour was not working for me (raulk), - // and disabling it (such that the state transformations are written immediately - // to the blockstore) worked. - _ = os.Setenv("LOTUS_DISABLE_VM_BUF", "iknowitsabadidea") - - ctx := context.Background() - - // Make the API client. - fapi, closer, err := lcli.GetFullNodeAPI(c) - if err != nil { - return err - } - defer closer() - - return doExtract(ctx, fapi, extractFlags) +func runExtract(_ *cli.Context) error { + return doExtract(extractFlags) } -func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { +func doExtract(opts extractOpts) error { + ctx := context.Background() + mcid, err := cid.Decode(opts.cid) if err != nil { return err } - msg, execTs, incTs, err := resolveFromChain(ctx, fapi, mcid, opts.block) + msg, execTs, incTs, err := resolveFromChain(ctx, FullAPI, mcid, opts.block) if err != nil { return fmt.Errorf("failed to resolve message and tipsets from chain: %w", err) } // get the circulating supply before the message was executed. - circSupplyDetail, err := fapi.StateVMCirculatingSupplyInternal(ctx, incTs.Key()) + circSupplyDetail, err := FullAPI.StateVMCirculatingSupplyInternal(ctx, incTs.Key()) if err != nil { return fmt.Errorf("failed while fetching circulating supply: %w", err) } @@ -148,7 +138,7 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { log.Printf("finding precursor messages using mode: %s", opts.precursor) // Fetch messages in canonical order from inclusion tipset. - msgs, err := fapi.ChainGetParentMessages(ctx, execTs.Blocks()[0].Cid()) + msgs, err := FullAPI.ChainGetParentMessages(ctx, execTs.Blocks()[0].Cid()) if err != nil { return fmt.Errorf("failed to fetch messages in canonical order from inclusion tipset: %w", err) } @@ -175,8 +165,8 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { var ( // create a read-through store that uses ChainGetObject to fetch unknown CIDs. - pst = NewProxyingStores(ctx, fapi) - g = NewSurgeon(ctx, fapi, pst) + pst = NewProxyingStores(ctx, FullAPI) + g = NewSurgeon(ctx, FullAPI, pst) ) driver := conformance.NewDriver(ctx, schema.Selector{}, conformance.DriverOpts{ @@ -201,7 +191,7 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { CircSupply: circSupplyDetail.FilCirculating, BaseFee: basefee, // recorded randomness will be discarded. - Rand: conformance.NewRecordingRand(new(conformance.LogReporter), fapi), + Rand: conformance.NewRecordingRand(new(conformance.LogReporter), FullAPI), }) if err != nil { return fmt.Errorf("failed to execute precursor message: %w", err) @@ -216,7 +206,7 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { retention = opts.retain // recordingRand will record randomness so we can embed it in the test vector. - recordingRand = conformance.NewRecordingRand(new(conformance.LogReporter), fapi) + recordingRand = conformance.NewRecordingRand(new(conformance.LogReporter), FullAPI) ) log.Printf("using state retention strategy: %s", retention) @@ -249,7 +239,7 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { case "accessed-actors": log.Printf("calculating accessed actors") // get actors accessed by message. - retain, err := g.GetAccessedActors(ctx, fapi, mcid) + retain, err := g.GetAccessedActors(ctx, FullAPI, mcid) if err != nil { return fmt.Errorf("failed to calculate accessed actors: %w", err) } @@ -287,7 +277,7 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { // TODO sometimes this returns a nil receipt and no error ¯\_(ツ)_/¯ // ex: https://filfox.info/en/message/bafy2bzacebpxw3yiaxzy2bako62akig46x3imji7fewszen6fryiz6nymu2b2 // This code is lenient and skips receipt comparison in case of a nil receipt. - rec, err := fapi.StateGetReceipt(ctx, mcid, execTs.Key()) + rec, err := FullAPI.StateGetReceipt(ctx, mcid, execTs.Key()) if err != nil { return fmt.Errorf("failed to find receipt on chain: %w", err) } @@ -301,13 +291,20 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { ReturnValue: rec.Return, GasUsed: rec.GasUsed, } + reporter := new(conformance.LogReporter) conformance.AssertMsgResult(reporter, receipt, applyret, "as locally executed") if reporter.Failed() { - log.Println(color.RedString("receipt sanity check failed; aborting")) - return fmt.Errorf("vector generation aborted") + if opts.ignoreSanityChecks { + log.Println(color.YellowString("receipt sanity check failed; proceeding anyway")) + } else { + log.Println(color.RedString("receipt sanity check failed; aborting")) + return fmt.Errorf("vector generation aborted") + } + } else { + log.Println(color.GreenString("receipt sanity check succeeded")) } - log.Println(color.GreenString("receipt sanity check succeeded")) + } else { receipt = &schema.Receipt{ ExitCode: int64(applyret.ExitCode), @@ -337,17 +334,17 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { return err } - version, err := fapi.Version(ctx) + version, err := FullAPI.Version(ctx) if err != nil { return err } - ntwkName, err := fapi.StateNetworkName(ctx) + ntwkName, err := FullAPI.StateNetworkName(ctx) if err != nil { return err } - nv, err := fapi.StateNetworkVersion(ctx, execTs.Key()) + nv, err := FullAPI.StateNetworkVersion(ctx, execTs.Key()) if err != nil { return err } @@ -400,8 +397,12 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { }, } + return writeVector(vector, opts.file) +} + +func writeVector(vector schema.TestVector, file string) (err error) { output := io.WriteCloser(os.Stdout) - if file := opts.file; file != "" { + if file := file; file != "" { dir := filepath.Dir(file) if err := os.MkdirAll(dir, 0755); err != nil { return fmt.Errorf("unable to create directory %s: %w", dir, err) @@ -416,11 +417,7 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error { enc := json.NewEncoder(output) enc.SetIndent("", " ") - if err := enc.Encode(&vector); err != nil { - return err - } - - return nil + return enc.Encode(&vector) } // resolveFromChain queries the chain for the provided message, using the block CID to diff --git a/cmd/tvx/extract_many.go b/cmd/tvx/extract_many.go index fe0ce6a6c..048271456 100644 --- a/cmd/tvx/extract_many.go +++ b/cmd/tvx/extract_many.go @@ -1,7 +1,6 @@ package main import ( - "context" "encoding/csv" "fmt" "io" @@ -20,7 +19,6 @@ import ( "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/chain/stmgr" - lcli "github.com/filecoin-project/lotus/cli" ) var extractManyFlags struct { @@ -45,6 +43,8 @@ var extractManyCmd = &cli.Command{ after these compulsory seven. `, Action: runExtractMany, + Before: initialize, + After: destroy, Flags: []cli.Flag{ &repoFlag, &cli.StringFlag{ @@ -77,15 +77,6 @@ func runExtractMany(c *cli.Context) error { // to the blockstore) worked. _ = os.Setenv("LOTUS_DISABLE_VM_BUF", "iknowitsabadidea") - ctx := context.Background() - - // Make the API client. - fapi, closer, err := lcli.GetFullNodeAPI(c) - if err != nil { - return err - } - defer closer() - var ( in = extractManyFlags.in outdir = extractManyFlags.outdir @@ -198,8 +189,8 @@ func runExtractMany(c *cli.Context) error { precursor: PrecursorSelectSender, } - if err := doExtract(ctx, fapi, opts); err != nil { - log.Println(color.RedString("failed to extract vector for message %s: %s; queuing for 'canonical' precursor selection", mcid, err)) + if err := doExtract(opts); err != nil { + log.Println(color.RedString("failed to extract vector for message %s: %s; queuing for 'all' precursor selection", mcid, err)) retry = append(retry, opts) continue } @@ -215,7 +206,7 @@ func runExtractMany(c *cli.Context) error { log.Printf("retrying %s: %s", r.cid, r.id) r.precursor = PrecursorSelectAll - if err := doExtract(ctx, fapi, r); err != nil { + if err := doExtract(r); err != nil { merr = multierror.Append(merr, fmt.Errorf("failed to extract vector for message %s: %w", r.cid, err)) continue } diff --git a/cmd/tvx/main.go b/cmd/tvx/main.go index 6c887d163..8de851ed5 100644 --- a/cmd/tvx/main.go +++ b/cmd/tvx/main.go @@ -1,13 +1,26 @@ package main import ( + "fmt" "log" "os" "sort" + "github.com/filecoin-project/go-jsonrpc" "github.com/urfave/cli/v2" + + "github.com/filecoin-project/lotus/api" + lcli "github.com/filecoin-project/lotus/cli" ) +// FullAPI is a JSON-RPC client targeting a full node. It's initialized in a +// cli.BeforeFunc. +var FullAPI api.FullNode + +// Closer is the closer for the JSON-RPC client, which must be called on +// cli.AfterFunc. +var Closer jsonrpc.ClientCloser + // DefaultLotusRepoPath is where the fallback path where to look for a Lotus // client repo. It is expanded with mitchellh/go-homedir, so it'll work with all // OSes despite the Unix twiddle notation. @@ -23,7 +36,7 @@ var repoFlag = cli.StringFlag{ func main() { app := &cli.App{ Name: "tvx", - Description: `tvx is a tool for extracting and executing test vectors. It has three subcommands. + Description: `tvx is a tool for extracting and executing test vectors. It has four subcommands. tvx extract extracts a test vector from a live network. It requires access to a Filecoin client that exposes the standard JSON-RPC API endpoint. Only @@ -35,6 +48,10 @@ func main() { tvx extract-many performs a batch extraction of many messages, supplied in a CSV file. Refer to the help of that subcommand for more info. + tvx simulate takes a raw message and simulates it on top of the supplied + epoch, reporting the result on stderr and writing a test vector on stdout + or into the specified file. + SETTING THE JSON-RPC API ENDPOINT You can set the JSON-RPC API endpoint through one of the following methods. @@ -57,6 +74,7 @@ func main() { extractCmd, execCmd, extractManyCmd, + simulateCmd, }, } @@ -69,3 +87,29 @@ func main() { log.Fatal(err) } } + +func initialize(c *cli.Context) error { + // LOTUS_DISABLE_VM_BUF disables what's called "VM state tree buffering", + // which stashes write operations in a BufferedBlockstore + // (https://github.com/filecoin-project/lotus/blob/b7a4dbb07fd8332b4492313a617e3458f8003b2a/lib/bufbstore/buf_bstore.go#L21) + // such that they're not written until the VM is actually flushed. + // + // For some reason, the standard behaviour was not working for me (raulk), + // and disabling it (such that the state transformations are written immediately + // to the blockstore) worked. + _ = os.Setenv("LOTUS_DISABLE_VM_BUF", "iknowitsabadidea") + + // Make the API client. + var err error + if FullAPI, Closer, err = lcli.GetFullNodeAPI(c); err != nil { + err = fmt.Errorf("failed to locate Lotus node; ") + } + return err +} + +func destroy(_ *cli.Context) error { + if Closer != nil { + Closer() + } + return nil +} diff --git a/cmd/tvx/simulate.go b/cmd/tvx/simulate.go new file mode 100644 index 000000000..82b2bc118 --- /dev/null +++ b/cmd/tvx/simulate.go @@ -0,0 +1,235 @@ +package main + +import ( + "bytes" + "compress/gzip" + "context" + "encoding/base64" + "encoding/json" + "fmt" + "log" + "os/exec" + + "github.com/fatih/color" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/test-vectors/schema" + "github.com/urfave/cli/v2" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/conformance" +) + +var simulateFlags struct { + msg string + epoch int64 + out string + statediff bool +} + +var simulateCmd = &cli.Command{ + Name: "simulate", + Description: "simulate a raw message on top of the supplied epoch (or HEAD), " + + "reporting the result on stderr and writing a test vector on stdout " + + "or into the specified file", + Action: runSimulateCmd, + Before: initialize, + After: destroy, + Flags: []cli.Flag{ + &repoFlag, + &cli.StringFlag{ + Name: "msg", + Usage: "base64 cbor-encoded message", + Destination: &simulateFlags.msg, + Required: true, + }, + &cli.Int64Flag{ + Name: "at-epoch", + Usage: "epoch at which to run this message (or HEAD if not provided)", + Destination: &simulateFlags.epoch, + }, + &cli.StringFlag{ + Name: "out", + Usage: "file to write the test vector to; if nil, the vector will be written to stdout", + TakesFile: true, + Destination: &simulateFlags.out, + }, + &cli.BoolFlag{ + Name: "statediff", + Usage: "display a statediff of the precondition and postcondition states", + Destination: &simulateFlags.statediff, + }, + }, +} + +func runSimulateCmd(_ *cli.Context) error { + ctx := context.Background() + r := new(conformance.LogReporter) + + msgb, err := base64.StdEncoding.DecodeString(simulateFlags.msg) + if err != nil { + return fmt.Errorf("failed to base64-decode message: %w", err) + } + + msg, err := types.DecodeMessage(msgb) + if err != nil { + return fmt.Errorf("failed to deserialize message: %w", err) + } + + log.Printf("message to simulate has CID: %s", msg.Cid()) + + msgjson, err := json.Marshal(msg) + if err != nil { + return fmt.Errorf("failed to serialize message to json for printing: %w", err) + } + + log.Printf("message to simulate: %s", string(msgjson)) + + // Resolve the tipset, root, epoch. + var ts *types.TipSet + if epochIn := simulateFlags.epoch; epochIn == 0 { + ts, err = FullAPI.ChainHead(ctx) + } else { + ts, err = FullAPI.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(epochIn), types.EmptyTSK) + } + + if err != nil { + return fmt.Errorf("failed to get tipset: %w", err) + } + + var ( + preroot = ts.ParentState() + epoch = ts.Height() + baseFee = ts.Blocks()[0].ParentBaseFee + circSupply api.CirculatingSupply + ) + + // Get circulating supply. + circSupply, err = FullAPI.StateVMCirculatingSupplyInternal(ctx, ts.Key()) + if err != nil { + return fmt.Errorf("failed to get circulating supply for tipset %s: %w", ts.Key(), err) + } + + // Create the driver. + stores := NewProxyingStores(ctx, FullAPI) + driver := conformance.NewDriver(ctx, schema.Selector{}, conformance.DriverOpts{ + DisableVMFlush: true, + }) + rand := conformance.NewRecordingRand(r, FullAPI) + + tbs, ok := stores.Blockstore.(TracingBlockstore) + if !ok { + return fmt.Errorf("no tracing blockstore available") + } + tbs.StartTracing() + applyret, postroot, err := driver.ExecuteMessage(stores.Blockstore, conformance.ExecuteMessageParams{ + Preroot: preroot, + Epoch: epoch, + Message: msg, + CircSupply: circSupply.FilCirculating, + BaseFee: baseFee, + Rand: rand, + }) + if err != nil { + return fmt.Errorf("failed to apply message: %w", err) + } + + accessed := tbs.FinishTracing() + + var ( + out = new(bytes.Buffer) + gw = gzip.NewWriter(out) + g = NewSurgeon(ctx, FullAPI, stores) + ) + if err := g.WriteCARIncluding(gw, accessed, preroot, postroot); err != nil { + return err + } + if err = gw.Flush(); err != nil { + return err + } + if err = gw.Close(); err != nil { + return err + } + + version, err := FullAPI.Version(ctx) + if err != nil { + log.Printf("failed to get node version: %s; falling back to unknown", err) + version = api.Version{} + } + + nv, err := FullAPI.StateNetworkVersion(ctx, ts.Key()) + if err != nil { + return err + } + + codename := GetProtocolCodename(epoch) + + // Write out the test vector. + vector := schema.TestVector{ + Class: schema.ClassMessage, + Meta: &schema.Metadata{ + ID: fmt.Sprintf("simulated-%s", msg.Cid()), + Gen: []schema.GenerationData{ + {Source: "github.com/filecoin-project/lotus", Version: version.String()}}, + }, + Selector: schema.Selector{ + schema.SelectorMinProtocolVersion: codename, + }, + Randomness: rand.Recorded(), + CAR: out.Bytes(), + Pre: &schema.Preconditions{ + Variants: []schema.Variant{ + {ID: codename, Epoch: int64(epoch), NetworkVersion: uint(nv)}, + }, + CircSupply: circSupply.FilCirculating.Int, + BaseFee: baseFee.Int, + StateTree: &schema.StateTree{ + RootCID: preroot, + }, + }, + ApplyMessages: []schema.Message{{Bytes: msgb}}, + Post: &schema.Postconditions{ + StateTree: &schema.StateTree{ + RootCID: postroot, + }, + Receipts: []*schema.Receipt{ + { + ExitCode: int64(applyret.ExitCode), + ReturnValue: applyret.Return, + GasUsed: applyret.GasUsed, + }, + }, + }, + } + + if err := writeVector(vector, simulateFlags.out); err != nil { + return fmt.Errorf("failed to write vector: %w", err) + } + + log.Printf(color.GreenString("wrote vector at: %s"), simulateFlags.out) + + if !simulateFlags.statediff { + return nil + } + + if simulateFlags.out == "" { + log.Print("omitting statediff in non-file mode") + return nil + } + + // check if statediff is installed; if not, skip. + if err := exec.Command("statediff", "--help").Run(); err != nil { + log.Printf("could not perform statediff on generated vector; command not found (%s)", err) + log.Printf("install statediff with:") + log.Printf("$ GOMODULE111=off go get github.com/filecoin-project/statediff/cmd/statediff") + return err + } + + stdiff, err := exec.Command("statediff", "vector", "--file", simulateFlags.out).CombinedOutput() + if err != nil { + return fmt.Errorf("failed to statediff: %w", err) + } + + log.Print(string(stdiff)) + return nil +} diff --git a/conformance/chaos/actor.go b/conformance/chaos/actor.go index d5e0b4352..cdda1db83 100644 --- a/conformance/chaos/actor.go +++ b/conformance/chaos/actor.go @@ -6,9 +6,11 @@ import ( "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/go-state-types/rt" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/ipfs/go-cid" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + runtime2 "github.com/filecoin-project/specs-actors/v2/actors/runtime" ) //go:generate go run ./gen @@ -104,19 +106,19 @@ type SendArgs struct { // SendReturn is the return values for the Send method. type SendReturn struct { - Return runtime.CBORBytes + Return builtin2.CBORBytes Code exitcode.ExitCode } // Send requests for this actor to send a message to an actor with the // passed parameters. -func (a Actor) Send(rt runtime.Runtime, args *SendArgs) *SendReturn { +func (a Actor) Send(rt runtime2.Runtime, args *SendArgs) *SendReturn { rt.ValidateImmediateCallerAcceptAny() - var out runtime.CBORBytes + var out builtin2.CBORBytes code := rt.Send( args.To, args.Method, - runtime.CBORBytes(args.Params), + builtin2.CBORBytes(args.Params), args.Value, &out, ) @@ -127,7 +129,7 @@ func (a Actor) Send(rt runtime.Runtime, args *SendArgs) *SendReturn { } // Constructor will panic because the Chaos actor is a singleton. -func (a Actor) Constructor(_ runtime.Runtime, _ *abi.EmptyValue) *abi.EmptyValue { +func (a Actor) Constructor(_ runtime2.Runtime, _ *abi.EmptyValue) *abi.EmptyValue { panic("constructor should not be called; the Chaos actor is a singleton actor") } @@ -144,7 +146,7 @@ type CallerValidationArgs struct { // CallerValidationBranchTwice validates twice. // CallerValidationBranchIsAddress validates caller against CallerValidationArgs.Addrs. // CallerValidationBranchIsType validates caller against CallerValidationArgs.Types. -func (a Actor) CallerValidation(rt runtime.Runtime, args *CallerValidationArgs) *abi.EmptyValue { +func (a Actor) CallerValidation(rt runtime2.Runtime, args *CallerValidationArgs) *abi.EmptyValue { switch args.Branch { case CallerValidationBranchNone: case CallerValidationBranchTwice: @@ -174,7 +176,7 @@ type CreateActorArgs struct { } // CreateActor creates an actor with the supplied CID and Address. -func (a Actor) CreateActor(rt runtime.Runtime, args *CreateActorArgs) *abi.EmptyValue { +func (a Actor) CreateActor(rt runtime2.Runtime, args *CreateActorArgs) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() var ( @@ -199,7 +201,7 @@ type ResolveAddressResponse struct { Success bool } -func (a Actor) ResolveAddress(rt runtime.Runtime, args *address.Address) *ResolveAddressResponse { +func (a Actor) ResolveAddress(rt runtime2.Runtime, args *address.Address) *ResolveAddressResponse { rt.ValidateImmediateCallerAcceptAny() resolvedAddr, ok := rt.ResolveAddress(*args) @@ -212,7 +214,7 @@ func (a Actor) ResolveAddress(rt runtime.Runtime, args *address.Address) *Resolv // DeleteActor deletes the executing actor from the state tree, transferring any // balance to beneficiary. -func (a Actor) DeleteActor(rt runtime.Runtime, beneficiary *address.Address) *abi.EmptyValue { +func (a Actor) DeleteActor(rt runtime2.Runtime, beneficiary *address.Address) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() rt.DeleteActor(*beneficiary) return nil @@ -226,7 +228,7 @@ type MutateStateArgs struct { } // MutateState attempts to mutate a state value in the actor. -func (a Actor) MutateState(rt runtime.Runtime, args *MutateStateArgs) *abi.EmptyValue { +func (a Actor) MutateState(rt runtime2.Runtime, args *MutateStateArgs) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() var st State switch args.Branch { @@ -257,7 +259,7 @@ type AbortWithArgs struct { } // AbortWith simply causes a panic with the passed exit code. -func (a Actor) AbortWith(rt runtime.Runtime, args *AbortWithArgs) *abi.EmptyValue { +func (a Actor) AbortWith(rt runtime2.Runtime, args *AbortWithArgs) *abi.EmptyValue { if args.Uncontrolled { // uncontrolled abort: directly panic panic(args.Message) } else { @@ -277,7 +279,7 @@ type InspectRuntimeReturn struct { } // InspectRuntime returns a copy of the serializable values available in the Runtime. -func (a Actor) InspectRuntime(rt runtime.Runtime, _ *abi.EmptyValue) *InspectRuntimeReturn { +func (a Actor) InspectRuntime(rt runtime2.Runtime, _ *abi.EmptyValue) *InspectRuntimeReturn { rt.ValidateImmediateCallerAcceptAny() var st State rt.StateReadonly(&st) diff --git a/conformance/chaos/actor_test.go b/conformance/chaos/actor_test.go index 2061efb82..dbce4f4c5 100644 --- a/conformance/chaos/actor_test.go +++ b/conformance/chaos/actor_test.go @@ -7,15 +7,16 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/exitcode" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/support/mock" - atesting "github.com/filecoin-project/specs-actors/support/testing" "github.com/ipfs/go-cid" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + mock2 "github.com/filecoin-project/specs-actors/v2/support/mock" + atesting2 "github.com/filecoin-project/specs-actors/v2/support/testing" ) func TestSingleton(t *testing.T) { - receiver := atesting.NewIDAddr(t, 100) - builder := mock.NewBuilder(context.Background(), receiver) + receiver := atesting2.NewIDAddr(t, 100) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) var a Actor @@ -28,8 +29,8 @@ func TestSingleton(t *testing.T) { } func TestCallerValidationNone(t *testing.T) { - receiver := atesting.NewIDAddr(t, 100) - builder := mock.NewBuilder(context.Background(), receiver) + receiver := atesting2.NewIDAddr(t, 100) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) var a Actor @@ -39,19 +40,19 @@ func TestCallerValidationNone(t *testing.T) { } func TestCallerValidationIs(t *testing.T) { - caller := atesting.NewIDAddr(t, 100) - receiver := atesting.NewIDAddr(t, 101) - builder := mock.NewBuilder(context.Background(), receiver) + caller := atesting2.NewIDAddr(t, 100) + receiver := atesting2.NewIDAddr(t, 101) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) - rt.SetCaller(caller, builtin.AccountActorCodeID) + rt.SetCaller(caller, builtin2.AccountActorCodeID) var a Actor - caddrs := []address.Address{atesting.NewIDAddr(t, 101)} + caddrs := []address.Address{atesting2.NewIDAddr(t, 101)} rt.ExpectValidateCallerAddr(caddrs...) - // FIXME: https://github.com/filecoin-project/specs-actors/pull/1155 - rt.ExpectAbort(exitcode.ErrForbidden, func() { + // fixed in: https://github.com/filecoin-project/specs-actors/pull/1155 + rt.ExpectAbort(exitcode.SysErrForbidden, func() { rt.Call(a.CallerValidation, &CallerValidationArgs{ Branch: CallerValidationBranchIsAddress, Addrs: caddrs, @@ -68,35 +69,34 @@ func TestCallerValidationIs(t *testing.T) { } func TestCallerValidationType(t *testing.T) { - caller := atesting.NewIDAddr(t, 100) - receiver := atesting.NewIDAddr(t, 101) - builder := mock.NewBuilder(context.Background(), receiver) + caller := atesting2.NewIDAddr(t, 100) + receiver := atesting2.NewIDAddr(t, 101) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) - rt.SetCaller(caller, builtin.AccountActorCodeID) + rt.SetCaller(caller, builtin2.AccountActorCodeID) var a Actor - rt.ExpectValidateCallerType(builtin.CronActorCodeID) - // FIXME: https://github.com/filecoin-project/specs-actors/pull/1155 - rt.ExpectAbort(exitcode.ErrForbidden, func() { + rt.ExpectValidateCallerType(builtin2.CronActorCodeID) + rt.ExpectAbort(exitcode.SysErrForbidden, func() { rt.Call(a.CallerValidation, &CallerValidationArgs{ Branch: CallerValidationBranchIsType, - Types: []cid.Cid{builtin.CronActorCodeID}, + Types: []cid.Cid{builtin2.CronActorCodeID}, }) }) rt.Verify() - rt.ExpectValidateCallerType(builtin.AccountActorCodeID) + rt.ExpectValidateCallerType(builtin2.AccountActorCodeID) rt.Call(a.CallerValidation, &CallerValidationArgs{ Branch: CallerValidationBranchIsType, - Types: []cid.Cid{builtin.AccountActorCodeID}, + Types: []cid.Cid{builtin2.AccountActorCodeID}, }) rt.Verify() } func TestCallerValidationInvalidBranch(t *testing.T) { - receiver := atesting.NewIDAddr(t, 100) - builder := mock.NewBuilder(context.Background(), receiver) + receiver := atesting2.NewIDAddr(t, 100) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) var a Actor @@ -108,9 +108,9 @@ func TestCallerValidationInvalidBranch(t *testing.T) { } func TestDeleteActor(t *testing.T) { - receiver := atesting.NewIDAddr(t, 100) - beneficiary := atesting.NewIDAddr(t, 101) - builder := mock.NewBuilder(context.Background(), receiver) + receiver := atesting2.NewIDAddr(t, 100) + beneficiary := atesting2.NewIDAddr(t, 101) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) var a Actor @@ -122,8 +122,8 @@ func TestDeleteActor(t *testing.T) { } func TestMutateStateInTransaction(t *testing.T) { - receiver := atesting.NewIDAddr(t, 100) - builder := mock.NewBuilder(context.Background(), receiver) + receiver := atesting2.NewIDAddr(t, 100) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) var a Actor @@ -148,8 +148,8 @@ func TestMutateStateInTransaction(t *testing.T) { } func TestMutateStateAfterTransaction(t *testing.T) { - receiver := atesting.NewIDAddr(t, 100) - builder := mock.NewBuilder(context.Background(), receiver) + receiver := atesting2.NewIDAddr(t, 100) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) var a Actor @@ -175,8 +175,8 @@ func TestMutateStateAfterTransaction(t *testing.T) { } func TestMutateStateReadonly(t *testing.T) { - receiver := atesting.NewIDAddr(t, 100) - builder := mock.NewBuilder(context.Background(), receiver) + receiver := atesting2.NewIDAddr(t, 100) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) var a Actor @@ -201,8 +201,8 @@ func TestMutateStateReadonly(t *testing.T) { } func TestMutateStateInvalidBranch(t *testing.T) { - receiver := atesting.NewIDAddr(t, 100) - builder := mock.NewBuilder(context.Background(), receiver) + receiver := atesting2.NewIDAddr(t, 100) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) var a Actor @@ -215,8 +215,8 @@ func TestMutateStateInvalidBranch(t *testing.T) { } func TestAbortWith(t *testing.T) { - receiver := atesting.NewIDAddr(t, 100) - builder := mock.NewBuilder(context.Background(), receiver) + receiver := atesting2.NewIDAddr(t, 100) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) var a Actor @@ -233,8 +233,8 @@ func TestAbortWith(t *testing.T) { } func TestAbortWithUncontrolled(t *testing.T) { - receiver := atesting.NewIDAddr(t, 100) - builder := mock.NewBuilder(context.Background(), receiver) + receiver := atesting2.NewIDAddr(t, 100) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) var a Actor @@ -250,12 +250,12 @@ func TestAbortWithUncontrolled(t *testing.T) { } func TestInspectRuntime(t *testing.T) { - caller := atesting.NewIDAddr(t, 100) - receiver := atesting.NewIDAddr(t, 101) - builder := mock.NewBuilder(context.Background(), receiver) + caller := atesting2.NewIDAddr(t, 100) + receiver := atesting2.NewIDAddr(t, 101) + builder := mock2.NewBuilder(context.Background(), receiver) rt := builder.Build(t) - rt.SetCaller(caller, builtin.AccountActorCodeID) + rt.SetCaller(caller, builtin2.AccountActorCodeID) rt.StateCreate(&State{}) var a Actor diff --git a/conformance/chaos/cbor_gen.go b/conformance/chaos/cbor_gen.go index 882af7026..876d6a893 100644 --- a/conformance/chaos/cbor_gen.go +++ b/conformance/chaos/cbor_gen.go @@ -587,7 +587,7 @@ func (t *SendReturn) MarshalCBOR(w io.Writer) error { scratch := make([]byte, 9) - // t.Return (runtime.CBORBytes) (slice) + // t.Return (builtin.CBORBytes) (slice) if len(t.Return) > cbg.ByteArrayMaxLen { return xerrors.Errorf("Byte array in field t.Return was too long") } @@ -631,7 +631,7 @@ func (t *SendReturn) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input had wrong number of fields") } - // t.Return (runtime.CBORBytes) (slice) + // t.Return (builtin.CBORBytes) (slice) maj, extra, err = cbg.CborReadHeaderBuf(br, scratch) if err != nil { diff --git a/conformance/driver.go b/conformance/driver.go index fbb7dda6d..95b6f2659 100644 --- a/conformance/driver.go +++ b/conformance/driver.go @@ -248,7 +248,7 @@ func BaseFeeOrDefault(basefee *gobig.Int) abi.TokenAmount { // DefaultCirculatingSupply. func CircSupplyOrDefault(circSupply *gobig.Int) abi.TokenAmount { if circSupply == nil { - return DefaultBaseFee + return DefaultCirculatingSupply } return big.NewFromGo(circSupply) } diff --git a/documentation/en/api-methods.md b/documentation/en/api-methods.md index 74f132d66..d77252538 100644 --- a/documentation/en/api-methods.md +++ b/documentation/en/api-methods.md @@ -38,6 +38,7 @@ * [ClientFindData](#ClientFindData) * [ClientGenCar](#ClientGenCar) * [ClientGetDealInfo](#ClientGetDealInfo) + * [ClientGetDealStatus](#ClientGetDealStatus) * [ClientGetDealUpdates](#ClientGetDealUpdates) * [ClientHasLocal](#ClientHasLocal) * [ClientImport](#ClientImport) @@ -70,6 +71,9 @@ * [MinerCreateBlock](#MinerCreateBlock) * [MinerGetBaseInfo](#MinerGetBaseInfo) * [Mpool](#Mpool) + * [MpoolBatchPush](#MpoolBatchPush) + * [MpoolBatchPushMessage](#MpoolBatchPushMessage) + * [MpoolBatchPushUntrusted](#MpoolBatchPushUntrusted) * [MpoolClear](#MpoolClear) * [MpoolGetConfig](#MpoolGetConfig) * [MpoolGetNonce](#MpoolGetNonce) @@ -983,6 +987,21 @@ Response: } ``` +### ClientGetDealStatus +ClientGetDealStatus returns status given a code + + +Perms: read + +Inputs: +```json +[ + 42 +] +``` + +Response: `"string value"` + ### ClientGetDealUpdates ClientGetDealUpdates returns the status of updated deals @@ -1692,6 +1711,54 @@ The Mpool methods are for interacting with the message pool. The message pool manages all incoming and outgoing 'messages' going over the network. +### MpoolBatchPush +MpoolBatchPush batch pushes a signed message to mempool. + + +Perms: write + +Inputs: +```json +[ + null +] +``` + +Response: `null` + +### MpoolBatchPushMessage +MpoolBatchPushMessage batch pushes a unsigned message to mempool. + + +Perms: sign + +Inputs: +```json +[ + null, + { + "MaxFee": "0" + } +] +``` + +Response: `null` + +### MpoolBatchPushUntrusted +MpoolBatchPushUntrusted batch pushes a signed message to mempool from untrusted sources. + + +Perms: write + +Inputs: +```json +[ + null +] +``` + +Response: `null` + ### MpoolClear MpoolClear clears pending messages from the mpool @@ -4039,7 +4106,7 @@ Inputs: ] ``` -Response: `5` +Response: `6` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/extern/sector-storage/faults.go b/extern/sector-storage/faults.go index fb6910466..c4e1364ad 100644 --- a/extern/sector-storage/faults.go +++ b/extern/sector-storage/faults.go @@ -15,14 +15,14 @@ import ( // FaultTracker TODO: Track things more actively type FaultTracker interface { - CheckProvable(ctx context.Context, spt abi.RegisteredSealProof, sectors []abi.SectorID) ([]abi.SectorID, error) + CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []abi.SectorID) ([]abi.SectorID, error) } // CheckProvable returns unprovable sectors -func (m *Manager) CheckProvable(ctx context.Context, spt abi.RegisteredSealProof, sectors []abi.SectorID) ([]abi.SectorID, error) { +func (m *Manager) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []abi.SectorID) ([]abi.SectorID, error) { var bad []abi.SectorID - ssize, err := spt.SectorSize() + ssize, err := pp.SectorSize() if err != nil { return nil, err } @@ -44,7 +44,7 @@ func (m *Manager) CheckProvable(ctx context.Context, spt abi.RegisteredSealProof return nil } - lp, _, err := m.localStore.AcquireSector(ctx, sector, spt, storiface.FTSealed|storiface.FTCache, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) + lp, _, err := m.localStore.AcquireSector(ctx, sector, ssize, storiface.FTSealed|storiface.FTCache, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) if err != nil { log.Warnw("CheckProvable Sector FAULT: acquire sector in checkProvable", "sector", sector, "error", err) bad = append(bad, sector) diff --git a/extern/sector-storage/ffiwrapper/sealer_test.go b/extern/sector-storage/ffiwrapper/sealer_test.go index 1b0b88187..5ae5cec67 100644 --- a/extern/sector-storage/ffiwrapper/sealer_test.go +++ b/extern/sector-storage/ffiwrapper/sealer_test.go @@ -15,7 +15,7 @@ import ( "testing" "time" - saproof "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/ipfs/go-cid" @@ -93,7 +93,7 @@ func (s *seal) commit(t *testing.T, sb *Sealer, done func()) { t.Fatalf("%+v", err) } - ok, err := ProofVerifier.VerifySeal(saproof.SealVerifyInfo{ + ok, err := ProofVerifier.VerifySeal(proof2.SealVerifyInfo{ SectorID: s.id, SealedCID: s.cids.Sealed, SealProof: sealProofType, @@ -171,9 +171,9 @@ func (s *seal) unseal(t *testing.T, sb *Sealer, sp *basicfs.Provider, si abi.Sec func post(t *testing.T, sealer *Sealer, skipped []abi.SectorID, seals ...seal) { randomness := abi.PoStRandomness{0, 9, 2, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 45, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 7} - sis := make([]saproof.SectorInfo, len(seals)) + sis := make([]proof2.SectorInfo, len(seals)) for i, s := range seals { - sis[i] = saproof.SectorInfo{ + sis[i] = proof2.SectorInfo{ SealProof: sealProofType, SectorNumber: s.id.Number, SealedCID: s.cids.Sealed, @@ -191,7 +191,7 @@ func post(t *testing.T, sealer *Sealer, skipped []abi.SectorID, seals ...seal) { t.Fatalf("%+v", err) } - ok, err := ProofVerifier.VerifyWindowPoSt(context.TODO(), saproof.WindowPoStVerifyInfo{ + ok, err := ProofVerifier.VerifyWindowPoSt(context.TODO(), proof2.WindowPoStVerifyInfo{ Randomness: randomness, Proofs: proofs, ChallengedSectors: sis, diff --git a/extern/sector-storage/ffiwrapper/types.go b/extern/sector-storage/ffiwrapper/types.go index 9a1128ea3..b67f9c595 100644 --- a/extern/sector-storage/ffiwrapper/types.go +++ b/extern/sector-storage/ffiwrapper/types.go @@ -4,7 +4,7 @@ import ( "context" "io" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/ipfs/go-cid" @@ -34,9 +34,9 @@ type Storage interface { } type Verifier interface { - VerifySeal(proof.SealVerifyInfo) (bool, error) - VerifyWinningPoSt(ctx context.Context, info proof.WinningPoStVerifyInfo) (bool, error) - VerifyWindowPoSt(ctx context.Context, info proof.WindowPoStVerifyInfo) (bool, error) + VerifySeal(proof2.SealVerifyInfo) (bool, error) + VerifyWinningPoSt(ctx context.Context, info proof2.WinningPoStVerifyInfo) (bool, error) + VerifyWindowPoSt(ctx context.Context, info proof2.WindowPoStVerifyInfo) (bool, error) GenerateWinningPoStSectorChallenge(context.Context, abi.RegisteredPoStProof, abi.ActorID, abi.PoStRandomness, uint64) ([]uint64, error) } diff --git a/extern/sector-storage/ffiwrapper/verifier_cgo.go b/extern/sector-storage/ffiwrapper/verifier_cgo.go index 8a9ac16d8..9dab7103e 100644 --- a/extern/sector-storage/ffiwrapper/verifier_cgo.go +++ b/extern/sector-storage/ffiwrapper/verifier_cgo.go @@ -10,12 +10,12 @@ import ( ffi "github.com/filecoin-project/filecoin-ffi" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/filecoin-project/lotus/extern/sector-storage/storiface" ) -func (sb *Sealer) GenerateWinningPoSt(ctx context.Context, minerID abi.ActorID, sectorInfo []proof.SectorInfo, randomness abi.PoStRandomness) ([]proof.PoStProof, error) { +func (sb *Sealer) GenerateWinningPoSt(ctx context.Context, minerID abi.ActorID, sectorInfo []proof2.SectorInfo, randomness abi.PoStRandomness) ([]proof2.PoStProof, error) { randomness[31] &= 0x3f privsectors, skipped, done, err := sb.pubSectorToPriv(ctx, minerID, sectorInfo, nil, abi.RegisteredSealProof.RegisteredWinningPoStProof) // TODO: FAULTS? if err != nil { @@ -29,7 +29,7 @@ func (sb *Sealer) GenerateWinningPoSt(ctx context.Context, minerID abi.ActorID, return ffi.GenerateWinningPoSt(minerID, privsectors, randomness) } -func (sb *Sealer) GenerateWindowPoSt(ctx context.Context, minerID abi.ActorID, sectorInfo []proof.SectorInfo, randomness abi.PoStRandomness) ([]proof.PoStProof, []abi.SectorID, error) { +func (sb *Sealer) GenerateWindowPoSt(ctx context.Context, minerID abi.ActorID, sectorInfo []proof2.SectorInfo, randomness abi.PoStRandomness) ([]proof2.PoStProof, []abi.SectorID, error) { randomness[31] &= 0x3f privsectors, skipped, done, err := sb.pubSectorToPriv(ctx, minerID, sectorInfo, nil, abi.RegisteredSealProof.RegisteredWindowPoStProof) if err != nil { @@ -54,7 +54,7 @@ func (sb *Sealer) GenerateWindowPoSt(ctx context.Context, minerID abi.ActorID, s return proof, faultyIDs, err } -func (sb *Sealer) pubSectorToPriv(ctx context.Context, mid abi.ActorID, sectorInfo []proof.SectorInfo, faults []abi.SectorNumber, rpt func(abi.RegisteredSealProof) (abi.RegisteredPoStProof, error)) (ffi.SortedPrivateSectorInfo, []abi.SectorID, func(), error) { +func (sb *Sealer) pubSectorToPriv(ctx context.Context, mid abi.ActorID, sectorInfo []proof2.SectorInfo, faults []abi.SectorNumber, rpt func(abi.RegisteredSealProof) (abi.RegisteredPoStProof, error)) (ffi.SortedPrivateSectorInfo, []abi.SectorID, func(), error) { fmap := map[abi.SectorNumber]struct{}{} for _, fault := range faults { fmap[fault] = struct{}{} @@ -107,11 +107,11 @@ type proofVerifier struct{} var ProofVerifier = proofVerifier{} -func (proofVerifier) VerifySeal(info proof.SealVerifyInfo) (bool, error) { +func (proofVerifier) VerifySeal(info proof2.SealVerifyInfo) (bool, error) { return ffi.VerifySeal(info) } -func (proofVerifier) VerifyWinningPoSt(ctx context.Context, info proof.WinningPoStVerifyInfo) (bool, error) { +func (proofVerifier) VerifyWinningPoSt(ctx context.Context, info proof2.WinningPoStVerifyInfo) (bool, error) { info.Randomness[31] &= 0x3f _, span := trace.StartSpan(ctx, "VerifyWinningPoSt") defer span.End() @@ -119,7 +119,7 @@ func (proofVerifier) VerifyWinningPoSt(ctx context.Context, info proof.WinningPo return ffi.VerifyWinningPoSt(info) } -func (proofVerifier) VerifyWindowPoSt(ctx context.Context, info proof.WindowPoStVerifyInfo) (bool, error) { +func (proofVerifier) VerifyWindowPoSt(ctx context.Context, info proof2.WindowPoStVerifyInfo) (bool, error) { info.Randomness[31] &= 0x3f _, span := trace.StartSpan(ctx, "VerifyWindowPoSt") defer span.End() diff --git a/extern/sector-storage/manager.go b/extern/sector-storage/manager.go index 0a8ff4339..f32a363e7 100644 --- a/extern/sector-storage/manager.go +++ b/extern/sector-storage/manager.go @@ -111,7 +111,7 @@ func New(ctx context.Context, ls stores.LocalStorage, si stores.SectorIndex, cfg return nil, err } - prover, err := ffiwrapper.New(&readonlyProvider{stor: lstor, index: si}, cfg) + prover, err := ffiwrapper.New(&readonlyProvider{stor: lstor, index: si, spt: cfg.SealProofType}, cfg) if err != nil { return nil, xerrors.Errorf("creating prover instance: %w", err) } diff --git a/extern/sector-storage/manager_test.go b/extern/sector-storage/manager_test.go index da89a0452..6efcc304e 100644 --- a/extern/sector-storage/manager_test.go +++ b/extern/sector-storage/manager_test.go @@ -97,7 +97,7 @@ func newTestMgr(ctx context.Context, t *testing.T, ds datastore.Datastore) (*Man lstor, err := stores.NewLocal(ctx, st, si, nil) require.NoError(t, err) - prover, err := ffiwrapper.New(&readonlyProvider{stor: lstor}, cfg) + prover, err := ffiwrapper.New(&readonlyProvider{stor: lstor, spt: cfg.SealProofType}, cfg) require.NoError(t, err) stor := stores.NewRemote(lstor, si, nil, 6000) diff --git a/extern/sector-storage/mock/mock.go b/extern/sector-storage/mock/mock.go index 390e4524c..b3de99ce5 100644 --- a/extern/sector-storage/mock/mock.go +++ b/extern/sector-storage/mock/mock.go @@ -9,7 +9,7 @@ import ( "math/rand" "sync" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/go-state-types/abi" @@ -293,12 +293,12 @@ func AddOpFinish(ctx context.Context) (context.Context, func()) { } } -func (mgr *SectorMgr) GenerateWinningPoSt(ctx context.Context, minerID abi.ActorID, sectorInfo []proof.SectorInfo, randomness abi.PoStRandomness) ([]proof.PoStProof, error) { +func (mgr *SectorMgr) GenerateWinningPoSt(ctx context.Context, minerID abi.ActorID, sectorInfo []proof2.SectorInfo, randomness abi.PoStRandomness) ([]proof2.PoStProof, error) { return generateFakePoSt(sectorInfo, abi.RegisteredSealProof.RegisteredWinningPoStProof, randomness), nil } -func (mgr *SectorMgr) GenerateWindowPoSt(ctx context.Context, minerID abi.ActorID, sectorInfo []proof.SectorInfo, randomness abi.PoStRandomness) ([]proof.PoStProof, []abi.SectorID, error) { - si := make([]proof.SectorInfo, 0, len(sectorInfo)) +func (mgr *SectorMgr) GenerateWindowPoSt(ctx context.Context, minerID abi.ActorID, sectorInfo []proof2.SectorInfo, randomness abi.PoStRandomness) ([]proof2.PoStProof, []abi.SectorID, error) { + si := make([]proof2.SectorInfo, 0, len(sectorInfo)) var skipped []abi.SectorID var err error @@ -326,7 +326,7 @@ func (mgr *SectorMgr) GenerateWindowPoSt(ctx context.Context, minerID abi.ActorI return generateFakePoSt(si, abi.RegisteredSealProof.RegisteredWindowPoStProof, randomness), skipped, nil } -func generateFakePoStProof(sectorInfo []proof.SectorInfo, randomness abi.PoStRandomness) []byte { +func generateFakePoStProof(sectorInfo []proof2.SectorInfo, randomness abi.PoStRandomness) []byte { hasher := sha256.New() _, _ = hasher.Write(randomness) for _, info := range sectorInfo { @@ -339,13 +339,13 @@ func generateFakePoStProof(sectorInfo []proof.SectorInfo, randomness abi.PoStRan } -func generateFakePoSt(sectorInfo []proof.SectorInfo, rpt func(abi.RegisteredSealProof) (abi.RegisteredPoStProof, error), randomness abi.PoStRandomness) []proof.PoStProof { +func generateFakePoSt(sectorInfo []proof2.SectorInfo, rpt func(abi.RegisteredSealProof) (abi.RegisteredPoStProof, error), randomness abi.PoStRandomness) []proof2.PoStProof { wp, err := rpt(sectorInfo[0].SealProof) if err != nil { panic(err) } - return []proof.PoStProof{ + return []proof2.PoStProof{ { PoStProof: wp, ProofBytes: generateFakePoStProof(sectorInfo, randomness), @@ -405,7 +405,7 @@ func (mgr *SectorMgr) Remove(ctx context.Context, sector abi.SectorID) error { return nil } -func (mgr *SectorMgr) CheckProvable(ctx context.Context, spt abi.RegisteredSealProof, ids []abi.SectorID) ([]abi.SectorID, error) { +func (mgr *SectorMgr) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, ids []abi.SectorID) ([]abi.SectorID, error) { var bad []abi.SectorID for _, sid := range ids { @@ -463,7 +463,7 @@ func (mgr *SectorMgr) ReturnFetch(ctx context.Context, callID storiface.CallID, panic("not supported") } -func (m mockVerif) VerifySeal(svi proof.SealVerifyInfo) (bool, error) { +func (m mockVerif) VerifySeal(svi proof2.SealVerifyInfo) (bool, error) { if len(svi.Proof) != 1920 { return false, nil } @@ -478,11 +478,11 @@ func (m mockVerif) VerifySeal(svi proof.SealVerifyInfo) (bool, error) { return true, nil } -func (m mockVerif) VerifyWinningPoSt(ctx context.Context, info proof.WinningPoStVerifyInfo) (bool, error) { +func (m mockVerif) VerifyWinningPoSt(ctx context.Context, info proof2.WinningPoStVerifyInfo) (bool, error) { return true, nil } -func (m mockVerif) VerifyWindowPoSt(ctx context.Context, info proof.WindowPoStVerifyInfo) (bool, error) { +func (m mockVerif) VerifyWindowPoSt(ctx context.Context, info proof2.WindowPoStVerifyInfo) (bool, error) { if len(info.Proofs) != 1 { return false, xerrors.Errorf("expected 1 proof entry") } diff --git a/extern/sector-storage/roprov.go b/extern/sector-storage/roprov.go index 996d70721..7f051b549 100644 --- a/extern/sector-storage/roprov.go +++ b/extern/sector-storage/roprov.go @@ -22,6 +22,11 @@ func (l *readonlyProvider) AcquireSector(ctx context.Context, id abi.SectorID, e return storiface.SectorPaths{}, nil, xerrors.New("read-only storage") } + ssize, err := l.spt.SectorSize() + if err != nil { + return storiface.SectorPaths{}, nil, xerrors.Errorf("failed to determine sector size: %w", err) + } + ctx, cancel := context.WithCancel(ctx) // use TryLock to avoid blocking @@ -35,7 +40,7 @@ func (l *readonlyProvider) AcquireSector(ctx context.Context, id abi.SectorID, e return storiface.SectorPaths{}, nil, xerrors.Errorf("failed to acquire sector lock") } - p, _, err := l.stor.AcquireSector(ctx, id, l.spt, existing, allocate, sealing, storiface.AcquireMove) + p, _, err := l.stor.AcquireSector(ctx, id, ssize, existing, allocate, sealing, storiface.AcquireMove) return p, cancel, err } diff --git a/extern/sector-storage/selector_alloc.go b/extern/sector-storage/selector_alloc.go index 77ed44708..9afa6abaa 100644 --- a/extern/sector-storage/selector_alloc.go +++ b/extern/sector-storage/selector_alloc.go @@ -45,7 +45,12 @@ func (s *allocSelector) Ok(ctx context.Context, task sealtasks.TaskType, spt abi have[path.ID] = struct{}{} } - best, err := s.index.StorageBestAlloc(ctx, s.alloc, spt, s.ptype) + ssize, err := spt.SectorSize() + if err != nil { + return false, xerrors.Errorf("getting sector size: %w", err) + } + + best, err := s.index.StorageBestAlloc(ctx, s.alloc, ssize, s.ptype) if err != nil { return false, xerrors.Errorf("finding best alloc storage: %w", err) } diff --git a/extern/sector-storage/selector_existing.go b/extern/sector-storage/selector_existing.go index 100f6dc4d..025ad3f21 100644 --- a/extern/sector-storage/selector_existing.go +++ b/extern/sector-storage/selector_existing.go @@ -47,7 +47,12 @@ func (s *existingSelector) Ok(ctx context.Context, task sealtasks.TaskType, spt have[path.ID] = struct{}{} } - best, err := s.index.StorageFindSector(ctx, s.sector, s.alloc, spt, s.allowFetch) + ssize, err := spt.SectorSize() + if err != nil { + return false, xerrors.Errorf("getting sector size: %w", err) + } + + best, err := s.index.StorageFindSector(ctx, s.sector, s.alloc, ssize, s.allowFetch) if err != nil { return false, xerrors.Errorf("finding best storage: %w", err) } diff --git a/extern/sector-storage/stores/index.go b/extern/sector-storage/stores/index.go index 9b3798ae1..acd799ab7 100644 --- a/extern/sector-storage/stores/index.go +++ b/extern/sector-storage/stores/index.go @@ -56,9 +56,9 @@ type SectorIndex interface { // part of storage-miner api StorageDeclareSector(ctx context.Context, storageID ID, s abi.SectorID, ft storiface.SectorFileType, primary bool) error StorageDropSector(ctx context.Context, storageID ID, s abi.SectorID, ft storiface.SectorFileType) error - StorageFindSector(ctx context.Context, sector abi.SectorID, ft storiface.SectorFileType, spt abi.RegisteredSealProof, allowFetch bool) ([]SectorStorageInfo, error) + StorageFindSector(ctx context.Context, sector abi.SectorID, ft storiface.SectorFileType, ssize abi.SectorSize, allowFetch bool) ([]SectorStorageInfo, error) - StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, spt abi.RegisteredSealProof, pathType storiface.PathType) ([]StorageInfo, error) + StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pathType storiface.PathType) ([]StorageInfo, error) // atomically acquire locks on all sector file types. close ctx to unlock StorageLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error @@ -247,7 +247,7 @@ func (i *Index) StorageDropSector(ctx context.Context, storageID ID, s abi.Secto return nil } -func (i *Index) StorageFindSector(ctx context.Context, s abi.SectorID, ft storiface.SectorFileType, spt abi.RegisteredSealProof, allowFetch bool) ([]SectorStorageInfo, error) { +func (i *Index) StorageFindSector(ctx context.Context, s abi.SectorID, ft storiface.SectorFileType, ssize abi.SectorSize, allowFetch bool) ([]SectorStorageInfo, error) { i.lk.RLock() defer i.lk.RUnlock() @@ -298,7 +298,7 @@ func (i *Index) StorageFindSector(ctx context.Context, s abi.SectorID, ft storif } if allowFetch { - spaceReq, err := ft.SealSpaceUse(spt) + spaceReq, err := ft.SealSpaceUse(ssize) if err != nil { return nil, xerrors.Errorf("estimating required space: %w", err) } @@ -366,13 +366,13 @@ func (i *Index) StorageInfo(ctx context.Context, id ID) (StorageInfo, error) { return *si.info, nil } -func (i *Index) StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, spt abi.RegisteredSealProof, pathType storiface.PathType) ([]StorageInfo, error) { +func (i *Index) StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pathType storiface.PathType) ([]StorageInfo, error) { i.lk.RLock() defer i.lk.RUnlock() var candidates []storageEntry - spaceReq, err := allocate.SealSpaceUse(spt) + spaceReq, err := allocate.SealSpaceUse(ssize) if err != nil { return nil, xerrors.Errorf("estimating required space: %w", err) } diff --git a/extern/sector-storage/stores/interface.go b/extern/sector-storage/stores/interface.go index f1b1bb72d..574ec599e 100644 --- a/extern/sector-storage/stores/interface.go +++ b/extern/sector-storage/stores/interface.go @@ -10,7 +10,7 @@ import ( ) type Store interface { - AcquireSector(ctx context.Context, s abi.SectorID, spt abi.RegisteredSealProof, existing storiface.SectorFileType, allocate storiface.SectorFileType, sealing storiface.PathType, op storiface.AcquireMode) (paths storiface.SectorPaths, stores storiface.SectorPaths, err error) + AcquireSector(ctx context.Context, s abi.SectorID, ssize abi.SectorSize, existing storiface.SectorFileType, allocate storiface.SectorFileType, sealing storiface.PathType, op storiface.AcquireMode) (paths storiface.SectorPaths, stores storiface.SectorPaths, err error) Remove(ctx context.Context, s abi.SectorID, types storiface.SectorFileType, force bool) error // like remove, but doesn't remove the primary sector copy, nor the last @@ -18,7 +18,7 @@ type Store interface { RemoveCopies(ctx context.Context, s abi.SectorID, types storiface.SectorFileType) error // move sectors into storage - MoveStorage(ctx context.Context, s abi.SectorID, spt abi.RegisteredSealProof, types storiface.SectorFileType) error + MoveStorage(ctx context.Context, s abi.SectorID, ssize abi.SectorSize, types storiface.SectorFileType) error FsStat(ctx context.Context, id ID) (fsutil.FsStat, error) } diff --git a/extern/sector-storage/stores/local.go b/extern/sector-storage/stores/local.go index 7d2509bf9..89c22bd99 100644 --- a/extern/sector-storage/stores/local.go +++ b/extern/sector-storage/stores/local.go @@ -320,12 +320,7 @@ func (st *Local) reportHealth(ctx context.Context) { } } -func (st *Local) Reserve(ctx context.Context, sid abi.SectorID, spt abi.RegisteredSealProof, ft storiface.SectorFileType, storageIDs storiface.SectorPaths, overheadTab map[storiface.SectorFileType]int) (func(), error) { - ssize, err := spt.SectorSize() - if err != nil { - return nil, xerrors.Errorf("getting sector size: %w", err) - } - +func (st *Local) Reserve(ctx context.Context, sid abi.SectorID, ssize abi.SectorSize, ft storiface.SectorFileType, storageIDs storiface.SectorPaths, overheadTab map[storiface.SectorFileType]int) (func(), error) { st.localLk.Lock() done := func() {} @@ -375,7 +370,7 @@ func (st *Local) Reserve(ctx context.Context, sid abi.SectorID, spt abi.Register return done, nil } -func (st *Local) AcquireSector(ctx context.Context, sid abi.SectorID, spt abi.RegisteredSealProof, existing storiface.SectorFileType, allocate storiface.SectorFileType, pathType storiface.PathType, op storiface.AcquireMode) (storiface.SectorPaths, storiface.SectorPaths, error) { +func (st *Local) AcquireSector(ctx context.Context, sid abi.SectorID, ssize abi.SectorSize, existing storiface.SectorFileType, allocate storiface.SectorFileType, pathType storiface.PathType, op storiface.AcquireMode) (storiface.SectorPaths, storiface.SectorPaths, error) { if existing|allocate != existing^allocate { return storiface.SectorPaths{}, storiface.SectorPaths{}, xerrors.New("can't both find and allocate a sector") } @@ -391,7 +386,7 @@ func (st *Local) AcquireSector(ctx context.Context, sid abi.SectorID, spt abi.Re continue } - si, err := st.index.StorageFindSector(ctx, sid, fileType, spt, false) + si, err := st.index.StorageFindSector(ctx, sid, fileType, ssize, false) if err != nil { log.Warnf("finding existing sector %d(t:%d) failed: %+v", sid, fileType, err) continue @@ -421,7 +416,7 @@ func (st *Local) AcquireSector(ctx context.Context, sid abi.SectorID, spt abi.Re continue } - sis, err := st.index.StorageBestAlloc(ctx, fileType, spt, pathType) + sis, err := st.index.StorageBestAlloc(ctx, fileType, ssize, pathType) if err != nil { return storiface.SectorPaths{}, storiface.SectorPaths{}, xerrors.Errorf("finding best storage for allocating : %w", err) } @@ -576,13 +571,13 @@ func (st *Local) removeSector(ctx context.Context, sid abi.SectorID, typ storifa return nil } -func (st *Local) MoveStorage(ctx context.Context, s abi.SectorID, spt abi.RegisteredSealProof, types storiface.SectorFileType) error { - dest, destIds, err := st.AcquireSector(ctx, s, spt, storiface.FTNone, types, storiface.PathStorage, storiface.AcquireMove) +func (st *Local) MoveStorage(ctx context.Context, s abi.SectorID, ssize abi.SectorSize, types storiface.SectorFileType) error { + dest, destIds, err := st.AcquireSector(ctx, s, ssize, storiface.FTNone, types, storiface.PathStorage, storiface.AcquireMove) if err != nil { return xerrors.Errorf("acquire dest storage: %w", err) } - src, srcIds, err := st.AcquireSector(ctx, s, spt, types, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) + src, srcIds, err := st.AcquireSector(ctx, s, ssize, types, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) if err != nil { return xerrors.Errorf("acquire src storage: %w", err) } diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index 42b63b05a..37dde910d 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -58,7 +58,7 @@ func NewRemote(local *Local, index SectorIndex, auth http.Header, fetchLimit int } } -func (r *Remote) AcquireSector(ctx context.Context, s abi.SectorID, spt abi.RegisteredSealProof, existing storiface.SectorFileType, allocate storiface.SectorFileType, pathType storiface.PathType, op storiface.AcquireMode) (storiface.SectorPaths, storiface.SectorPaths, error) { +func (r *Remote) AcquireSector(ctx context.Context, s abi.SectorID, ssize abi.SectorSize, existing storiface.SectorFileType, allocate storiface.SectorFileType, pathType storiface.PathType, op storiface.AcquireMode) (storiface.SectorPaths, storiface.SectorPaths, error) { if existing|allocate != existing^allocate { return storiface.SectorPaths{}, storiface.SectorPaths{}, xerrors.New("can't both find and allocate a sector") } @@ -90,7 +90,7 @@ func (r *Remote) AcquireSector(ctx context.Context, s abi.SectorID, spt abi.Regi r.fetchLk.Unlock() }() - paths, stores, err := r.local.AcquireSector(ctx, s, spt, existing, allocate, pathType, op) + paths, stores, err := r.local.AcquireSector(ctx, s, ssize, existing, allocate, pathType, op) if err != nil { return storiface.SectorPaths{}, storiface.SectorPaths{}, xerrors.Errorf("local acquire error: %w", err) } @@ -106,7 +106,7 @@ func (r *Remote) AcquireSector(ctx context.Context, s abi.SectorID, spt abi.Regi } } - apaths, ids, err := r.local.AcquireSector(ctx, s, spt, storiface.FTNone, toFetch, pathType, op) + apaths, ids, err := r.local.AcquireSector(ctx, s, ssize, storiface.FTNone, toFetch, pathType, op) if err != nil { return storiface.SectorPaths{}, storiface.SectorPaths{}, xerrors.Errorf("allocate local sector for fetching: %w", err) } @@ -116,7 +116,7 @@ func (r *Remote) AcquireSector(ctx context.Context, s abi.SectorID, spt abi.Regi odt = storiface.FsOverheadFinalized } - releaseStorage, err := r.local.Reserve(ctx, s, spt, toFetch, ids, odt) + releaseStorage, err := r.local.Reserve(ctx, s, ssize, toFetch, ids, odt) if err != nil { return storiface.SectorPaths{}, storiface.SectorPaths{}, xerrors.Errorf("reserving storage space: %w", err) } @@ -281,14 +281,14 @@ func (r *Remote) fetch(ctx context.Context, url, outname string) error { } } -func (r *Remote) MoveStorage(ctx context.Context, s abi.SectorID, spt abi.RegisteredSealProof, types storiface.SectorFileType) error { +func (r *Remote) MoveStorage(ctx context.Context, s abi.SectorID, ssize abi.SectorSize, types storiface.SectorFileType) error { // Make sure we have the data local - _, _, err := r.AcquireSector(ctx, s, spt, types, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) + _, _, err := r.AcquireSector(ctx, s, ssize, types, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) if err != nil { return xerrors.Errorf("acquire src storage (remote): %w", err) } - return r.local.MoveStorage(ctx, s, spt, types) + return r.local.MoveStorage(ctx, s, ssize, types) } func (r *Remote) Remove(ctx context.Context, sid abi.SectorID, typ storiface.SectorFileType, force bool) error { diff --git a/extern/sector-storage/storiface/filetype.go b/extern/sector-storage/storiface/filetype.go index c1ba733bc..3f7c7455e 100644 --- a/extern/sector-storage/storiface/filetype.go +++ b/extern/sector-storage/storiface/filetype.go @@ -55,12 +55,7 @@ func (t SectorFileType) Has(singleType SectorFileType) bool { return t&singleType == singleType } -func (t SectorFileType) SealSpaceUse(spt abi.RegisteredSealProof) (uint64, error) { - ssize, err := spt.SectorSize() - if err != nil { - return 0, xerrors.Errorf("getting sector size: %w", err) - } - +func (t SectorFileType) SealSpaceUse(ssize abi.SectorSize) (uint64, error) { var need uint64 for _, pathType := range PathTypes { if !t.Has(pathType) { diff --git a/extern/sector-storage/worker_local.go b/extern/sector-storage/worker_local.go index ec027b4e2..54b26b0ac 100644 --- a/extern/sector-storage/worker_local.go +++ b/extern/sector-storage/worker_local.go @@ -115,13 +115,17 @@ type localWorkerPathProvider struct { } func (l *localWorkerPathProvider) AcquireSector(ctx context.Context, sector abi.SectorID, existing storiface.SectorFileType, allocate storiface.SectorFileType, sealing storiface.PathType) (storiface.SectorPaths, func(), error) { - - paths, storageIDs, err := l.w.storage.AcquireSector(ctx, sector, l.w.scfg.SealProofType, existing, allocate, sealing, l.op) + ssize, err := l.w.scfg.SealProofType.SectorSize() if err != nil { return storiface.SectorPaths{}, nil, err } - releaseStorage, err := l.w.localStore.Reserve(ctx, sector, l.w.scfg.SealProofType, allocate, storageIDs, storiface.FSOverheadSeal) + paths, storageIDs, err := l.w.storage.AcquireSector(ctx, sector, ssize, existing, allocate, sealing, l.op) + if err != nil { + return storiface.SectorPaths{}, nil, err + } + + releaseStorage, err := l.w.localStore.Reserve(ctx, sector, ssize, allocate, storageIDs, storiface.FSOverheadSeal) if err != nil { return storiface.SectorPaths{}, nil, xerrors.Errorf("reserving storage space: %w", err) } @@ -404,7 +408,12 @@ func (l *LocalWorker) Remove(ctx context.Context, sector abi.SectorID) error { func (l *LocalWorker) MoveStorage(ctx context.Context, sector abi.SectorID, types storiface.SectorFileType) (storiface.CallID, error) { return l.asyncCall(ctx, sector, "MoveStorage", func(ctx context.Context, ci storiface.CallID) (interface{}, error) { - return nil, l.storage.MoveStorage(ctx, sector, l.scfg.SealProofType, types) + ssize, err := l.scfg.SealProofType.SectorSize() + if err != nil { + return nil, err + } + + return nil, l.storage.MoveStorage(ctx, sector, ssize, types) }) } diff --git a/extern/storage-sealing/checks.go b/extern/storage-sealing/checks.go index 1010d31b2..ed7a691ef 100644 --- a/extern/storage-sealing/checks.go +++ b/extern/storage-sealing/checks.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/policy" - proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "golang.org/x/xerrors" @@ -179,7 +179,7 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte, log.Warn("on-chain sealed CID doesn't match!") } - ok, err := m.verif.VerifySeal(proof0.SealVerifyInfo{ + ok, err := m.verif.VerifySeal(proof2.SealVerifyInfo{ SectorID: m.minerSector(si.SectorNumber), SealedCID: pci.Info.SealedCID, SealProof: spt, diff --git a/extern/storage-sealing/states_sealing.go b/extern/storage-sealing/states_sealing.go index 415335f68..d4e5535a2 100644 --- a/extern/storage-sealing/states_sealing.go +++ b/extern/storage-sealing/states_sealing.go @@ -255,7 +255,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf deposit := big.Max(depositMinimum, collateral) log.Infof("submitting precommit for sector %d (deposit: %s): ", sector.SectorNumber, deposit) - mcid, err := m.api.SendMsg(ctx.Context(), waddr, m.maddr, builtin0.MethodsMiner.PreCommitSector, deposit, m.feeCfg.MaxPreCommitGasFee, enc.Bytes()) + mcid, err := m.api.SendMsg(ctx.Context(), waddr, m.maddr, miner.Methods.PreCommitSector, deposit, m.feeCfg.MaxPreCommitGasFee, enc.Bytes()) if err != nil { if params.ReplaceCapacity { m.remarkForUpgrade(params.ReplaceSectorNumber) @@ -436,7 +436,7 @@ func (m *Sealing) handleSubmitCommit(ctx statemachine.Context, sector SectorInfo } // TODO: check seed / ticket / deals are up to date - mcid, err := m.api.SendMsg(ctx.Context(), waddr, m.maddr, builtin0.MethodsMiner.ProveCommitSector, collateral, m.feeCfg.MaxCommitGasFee, enc.Bytes()) + mcid, err := m.api.SendMsg(ctx.Context(), waddr, m.maddr, miner.Methods.ProveCommitSector, collateral, m.feeCfg.MaxCommitGasFee, enc.Bytes()) if err != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) } diff --git a/extern/storage-sealing/types.go b/extern/storage-sealing/types.go index 046271a7f..8f3e82a0b 100644 --- a/extern/storage-sealing/types.go +++ b/extern/storage-sealing/types.go @@ -9,9 +9,9 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/exitcode" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-storage/storage" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" ) @@ -82,7 +82,7 @@ type SectorInfo struct { CommR *cid.Cid Proof []byte - PreCommitInfo *miner0.SectorPreCommitInfo + PreCommitInfo *miner.SectorPreCommitInfo PreCommitDeposit big.Int PreCommitMessage *cid.Cid PreCommitTipSet TipSetToken diff --git a/extern/storage-sealing/types_test.go b/extern/storage-sealing/types_test.go index fc56620dc..0b3c97032 100644 --- a/extern/storage-sealing/types_test.go +++ b/extern/storage-sealing/types_test.go @@ -8,7 +8,7 @@ import ( cborutil "github.com/filecoin-project/go-cbor-util" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) func TestSectorInfoSelialization(t *testing.T) { @@ -22,7 +22,7 @@ func TestSectorInfoSelialization(t *testing.T) { }, } - dummyCid := builtin.AccountActorCodeID + dummyCid := builtin2.AccountActorCodeID si := &SectorInfo{ State: "stateful", diff --git a/genesis/types.go b/genesis/types.go index 79656feac..db8d32a3b 100644 --- a/genesis/types.go +++ b/genesis/types.go @@ -5,9 +5,10 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" + + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" ) type ActorType string @@ -21,7 +22,7 @@ type PreSeal struct { CommR cid.Cid CommD cid.Cid SectorID abi.SectorNumber - Deal market.DealProposal + Deal market2.DealProposal ProofType abi.RegisteredSealProof } diff --git a/go.mod b/go.mod index a6a074e49..98925e736 100644 --- a/go.mod +++ b/go.mod @@ -11,13 +11,14 @@ require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129 - github.com/cockroachdb/pebble v0.0.0-20200916222308-4e219a90ba5b + github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e + github.com/cockroachdb/pebble v0.0.0-20201001221639-879f3bfeef07 github.com/coreos/go-systemd/v22 v22.0.0 github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e github.com/dgraph-io/badger/v2 v2.2007.2 github.com/docker/go-units v0.4.0 - github.com/drand/drand v1.1.2-0.20200905144319-79c957281b32 - github.com/drand/kyber v1.1.2 + github.com/drand/drand v1.2.1 + github.com/drand/kyber v1.1.4 github.com/dustin/go-humanize v1.0.0 github.com/elastic/go-sysinfo v1.3.0 github.com/fatih/color v1.9.0 @@ -29,17 +30,17 @@ require ( github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v0.9.0 github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f - github.com/filecoin-project/go-fil-markets v0.9.1 + github.com/filecoin-project/go-fil-markets v1.0.0 github.com/filecoin-project/go-jsonrpc v0.1.2-0.20201008195726-68c6a2704e49 github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 - github.com/filecoin-project/go-state-types v0.0.0-20201003010437-c33112184a2b + github.com/filecoin-project/go-state-types v0.0.0-20201013222834-41ea465f274f github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.12 - github.com/filecoin-project/specs-actors/v2 v2.1.0 + github.com/filecoin-project/specs-actors/v2 v2.2.0 github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 github.com/filecoin-project/test-vectors/schema v0.0.5 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 @@ -66,7 +67,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.3.0 + github.com/ipfs/go-graphsync v0.3.1 github.com/ipfs/go-ipfs-blockstore v1.0.1 github.com/ipfs/go-ipfs-chunker v0.0.5 github.com/ipfs/go-ipfs-ds-help v1.0.0 @@ -80,6 +81,7 @@ require ( github.com/ipfs/go-log v1.0.4 github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4 github.com/ipfs/go-merkledag v0.3.2 + github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-path v0.0.7 github.com/ipfs/go-unixfs v0.2.4 github.com/ipfs/interface-go-ipfs-core v0.2.3 @@ -114,6 +116,7 @@ require ( github.com/multiformats/go-multihash v0.0.14 github.com/opentracing/opentracing-go v1.2.0 github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a + github.com/prometheus/client_golang v1.6.0 github.com/raulk/clock v1.1.0 github.com/stretchr/testify v1.6.1 github.com/supranational/blst v0.1.1 @@ -131,7 +134,7 @@ require ( go.uber.org/multierr v1.5.0 go.uber.org/zap v1.15.0 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 - golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 + golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 gopkg.in/cheggaaa/pb.v1 v1.0.28 diff --git a/go.sum b/go.sum index 4cf7b3628..f0ef4ea6b 100644 --- a/go.sum +++ b/go.sum @@ -91,6 +91,7 @@ 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/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 h1:OixPqDEcX3juo5AjQZAnFPbeUA0jvkp2qzB5gOZJ/L0= github.com/briandowns/spinner v1.11.1/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= @@ -120,8 +121,11 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -133,6 +137,8 @@ github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOi github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/cockroachdb/pebble v0.0.0-20200916222308-4e219a90ba5b h1:OKALTB609+19AM7wsO0k8yMwAqjEIppcnYvyIhA+ZlQ= github.com/cockroachdb/pebble v0.0.0-20200916222308-4e219a90ba5b/go.mod h1:hU7vhtrqonEphNF+xt8/lHdaBprxmV1h8BOGrd9XwmQ= +github.com/cockroachdb/pebble v0.0.0-20201001221639-879f3bfeef07 h1:Cb2pZUCFXlLA8i7My+wrN51D41GeuhYOKa1dJeZt6NY= +github.com/cockroachdb/pebble v0.0.0-20201001221639-879f3bfeef07/go.mod h1:hU7vhtrqonEphNF+xt8/lHdaBprxmV1h8BOGrd9XwmQ= github.com/cockroachdb/redact v0.0.0-20200622112456-cd282804bbd3 h1:2+dpIJzYMSbLi0587YXpi8tOJT52qCOI/1I0UNThc/I= github.com/cockroachdb/redact v0.0.0-20200622112456-cd282804bbd3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= @@ -191,14 +197,15 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/drand/bls12-381 v0.3.2 h1:RImU8Wckmx8XQx1tp1q04OV73J9Tj6mmpQLYDP7V1XE= github.com/drand/bls12-381 v0.3.2/go.mod h1:dtcLgPtYT38L3NO6mPDYH0nbpc5tjPassDqiniuAt4Y= -github.com/drand/drand v1.1.2-0.20200905144319-79c957281b32 h1:sU+51aQRaDxg0KnjQg19KuYRIxDBEUHffBAICSnBys8= -github.com/drand/drand v1.1.2-0.20200905144319-79c957281b32/go.mod h1:0sQEVg+ngs1jaDPVIiEgY0lbENWJPaUlWxGHEaSmKVM= +github.com/drand/drand v1.2.1 h1:KB7z+69YbnQ5z22AH/LMi0ObDR8DzYmrkS6vZXTR9jI= +github.com/drand/drand v1.2.1/go.mod h1:j0P7RGmVaY7E/OuO2yQOcQj7OgeZCuhgu2gdv0JAm+g= github.com/drand/kyber v1.0.1-0.20200110225416-8de27ed8c0e2/go.mod h1:UpXoA0Upd1N9l4TvRPHr1qAUBBERj6JQ/mnKI3BPEmw= github.com/drand/kyber v1.0.2/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw= -github.com/drand/kyber v1.1.2 h1:faemqlaFyLrbBSjZGRzzu5SG/do+uTYpHlnrJIHbAhQ= -github.com/drand/kyber v1.1.2/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw= -github.com/drand/kyber-bls12381 v0.1.0 h1:/P4C65VnyEwxzR5ZYYVMNzY1If+aYBrdUU5ukwh7LQw= -github.com/drand/kyber-bls12381 v0.1.0/go.mod h1:N1emiHpm+jj7kMlxEbu3MUyOiooTgNySln564cgD9mk= +github.com/drand/kyber v1.1.4 h1:YvKM03QWGvLrdTnYmxxP5iURAX+Gdb6qRDUOgg8i60Q= +github.com/drand/kyber v1.1.4/go.mod h1:9+IgTq7kadePhZg7eRwSD7+bA+bmvqRK+8DtmoV5a3U= +github.com/drand/kyber-bls12381 v0.2.0/go.mod h1:zQip/bHdeEB6HFZSU3v+d3cQE0GaBVQw9aR2E7AdoeI= +github.com/drand/kyber-bls12381 v0.2.1 h1:/d5/YAdaCmHpYjF1NZevOEcKGaq6LBbyvkCTIdGqDjs= +github.com/drand/kyber-bls12381 v0.2.1/go.mod h1:JwWn4nHO9Mp4F5qCie5sVIPQZ0X6cw8XAeMRvc/GXBE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -246,8 +253,8 @@ github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl 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 h1:GxJzR3oRIMTPtpZ0b7QF8FKPK6/iPAc7trhlL5k/g+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-markets v0.9.1 h1:MgO+UkpreD6x8DV2Zkw2xlBogixfpw9/wf4+nBii7bU= -github.com/filecoin-project/go-fil-markets v0.9.1/go.mod h1:h+bJ/IUnYjnW5HMKyt9JQSnhslqetkpuzwwugc3K8vM= +github.com/filecoin-project/go-fil-markets v1.0.0 h1:np9+tlnWXh9xYG4oZfha6HZFLYOaAZoMGR3V4w6DM48= +github.com/filecoin-project/go-fil-markets v1.0.0/go.mod h1:lXExJyYHwpMMddCqhEdNrc7euYJKNkp04K76NZqJLGg= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= 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= @@ -266,8 +273,8 @@ github.com/filecoin-project/go-state-types v0.0.0-20200903145444-247639ffa6ad/go github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab h1:cEDC5Ei8UuT99hPWhCjA72SM9AuRtnpvdSTIYbnzN8I= github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= -github.com/filecoin-project/go-state-types v0.0.0-20201003010437-c33112184a2b h1:bMUfG6Sy6YSMbsjQAO1Q2vEZldbSdsbRy/FX3OlTck0= -github.com/filecoin-project/go-state-types v0.0.0-20201003010437-c33112184a2b/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= +github.com/filecoin-project/go-state-types v0.0.0-20201013222834-41ea465f274f h1:TZDTu4MtBKSFLXWGKLy+cvC3nHfMFIrVgWLAz/+GgZQ= +github.com/filecoin-project/go-state-types v0.0.0-20201013222834-41ea465f274f/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ= @@ -278,8 +285,8 @@ github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07 github.com/filecoin-project/specs-actors v0.9.12 h1:iIvk58tuMtmloFNHhAOQHG+4Gci6Lui0n7DYQGi3cJk= github.com/filecoin-project/specs-actors v0.9.12/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.1.0 h1:ocEuGz8DG2cUWw32c/tvF8D6xT+dGVWJTr5yDevU00g= -github.com/filecoin-project/specs-actors/v2 v2.1.0/go.mod h1:E7fAX4CZkDVQvDNRCxfq+hc3nx56KcCKyuZf0hlQJ20= +github.com/filecoin-project/specs-actors/v2 v2.2.0 h1:IyCICb0NHYeD0sdSqjVGwWydn/7r7xXuxdpvGAcRCGY= +github.com/filecoin-project/specs-actors/v2 v2.2.0/go.mod h1:rlv5Mx9wUhV8Qsz+vUezZNm+zL4tK08O0HreKKPB2Wc= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg= @@ -376,6 +383,8 @@ 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 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/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= @@ -540,6 +549,8 @@ 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.3.0 h1:I6Y20kSuCWkUvPoUWo4V3am704/9QjgDVVkf0zIV8+8= github.com/ipfs/go-graphsync v0.3.0/go.mod h1:gEBvJUNelzMkaRPJTpg/jaKN4AQW/7wDWu0K92D8o10= +github.com/ipfs/go-graphsync v0.3.1 h1:dJLYrck4oyJDfMVhGEKiWHxaY8oYMWko4m2Fi+4bofo= +github.com/ipfs/go-graphsync v0.3.1/go.mod h1:bw4LiLM5Oq/uLdzEtih9LK8GrwSijv+XqYiWCTxHMqs= github.com/ipfs/go-hamt-ipld v0.1.1 h1:0IQdvwnAAUKmDE+PMJa5y1QiwOPHpI9+eAbQEEEYthk= 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= @@ -623,6 +634,8 @@ github.com/ipfs/go-merkledag v0.3.2 h1:MRqj40QkrWkvPswXs4EfSslhZ4RVPRbxwX11js0t1 github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZaGVF1CUVdE+s= +github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnzdSH3u5UVlCdqSXnEks= github.com/ipfs/go-path v0.0.3/go.mod h1:zIRQUez3LuQIU25zFjC2hpBTHimWx7VK5bjZgRLbbdo= github.com/ipfs/go-path v0.0.7 h1:H06hKMquQ0aYtHiHryOMLpQC1qC3QwXwkahcEVD51Ho= github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= @@ -705,6 +718,9 @@ github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dv github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f h1:qET3Wx0v8tMtoTOQnsJXVvqvCopSf48qobR6tcJuDHo= github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f/go.mod h1:XXfR6YFCRSrkEXbNlIyDsgXVNJWVUV30m/ebkVy9n6s= +github.com/kilic/bls12-381 v0.0.0-20200731194930-64c428e1bff5/go.mod h1:XXfR6YFCRSrkEXbNlIyDsgXVNJWVUV30m/ebkVy9n6s= +github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391 h1:51kHw7l/dUDdOdW06AlUGT5jnpj6nqQSILebcsikSjA= +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/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -1537,6 +1553,9 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= 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/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= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1691,6 +1710,9 @@ golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200812155832-6a926be9bd1d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c h1:38q6VNPWR010vN82/SB121GujZNIfAUb4YttE2rhGuc= +golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= @@ -1818,6 +1840,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/lib/blockstore/blockstore.go b/lib/blockstore/blockstore.go index f274cd708..99d849188 100644 --- a/lib/blockstore/blockstore.go +++ b/lib/blockstore/blockstore.go @@ -50,9 +50,16 @@ type GCLocker = blockstore.GCLocker var NewGCLocker = blockstore.NewGCLocker var NewGCBlockstore = blockstore.NewGCBlockstore -var DefaultCacheOpts = blockstore.DefaultCacheOpts var ErrNotFound = blockstore.ErrNotFound +func DefaultCacheOpts() CacheOpts { + return CacheOpts{ + HasBloomFilterSize: 0, + HasBloomFilterHashes: 0, + HasARCCacheSize: 512 << 10, + } +} + func CachedBlockstore(ctx context.Context, bs Blockstore, opts CacheOpts) (Blockstore, error) { bs, err := blockstore.CachedBlockstore(ctx, bs, opts) if err != nil { diff --git a/lib/timedbs/timedbs.go b/lib/timedbs/timedbs.go index bb03a59e9..c5c1a8fe0 100644 --- a/lib/timedbs/timedbs.go +++ b/lib/timedbs/timedbs.go @@ -8,6 +8,7 @@ import ( blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" + "github.com/raulk/clock" "go.uber.org/multierr" "github.com/filecoin-project/lotus/build" @@ -24,9 +25,10 @@ import ( type TimedCacheBS struct { mu sync.RWMutex active, inactive blockstore.MemStore - - interval time.Duration - closeCh chan struct{} + clock clock.Clock + interval time.Duration + closeCh chan struct{} + doneRotatingCh chan struct{} } func NewTimedCacheBS(cacheTime time.Duration) *TimedCacheBS { @@ -34,6 +36,7 @@ func NewTimedCacheBS(cacheTime time.Duration) *TimedCacheBS { active: blockstore.NewTemporary(), inactive: blockstore.NewTemporary(), interval: cacheTime, + clock: build.Clock, } } @@ -45,12 +48,15 @@ func (t *TimedCacheBS) Start(ctx context.Context) error { } t.closeCh = make(chan struct{}) go func() { - ticker := build.Clock.Ticker(t.interval) + ticker := t.clock.Ticker(t.interval) defer ticker.Stop() for { select { case <-ticker.C: t.rotate() + if t.doneRotatingCh != nil { + t.doneRotatingCh <- struct{}{} + } case <-t.closeCh: return } diff --git a/lib/timedbs/timedbs_test.go b/lib/timedbs/timedbs_test.go index 2126b9287..e01215bbd 100644 --- a/lib/timedbs/timedbs_test.go +++ b/lib/timedbs/timedbs_test.go @@ -1,21 +1,27 @@ -package timedbs_test +package timedbs import ( "context" "testing" "time" + "github.com/raulk/clock" "github.com/stretchr/testify/require" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/lib/timedbs" ) func TestTimedBSSimple(t *testing.T) { - tc := timedbs.NewTimedCacheBS(10 * time.Millisecond) + tc := NewTimedCacheBS(10 * time.Millisecond) + mClock := clock.NewMock() + mClock.Set(time.Now()) + tc.clock = mClock + tc.doneRotatingCh = make(chan struct{}) + _ = tc.Start(context.Background()) + mClock.Add(1) // IDK why it is needed but it makes it work + defer func() { _ = tc.Stop(context.Background()) }() @@ -36,7 +42,8 @@ func TestTimedBSSimple(t *testing.T) { require.NoError(t, err) require.True(t, has) - time.Sleep(15 * time.Millisecond) + mClock.Add(10 * time.Millisecond) + <-tc.doneRotatingCh // We should still have everything. has, err = tc.Has(b1.Cid()) @@ -60,8 +67,8 @@ func TestTimedBSSimple(t *testing.T) { require.NoError(t, err) require.ElementsMatch(t, ks, []cid.Cid{b1.Cid(), b2.Cid(), b3.Cid()}) - time.Sleep(10 * time.Millisecond) - + mClock.Add(10 * time.Millisecond) + <-tc.doneRotatingCh // should still have b2, and b3, but not b1 has, err = tc.Has(b1.Cid()) diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 6496fffad..f299dd4d5 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -6,20 +6,20 @@ import ( "bytes" "context" - "golang.org/x/xerrors" - - "github.com/ipfs/go-cid" - "github.com/filecoin-project/go-address" cborutil "github.com/filecoin-project/go-cbor-util" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + "github.com/filecoin-project/go-fil-markets/shared" "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/exitcode" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" + + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" @@ -27,8 +27,6 @@ import ( "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/events/state" "github.com/filecoin-project/lotus/chain/market" - "github.com/filecoin-project/lotus/chain/stmgr" - "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sigs" "github.com/filecoin-project/lotus/markets/utils" @@ -40,8 +38,6 @@ type ClientNodeAdapter struct { full.ChainAPI full.MpoolAPI - sm *stmgr.StateManager - cs *store.ChainStore fm *market.FundMgr ev *events.Events } @@ -51,14 +47,12 @@ type clientApi struct { full.StateAPI } -func NewClientNodeAdapter(state full.StateAPI, chain full.ChainAPI, mpool full.MpoolAPI, sm *stmgr.StateManager, cs *store.ChainStore, fm *market.FundMgr) storagemarket.StorageClientNode { +func NewClientNodeAdapter(state full.StateAPI, chain full.ChainAPI, mpool full.MpoolAPI, fm *market.FundMgr) storagemarket.StorageClientNode { return &ClientNodeAdapter{ StateAPI: state, ChainAPI: chain, MpoolAPI: mpool, - sm: sm, - cs: cs, fm: fm, ev: events.NewEvents(context.TODO(), &clientApi{chain, state}), } @@ -103,10 +97,10 @@ func (c *ClientNodeAdapter) VerifySignature(ctx context.Context, sig crypto.Sign func (c *ClientNodeAdapter) AddFunds(ctx context.Context, addr address.Address, amount abi.TokenAmount) (cid.Cid, error) { // (Provider Node API) smsg, err := c.MpoolPushMessage(ctx, &types.Message{ - To: miner0.StorageMarketActorAddr, + To: miner2.StorageMarketActorAddr, From: addr, Value: amount, - Method: miner0.MethodsMarket.AddBalance, + Method: miner2.MethodsMarket.AddBalance, }, nil) if err != nil { return cid.Undef, err @@ -138,12 +132,12 @@ func (c *ClientNodeAdapter) GetBalance(ctx context.Context, addr address.Address func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal storagemarket.ClientDeal) (abi.DealID, error) { log.Infow("DEAL ACCEPTED!") - pubmsg, err := c.cs.GetMessage(*deal.PublishMessage) + pubmsg, err := c.ChainGetMessage(ctx, *deal.PublishMessage) if err != nil { return 0, xerrors.Errorf("getting deal publish message: %w", err) } - mi, err := stmgr.StateMinerInfo(ctx, c.sm, c.cs.GetHeaviestTipSet(), deal.Proposal.Provider) + mi, err := c.StateMinerInfo(ctx, deal.Proposal.Provider, types.EmptyTSK) if err != nil { return 0, xerrors.Errorf("getting miner worker failed: %w", err) } @@ -157,15 +151,15 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor return 0, xerrors.Errorf("deal wasn't published by storage provider: from=%s, provider=%s", pubmsg.From, deal.Proposal.Provider) } - if pubmsg.To != miner0.StorageMarketActorAddr { + if pubmsg.To != miner2.StorageMarketActorAddr { return 0, xerrors.Errorf("deal publish message wasn't set to StorageMarket actor (to=%s)", pubmsg.To) } - if pubmsg.Method != miner0.MethodsMarket.PublishStorageDeals { + if pubmsg.Method != miner2.MethodsMarket.PublishStorageDeals { return 0, xerrors.Errorf("deal publish message called incorrect method (method=%s)", pubmsg.Method) } - var params market0.PublishStorageDealsParams + var params market2.PublishStorageDealsParams if err := params.UnmarshalCBOR(bytes.NewReader(pubmsg.Params)); err != nil { return 0, err } @@ -189,16 +183,16 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor } // TODO: timeout - _, ret, _, err := c.sm.WaitForMessage(ctx, *deal.PublishMessage, build.MessageConfidence, stmgr.LookbackNoLimit) + ret, err := c.StateWaitMsg(ctx, *deal.PublishMessage, build.MessageConfidence) if err != nil { return 0, xerrors.Errorf("waiting for deal publish message: %w", err) } - if ret.ExitCode != 0 { - return 0, xerrors.Errorf("deal publish failed: exit=%d", ret.ExitCode) + if ret.Receipt.ExitCode != 0 { + return 0, xerrors.Errorf("deal publish failed: exit=%d", ret.Receipt.ExitCode) } - var res market0.PublishStorageDealsReturn - if err := res.UnmarshalCBOR(bytes.NewReader(ret.Return)); err != nil { + var res market2.PublishStorageDealsReturn + if err := res.UnmarshalCBOR(bytes.NewReader(ret.Receipt.Return)); err != nil { return 0, err } @@ -218,7 +212,7 @@ func (c *ClientNodeAdapter) DealProviderCollateralBounds(ctx context.Context, si func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider address.Address, dealId abi.DealID, cb storagemarket.DealSectorCommittedCallback) error { checkFunc := func(ts *types.TipSet) (done bool, more bool, err error) { - sd, err := stmgr.GetStorageDeal(ctx, c.StateManager, dealId, ts) + sd, err := c.StateMarketStorageDeal(ctx, dealId, ts.Key()) if err != nil { // TODO: This may be fine for some errors @@ -245,7 +239,7 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider return false, nil } - sd, err := stmgr.GetStorageDeal(ctx, c.StateManager, dealId, ts) + sd, err := c.StateMarketStorageDeal(ctx, dealId, ts.Key()) if err != nil { return false, xerrors.Errorf("failed to look up deal on chain: %w", err) } @@ -275,7 +269,7 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider } switch msg.Method { - case miner0.MethodsMiner.PreCommitSector: + case miner2.MethodsMiner.PreCommitSector: var params miner.SectorPreCommitInfo if err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)); err != nil { return true, false, xerrors.Errorf("unmarshal pre commit: %w", err) @@ -290,7 +284,7 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider } return true, false, nil - case miner0.MethodsMiner.ProveCommitSector: + case miner2.MethodsMiner.ProveCommitSector: var params miner.ProveCommitSectorParams if err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)); err != nil { return true, false, xerrors.Errorf("failed to unmarshal prove commit sector params: %w", err) @@ -412,7 +406,7 @@ func (c *ClientNodeAdapter) OnDealExpiredOrSlashed(ctx context.Context, dealID a return nil } -func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Address, proposal market0.DealProposal) (*market0.ClientDealProposal, error) { +func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Address, proposal market2.DealProposal) (*market2.ClientDealProposal, error) { // TODO: output spec signed proposal buf, err := cborutil.Dump(&proposal) if err != nil { @@ -431,7 +425,7 @@ func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Add return nil, err } - return &market0.ClientDealProposal{ + return &market2.ClientDealProposal{ Proposal: proposal, ClientSignature: *sig, }, nil diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index b1071adcd..ce7c8e917 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -12,8 +12,7 @@ import ( logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/shared" @@ -79,8 +78,8 @@ func (n *ProviderNodeAdapter) PublishDeals(ctx context.Context, deal storagemark return cid.Undef, err } - params, err := actors.SerializeParams(&market0.PublishStorageDealsParams{ - Deals: []market0.ClientDealProposal{deal.ClientDealProposal}, + params, err := actors.SerializeParams(&market2.PublishStorageDealsParams{ + Deals: []market2.ClientDealProposal{deal.ClientDealProposal}, }) if err != nil { @@ -92,7 +91,7 @@ func (n *ProviderNodeAdapter) PublishDeals(ctx context.Context, deal storagemark To: market.Address, From: mi.Worker, Value: types.NewInt(0), - Method: builtin0.MethodsMarket.PublishStorageDeals, + Method: market.Methods.PublishStorageDeals, Params: params, }, n.publishSpec) if err != nil { @@ -192,7 +191,7 @@ func (n *ProviderNodeAdapter) AddFunds(ctx context.Context, addr address.Address To: market.Address, From: addr, Value: amount, - Method: builtin0.MethodsMarket.AddBalance, + Method: market.Methods.AddBalance, }, n.addBalanceSpec) if err != nil { return cid.Undef, err @@ -314,7 +313,7 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide } switch msg.Method { - case builtin0.MethodsMiner.PreCommitSector: + case miner.Methods.PreCommitSector: var params miner.SectorPreCommitInfo if err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)); err != nil { return true, false, xerrors.Errorf("unmarshal pre commit: %w", err) @@ -329,7 +328,7 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide } return true, false, nil - case builtin0.MethodsMiner.ProveCommitSector: + case miner.Methods.ProveCommitSector: var params miner.ProveCommitSectorParams if err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)); err != nil { return true, false, xerrors.Errorf("failed to unmarshal prove commit sector params: %w", err) diff --git a/metrics/metrics.go b/metrics/metrics.go index 5dd865263..33d9e9174 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -1,6 +1,7 @@ package metrics import ( + "context" "time" "go.opencensus.io/stats" @@ -24,6 +25,8 @@ var ( MessageTo, _ = tag.NewKey("message_to") MessageNonce, _ = tag.NewKey("message_nonce") ReceivedFrom, _ = tag.NewKey("received_from") + Endpoint, _ = tag.NewKey("endpoint") + APIInterface, _ = tag.NewKey("api") // to distinguish between gateway api and full node api endpoint calls ) // Measures @@ -49,6 +52,7 @@ var ( PubsubRecvRPC = stats.Int64("pubsub/recv_rpc", "Counter for total received RPCs", stats.UnitDimensionless) PubsubSendRPC = stats.Int64("pubsub/send_rpc", "Counter for total sent RPCs", stats.UnitDimensionless) PubsubDropRPC = stats.Int64("pubsub/drop_rpc", "Counter for total dropped RPCs", stats.UnitDimensionless) + APIRequestDuration = stats.Float64("api/request_duration_ms", "Duration of API requests", stats.UnitMilliseconds) ) var ( @@ -137,6 +141,11 @@ var ( Measure: PubsubDropRPC, Aggregation: view.Count(), } + APIRequestDurationView = &view.View{ + Measure: APIRequestDuration, + Aggregation: defaultMillisecondsDistribution, + TagKeys: []tag.Key{APIInterface, Endpoint}, + } ) // DefaultViews is an array of OpenCensus views for metric gathering purposes @@ -161,6 +170,7 @@ var DefaultViews = append([]*view.View{ PubsubRecvRPCView, PubsubSendRPCView, PubsubDropRPCView, + APIRequestDurationView, }, rpcmetrics.DefaultViews...) @@ -168,3 +178,12 @@ var DefaultViews = append([]*view.View{ func SinceInMilliseconds(startTime time.Time) float64 { return float64(time.Since(startTime).Nanoseconds()) / 1e6 } + +// Timer is a function stopwatch, calling it starts the timer, +// calling the returned function will record the duration. +func Timer(ctx context.Context, m *stats.Float64Measure) func() { + start := time.Now() + return func() { + stats.Record(ctx, m.M(SinceInMilliseconds(start))) + } +} diff --git a/metrics/proxy.go b/metrics/proxy.go new file mode 100644 index 000000000..f3714ec2e --- /dev/null +++ b/metrics/proxy.go @@ -0,0 +1,65 @@ +package metrics + +import ( + "context" + "reflect" + + "go.opencensus.io/tag" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/apistruct" +) + +func MetricedStorMinerAPI(a api.StorageMiner) api.StorageMiner { + var out apistruct.StorageMinerStruct + proxy(a, &out.Internal) + proxy(a, &out.CommonStruct.Internal) + return &out +} + +func MetricedFullAPI(a api.FullNode) api.FullNode { + var out apistruct.FullNodeStruct + proxy(a, &out.Internal) + proxy(a, &out.CommonStruct.Internal) + return &out +} + +func MetricedWorkerAPI(a api.WorkerAPI) api.WorkerAPI { + var out apistruct.WorkerStruct + proxy(a, &out.Internal) + return &out +} + +func MetricedWalletAPI(a api.WalletAPI) api.WalletAPI { + var out apistruct.WalletStruct + proxy(a, &out.Internal) + return &out +} + +func MetricedGatewayAPI(a api.GatewayAPI) api.GatewayAPI { + var out apistruct.GatewayStruct + proxy(a, &out.Internal) + return &out +} + +func proxy(in interface{}, out interface{}) { + rint := reflect.ValueOf(out).Elem() + ra := reflect.ValueOf(in) + + for f := 0; f < rint.NumField(); f++ { + field := rint.Type().Field(f) + fn := ra.MethodByName(field.Name) + + rint.Field(f).Set(reflect.MakeFunc(field.Type, func(args []reflect.Value) (results []reflect.Value) { + ctx := args[0].Interface().(context.Context) + // upsert function name into context + ctx, _ = tag.New(ctx, tag.Upsert(Endpoint, field.Name)) + stop := Timer(ctx, APIRequestDuration) + defer stop() + // pass tagged ctx back into function call + args[0] = reflect.ValueOf(ctx) + return fn.Call(args) + })) + + } +} diff --git a/miner/miner.go b/miner/miner.go index 73985a649..f2468a911 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -9,7 +9,7 @@ import ( "sync" "time" - proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/filecoin-project/lotus/chain/gen/slashfilter" @@ -280,7 +280,7 @@ minerLoop: m.minedBlockHeights.Add(blkKey, true) if err := m.api.SyncSubmitBlock(ctx, b); err != nil { - log.Errorf("failed to submit newly mined block: %s", err) + log.Errorf("failed to submit newly mined block: %+v", err) } } else { base.NullRounds++ @@ -386,7 +386,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, rbase = bvals[len(bvals)-1] } - ticket, err := m.computeTicket(ctx, &rbase, base) + ticket, err := m.computeTicket(ctx, &rbase, base, mbi) if err != nil { return nil, xerrors.Errorf("scratching ticket failed: %w", err) } @@ -456,16 +456,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, return b, nil } -func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, base *MiningBase) (*types.Ticket, error) { - mi, err := m.api.StateMinerInfo(ctx, m.address, types.EmptyTSK) - if err != nil { - return nil, err - } - worker, err := m.api.StateAccountKey(ctx, mi.Worker, types.EmptyTSK) - if err != nil { - return nil, err - } - +func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, base *MiningBase, mbi *api.MiningBaseInfo) (*types.Ticket, error) { buf := new(bytes.Buffer) if err := m.address.MarshalCBOR(buf); err != nil { return nil, xerrors.Errorf("failed to marshal address to cbor: %w", err) @@ -481,7 +472,7 @@ func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, bas return nil, err } - vrfOut, err := gen.ComputeVRF(ctx, m.api.WalletSign, worker, input) + vrfOut, err := gen.ComputeVRF(ctx, m.api.WalletSign, mbi.WorkerKey, input) if err != nil { return nil, err } @@ -492,7 +483,7 @@ func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, bas } func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *types.Ticket, - eproof *types.ElectionProof, bvals []types.BeaconEntry, wpostProof []proof0.PoStProof, msgs []*types.SignedMessage) (*types.BlockMsg, error) { + eproof *types.ElectionProof, bvals []types.BeaconEntry, wpostProof []proof2.PoStProof, msgs []*types.SignedMessage) (*types.BlockMsg, error) { uts := base.TipSet.MinTimestamp() + build.BlockDelaySecs*(uint64(base.NullRounds)+1) nheight := base.TipSet.Height() + base.NullRounds + 1 diff --git a/node/builder.go b/node/builder.go index dcff54e2b..bb039cb76 100644 --- a/node/builder.go +++ b/node/builder.go @@ -251,7 +251,6 @@ func Online() Option { Override(new(*store.ChainStore), modules.ChainStore), Override(new(stmgr.UpgradeSchedule), stmgr.DefaultUpgradeSchedule()), Override(new(*stmgr.StateManager), stmgr.NewStateManagerWithUpgradeSchedule), - Override(new(stmgr.StateManagerAPI), From(new(*stmgr.StateManager))), Override(new(*wallet.LocalWallet), wallet.NewWallet), Override(new(wallet.Default), From(new(*wallet.LocalWallet))), Override(new(api.WalletAPI), From(new(wallet.MultiWallet))), diff --git a/node/impl/client/client.go b/node/impl/client/client.go index f04d310ce..37a24998e 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -65,9 +65,9 @@ type API struct { fx.In full.ChainAPI - full.StateAPI full.WalletAPI paych.PaychAPI + full.StateAPI SMDealClient storagemarket.StorageClient RetDiscovery discovery.PeerResolver @@ -117,7 +117,7 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams) } } - walletKey, err := a.StateAPI.StateManager.ResolveToKeyAddress(ctx, params.Wallet, nil) + walletKey, err := a.StateAccountKey(ctx, params.Wallet, types.EmptyTSK) if err != nil { return nil, xerrors.Errorf("failed resolving params.Wallet addr: %w", params.Wallet) } @@ -878,3 +878,12 @@ func newDealInfo(v storagemarket.ClientDeal) api.DealInfo { func (a *API) ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error { return a.Retrieval.TryRestartInsufficientFunds(paymentChannel) } + +func (a *API) ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error) { + ststr, ok := storagemarket.DealStates[statusCode] + if !ok { + return "", fmt.Errorf("no such deal state %d", statusCode) + } + + return ststr, nil +} diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 095b51ed8..a3410b8db 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -40,8 +40,11 @@ import ( var log = logging.Logger("fullnode") type ChainModuleAPI interface { + ChainNotify(context.Context) (<-chan []*api.HeadChange, error) + ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainHasObj(context.Context, cid.Cid) (bool, error) ChainHead(context.Context) (*types.TipSet, error) + ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) @@ -67,8 +70,8 @@ type ChainAPI struct { Chain *store.ChainStore } -func (a *ChainAPI) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, error) { - return a.Chain.SubHeadChanges(ctx), nil +func (m *ChainModule) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, error) { + return m.Chain.SubHeadChanges(ctx), nil } func (m *ChainModule) ChainHead(context.Context) (*types.TipSet, error) { @@ -101,13 +104,13 @@ func (m *ChainModule) ChainGetTipSet(ctx context.Context, key types.TipSetKey) ( return m.Chain.LoadTipSet(key) } -func (a *ChainAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) (*api.BlockMessages, error) { - b, err := a.Chain.GetBlock(msg) +func (m *ChainModule) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) (*api.BlockMessages, error) { + b, err := m.Chain.GetBlock(msg) if err != nil { return nil, err } - bmsgs, smsgs, err := a.Chain.MessagesForBlock(b) + bmsgs, smsgs, err := m.Chain.MessagesForBlock(b) if err != nil { return nil, err } @@ -532,8 +535,8 @@ func (a *ChainAPI) ChainGetNode(ctx context.Context, p string) (*api.IpldObject, }, nil } -func (a *ChainAPI) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) { - cm, err := a.Chain.GetCMessage(mc) +func (m *ChainModule) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) { + cm, err := m.Chain.GetCMessage(mc) if err != nil { return nil, err } diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index 2e5063ccb..e0cbd2192 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -7,6 +7,7 @@ import ( "sort" "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "go.uber.org/fx" "golang.org/x/xerrors" @@ -16,8 +17,6 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/exitcode" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/messagepool" @@ -259,7 +258,7 @@ func gasEstimateGasLimit( if !builtin.IsPaymentChannelActor(act.Code) { return res.MsgRct.GasUsed, nil } - if msgIn.Method != builtin0.MethodsPaych.Collect { + if msgIn.Method != paych.Methods.Collect { return res.MsgRct.GasUsed, nil } diff --git a/node/impl/full/mpool.go b/node/impl/full/mpool.go index 8ad209f3f..b1e9f94f9 100644 --- a/node/impl/full/mpool.go +++ b/node/impl/full/mpool.go @@ -187,6 +187,42 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spe }) } +func (a *MpoolAPI) MpoolBatchPush(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) { + var messageCids []cid.Cid + for _, smsg := range smsgs { + smsgCid, err := a.Mpool.Push(smsg) + if err != nil { + return messageCids, err + } + messageCids = append(messageCids, smsgCid) + } + return messageCids, nil +} + +func (a *MpoolAPI) MpoolBatchPushUntrusted(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) { + var messageCids []cid.Cid + for _, smsg := range smsgs { + smsgCid, err := a.Mpool.PushUntrusted(smsg) + if err != nil { + return messageCids, err + } + messageCids = append(messageCids, smsgCid) + } + return messageCids, nil +} + +func (a *MpoolAPI) MpoolBatchPushMessage(ctx context.Context, msgs []*types.Message, spec *api.MessageSendSpec) ([]*types.SignedMessage, error) { + var smsgs []*types.SignedMessage + for _, msg := range msgs { + smsg, err := a.MpoolPushMessage(ctx, msg, spec) + if err != nil { + return smsgs, err + } + smsgs = append(smsgs, smsg) + } + return smsgs, nil +} + func (a *MpoolAPI) MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error) { return a.Mpool.GetNonce(addr) } diff --git a/node/impl/full/multisig.go b/node/impl/full/multisig.go index d840620eb..9c5f683c4 100644 --- a/node/impl/full/multisig.go +++ b/node/impl/full/multisig.go @@ -12,8 +12,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/types" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" "github.com/ipfs/go-cid" "go.uber.org/fx" @@ -85,7 +84,7 @@ func (a *MsigAPI) MsigAddPropose(ctx context.Context, msig address.Address, src return cid.Undef, actErr } - return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(builtin0.MethodsMultisig.AddSigner), enc) + return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc) } func (a *MsigAPI) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) { @@ -94,7 +93,7 @@ func (a *MsigAPI) MsigAddApprove(ctx context.Context, msig address.Address, src return cid.Undef, actErr } - return a.MsigApproveTxnHash(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(builtin0.MethodsMultisig.AddSigner), enc) + return a.MsigApproveTxnHash(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc) } func (a *MsigAPI) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) { @@ -103,7 +102,7 @@ func (a *MsigAPI) MsigAddCancel(ctx context.Context, msig address.Address, src a return cid.Undef, actErr } - return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(builtin0.MethodsMultisig.AddSigner), enc) + return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc) } func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) { @@ -112,7 +111,7 @@ func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src return cid.Undef, actErr } - return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(builtin0.MethodsMultisig.SwapSigner), enc) + return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc) } func (a *MsigAPI) MsigSwapApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) { @@ -121,7 +120,7 @@ func (a *MsigAPI) MsigSwapApprove(ctx context.Context, msig address.Address, src return cid.Undef, actErr } - return a.MsigApproveTxnHash(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(builtin0.MethodsMultisig.SwapSigner), enc) + return a.MsigApproveTxnHash(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc) } func (a *MsigAPI) MsigSwapCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) { @@ -130,7 +129,7 @@ func (a *MsigAPI) MsigSwapCancel(ctx context.Context, msig address.Address, src return cid.Undef, actErr } - return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(builtin0.MethodsMultisig.SwapSigner), enc) + return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc) } func (a *MsigAPI) MsigApprove(ctx context.Context, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) { @@ -151,7 +150,7 @@ func (a *MsigAPI) MsigRemoveSigner(ctx context.Context, msig address.Address, pr return cid.Undef, actErr } - return a.MsigPropose(ctx, msig, msig, types.NewInt(0), proposer, uint64(builtin0.MethodsMultisig.RemoveSigner), enc) + return a.MsigPropose(ctx, msig, msig, types.NewInt(0), proposer, uint64(multisig.Methods.RemoveSigner), enc) } func (a *MsigAPI) msigApproveOrCancelSimple(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) { @@ -242,7 +241,7 @@ func (a *MsigAPI) msigApproveOrCancelTxnHash(ctx context.Context, operation api. } func serializeAddParams(new address.Address, inc bool) ([]byte, error) { - enc, actErr := actors.SerializeParams(&multisig0.AddSignerParams{ + enc, actErr := actors.SerializeParams(&multisig2.AddSignerParams{ Signer: new, Increase: inc, }) @@ -254,7 +253,7 @@ func serializeAddParams(new address.Address, inc bool) ([]byte, error) { } func serializeSwapParams(old address.Address, new address.Address) ([]byte, error) { - enc, actErr := actors.SerializeParams(&multisig0.SwapSignerParams{ + enc, actErr := actors.SerializeParams(&multisig2.SwapSignerParams{ From: old, To: new, }) @@ -266,7 +265,7 @@ func serializeSwapParams(old address.Address, new address.Address) ([]byte, erro } func serializeRemoveParams(rem address.Address, dec bool) ([]byte, error) { - enc, actErr := actors.SerializeParams(&multisig0.RemoveSignerParams{ + enc, actErr := actors.SerializeParams(&multisig2.RemoveSignerParams{ Signer: rem, Decrease: dec, }) diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 43efd3d6a..9a6c772ae 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -40,12 +40,22 @@ import ( ) type StateModuleAPI interface { - StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) - StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) - StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) - StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, 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) + 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, tsk types.TipSetKey) (*types.Actor, error) + StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) + StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) + StateLookupID(ctx context.Context, addr address.Address, 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) + StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) + StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) + StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) + StateNetworkVersion(ctx context.Context, key types.TipSetKey) (network.Version, error) + StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) + StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) } // StateModule provides a default implementation of StateModuleAPI. @@ -112,13 +122,13 @@ func (a *StateAPI) StateMinerActiveSectors(ctx context.Context, maddr address.Ad return stmgr.GetMinerSectorSet(ctx, a.StateManager, ts, maddr, &activeSectors) } -func (a *StateAPI) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) { - act, err := a.StateManager.LoadActorTsk(ctx, actor, tsk) +func (m *StateModule) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) { + act, err := m.StateManager.LoadActorTsk(ctx, actor, tsk) if err != nil { return miner.MinerInfo{}, xerrors.Errorf("failed to load miner actor: %w", err) } - mas, err := miner.Load(a.StateManager.ChainStore().Store(ctx), act) + mas, err := miner.Load(m.StateManager.ChainStore().Store(ctx), act) if err != nil { return miner.MinerInfo{}, xerrors.Errorf("failed to load miner actor state: %w", err) } @@ -215,18 +225,18 @@ func (a *StateAPI) StateMinerPartitions(ctx context.Context, m address.Address, return out, err } -func (a *StateAPI) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) { - ts, err := a.StateManager.ChainStore().GetTipSetFromKey(tsk) +func (m *StateModule) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - act, err := a.StateManager.LoadActor(ctx, addr, ts) + act, err := m.StateManager.LoadActor(ctx, addr, ts) if err != nil { return nil, xerrors.Errorf("failed to load miner actor: %w", err) } - mas, err := miner.Load(a.StateManager.ChainStore().Store(ctx), act) + mas, err := miner.Load(m.StateManager.ChainStore().Store(ctx), act) if err != nil { return nil, xerrors.Errorf("failed to load miner actor state: %w", err) } @@ -310,19 +320,19 @@ func (a *StateAPI) StateMinerRecoveries(ctx context.Context, addr address.Addres return miner.AllPartSectors(mas, miner.Partition.RecoveringSectors) } -func (a *StateAPI) StateMinerPower(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*api.MinerPower, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) +func (m *StateModule) StateMinerPower(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*api.MinerPower, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - m, net, hmp, err := stmgr.GetPower(ctx, a.StateManager, ts, addr) + mp, net, hmp, err := stmgr.GetPower(ctx, m.StateManager, ts, addr) if err != nil { return nil, err } return &api.MinerPower{ - MinerPower: m, + MinerPower: mp, TotalPower: net, HasMinPower: hmp, }, nil @@ -349,6 +359,7 @@ func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, tsk types. func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.Cid) (*api.InvocResult, error) { msgToReplay := mc var ts *types.TipSet + var err error if tsk == types.EmptyTSK { mlkp, err := a.StateSearchMsg(ctx, mc) if err != nil { @@ -370,7 +381,10 @@ func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid. return nil, xerrors.Errorf("loading parent tipset %s: %w", mlkp.TipSet, err) } } else { - ts = a.Chain.GetHeaviestTipSet() + ts, err = a.Chain.LoadTipSet(tsk) + if err != nil { + return nil, xerrors.Errorf("loading specified tipset %s: %w", tsk, err) + } } m, r, err := a.StateManager.Replay(ctx, ts, msgToReplay) @@ -559,20 +573,20 @@ func (a *StateAPI) StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLoo return nil, nil } -func (a *StateAPI) StateGetReceipt(ctx context.Context, msg cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) +func (m *StateModule) StateGetReceipt(ctx context.Context, msg cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return a.StateManager.GetReceipt(ctx, msg, ts) + return m.StateManager.GetReceipt(ctx, msg, ts) } -func (a *StateAPI) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) +func (m *StateModule) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return stmgr.ListMinerActors(ctx, a.StateManager, ts) + return stmgr.ListMinerActors(ctx, m.StateManager, ts) } func (a *StateAPI) StateListActors(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { @@ -583,12 +597,12 @@ func (a *StateAPI) StateListActors(ctx context.Context, tsk types.TipSetKey) ([] return a.StateManager.ListAllActors(ctx, ts) } -func (a *StateAPI) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) +func (m *StateModule) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return api.MarketBalance{}, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return a.StateManager.MarketBalance(ctx, addr, ts) + return m.StateManager.MarketBalance(ctx, addr, ts) } func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSetKey) (map[string]api.MarketBalance, error) { @@ -672,12 +686,12 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (m return out, nil } -func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) +func (m *StateModule) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return stmgr.GetStorageDeal(ctx, a.StateManager, dealId, ts) + return stmgr.GetStorageDeal(ctx, m.StateManager, dealId, ts) } func (a *StateAPI) StateChangedActors(ctx context.Context, old cid.Cid, new cid.Cid) (map[string]types.Actor, error) { @@ -1173,19 +1187,19 @@ func (a *StateAPI) StateVerifierStatus(ctx context.Context, addr address.Address // StateVerifiedClientStatus returns the data cap for the given address. // Returns zero if there is no entry in the data cap table for the // address. -func (a *StateAPI) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) { - act, err := a.StateGetActor(ctx, verifreg.Address, tsk) +func (m *StateModule) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) { + act, err := m.StateGetActor(ctx, verifreg.Address, tsk) if err != nil { return nil, err } - aid, err := a.StateLookupID(ctx, addr, tsk) + aid, err := m.StateLookupID(ctx, addr, tsk) if err != nil { log.Warnf("lookup failure %v", err) return nil, err } - vrs, err := verifreg.Load(a.StateManager.ChainStore().Store(ctx), act) + vrs, err := verifreg.Load(m.StateManager.ChainStore().Store(ctx), act) if err != nil { return nil, xerrors.Errorf("failed to load verified registry state: %w", err) } @@ -1220,33 +1234,33 @@ var dealProviderCollateralDen = types.NewInt(100) // StateDealProviderCollateralBounds returns the min and max collateral a storage provider // can issue. It takes the deal size and verified status as parameters. -func (a *StateAPI) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) +func (m *StateModule) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return api.DealCollateralBounds{}, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - pact, err := a.StateGetActor(ctx, power.Address, tsk) + pact, err := m.StateGetActor(ctx, power.Address, tsk) if err != nil { return api.DealCollateralBounds{}, xerrors.Errorf("failed to load power actor: %w", err) } - ract, err := a.StateGetActor(ctx, reward.Address, tsk) + ract, err := m.StateGetActor(ctx, reward.Address, tsk) if err != nil { return api.DealCollateralBounds{}, xerrors.Errorf("failed to load reward actor: %w", err) } - pst, err := power.Load(a.StateManager.ChainStore().Store(ctx), pact) + pst, err := power.Load(m.StateManager.ChainStore().Store(ctx), pact) if err != nil { return api.DealCollateralBounds{}, xerrors.Errorf("failed to load power actor state: %w", err) } - rst, err := reward.Load(a.StateManager.ChainStore().Store(ctx), ract) + rst, err := reward.Load(m.StateManager.ChainStore().Store(ctx), ract) if err != nil { return api.DealCollateralBounds{}, xerrors.Errorf("failed to load reward actor state: %w", err) } - circ, err := a.StateVMCirculatingSupplyInternal(ctx, ts.Key()) + circ, err := stateVMCirculatingSupplyInternal(ctx, ts.Key(), m.Chain, m.StateManager) if err != nil { return api.DealCollateralBounds{}, xerrors.Errorf("getting total circulating supply: %w", err) } @@ -1267,7 +1281,7 @@ func (a *StateAPI) StateDealProviderCollateralBounds(ctx context.Context, size a powClaim.QualityAdjPower, rewPow, circ.FilCirculating, - a.StateManager.GetNtwkVersion(ctx, ts.Height())) + m.StateManager.GetNtwkVersion(ctx, ts.Height())) return api.DealCollateralBounds{ Min: types.BigDiv(types.BigMul(min, dealProviderCollateralNum), dealProviderCollateralDen), Max: max, @@ -1288,23 +1302,32 @@ func (a *StateAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSetK } func (a *StateAPI) StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) + return stateVMCirculatingSupplyInternal(ctx, tsk, a.Chain, a.StateManager) +} +func stateVMCirculatingSupplyInternal( + ctx context.Context, + tsk types.TipSetKey, + cstore *store.ChainStore, + smgr *stmgr.StateManager, +) (api.CirculatingSupply, error) { + ts, err := cstore.GetTipSetFromKey(tsk) if err != nil { return api.CirculatingSupply{}, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - sTree, err := a.stateForTs(ctx, ts) + sTree, err := stateForTs(ctx, ts, cstore, smgr) if err != nil { return api.CirculatingSupply{}, err } - return a.StateManager.GetVMCirculatingSupplyDetailed(ctx, ts.Height(), sTree) + + return smgr.GetVMCirculatingSupplyDetailed(ctx, ts.Height(), sTree) } -func (a *StateAPI) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) +func (m *StateModule) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return network.VersionMax, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return a.StateManager.GetNtwkVersion(ctx, ts.Height()), nil + return m.StateManager.GetNtwkVersion(ctx, ts.Height()), nil } diff --git a/node/impl/paych/paych.go b/node/impl/paych/paych.go index af0a1db15..773a5efab 100644 --- a/node/impl/paych/paych.go +++ b/node/impl/paych/paych.go @@ -13,17 +13,12 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/types" - full "github.com/filecoin-project/lotus/node/impl/full" "github.com/filecoin-project/lotus/paychmgr" ) type PaychAPI struct { fx.In - full.MpoolAPI - full.WalletAPI - full.ChainAPI - PaychMgr *paychmgr.Manager } diff --git a/node/modules/chain.go b/node/modules/chain.go index ce3e9f749..d1414b307 100644 --- a/node/modules/chain.go +++ b/node/modules/chain.go @@ -168,14 +168,19 @@ func SetGenesis(cs *store.ChainStore, g Genesis) (dtypes.AfterGenesisSet, error) return dtypes.AfterGenesisSet{}, cs.SetGenesis(genesis) } -func NetworkName(mctx helpers.MetricsCtx, lc fx.Lifecycle, cs *store.ChainStore, _ dtypes.AfterGenesisSet) (dtypes.NetworkName, error) { +func NetworkName(mctx helpers.MetricsCtx, lc fx.Lifecycle, cs *store.ChainStore, us stmgr.UpgradeSchedule, _ dtypes.AfterGenesisSet) (dtypes.NetworkName, error) { if !build.Devnet { return "testnetnet", nil } ctx := helpers.LifecycleCtx(mctx, lc) - netName, err := stmgr.GetNetworkName(ctx, stmgr.NewStateManager(cs), cs.GetHeaviestTipSet().ParentState()) + sm, err := stmgr.NewStateManagerWithUpgradeSchedule(cs, us) + if err != nil { + return "", err + } + + netName, err := stmgr.GetNetworkName(ctx, sm, cs.GetHeaviestTipSet().ParentState()) return netName, err } diff --git a/node/modules/rpcstatemanager.go b/node/modules/rpcstatemanager.go index 0ed054d45..7d7b92437 100644 --- a/node/modules/rpcstatemanager.go +++ b/node/modules/rpcstatemanager.go @@ -3,19 +3,40 @@ package modules import ( "context" - "github.com/filecoin-project/lotus/api" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/apibstore" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" + cbor "github.com/ipfs/go-ipld-cbor" ) type RPCStateManager struct { - gapi api.GatewayAPI + gapi api.GatewayAPI + cstore *cbor.BasicIpldStore } func NewRPCStateManager(api api.GatewayAPI) *RPCStateManager { - return &RPCStateManager{gapi: api} + cstore := cbor.NewCborStore(apibstore.NewAPIBlockstore(api)) + return &RPCStateManager{gapi: api, cstore: cstore} +} + +func (s *RPCStateManager) GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error) { + act, err := s.gapi.StateGetActor(ctx, addr, ts.Key()) + if err != nil { + return nil, nil, err + } + + actState, err := paych.Load(adt.WrapStore(ctx, s.cstore), act) + if err != nil { + return nil, nil, err + } + return act, actState, nil + } func (s *RPCStateManager) LoadActorTsk(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) { @@ -30,4 +51,8 @@ func (s *RPCStateManager) ResolveToKeyAddress(ctx context.Context, addr address. return s.gapi.StateAccountKey(ctx, addr, ts.Key()) } +func (s *RPCStateManager) Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) { + return nil, xerrors.Errorf("RPCStateManager does not implement StateManager.Call") +} + var _ stmgr.StateManagerAPI = (*RPCStateManager)(nil) diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 9040a91a4..cda82e4be 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -45,7 +45,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-statestore" "github.com/filecoin-project/go-storedcounter" - "github.com/filecoin-project/specs-actors/actors/builtin" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" @@ -55,6 +54,7 @@ import ( lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen/slashfilter" "github.com/filecoin-project/lotus/chain/types" @@ -399,8 +399,6 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat if err != nil { return nil, err } - a := storedAsk.GetAsk().Ask - err = storedAsk.SetAsk(a.Price, a.VerifiedPrice, a.Expiry-a.Timestamp) if err != nil { return storedAsk, err } diff --git a/node/test/builder.go b/node/test/builder.go index 4aa8a55ea..ea9a82220 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -24,6 +24,8 @@ import ( "github.com/filecoin-project/lotus/api/test" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/gen" genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis" "github.com/filecoin-project/lotus/chain/types" @@ -33,14 +35,13 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/lotus/extern/sector-storage/mock" "github.com/filecoin-project/lotus/genesis" - miner2 "github.com/filecoin-project/lotus/miner" + lotusminer "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/modules" testing2 "github.com/filecoin-project/lotus/node/modules/testing" "github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/storage/mockstorage" - "github.com/filecoin-project/specs-actors/actors/builtin" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" "github.com/ipfs/go-datastore" "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" @@ -86,13 +87,13 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr peerid, err := peer.IDFromPrivateKey(pk) require.NoError(t, err) - enc, err := actors.SerializeParams(&miner0.ChangePeerIDParams{NewID: abi.PeerID(peerid)}) + enc, err := actors.SerializeParams(&miner2.ChangePeerIDParams{NewID: abi.PeerID(peerid)}) require.NoError(t, err) msg := &types.Message{ To: act, From: waddr, - Method: builtin.MethodsMiner.ChangePeerID, + Method: miner.Methods.ChangePeerID, Params: enc, Value: types.NewInt(0), } @@ -103,7 +104,7 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr // start node var minerapi api.StorageMiner - mineBlock := make(chan miner2.MineReq) + mineBlock := make(chan lotusminer.MineReq) stop, err := node.New(ctx, node.StorageMiner(&minerapi), node.Online(), @@ -113,7 +114,7 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr node.MockHost(mn), node.Override(new(api.FullNode), tnd), - node.Override(new(*miner2.Miner), miner2.NewTestMiner(mineBlock, act)), + node.Override(new(*lotusminer.Miner), lotusminer.NewTestMiner(mineBlock, act)), opts, ) @@ -129,7 +130,7 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr err = minerapi.NetConnect(ctx, remoteAddrs) require.NoError(t, err)*/ - mineOne := func(ctx context.Context, req miner2.MineReq) error { + mineOne := func(ctx context.Context, req lotusminer.MineReq) error { select { case mineBlock <- req: return nil @@ -444,7 +445,7 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes storers[i] = CreateTestStorageNode(ctx, t, genms[i].Worker, maddrs[i], pidKeys[i], f, mn, node.Options( node.Override(new(sectorstorage.SectorManager), func() (sectorstorage.SectorManager, error) { - return mock.NewMockSectorMgr(build.DefaultSectorSize(), sectors), nil + return mock.NewMockSectorMgr(policy.GetDefaultSectorSize(), sectors), nil }), node.Override(new(ffiwrapper.Verifier), mock.MockVerifier), node.Unset(new(*sectorstorage.Manager)), diff --git a/paychmgr/manager.go b/paychmgr/manager.go index f2fc190c7..5e0aa88ce 100644 --- a/paychmgr/manager.go +++ b/paychmgr/manager.go @@ -16,7 +16,6 @@ import ( "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" @@ -61,14 +60,10 @@ type managerAPI interface { // managerAPIImpl is used to create a composite that implements managerAPI type managerAPIImpl struct { - *stmgr.StateManager + stmgr.StateManagerAPI paychAPI } -func (m *managerAPIImpl) AdtStore(ctx context.Context) adt.Store { - return m.ChainStore().Store(ctx) -} - type Manager struct { // The Manager context is used to terminate wait operations on shutdown ctx context.Context @@ -82,11 +77,11 @@ type Manager struct { channels map[string]*channelAccessor } -func NewManager(mctx helpers.MetricsCtx, lc fx.Lifecycle, sm *stmgr.StateManager, pchstore *Store, api PaychAPI) *Manager { +func NewManager(mctx helpers.MetricsCtx, lc fx.Lifecycle, sm stmgr.StateManagerAPI, pchstore *Store, api PaychAPI) *Manager { ctx := helpers.LifecycleCtx(mctx, lc) ctx, shutdown := context.WithCancel(ctx) - impl := &managerAPIImpl{StateManager: sm, paychAPI: &api} + impl := &managerAPIImpl{StateManagerAPI: sm, paychAPI: &api} return &Manager{ ctx: ctx, shutdown: shutdown, diff --git a/paychmgr/paych_test.go b/paychmgr/paych_test.go index fcd3d50a8..8557dfb63 100644 --- a/paychmgr/paych_test.go +++ b/paychmgr/paych_test.go @@ -14,9 +14,9 @@ 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" - "github.com/filecoin-project/specs-actors/actors/builtin" - tutils "github.com/filecoin-project/specs-actors/support/testing" + "github.com/filecoin-project/specs-actors/v2/actors/builtin" paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" + tutils "github.com/filecoin-project/specs-actors/v2/support/testing" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" @@ -237,7 +237,7 @@ func TestCreateVoucher(t *testing.T) { // Create a voucher in lane 1 voucherLane1Amt := big.NewInt(5) - voucher := paych2.SignedVoucher{ + voucher := paych.SignedVoucher{ Lane: 1, Amount: voucherLane1Amt, } @@ -252,7 +252,7 @@ func TestCreateVoucher(t *testing.T) { // Create a voucher in lane 1 again, with a higher amount voucherLane1Amt = big.NewInt(8) - voucher = paych2.SignedVoucher{ + voucher = paych.SignedVoucher{ Lane: 1, Amount: voucherLane1Amt, } @@ -267,7 +267,7 @@ func TestCreateVoucher(t *testing.T) { // Create a voucher in lane 2 that covers all the remaining funds // in the channel voucherLane2Amt := big.Sub(s.amt, voucherLane1Amt) - voucher = paych2.SignedVoucher{ + voucher = paych.SignedVoucher{ Lane: 2, Amount: voucherLane2Amt, } @@ -281,7 +281,7 @@ func TestCreateVoucher(t *testing.T) { // Create a voucher in lane 2 that exceeds the remaining funds in the // channel voucherLane2Amt = big.Add(voucherLane2Amt, big.NewInt(1)) - voucher = paych2.SignedVoucher{ + voucher = paych.SignedVoucher{ Lane: 2, Amount: voucherLane2Amt, } diff --git a/paychmgr/paychvoucherfunds_test.go b/paychmgr/paychvoucherfunds_test.go index dcbb4acc9..f83a7cd62 100644 --- a/paychmgr/paychvoucherfunds_test.go +++ b/paychmgr/paychvoucherfunds_test.go @@ -4,19 +4,19 @@ import ( "context" "testing" - "github.com/filecoin-project/lotus/chain/actors/builtin/paych" - paychmock "github.com/filecoin-project/lotus/chain/actors/builtin/paych/mock" - - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - tutils "github.com/filecoin-project/specs-actors/support/testing" "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" ds_sync "github.com/ipfs/go-datastore/sync" "github.com/stretchr/testify/require" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + tutils2 "github.com/filecoin-project/specs-actors/v2/support/testing" + + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" + paychmock "github.com/filecoin-project/lotus/chain/actors/builtin/paych/mock" + "github.com/filecoin-project/lotus/chain/types" ) // TestPaychAddVoucherAfterAddFunds tests adding a voucher to a channel with @@ -27,11 +27,11 @@ func TestPaychAddVoucherAfterAddFunds(t *testing.T) { store := NewStore(ds_sync.MutexWrap(ds.NewMapDatastore())) fromKeyPrivate, fromKeyPublic := testGenerateKeyPair(t) - ch := tutils.NewIDAddr(t, 100) - from := tutils.NewSECP256K1Addr(t, string(fromKeyPublic)) - to := tutils.NewSECP256K1Addr(t, "secpTo") - fromAcct := tutils.NewActorAddr(t, "fromAct") - toAcct := tutils.NewActorAddr(t, "toAct") + ch := tutils2.NewIDAddr(t, 100) + from := tutils2.NewSECP256K1Addr(t, string(fromKeyPublic)) + to := tutils2.NewSECP256K1Addr(t, "secpTo") + fromAcct := tutils2.NewActorAddr(t, "fromAct") + toAcct := tutils2.NewActorAddr(t, "toAct") mock := newMockManagerAPI() defer mock.close() @@ -55,7 +55,7 @@ func TestPaychAddVoucherAfterAddFunds(t *testing.T) { // Create an actor in state for the channel with the initial channel balance act := &types.Actor{ - Code: builtin.AccountActorCodeID, + Code: builtin2.AccountActorCodeID, Head: cid.Cid{}, Nonce: 0, Balance: createAmt, diff --git a/paychmgr/settler/settler.go b/paychmgr/settler/settler.go index 02fe9256e..d2a0900b5 100644 --- a/paychmgr/settler/settler.go +++ b/paychmgr/settler/settler.go @@ -14,8 +14,6 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" @@ -107,7 +105,7 @@ func (pcs *paymentChannelSettler) revertHandler(ctx context.Context, ts *types.T func (pcs *paymentChannelSettler) matcher(msg *types.Message) (matchOnce bool, matched bool, err error) { // Check if this is a settle payment channel message - if msg.Method != builtin0.MethodsPaych.Settle { + if msg.Method != paych.Methods.Settle { return false, false, nil } // Check if this payment channel is of concern to this node (i.e. tracked in payment channel store), diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 8d74a897a..2279a9201 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -15,8 +15,7 @@ import ( "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" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apibstore" @@ -147,7 +146,7 @@ func (s SealingAPIAdapter) StateComputeDataCommitment(ctx context.Context, maddr return cid.Undef, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err) } - ccparams, err := actors.SerializeParams(&market0.ComputeDataCommitmentParams{ + ccparams, err := actors.SerializeParams(&market2.ComputeDataCommitmentParams{ DealIDs: deals, SectorType: sectorType, }) @@ -159,7 +158,7 @@ func (s SealingAPIAdapter) StateComputeDataCommitment(ctx context.Context, maddr To: market.Address, From: maddr, Value: types.NewInt(0), - Method: builtin0.MethodsMarket.ComputeDataCommitment, + Method: market.Methods.ComputeDataCommitment, Params: ccparams, } r, err := s.delegate.StateCall(ctx, ccmt, tsk) diff --git a/storage/miner.go b/storage/miner.go index b8985c1a5..0989d5d30 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -5,9 +5,6 @@ import ( "errors" "time" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" - "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/go-state-types/dline" @@ -29,7 +26,9 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" @@ -151,7 +150,7 @@ func (m *Miner) Run(ctx context.Context) error { evts := events.NewEvents(ctx, m.api) adaptedAPI := NewSealingAPIAdapter(m.api) // TODO: Maybe we update this policy after actor upgrades? - pcp := sealing.NewBasicPreCommitPolicy(adaptedAPI, miner0.MaxSectorExpirationExtension-(miner0.WPoStProvingPeriod*2), md.PeriodStart%miner0.WPoStProvingPeriod) + pcp := sealing.NewBasicPreCommitPolicy(adaptedAPI, policy.GetMaxSectorExpirationExtension()-(md.WPoStProvingPeriod*2), md.PeriodStart%md.WPoStProvingPeriod) 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) go m.sealing.Run(ctx) //nolint:errcheck // logged intside the function @@ -239,9 +238,9 @@ func (wpp *StorageWpp) GenerateCandidates(ctx context.Context, randomness abi.Po return cds, nil } -func (wpp *StorageWpp) ComputeProof(ctx context.Context, ssi []proof0.SectorInfo, rand abi.PoStRandomness) ([]proof0.PoStProof, error) { +func (wpp *StorageWpp) ComputeProof(ctx context.Context, ssi []builtin.SectorInfo, rand abi.PoStRandomness) ([]builtin.PoStProof, error) { if build.InsecurePoStValidation { - return []proof0.PoStProof{{ProofBytes: []byte("valid proof")}}, nil + return []builtin.PoStProof{{ProofBytes: []byte("valid proof")}}, nil } log.Infof("Computing WinningPoSt ;%+v; %v", ssi, rand) diff --git a/storage/mockstorage/preseal.go b/storage/mockstorage/preseal.go index 090aacc3c..0417405c8 100644 --- a/storage/mockstorage/preseal.go +++ b/storage/mockstorage/preseal.go @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/lotus/extern/sector-storage/mock" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" @@ -48,7 +48,7 @@ func PreSeal(ssize abi.SectorSize, maddr address.Address, sectors int) (*genesis r := mock.CommDR(d) preseal.CommR, _ = commcid.ReplicaCommitmentV1ToCID(r[:]) preseal.SectorID = abi.SectorNumber(i + 1) - preseal.Deal = market0.DealProposal{ + preseal.Deal = market2.DealProposal{ PieceCID: preseal.CommD, PieceSize: abi.PaddedPieceSize(ssize), Client: k.Address, diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index d4ed4d64c..fd3053a34 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -12,19 +12,19 @@ import ( "github.com/filecoin-project/go-state-types/big" "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/ipfs/go-cid" "go.opencensus.io/trace" "golang.org/x/xerrors" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - "github.com/filecoin-project/specs-actors/actors/runtime/proof" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/types" ) @@ -152,7 +152,15 @@ func (s *WindowPoStScheduler) runSubmitPoST( defer span.End() // Get randomness from tickets + // use the challenge epoch if we've upgraded to network version 4 + // (actors version 2). We want to go back as far as possible to be safe. commEpoch := deadline.Open + if ver, err := s.api.StateNetworkVersion(ctx, types.EmptyTSK); err != nil { + log.Errorw("failed to get network version to determine PoSt epoch randomness lookback", "error", err) + } else if ver >= network.Version4 { + commEpoch = deadline.Challenge + } + 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) @@ -181,11 +189,6 @@ func (s *WindowPoStScheduler) runSubmitPoST( } func (s *WindowPoStScheduler) checkSectors(ctx context.Context, check bitfield.BitField) (bitfield.BitField, error) { - spt, err := s.proofType.RegisteredSealProof() - if err != nil { - return bitfield.BitField{}, xerrors.Errorf("getting seal proof type: %w", err) - } - mid, err := address.IDFromAddress(s.actor) if err != nil { return bitfield.BitField{}, err @@ -207,7 +210,7 @@ func (s *WindowPoStScheduler) checkSectors(ctx context.Context, check bitfield.B return bitfield.BitField{}, xerrors.Errorf("iterating over bitfield: %w", err) } - bad, err := s.faultTracker.CheckProvable(ctx, spt, tocheck) + bad, err := s.faultTracker.CheckProvable(ctx, s.proofType, tocheck) if err != nil { return bitfield.BitField{}, xerrors.Errorf("checking provable sectors: %w", err) } @@ -290,7 +293,7 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uin msg := &types.Message{ To: s.actor, From: s.worker, - Method: builtin0.MethodsMiner.DeclareFaultsRecovered, + Method: miner.Methods.DeclareFaultsRecovered, Params: enc, Value: types.NewInt(0), } @@ -374,7 +377,7 @@ func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64, msg := &types.Message{ To: s.actor, From: s.worker, - Method: builtin0.MethodsMiner.DeclareFaults, + Method: miner.Methods.DeclareFaults, Params: enc, Value: types.NewInt(0), // TODO: Is there a fee? } @@ -505,12 +508,12 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty skipCount := uint64(0) postSkipped := bitfield.New() - var postOut []proof.PoStProof + var postOut []proof2.PoStProof somethingToProve := true for retries := 0; retries < 5; retries++ { var partitions []miner.PoStPartition - var sinfos []proof.SectorInfo + var sinfos []proof2.SectorInfo for partIdx, partition := range batch { // TODO: Can do this in parallel toProve, err := bitfield.SubtractBitField(partition.LiveSectors, partition.FaultySectors) @@ -625,12 +628,6 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty } func (s *WindowPoStScheduler) batchPartitions(partitions []api.Partition) ([][]api.Partition, error) { - // Get the number of sectors allowed in a partition, for this proof size - sectorsPerPartition, err := builtin0.PoStProofWindowPoStPartitionSectors(s.proofType) - if err != nil { - return nil, xerrors.Errorf("getting sectors per partition: %w", err) - } - // We don't want to exceed the number of sectors allowed in a message. // So given the number of sectors in a partition, work out the number of // partitions that can be in a message without exceeding sectors per @@ -641,9 +638,10 @@ func (s *WindowPoStScheduler) batchPartitions(partitions []api.Partition) ([][]a // sectors per partition 3: ooo // partitions per message 2: oooOOO // <1><2> (3rd doesn't fit) - // TODO(NETUPGRADE): we're going to need some form of policy abstraction - // where we can get policy from the future. Unfortunately, we can't just get this from the state. - partitionsPerMsg := int(miner0.AddressedSectorsMax / sectorsPerPartition) + partitionsPerMsg, err := policy.GetMaxPoStPartitions(s.proofType) + if err != nil { + return nil, xerrors.Errorf("getting sectors per partition: %w", err) + } // The number of messages will be: // ceiling(number of partitions / partitions per message) @@ -665,7 +663,7 @@ func (s *WindowPoStScheduler) batchPartitions(partitions []api.Partition) ([][]a return batches, nil } -func (s *WindowPoStScheduler) sectorsForProof(ctx context.Context, goodSectors, allSectors bitfield.BitField, ts *types.TipSet) ([]proof.SectorInfo, error) { +func (s *WindowPoStScheduler) sectorsForProof(ctx context.Context, goodSectors, allSectors bitfield.BitField, ts *types.TipSet) ([]proof2.SectorInfo, error) { sset, err := s.api.StateMinerSectors(ctx, s.actor, &goodSectors, ts.Key()) if err != nil { return nil, err @@ -675,22 +673,22 @@ func (s *WindowPoStScheduler) sectorsForProof(ctx context.Context, goodSectors, return nil, nil } - substitute := proof.SectorInfo{ + substitute := proof2.SectorInfo{ SectorNumber: sset[0].SectorNumber, SealedCID: sset[0].SealedCID, SealProof: sset[0].SealProof, } - sectorByID := make(map[uint64]proof.SectorInfo, len(sset)) + sectorByID := make(map[uint64]proof2.SectorInfo, len(sset)) for _, sector := range sset { - sectorByID[uint64(sector.SectorNumber)] = proof.SectorInfo{ + sectorByID[uint64(sector.SectorNumber)] = proof2.SectorInfo{ SectorNumber: sector.SectorNumber, SealedCID: sector.SealedCID, SealProof: sector.SealProof, } } - proofSectors := make([]proof.SectorInfo, 0, len(sset)) + proofSectors := make([]proof2.SectorInfo, 0, len(sset)) if err := allSectors.ForEach(func(sectorNo uint64) error { if info, found := sectorByID[sectorNo]; found { proofSectors = append(proofSectors, info) @@ -719,7 +717,7 @@ func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.Submi msg := &types.Message{ To: s.actor, From: s.worker, - Method: builtin0.MethodsMiner.SubmitWindowedPoSt, + Method: miner.Methods.SubmitWindowedPoSt, Params: enc, Value: types.NewInt(0), } diff --git a/storage/wdpost_run_test.go b/storage/wdpost_run_test.go index 10dfbd281..b987b604c 100644 --- a/storage/wdpost_run_test.go +++ b/storage/wdpost_run_test.go @@ -16,12 +16,13 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/dline" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" - tutils "github.com/filecoin-project/specs-actors/support/testing" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" + tutils "github.com/filecoin-project/specs-actors/v2/support/testing" "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/journal" @@ -94,12 +95,12 @@ func (m *mockStorageMinerAPI) StateWaitMsg(ctx context.Context, cid cid.Cid, con type mockProver struct { } -func (m *mockProver) GenerateWinningPoSt(context.Context, abi.ActorID, []proof0.SectorInfo, abi.PoStRandomness) ([]proof0.PoStProof, error) { +func (m *mockProver) GenerateWinningPoSt(context.Context, abi.ActorID, []proof2.SectorInfo, abi.PoStRandomness) ([]proof2.PoStProof, error) { panic("implement me") } -func (m *mockProver) GenerateWindowPoSt(ctx context.Context, aid abi.ActorID, sis []proof0.SectorInfo, pr abi.PoStRandomness) ([]proof0.PoStProof, []abi.SectorID, error) { - return []proof0.PoStProof{ +func (m *mockProver) GenerateWindowPoSt(ctx context.Context, aid abi.ActorID, sis []proof2.SectorInfo, pr abi.PoStRandomness) ([]proof2.PoStProof, []abi.SectorID, error) { + return []proof2.PoStProof{ { PoStProof: abi.RegisteredPoStProof_StackedDrgWindow2KiBV1, ProofBytes: []byte("post-proof"), @@ -110,7 +111,7 @@ func (m *mockProver) GenerateWindowPoSt(ctx context.Context, aid abi.ActorID, si type mockFaultTracker struct { } -func (m mockFaultTracker) CheckProvable(ctx context.Context, spt abi.RegisteredSealProof, sectors []abi.SectorID) ([]abi.SectorID, error) { +func (m mockFaultTracker) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []abi.SectorID) ([]abi.SectorID, error) { // Returns "bad" sectors so just return nil meaning all sectors are good return nil, nil } @@ -128,13 +129,13 @@ func TestWDPostDoPost(t *testing.T) { mockStgMinerAPI := newMockStorageMinerAPI() // Get the number of sectors allowed in a partition for this proof type - sectorsPerPartition, err := builtin0.PoStProofWindowPoStPartitionSectors(proofType) + sectorsPerPartition, err := builtin2.PoStProofWindowPoStPartitionSectors(proofType) require.NoError(t, err) // Work out the number of partitions that can be included in a message // without exceeding the message sector limit require.NoError(t, err) - partitionsPerMsg := int(miner0.AddressedSectorsMax / sectorsPerPartition) + partitionsPerMsg := int(miner2.AddressedSectorsMax / sectorsPerPartition) // Enough partitions to fill expectedMsgCount-1 messages partitionCount := (expectedMsgCount - 1) * partitionsPerMsg @@ -169,11 +170,11 @@ func TestWDPostDoPost(t *testing.T) { } di := &dline.Info{ - WPoStPeriodDeadlines: miner0.WPoStPeriodDeadlines, - WPoStProvingPeriod: miner0.WPoStProvingPeriod, - WPoStChallengeWindow: miner0.WPoStChallengeWindow, - WPoStChallengeLookback: miner0.WPoStChallengeLookback, - FaultDeclarationCutoff: miner0.FaultDeclarationCutoff, + WPoStPeriodDeadlines: miner2.WPoStPeriodDeadlines, + WPoStProvingPeriod: miner2.WPoStProvingPeriod, + WPoStChallengeWindow: miner2.WPoStChallengeWindow, + WPoStChallengeLookback: miner2.WPoStChallengeLookback, + FaultDeclarationCutoff: miner2.FaultDeclarationCutoff, } ts := mockTipSet(t) @@ -184,7 +185,7 @@ func TestWDPostDoPost(t *testing.T) { // Read the window PoST messages for i := 0; i < expectedMsgCount; i++ { msg := <-mockStgMinerAPI.pushedMessages - require.Equal(t, builtin0.MethodsMiner.SubmitWindowedPoSt, msg.Method) + require.Equal(t, miner.Methods.SubmitWindowedPoSt, msg.Method) var params miner.SubmitWindowedPoStParams err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)) require.NoError(t, err) @@ -250,11 +251,11 @@ func (m *mockStorageMinerAPI) StateMinerProvingDeadline(ctx context.Context, add Close: 0, Challenge: 0, FaultCutoff: 0, - WPoStPeriodDeadlines: miner0.WPoStPeriodDeadlines, - WPoStProvingPeriod: miner0.WPoStProvingPeriod, - WPoStChallengeWindow: miner0.WPoStChallengeWindow, - WPoStChallengeLookback: miner0.WPoStChallengeLookback, - FaultDeclarationCutoff: miner0.FaultDeclarationCutoff, + WPoStPeriodDeadlines: miner2.WPoStPeriodDeadlines, + WPoStProvingPeriod: miner2.WPoStProvingPeriod, + WPoStChallengeWindow: miner2.WPoStChallengeWindow, + WPoStChallengeLookback: miner2.WPoStChallengeLookback, + FaultDeclarationCutoff: miner2.FaultDeclarationCutoff, }, nil } @@ -272,7 +273,7 @@ func (m *mockStorageMinerAPI) StateSearchMsg(ctx context.Context, cid cid.Cid) ( func (m *mockStorageMinerAPI) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) { return &types.Actor{ - Code: builtin0.StorageMinerActorCodeID, + Code: builtin2.StorageMinerActorCodeID, }, nil }