Merge remote-tracking branch 'origin/master' into feat/async-restartable-workers

This commit is contained in:
Łukasz Magiera 2020-10-23 23:24:50 +02:00
commit 660236b224
172 changed files with 4267 additions and 1437 deletions

View File

@ -188,6 +188,14 @@ jobs:
command: | command: |
bash <(curl -s https://codecov.io/bash) bash <(curl -s https://codecov.io/bash)
test-chain:
<<: *test
test-node:
<<: *test
test-storage:
<<: *test
test-cli:
<<: *test
test-short: test-short:
<<: *test <<: *test
test-window-post: test-window-post:
@ -428,6 +436,22 @@ workflows:
- test: - test:
codecov-upload: true codecov-upload: true
test-suite-name: full 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: - test-window-post:
go-test-flags: "-run=TestWindowedPost" go-test-flags: "-run=TestWindowedPost"
winpost-test: "1" winpost-test: "1"

View File

@ -1,5 +1,49 @@
# Lotus changelog # 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 # 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. 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.

View File

@ -133,18 +133,30 @@ benchmarks:
lotus-pond: 2k lotus-pond: 2k
go build -o lotus-pond ./lotuspond go build -o lotus-pond ./lotuspond
(cd lotuspond/front && npm i && CI=false npm run build)
.PHONY: lotus-pond .PHONY: lotus-pond
BINS+=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: lotus-townhall:
rm -f lotus-townhall rm -f lotus-townhall
go build -o lotus-townhall ./cmd/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 .PHONY: lotus-townhall
BINS+=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: lotus-fountain:
rm -f lotus-fountain rm -f lotus-fountain
go build -o lotus-fountain ./cmd/lotus-fountain go build -o lotus-fountain ./cmd/lotus-fountain

View File

@ -207,6 +207,15 @@ type FullNode interface {
// based on current chain conditions // based on current chain conditions
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error) 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. // MpoolGetNonce gets next nonce for the specified sender.
// Note that this method may not be atomic. Use MpoolPushMessage instead. // Note that this method may not be atomic. Use MpoolPushMessage instead.
MpoolGetNonce(context.Context, address.Address) (uint64, error) MpoolGetNonce(context.Context, address.Address) (uint64, error)
@ -277,6 +286,8 @@ type FullNode interface {
ClientListDeals(ctx context.Context) ([]DealInfo, error) ClientListDeals(ctx context.Context) ([]DealInfo, error)
// ClientGetDealUpdates returns the status of updated deals // ClientGetDealUpdates returns the status of updated deals
ClientGetDealUpdates(ctx context.Context) (<-chan DealInfo, error) 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 indicates whether a certain CID is locally stored.
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
// ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer). // ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer).
@ -593,6 +604,8 @@ type MsgGasCost struct {
TotalCost abi.TokenAmount TotalCost abi.TokenAmount
} }
// BlsMessages[x].cid = Cids[x]
// SecpkMessages[y].cid = Cids[BlsMessages.length + y]
type BlockMessages struct { type BlockMessages struct {
BlsMessages []*types.Message BlsMessages []*types.Message
SecpkMessages []*types.SignedMessage SecpkMessages []*types.SignedMessage

View File

@ -3,24 +3,42 @@ package api
import ( import (
"context" "context"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "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/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-cid"
) )
type GatewayAPI interface { type GatewayAPI interface {
ChainHasObj(context.Context, cid.Cid) (bool, error) ChainHasObj(context.Context, cid.Cid) (bool, error)
ChainHead(ctx context.Context) (*types.TipSet, 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) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, 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) ChainReadObj(context.Context, cid.Cid) ([]byte, error)
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *MessageSendSpec, tsk types.TipSetKey) (*types.Message, 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) MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, 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) 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) 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) 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) 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) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*MsgLookup, error)
} }

View File

@ -132,6 +132,10 @@ type FullNodeStruct struct {
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"` MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, 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"` 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"` 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"` 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"` ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"`
ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"` 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"` ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"`
ClientGetDealUpdates func(ctx context.Context) (<-chan api.DealInfo, error) `perm:"read"` 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"` 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"` SealingSchedDiag func(context.Context) (interface{}, error) `perm:"admin"`
StorageList func(context.Context) (map[stores.ID][]stores.Decl, 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"` StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"`
StorageStat func(context.Context, stores.ID) (fsutil.FsStat, 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"`
DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"` DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"`
@ -382,20 +387,32 @@ type WorkerStruct struct {
type GatewayStruct struct { type GatewayStruct struct {
Internal struct { Internal struct {
// TODO: does the gateway need perms? ChainGetBlockMessages func(ctx context.Context, c cid.Cid) (*api.BlockMessages, error)
ChainHasObj func(context.Context, cid.Cid) (bool, error) ChainGetMessage func(ctx context.Context, mc cid.Cid) (*types.Message, error)
ChainGetTipSet func(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, 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) ChainGetTipSetByHeight func(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error)
ChainHead func(ctx context.Context) (*types.TipSet, error) ChainHasObj func(context.Context, cid.Cid) (bool, error)
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) ChainHead func(ctx context.Context) (*types.TipSet, error)
GasEstimateMessageGas func(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) ChainNotify func(ctx context.Context) (<-chan []*api.HeadChange, error)
MpoolPush func(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) ChainReadObj func(context.Context, cid.Cid) ([]byte, error)
MsigGetAvailableBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) GasEstimateMessageGas func(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
MsigGetVested func(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) MpoolPush func(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
StateAccountKey func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) MsigGetAvailableBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
StateGetActor func(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) MsigGetVested func(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) StateAccountKey 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) 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) 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) { func (c *FullNodeStruct) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) {
return c.Internal.ClientListDeals(ctx) 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) 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) { func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate, error) {
return c.Internal.MpoolSub(ctx) 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) 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) { 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, spt, allowFetch) return c.Internal.StorageFindSector(ctx, si, types, ssize, allowFetch)
} }
func (c *StorageMinerStruct) StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) { 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) 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) { 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, spt, pt) return c.Internal.StorageBestAlloc(ctx, allocate, ssize, pt)
} }
func (c *StorageMinerStruct) StorageReportHealth(ctx context.Context, id stores.ID, report stores.HealthReport) error { 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) return w.Internal.Session(ctx)
} }
func (g GatewayStruct) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) { func (g GatewayStruct) ChainGetBlockMessages(ctx context.Context, c cid.Cid) (*api.BlockMessages, error) {
return g.Internal.ChainHasObj(ctx, c) return g.Internal.ChainGetBlockMessages(ctx, c)
} }
func (g GatewayStruct) ChainHead(ctx context.Context) (*types.TipSet, error) { func (g GatewayStruct) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) {
return g.Internal.ChainHead(ctx) return g.Internal.ChainGetMessage(ctx, mc)
} }
func (g GatewayStruct) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) { 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) 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) { func (g GatewayStruct) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
return g.Internal.ChainReadObj(ctx, c) 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) 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) { func (g GatewayStruct) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) {
return g.Internal.StateGetActor(ctx, actor, ts) 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) { func (g GatewayStruct) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
return g.Internal.StateLookupID(ctx, addr, tsk) 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) { func (g GatewayStruct) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) {
return g.Internal.StateWaitMsg(ctx, msg, confidence) return g.Internal.StateWaitMsg(ctx, msg, confidence)
} }

View File

@ -3,7 +3,6 @@ package test
import ( import (
"context" "context"
"fmt" "fmt"
"os"
"sync/atomic" "sync/atomic"
"testing" "testing"
"time" "time"
@ -17,8 +16,6 @@ import (
) )
func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) { func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
for _, height := range []abi.ChainEpoch{ for _, height := range []abi.ChainEpoch{
1, // before 1, // before
162, // while sealing 162, // while sealing
@ -92,7 +89,7 @@ func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeH
t.Fatal(err) t.Fatal(err)
} }
makeDeal(t, ctx, 6, client, miner, false, false) MakeDeal(t, ctx, 6, client, miner, false, false)
// Validate upgrade // Validate upgrade

View File

@ -16,15 +16,12 @@ import (
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
files "github.com/ipfs/go-ipfs-files" files "github.com/ipfs/go-ipfs-files"
logging "github.com/ipfs/go-log/v2"
"github.com/ipld/go-car" "github.com/ipld/go-car"
"github.com/filecoin-project/go-fil-markets/storagemarket" "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/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
sealing "github.com/filecoin-project/lotus/extern/storage-sealing" sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
"github.com/filecoin-project/lotus/miner"
dag "github.com/ipfs/go-merkledag" dag "github.com/ipfs/go-merkledag"
dstest "github.com/ipfs/go-merkledag/test" dstest "github.com/ipfs/go-merkledag/test"
unixfile "github.com/ipfs/go-unixfs/file" unixfile "github.com/ipfs/go-unixfs/file"
@ -34,18 +31,7 @@ import (
ipld "github.com/ipfs/go-ipld-format" 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) { func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background() ctx := context.Background()
n, sn := b(t, OneFull, OneMiner) 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) atomic.AddInt64(&mine, -1)
fmt.Println("shutting down mining") 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) { func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background() ctx := context.Background()
n, sn := b(t, OneFull, OneMiner) 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, 6, client, miner, false, false)
makeDeal(t, ctx, 7, client, miner, false, false) MakeDeal(t, ctx, 7, client, miner, false, false)
atomic.AddInt64(&mine, -1) atomic.AddInt64(&mine, -1)
fmt.Println("shutting down mining") fmt.Println("shutting down mining")
<-done <-done
} }
func makeDeal(t *testing.T, ctx context.Context, rseed int, client *impl.FullNodeAPI, miner TestStorageNode, carExport, fastRet bool) { func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestStorageNode, carExport, fastRet bool) {
data := make([]byte, 1600) res, data, err := CreateClientFile(ctx, client, rseed)
rand.New(rand.NewSource(int64(rseed))).Read(data)
r := bytes.NewReader(data)
fcid, err := client.ClientImportLocal(ctx, r)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
fcid := res.Root
fmt.Println("FILE CID: ", fcid) fmt.Println("FILE CID: ", fcid)
deal := startDeal(t, ctx, miner, client, fcid, fastRet) 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) 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) { func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background() ctx := context.Background()
n, sn := b(t, OneFull, OneMiner) 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) { func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background() ctx := context.Background()
n, sn := b(t, OneFull, OneMiner) n, sn := b(t, OneFull, OneMiner)
@ -276,7 +278,7 @@ func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration
<-done <-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) maddr, err := miner.ActorAddress(ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -303,7 +305,7 @@ func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client
return deal 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: loop:
for { for {
di, err := client.ClientGetDealInfo(ctx, *deal) 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) offers, err := client.ClientFindData(ctx, fcid, piece)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -5,7 +5,6 @@ import (
"context" "context"
"fmt" "fmt"
"math/rand" "math/rand"
"os"
"sync/atomic" "sync/atomic"
"testing" "testing"
"time" "time"
@ -88,8 +87,6 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
} }
func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) { 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 // test making a deal with a fresh miner, and see if it starts to mine
ctx := context.Background() ctx := context.Background()

View File

@ -3,14 +3,10 @@ package test
import ( import (
"context" "context"
"fmt" "fmt"
"os"
"sync/atomic" "sync/atomic"
"testing" "testing"
"time" "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/abi"
"github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/big"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
@ -22,15 +18,15 @@ import (
"github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/adt" "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/builtin/paych"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/chain/events/state" "github.com/filecoin-project/lotus/chain/events/state"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )
func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background() ctx := context.Background()
n, sn := b(t, TwoFull, OneMiner) 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 // 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) creatorPreCollectBalance, err := paymentCreator.WalletBalance(ctx, createrAddr)
if err != nil { if err != nil {
@ -283,7 +279,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentRec
// Add a real block // Add a real block
m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{ m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{
To: builtin0.BurntFundsActorAddr, To: builtin.BurntFundsActorAddr,
From: receiverAddr, From: receiverAddr,
Value: types.NewInt(0), Value: types.NewInt(0),
}, nil) }, nil)

View File

@ -2,12 +2,15 @@ package test
import ( import (
"context" "context"
"fmt"
"os"
"testing" "testing"
"time" "time"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
logging "github.com/ipfs/go-log/v2"
"github.com/multiformats/go-multiaddr" "github.com/multiformats/go-multiaddr"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -22,6 +25,15 @@ import (
"github.com/filecoin-project/lotus/node" "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 { type TestNode struct {
api.FullNode api.FullNode
// ListenAddr is the address on which an API server is listening, if an // 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) { func (ts *testSuite) testVersion(t *testing.T) {
build.RunningNodeType = build.NodeFull build.RunningNodeType = build.NodeFull

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"sync/atomic" "sync/atomic"
"os"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -24,13 +23,6 @@ import (
"github.com/filecoin-project/lotus/node/impl" "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) { func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()

View File

@ -22,6 +22,8 @@ const UpgradeTapeHeight = -4
var UpgradeActorsV2Height = abi.ChainEpoch(10) var UpgradeActorsV2Height = abi.ChainEpoch(10)
var UpgradeLiftoffHeight = abi.ChainEpoch(-5) var UpgradeLiftoffHeight = abi.ChainEpoch(-5)
const UpgradeKumquatHeight = -6
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet, 0: DrandMainnet,
} }

View File

@ -12,7 +12,7 @@ import (
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors/policy" "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{ 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. // We still have upgrades and state changes to do, but can happen after signaling timing here.
const UpgradeLiftoffHeight = 148888 const UpgradeLiftoffHeight = 148888
const UpgradeKumquatHeight = 170000
func init() { func init() {
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40)) policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
policy.SetSupportedProofTypes( policy.SetSupportedProofTypes(
@ -55,6 +57,6 @@ func init() {
Devnet = false Devnet = false
} }
const BlockDelaySecs = uint64(builtin0.EpochDurationSeconds) const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
const PropagationDelaySecs = uint64(6) const PropagationDelaySecs = uint64(6)

View File

@ -1,36 +1,13 @@
package build package build
import ( import (
"sort"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/libp2p/go-libp2p-core/protocol" "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" "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 // Core network constants
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) } 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)) 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) { func SetAddressNetwork(n address.Network) {
address.CurrentNetwork = n address.CurrentNetwork = n
} }

View File

@ -7,12 +7,12 @@ import (
"os" "os"
"github.com/filecoin-project/go-address" "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/network"
"github.com/filecoin-project/go-state-types/abi" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/policy"
) )
// ///// // /////
@ -25,14 +25,14 @@ const UnixfsLinksPerLevel = 1024
// Consensus / Network // Consensus / Network
const AllowableClockDriftSecs = uint64(1) const AllowableClockDriftSecs = uint64(1)
const NewestNetworkVersion = network.Version5 const NewestNetworkVersion = network.Version6
const ActorUpgradeNetworkVersion = network.Version4 const ActorUpgradeNetworkVersion = network.Version4
// Epochs // Epochs
const ForkLengthThreshold = Finality const ForkLengthThreshold = Finality
// Blocks (e) // Blocks (e)
var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) var BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch)
// Epochs // Epochs
const Finality = policy.ChainFinality const Finality = policy.ChainFinality
@ -116,4 +116,4 @@ const PackingEfficiencyDenom = 5
// Actor consts // Actor consts
// TODO: Pull from actors when its made not private // TODO: Pull from actors when its made not private
var MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay) var MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)

View File

@ -12,7 +12,8 @@ import (
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network" "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" "github.com/filecoin-project/lotus/chain/actors/policy"
) )
@ -21,14 +22,14 @@ var (
UnixfsChunkSize = uint64(1 << 20) UnixfsChunkSize = uint64(1 << 20)
UnixfsLinksPerLevel = 1024 UnixfsLinksPerLevel = 1024
BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch) BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch)
BlockMessageLimit = 512 BlockMessageLimit = 512
BlockGasLimit = int64(100_000_000_000) BlockGasLimit = int64(100_000_000_000)
BlockGasTarget = int64(BlockGasLimit / 2) BlockGasTarget = int64(BlockGasLimit / 2)
BaseFeeMaxChangeDenom = int64(8) // 12.5% BaseFeeMaxChangeDenom = int64(8) // 12.5%
InitialBaseFee = int64(100e6) InitialBaseFee = int64(100e6)
MinimumBaseFee = int64(100) MinimumBaseFee = int64(100)
BlockDelaySecs = uint64(builtin.EpochDurationSeconds) BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
PropagationDelaySecs = uint64(6) PropagationDelaySecs = uint64(6)
AllowableClockDriftSecs = uint64(1) AllowableClockDriftSecs = uint64(1)
@ -72,7 +73,7 @@ var (
// Actor consts // Actor consts
// TODO: Pull from actors when its made not private // TODO: Pull from actors when its made not private
MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay) MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
PackingEfficiencyNum int64 = 4 PackingEfficiencyNum int64 = 4
PackingEfficiencyDenom int64 = 5 PackingEfficiencyDenom int64 = 5
@ -86,6 +87,7 @@ var (
UpgradeTapeHeight abi.ChainEpoch = -4 UpgradeTapeHeight abi.ChainEpoch = -4
UpgradeActorsV2Height abi.ChainEpoch = 10 UpgradeActorsV2Height abi.ChainEpoch = 10
UpgradeLiftoffHeight abi.ChainEpoch = -5 UpgradeLiftoffHeight abi.ChainEpoch = -5
UpgradeKumquatHeight abi.ChainEpoch = -6
DrandSchedule = map[abi.ChainEpoch]DrandEnum{ DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet, 0: DrandMainnet,

View File

@ -29,7 +29,7 @@ func buildType() string {
} }
// BuildVersion is the local build version, set by build system // BuildVersion is the local build version, set by build system
const BuildVersion = "0.10.2" const BuildVersion = "1.1.0"
func UserVersion() string { func UserVersion() string {
return BuildVersion + buildType() + CurrentCommit return BuildVersion + buildType() + CurrentCommit
@ -84,7 +84,7 @@ func VersionForType(nodeType NodeType) (Version, error) {
// semver versions of the rpc api exposed // semver versions of the rpc api exposed
var ( var (
FullAPIVersion = newVer(0, 17, 0) FullAPIVersion = newVer(0, 17, 0)
MinerAPIVersion = newVer(0, 16, 0) MinerAPIVersion = newVer(0, 17, 0)
WorkerAPIVersion = newVer(0, 16, 0) WorkerAPIVersion = newVer(0, 16, 0)
) )

View File

@ -12,8 +12,9 @@ import (
typegen "github.com/whyrusleeping/cbor-gen" typegen "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/go-state-types/abi" "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" bstore "github.com/filecoin-project/lotus/lib/blockstore"
) )
@ -22,24 +23,24 @@ func TestDiffAdtArray(t *testing.T) {
ctxstoreA := newContextStore() ctxstoreA := newContextStore()
ctxstoreB := newContextStore() ctxstoreB := newContextStore()
arrA := adt0.MakeEmptyArray(ctxstoreA) arrA := adt2.MakeEmptyArray(ctxstoreA)
arrB := adt0.MakeEmptyArray(ctxstoreB) 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, arrA.Set(1, builtin2.CBORBytes([]byte{0}))) // modify
require.NoError(t, arrB.Set(1, runtime.CBORBytes([]byte{1}))) 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, arrA.Set(3, builtin2.CBORBytes([]byte{0}))) // noop
require.NoError(t, arrB.Set(3, runtime.CBORBytes([]byte{0}))) require.NoError(t, arrB.Set(3, builtin2.CBORBytes([]byte{0})))
require.NoError(t, arrA.Set(4, runtime.CBORBytes([]byte{0}))) // modify require.NoError(t, arrA.Set(4, builtin2.CBORBytes([]byte{0}))) // modify
require.NoError(t, arrB.Set(4, runtime.CBORBytes([]byte{6}))) 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(5, builtin2.CBORBytes{8})) // add
require.NoError(t, arrB.Set(6, runtime.CBORBytes{9})) // add require.NoError(t, arrB.Set(6, builtin2.CBORBytes{9})) // add
changes := new(TestDiffArray) changes := new(TestDiffArray)
@ -76,24 +77,24 @@ func TestDiffAdtMap(t *testing.T) {
ctxstoreA := newContextStore() ctxstoreA := newContextStore()
ctxstoreB := newContextStore() ctxstoreB := newContextStore()
mapA := adt0.MakeEmptyMap(ctxstoreA) mapA := adt2.MakeEmptyMap(ctxstoreA)
mapB := adt0.MakeEmptyMap(ctxstoreB) 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, mapA.Put(abi.UIntKey(1), builtin2.CBORBytes([]byte{0}))) // modify
require.NoError(t, mapB.Put(abi.UIntKey(1), runtime.CBORBytes([]byte{1}))) 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, mapA.Put(abi.UIntKey(3), builtin2.CBORBytes([]byte{0}))) // noop
require.NoError(t, mapB.Put(abi.UIntKey(3), runtime.CBORBytes([]byte{0}))) 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, mapA.Put(abi.UIntKey(4), builtin2.CBORBytes([]byte{0}))) // modify
require.NoError(t, mapB.Put(abi.UIntKey(4), runtime.CBORBytes([]byte{6}))) 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(5), builtin2.CBORBytes{8})) // add
require.NoError(t, mapB.Put(abi.UIntKey(6), runtime.CBORBytes{9})) // add require.NoError(t, mapB.Put(abi.UIntKey(6), builtin2.CBORBytes{9})) // add
changes := new(TestDiffMap) 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 { 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)) err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil { if err != nil {
return err 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 { 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)) err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
if err != nil { if err != nil {
return err return err
} }
vTo := new(runtime.CBORBytes) vTo := new(builtin2.CBORBytes)
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw)) err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
if err != nil { if err != nil {
return err 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 { 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)) err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil { if err != nil {
return err return err
@ -212,7 +213,7 @@ func (t *TestDiffMap) Remove(key string, val *typegen.Deferred) error {
type adtMapDiffResult struct { type adtMapDiffResult struct {
key uint64 key uint64
val runtime.CBORBytes val builtin2.CBORBytes
} }
type TestAdtMapDiffModified struct { type TestAdtMapDiffModified struct {
@ -222,7 +223,7 @@ type TestAdtMapDiffModified struct {
type adtArrayDiffResult struct { type adtArrayDiffResult struct {
key uint64 key uint64
val runtime.CBORBytes val builtin2.CBORBytes
} }
type TestDiffArray struct { type TestDiffArray struct {
@ -239,7 +240,7 @@ type TestAdtArrayDiffModified struct {
} }
func (t *TestDiffArray) Add(key uint64, val *typegen.Deferred) error { 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)) err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil { if err != nil {
return err 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 { 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)) err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
if err != nil { if err != nil {
return err return err
} }
vTo := new(runtime.CBORBytes) vTo := new(builtin2.CBORBytes)
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw)) err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
if err != nil { if err != nil {
return err 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 { 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)) err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil { if err != nil {
return err return err

View File

@ -24,6 +24,8 @@ func init() {
}) })
} }
var Methods = builtin2.MethodsAccount
func Load(store adt.Store, act *types.Actor) (State, error) { func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code { switch act.Code {
case builtin0.AccountActorCodeID: case builtin0.AccountActorCodeID:

View File

@ -27,6 +27,21 @@ var SaftAddress = makeAddress("t0122")
var ReserveAddress = makeAddress("t090") var ReserveAddress = makeAddress("t090")
var RootVerifierAddress = makeAddress("t080") 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? // TODO: Why does actors have 2 different versions of this?
type SectorInfo = proof0.SectorInfo type SectorInfo = proof0.SectorInfo
type PoStProof = proof0.PoStProof type PoStProof = proof0.PoStProof

View File

@ -0,0 +1,10 @@
package cron
import (
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
)
var (
Address = builtin2.CronActorAddr
Methods = builtin2.MethodsCron
)

View File

@ -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) { func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code { switch act.Code {

View File

@ -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) { func Load(store adt.Store, act *types.Actor) (st State, err error) {
switch act.Code { switch act.Code {

View File

@ -31,6 +31,8 @@ func init() {
}) })
} }
var Methods = builtin2.MethodsMiner
// Unchanged between v0 and v2 actors // Unchanged between v0 and v2 actors
var WPoStProvingPeriod = miner0.WPoStProvingPeriod var WPoStProvingPeriod = miner0.WPoStProvingPeriod
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines

View File

@ -9,12 +9,15 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "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" multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )
var Methods = builtin2.MethodsMultisig
func Message(version actors.Version, from address.Address) MessageBuilder { func Message(version actors.Version, from address.Address) MessageBuilder {
switch version { switch version {
case actors.Version0: case actors.Version0:

View File

@ -7,8 +7,12 @@ import (
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types" "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 { func Message(version actors.Version, from address.Address) MessageBuilder {
switch version { switch version {
case actors.Version0: case actors.Version0:

View File

@ -2,6 +2,7 @@ package power
import ( import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"golang.org/x/xerrors" "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) { func Load(store adt.Store, act *types.Actor) (st State, err error) {
switch act.Code { switch act.Code {
@ -61,3 +65,10 @@ type Claim struct {
// Sum of quality adjusted power for a miner's sectors. // Sum of quality adjusted power for a miner's sectors.
QualityAdjPower abi.StoragePower 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),
}
}

View File

@ -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) { func Load(store adt.Store, act *types.Actor) (st State, err error) {
switch act.Code { switch act.Code {

View File

@ -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) { func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code { switch act.Code {

View File

@ -1,6 +1,8 @@
package policy package policy
import ( import (
"sort"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
@ -11,12 +13,14 @@ import (
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" 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" verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
) )
const ( const (
ChainFinality = miner0.ChainFinality ChainFinality = miner0.ChainFinality
SealRandomnessLookback = ChainFinality SealRandomnessLookback = ChainFinality
PaychSettleDelay = paych2.SettleDelay
) )
// SetSupportedProofTypes sets supported proof types, across all actor versions. // SetSupportedProofTypes sets supported proof types, across all actor versions.
@ -114,3 +118,35 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
return ChainFinality 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]
}

View File

@ -6,9 +6,13 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/filecoin-project/go-state-types/abi" "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" 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" 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" 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" 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) { func TestAssumptions(t *testing.T) {
require.EqualValues(t, miner0.SupportedProofTypes, miner2.SupportedProofTypes) require.EqualValues(t, miner0.SupportedProofTypes, miner2.SupportedProofTypes)
require.Equal(t, miner0.PreCommitChallengeDelay, miner2.PreCommitChallengeDelay) 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.ChainFinality, miner2.ChainFinality)
require.Equal(t, miner0.WPoStChallengeWindow, miner2.WPoStChallengeWindow) require.Equal(t, miner0.WPoStChallengeWindow, miner2.WPoStChallengeWindow)
require.Equal(t, miner0.WPoStProvingPeriod, miner2.WPoStProvingPeriod) require.Equal(t, miner0.WPoStProvingPeriod, miner2.WPoStProvingPeriod)
require.Equal(t, miner0.WPoStPeriodDeadlines, miner2.WPoStPeriodDeadlines) 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)) 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)
}
}

View File

@ -18,7 +18,7 @@ func VersionForNetwork(version network.Version) Version {
switch version { switch version {
case network.Version0, network.Version1, network.Version2, network.Version3: case network.Version0, network.Version1, network.Version2, network.Version3:
return Version0 return Version0
case network.Version4, network.Version5: case network.Version4, network.Version5, network.Version6:
return Version2 return Version2
default: default:
panic(fmt.Sprintf("unsupported network version %d", version)) panic(fmt.Sprintf("unsupported network version %d", version))

View File

@ -65,6 +65,11 @@ type DrandBeacon struct {
localCache map[uint64]types.BeaconEntry 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) { func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes.DrandConfig) (*DrandBeacon, error) {
if genesisTs == 0 { if genesisTs == 0 {
panic("what are you doing this cant be zero") 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 { if err != nil {
return nil, xerrors.Errorf("could not create http drand client: %w", err) return nil, xerrors.Errorf("could not create http drand client: %w", err)
} }
hc.(DrandHTTPClient).SetUserAgent("drand-client-lotus/" + build.BuildVersion)
clients = append(clients, hc) clients = append(clients, hc)
} }
@ -92,7 +98,6 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
dclient.WithChainInfo(drandChain), dclient.WithChainInfo(drandChain),
dclient.WithCacheSize(1024), dclient.WithCacheSize(1024),
dclient.WithLogger(dlogger), dclient.WithLogger(dlogger),
dclient.WithAutoWatch(),
} }
if ps != nil { if ps != nil {

View File

@ -18,14 +18,14 @@ import (
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto" "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" "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" "github.com/filecoin-project/lotus/chain/types"
bstore "github.com/filecoin-project/lotus/lib/blockstore" 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) { func TestMarketPredicates(t *testing.T) {
ctx := context.Background() ctx := context.Background()
bs := bstore.NewTemporarySync() 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, SectorStartEpoch: 1,
LastUpdatedEpoch: 2, LastUpdatedEpoch: 2,
SlashEpoch: 0, SlashEpoch: 0,
} }
oldDeal2 := &market0.DealState{ oldDeal2 := &market2.DealState{
SectorStartEpoch: 4, SectorStartEpoch: 4,
LastUpdatedEpoch: 5, LastUpdatedEpoch: 5,
SlashEpoch: 0, SlashEpoch: 0,
} }
oldDeals := map[abi.DealID]*market0.DealState{ oldDeals := map[abi.DealID]*market2.DealState{
abi.DealID(1): oldDeal1, abi.DealID(1): oldDeal1,
abi.DealID(2): oldDeal2, abi.DealID(2): oldDeal2,
} }
oldProp1 := &market0.DealProposal{ oldProp1 := &market2.DealProposal{
PieceCID: dummyCid, PieceCID: dummyCid,
PieceSize: 0, PieceSize: 0,
VerifiedDeal: false, VerifiedDeal: false,
@ -101,7 +101,7 @@ func TestMarketPredicates(t *testing.T) {
ProviderCollateral: big.Zero(), ProviderCollateral: big.Zero(),
ClientCollateral: big.Zero(), ClientCollateral: big.Zero(),
} }
oldProp2 := &market0.DealProposal{ oldProp2 := &market2.DealProposal{
PieceCID: dummyCid, PieceCID: dummyCid,
PieceSize: 0, PieceSize: 0,
VerifiedDeal: false, VerifiedDeal: false,
@ -113,7 +113,7 @@ func TestMarketPredicates(t *testing.T) {
ProviderCollateral: big.Zero(), ProviderCollateral: big.Zero(),
ClientCollateral: big.Zero(), ClientCollateral: big.Zero(),
} }
oldProps := map[abi.DealID]*market0.DealProposal{ oldProps := map[abi.DealID]*market2.DealProposal{
abi.DealID(1): oldProp1, abi.DealID(1): oldProp1,
abi.DealID(2): oldProp2, abi.DealID(2): oldProp2,
} }
@ -127,7 +127,7 @@ func TestMarketPredicates(t *testing.T) {
oldStateC := createMarketState(ctx, t, store, oldDeals, oldProps, oldBalances) oldStateC := createMarketState(ctx, t, store, oldDeals, oldProps, oldBalances)
newDeal1 := &market0.DealState{ newDeal1 := &market2.DealState{
SectorStartEpoch: 1, SectorStartEpoch: 1,
LastUpdatedEpoch: 3, LastUpdatedEpoch: 3,
SlashEpoch: 0, SlashEpoch: 0,
@ -136,19 +136,19 @@ func TestMarketPredicates(t *testing.T) {
// deal 2 removed // deal 2 removed
// added // added
newDeal3 := &market0.DealState{ newDeal3 := &market2.DealState{
SectorStartEpoch: 1, SectorStartEpoch: 1,
LastUpdatedEpoch: 2, LastUpdatedEpoch: 2,
SlashEpoch: 3, SlashEpoch: 3,
} }
newDeals := map[abi.DealID]*market0.DealState{ newDeals := map[abi.DealID]*market2.DealState{
abi.DealID(1): newDeal1, abi.DealID(1): newDeal1,
// deal 2 was removed // deal 2 was removed
abi.DealID(3): newDeal3, abi.DealID(3): newDeal3,
} }
// added // added
newProp3 := &market0.DealProposal{ newProp3 := &market2.DealProposal{
PieceCID: dummyCid, PieceCID: dummyCid,
PieceSize: 0, PieceSize: 0,
VerifiedDeal: false, VerifiedDeal: false,
@ -160,7 +160,7 @@ func TestMarketPredicates(t *testing.T) {
ProviderCollateral: big.Zero(), ProviderCollateral: big.Zero(),
ClientCollateral: big.Zero(), ClientCollateral: big.Zero(),
} }
newProps := map[abi.DealID]*market0.DealProposal{ newProps := map[abi.DealID]*market2.DealProposal{
abi.DealID(1): oldProp1, // 1 was persisted abi.DealID(1): oldProp1, // 1 was persisted
// prop 2 was removed // prop 2 was removed
abi.DealID(3): newProp3, // new abi.DealID(3): newProp3, // new
@ -183,8 +183,8 @@ func TestMarketPredicates(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
api := newMockAPI(bs) api := newMockAPI(bs)
api.setActor(oldState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: oldStateC}) api.setActor(oldState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: oldStateC})
api.setActor(newState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: newStateC}) api.setActor(newState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: newStateC})
t.Run("deal ID predicate", func(t *testing.T) { t.Run("deal ID predicate", func(t *testing.T) {
preds := NewStatePredicates(api) preds := NewStatePredicates(api)
@ -243,7 +243,7 @@ func TestMarketPredicates(t *testing.T) {
marketCid, err := store.Put(ctx, marketState0) marketCid, err := store.Put(ctx, marketState0)
require.NoError(t, err) require.NoError(t, err)
marketState, err := market.Load(store, &types.Actor{ marketState, err := market.Load(store, &types.Actor{
Code: builtin0.StorageMarketActorCodeID, Code: builtin2.StorageMarketActorCodeID,
Head: marketCid, Head: marketCid,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -356,7 +356,7 @@ func TestMarketPredicates(t *testing.T) {
marketCid, err := store.Put(ctx, marketState0) marketCid, err := store.Put(ctx, marketState0)
require.NoError(t, err) require.NoError(t, err)
marketState, err := market.Load(store, &types.Actor{ marketState, err := market.Load(store, &types.Actor{
Code: builtin0.StorageMarketActorCodeID, Code: builtin2.StorageMarketActorCodeID,
Head: marketCid, Head: marketCid,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -370,7 +370,7 @@ func TestMarketPredicates(t *testing.T) {
func TestMinerSectorChange(t *testing.T) { func TestMinerSectorChange(t *testing.T) {
ctx := context.Background() ctx := context.Background()
bs := bstore.NewTemporarySync() bs := bstore.NewTemporarySync()
store := adt.WrapStore(ctx, cbornode.NewCborStore(bs)) store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
nextID := uint64(0) nextID := uint64(0)
nextIDAddrF := func() address.Address { nextIDAddrF := func() address.Address {
@ -379,12 +379,12 @@ func TestMinerSectorChange(t *testing.T) {
} }
owner, worker := nextIDAddrF(), nextIDAddrF() owner, worker := nextIDAddrF(), nextIDAddrF()
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner0.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10)) si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner2.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)) si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner2.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)) 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}) 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 // 0 delete
// 1 extend // 1 extend
// 2 same // 2 same
@ -400,8 +400,8 @@ func TestMinerSectorChange(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
api := newMockAPI(bs) api := newMockAPI(bs)
api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin0.StorageMinerActorCodeID}) api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin2.StorageMinerActorCodeID})
api.setActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin0.StorageMinerActorCodeID}) api.setActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin2.StorageMinerActorCodeID})
preds := NewStatePredicates(api) preds := NewStatePredicates(api)
@ -467,7 +467,7 @@ type balance struct {
locked abi.TokenAmount 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) dealRootCid := createDealAMT(ctx, t, store, deals)
propRootCid := createProposalAMT(ctx, t, store, props) propRootCid := createProposalAMT(ctx, t, store, props)
balancesCids := createBalanceTable(ctx, t, store, balances) balancesCids := createBalanceTable(ctx, t, store, balances)
@ -482,16 +482,16 @@ func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals
return stateC return stateC
} }
func createEmptyMarketState(t *testing.T, store adt.Store) *market0.State { func createEmptyMarketState(t *testing.T, store adt2.Store) *market2.State {
emptyArrayCid, err := adt.MakeEmptyArray(store).Root() emptyArrayCid, err := adt2.MakeEmptyArray(store).Root()
require.NoError(t, err) require.NoError(t, err)
emptyMap, err := adt.MakeEmptyMap(store).Root() emptyMap, err := adt2.MakeEmptyMap(store).Root()
require.NoError(t, err) 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 { func createDealAMT(ctx context.Context, t *testing.T, store adt2.Store, deals map[abi.DealID]*market2.DealState) cid.Cid {
root := adt.MakeEmptyArray(store) root := adt2.MakeEmptyArray(store)
for dealID, dealState := range deals { for dealID, dealState := range deals {
err := root.Set(uint64(dealID), dealState) err := root.Set(uint64(dealID), dealState)
require.NoError(t, err) require.NoError(t, err)
@ -501,8 +501,8 @@ func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map
return rootCid return rootCid
} }
func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props map[abi.DealID]*market0.DealProposal) cid.Cid { func createProposalAMT(ctx context.Context, t *testing.T, store adt2.Store, props map[abi.DealID]*market2.DealProposal) cid.Cid {
root := adt.MakeEmptyArray(store) root := adt2.MakeEmptyArray(store)
for dealID, prop := range props { for dealID, prop := range props {
err := root.Set(uint64(dealID), prop) err := root.Set(uint64(dealID), prop)
require.NoError(t, err) require.NoError(t, err)
@ -512,16 +512,16 @@ func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props
return rootCid return rootCid
} }
func createBalanceTable(ctx context.Context, t *testing.T, store adt.Store, balances map[address.Address]balance) [2]cid.Cid { func createBalanceTable(ctx context.Context, t *testing.T, store adt2.Store, balances map[address.Address]balance) [2]cid.Cid {
escrowMapRoot := adt.MakeEmptyMap(store) escrowMapRoot := adt2.MakeEmptyMap(store)
escrowMapRootCid, err := escrowMapRoot.Root() escrowMapRootCid, err := escrowMapRoot.Root()
require.NoError(t, err) require.NoError(t, err)
escrowRoot, err := adt.AsBalanceTable(store, escrowMapRootCid) escrowRoot, err := adt2.AsBalanceTable(store, escrowMapRootCid)
require.NoError(t, err) require.NoError(t, err)
lockedMapRoot := adt.MakeEmptyMap(store) lockedMapRoot := adt2.MakeEmptyMap(store)
lockedMapRootCid, err := lockedMapRoot.Root() lockedMapRootCid, err := lockedMapRoot.Root()
require.NoError(t, err) require.NoError(t, err)
lockedRoot, err := adt.AsBalanceTable(store, lockedMapRootCid) lockedRoot, err := adt2.AsBalanceTable(store, lockedMapRootCid)
require.NoError(t, err) require.NoError(t, err)
for addr, balance := range balances { 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} 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) rootCid := createSectorsAMT(ctx, t, store, sectors)
state := createEmptyMinerState(ctx, t, store, owner, worker) 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 return stateC
} }
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address) *miner0.State { func createEmptyMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner, worker address.Address) *miner2.State {
emptyArrayCid, err := adt.MakeEmptyArray(store).Root() emptyArrayCid, err := adt2.MakeEmptyArray(store).Root()
require.NoError(t, err) require.NoError(t, err)
emptyMap, err := adt.MakeEmptyMap(store).Root() emptyMap, err := adt2.MakeEmptyMap(store).Root()
require.NoError(t, err) 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) require.NoError(t, err)
emptyVestingFunds := miner0.ConstructVestingFunds() emptyVestingFunds := miner2.ConstructVestingFunds()
emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds) emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds)
require.NoError(t, err) require.NoError(t, err)
emptyDeadlines := miner0.ConstructDeadlines(emptyDeadline) emptyDeadlines := miner2.ConstructDeadlines(emptyDeadline)
emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines) emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines)
require.NoError(t, err) 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) emptyBitfieldCid, err := store.Put(store.Context(), emptyBitfield)
require.NoError(t, err) 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) require.NoError(t, err)
return state return state
} }
func createSectorsAMT(ctx context.Context, t *testing.T, store adt.Store, sectors []miner.SectorOnChainInfo) cid.Cid { func createSectorsAMT(ctx context.Context, t *testing.T, store adt2.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
root := adt.MakeEmptyArray(store) root := adt2.MakeEmptyArray(store)
for _, sector := range sectors { 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), &sector) err := root.Set(uint64(sector.SectorNumber), &sector)
require.NoError(t, err) require.NoError(t, err)
} }
@ -614,8 +628,8 @@ const (
) )
// returns a unique SectorPreCommitInfo with each invocation with SectorNumber set to `sectorNo`. // 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 { func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner2.SectorPreCommitInfo {
return &miner0.SectorPreCommitInfo{ return &miner2.SectorPreCommitInfo{
SealProof: abi.RegisteredSealProof_StackedDrg32GiBV1, SealProof: abi.RegisteredSealProof_StackedDrg32GiBV1,
SectorNumber: sectorNo, SectorNumber: sectorNo,
SealedCID: sealed, 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 && return expected.LastUpdatedEpoch == actual.LastUpdatedEpoch &&
expected.SectorStartEpoch == actual.SectorStartEpoch && expected.SectorStartEpoch == actual.SectorStartEpoch &&
expected.SlashEpoch == actual.SlashEpoch expected.SlashEpoch == actual.SlashEpoch

View File

@ -8,13 +8,11 @@ import (
"sync/atomic" "sync/atomic"
"time" "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-address"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/crypto"
"github.com/google/uuid"
block "github.com/ipfs/go-block-format" block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-blockservice" "github.com/ipfs/go-blockservice"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
@ -26,6 +24,8 @@ import (
"go.opencensus.io/trace" "go.opencensus.io/trace"
"golang.org/x/xerrors" "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/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/actors/policy"
@ -50,7 +50,7 @@ const msgsPerBlock = 20
//nolint:deadcode,varcheck //nolint:deadcode,varcheck
var log = logging.Logger("gen") var log = logging.Logger("gen")
var ValidWpostForTesting = []proof.PoStProof{{ var ValidWpostForTesting = []proof2.PoStProof{{
ProofBytes: []byte("valid proof"), 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, func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticket *types.Ticket,
eticket *types.ElectionProof, bvals []types.BeaconEntry, height abi.ChainEpoch, 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 var ts uint64
if cg.Timestamper != nil { if cg.Timestamper != nil {
@ -605,7 +605,7 @@ func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*cr
type WinningPoStProver interface { type WinningPoStProver interface {
GenerateCandidates(context.Context, abi.PoStRandomness, uint64) ([]uint64, error) 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{} type wppProvider struct{}
@ -614,7 +614,7 @@ func (wpp *wppProvider) GenerateCandidates(ctx context.Context, _ abi.PoStRandom
return []uint64{0}, nil 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 return ValidWpostForTesting, nil
} }
@ -681,15 +681,15 @@ type genFakeVerifier struct{}
var _ ffiwrapper.Verifier = (*genFakeVerifier)(nil) 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 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") 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") panic("not supported")
} }

View File

@ -24,11 +24,12 @@ import (
"github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "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" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" 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/state"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
@ -47,7 +48,7 @@ func MinerAddress(genesisIndex uint64) address.Address {
} }
type fakedSigSyscalls struct { type fakedSigSyscalls struct {
runtime.Syscalls runtime2.Syscalls
} }
func (fss *fakedSigSyscalls) VerifySignature(signature crypto.Signature, signer address.Address, plaintext []byte) error { 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 { 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{ return &fakedSigSyscalls{
base(ctx, cstate, cst), base(ctx, cstate, cst),
} }
@ -114,7 +115,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
} }
params := mustEnc(constructorParams) 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 { if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err) 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()) { if m.MarketBalance.GreaterThan(big.Zero()) {
params := mustEnc(&minerInfos[i].maddr) 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 { if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner (add balance): %w", err) 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 { 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) 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 { if err != nil {
return xerrors.Errorf("failed to create genesis miner (publish deals): %w", err) 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) pledge = big.Add(pcd, pledge)
fmt.Println(types.FIL(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 { if err != nil {
return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err)
} }
// Commit one-by-one, otherwise pledge math tends to explode // Commit one-by-one, otherwise pledge math tends to explode
confirmParams := &builtin.ConfirmSectorProofsParams{ confirmParams := &builtin0.ConfirmSectorProofsParams{
Sectors: []abi.SectorNumber{preseal.SectorID}, 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 { if err != nil {
return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err) 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) { 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 { if err != nil {
return nil, err return nil, err
} }
@ -373,7 +374,7 @@ func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs [
market.Address, market.Address,
maddr, maddr,
abi.NewTokenAmount(0), abi.NewTokenAmount(0),
builtin.MethodsMarket.VerifyDealsForActivation, builtin0.MethodsMarket.VerifyDealsForActivation,
mustEnc(params), mustEnc(params),
) )
if err != nil { 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) { 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 { if err != nil {
return nil, err 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{ rt := unsafeVM.MakeRuntime(ctx, &types.Message{
GasLimit: 1_000_000_000, GasLimit: 1_000_000_000,
From: maddr, From: maddr,
}, maddr, 0, 0, 0) })
return rt.TotalFilCircSupply() return rt.TotalFilCircSupply()
} }

View File

@ -50,12 +50,27 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value
return ret.Return, nil return ret.Return, nil
} }
var GenesisNetworkVersion = func() network.Version { // TODO: Get from build/ // TODO: Get from build
if build.UseNewestNetwork() { // TODO: Get from build/ // TODO: make a list/schedule of these.
return build.NewestNetworkVersion // TODO: Get from build/ var GenesisNetworkVersion = func() network.Version {
} // TODO: Get from build/ // returns the version _before_ the first upgrade.
return network.Version1 // TODO: Get from build/ if build.UpgradeBreezeHeight >= 0 {
}() // TODO: Get from build/ 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/ func genesisNetworkVersion(context.Context, abi.ChainEpoch) network.Version { // TODO: Get from build/
return GenesisNetworkVersion // TODO: Get from build/ return GenesisNetworkVersion // TODO: Get from build/

View File

@ -4,17 +4,14 @@ import (
"context" "context"
"github.com/filecoin-project/go-state-types/crypto" "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" cid "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/api" "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/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/lib/sigs/bls" "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) 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 { if err != nil {
return nil, xerrors.Errorf("failed to get miner worker: %w", err) 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 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() nosigbytes, err := next.SigningBytes()
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to get signing bytes for block: %w", err) 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, Type: api.MTBlock,
}) })
if err != nil { if err != nil {
@ -181,8 +177,8 @@ func aggregateSignatures(sigs []crypto.Signature) (*crypto.Signature, error) {
}, nil }, nil
} }
func toArray(store adt.Store, cids []cid.Cid) (cid.Cid, error) { func toArray(store blockadt.Store, cids []cid.Cid) (cid.Cid, error) {
arr := adt.MakeEmptyArray(store) arr := blockadt.MakeEmptyArray(store)
for i, c := range cids { for i, c := range cids {
oc := cbg.CborCid(c) oc := cbg.CborCid(c)
if err := arr.Set(uint64(i), &oc); err != nil { if err := arr.Set(uint64(i), &oc); err != nil {

View File

@ -4,15 +4,13 @@ import (
"context" "context"
"sync" "sync"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big" "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" "github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log" 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/api"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/builtin/market" "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, To: market.Address,
From: wallet, From: wallet,
Value: toAdd, Value: toAdd,
Method: builtin.MethodsMarket.AddBalance, Method: market.Methods.AddBalance,
Params: params, Params: params,
}, nil) }, nil)
if err != nil { if err != nil {

View File

@ -12,8 +12,8 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto" "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/api"
"github.com/filecoin-project/lotus/chain/actors" "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, To: market.Address,
From: wallet, From: wallet,
Value: toAdd, Value: toAdd,
Method: builtin.MethodsMarket.AddBalance, Method: market.Methods.AddBalance,
Params: params, Params: params,
} }
} }

View File

@ -6,6 +6,7 @@ import (
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/go-address" "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) { func GuessGasUsed(ctx context.Context, tsk types.TipSetKey, msg *types.SignedMessage, al ActorLookup) (int64, error) {
// MethodSend is the same in all versions. // MethodSend is the same in all versions.
if msg.Message.Method == builtin0.MethodSend { if msg.Message.Method == builtin.MethodSend {
switch msg.Message.From.Protocol() { switch msg.Message.From.Protocol() {
case address.BLS: case address.BLS:
return 1298450, nil return 1298450, nil

View File

@ -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{}{} 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 { if err := mp.localMsgs.Put(datastore.NewKey(string(m.Cid().Bytes())), msgb); err != nil {
return xerrors.Errorf("persisting local message: %w", err) return xerrors.Errorf("persisting local message: %w", err)
} }
@ -507,11 +512,6 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
<-mp.addSema <-mp.addSema
}() }()
msgb, err := m.Serialize()
if err != nil {
return cid.Undef, err
}
mp.curTsLk.Lock() mp.curTsLk.Lock()
publish, err := mp.addTs(m, mp.curTs, true, false) publish, err := mp.addTs(m, mp.curTs, true, false)
if err != nil { if err != nil {
@ -520,18 +520,19 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
} }
mp.curTsLk.Unlock() 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 { 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) 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 { 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 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 { func (mp *MessagePool) addLoaded(m *types.SignedMessage) error {
@ -837,11 +850,6 @@ func (mp *MessagePool) PushUntrusted(m *types.SignedMessage) (cid.Cid, error) {
<-mp.addSema <-mp.addSema
}() }()
msgb, err := m.Serialize()
if err != nil {
return cid.Undef, err
}
mp.curTsLk.Lock() mp.curTsLk.Lock()
publish, err := mp.addTs(m, mp.curTs, false, true) publish, err := mp.addTs(m, mp.curTs, false, true)
if err != nil { if err != nil {
@ -850,18 +858,19 @@ func (mp *MessagePool) PushUntrusted(m *types.SignedMessage) (cid.Cid, error) {
} }
mp.curTsLk.Unlock() 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 { 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) 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) { func (mp *MessagePool) Remove(from address.Address, nonce uint64, applied bool) {

View File

@ -8,16 +8,18 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "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/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/mock" "github.com/filecoin-project/lotus/chain/types/mock"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
_ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp" _ "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() { func init() {
@ -142,7 +144,7 @@ func (tma *testMpoolAPI) GetActorAfter(addr address.Address, ts *types.TipSet) (
} }
return &types.Actor{ return &types.Actor{
Code: builtin.StorageMarketActorCodeID, Code: builtin2.StorageMarketActorCodeID,
Nonce: nonce, Nonce: nonce,
Balance: balance, Balance: balance,
}, nil }, nil
@ -449,7 +451,7 @@ func TestLoadLocal(t *testing.T) {
tma.setBalance(a1, 1) // in FIL tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 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{}) msgs := make(map[cid.Cid]struct{})
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) 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(a1, 1) // in FIL
tma.setBalance(a2, 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++ { for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
_, err := mp.Push(m) _, err := mp.Push(m)
@ -576,7 +578,7 @@ func TestClearNonLocal(t *testing.T) {
tma.setBalance(a1, 1) // in FIL tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 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++ { for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
_, err := mp.Push(m) _, err := mp.Push(m)
@ -642,7 +644,7 @@ func TestUpdates(t *testing.T) {
t.Fatal(err) 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(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL tma.setBalance(a2, 1) // in FIL

View File

@ -5,11 +5,13 @@ import (
"testing" "testing"
"time" "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/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet" "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) { func TestRepubMessages(t *testing.T) {
@ -48,7 +50,7 @@ func TestRepubMessages(t *testing.T) {
t.Fatal(err) 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(a1, 1) // in FIL

View File

@ -13,17 +13,18 @@ import (
"sort" "sort"
"testing" "testing"
"github.com/filecoin-project/go-address"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore"
logging "github.com/ipfs/go-log" 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/build"
"github.com/filecoin-project/lotus/chain/messagepool/gasguess" "github.com/filecoin-project/lotus/chain/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/mock" "github.com/filecoin-project/lotus/chain/types/mock"
"github.com/filecoin-project/lotus/chain/wallet" "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/api"
_ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/bls"
@ -94,7 +95,7 @@ func TestMessageChains(t *testing.T) {
block := tma.nextBlock() block := tma.nextBlock()
ts := mock.TipSet(block) 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 tma.setBalance(a1, 1) // in FIL
@ -332,7 +333,7 @@ func TestMessageChainSkipping(t *testing.T) {
block := tma.nextBlock() block := tma.nextBlock()
ts := mock.TipSet(block) 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) baseFee := types.NewInt(0)
tma.setBalance(a1, 1) // in FIL tma.setBalance(a1, 1) // in FIL
@ -409,7 +410,7 @@ func TestBasicMessageSelection(t *testing.T) {
ts := mock.TipSet(block) ts := mock.TipSet(block)
tma.applyBlock(t, 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(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL tma.setBalance(a2, 1) // in FIL
@ -553,7 +554,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
ts := mock.TipSet(block) ts := mock.TipSet(block)
tma.applyBlock(t, 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(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL tma.setBalance(a2, 1) // in FIL
@ -616,7 +617,7 @@ func TestPriorityMessageSelection(t *testing.T) {
ts := mock.TipSet(block) ts := mock.TipSet(block)
tma.applyBlock(t, 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(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL tma.setBalance(a2, 1) // in FIL
@ -695,7 +696,7 @@ func TestPriorityMessageSelection2(t *testing.T) {
ts := mock.TipSet(block) ts := mock.TipSet(block)
tma.applyBlock(t, 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(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL tma.setBalance(a2, 1) // in FIL
@ -764,7 +765,7 @@ func TestPriorityMessageSelection3(t *testing.T) {
ts := mock.TipSet(block) ts := mock.TipSet(block)
tma.applyBlock(t, 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(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL tma.setBalance(a2, 1) // in FIL
@ -861,7 +862,7 @@ func TestOptimalMessageSelection1(t *testing.T) {
ts := mock.TipSet(block) ts := mock.TipSet(block)
tma.applyBlock(t, 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(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL tma.setBalance(a2, 1) // in FIL
@ -928,7 +929,7 @@ func TestOptimalMessageSelection2(t *testing.T) {
ts := mock.TipSet(block) ts := mock.TipSet(block)
tma.applyBlock(t, 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(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL tma.setBalance(a2, 1) // in FIL
@ -1006,7 +1007,7 @@ func TestOptimalMessageSelection3(t *testing.T) {
ts := mock.TipSet(block) ts := mock.TipSet(block)
tma.applyBlock(t, 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 { for _, a := range actors {
tma.setBalance(a, 1) // in FIL tma.setBalance(a, 1) // in FIL
@ -1086,7 +1087,7 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
ts := mock.TipSet(block) ts := mock.TipSet(block)
tma.applyBlock(t, 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) baseFee := types.NewInt(0)
for _, a := range actors { for _, a := range actors {

View File

@ -26,16 +26,18 @@ var log = logging.Logger("statetree")
// StateTree stores actors state by their ID. // StateTree stores actors state by their ID.
type StateTree struct { type StateTree struct {
root adt.Map root adt.Map
version types.StateTreeVersion version types.StateTreeVersion
info cid.Cid info cid.Cid
Store cbor.IpldStore Store cbor.IpldStore
lookupIDFun func(address.Address) (address.Address, error)
snaps *stateSnaps snaps *stateSnaps
} }
type stateSnaps struct { type stateSnaps struct {
layers []*stateSnapLayer layers []*stateSnapLayer
lastMaybeNonEmptyResolveCache int
} }
type stateSnapLayer struct { type stateSnapLayer struct {
@ -67,7 +69,12 @@ func (ss *stateSnaps) addLayer() {
func (ss *stateSnaps) dropLayer() { func (ss *stateSnaps) dropLayer() {
ss.layers[len(ss.layers)-1] = nil // allow it to be GCed ss.layers[len(ss.layers)-1] = nil // allow it to be GCed
ss.layers = ss.layers[:len(ss.layers)-1] ss.layers = ss.layers[:len(ss.layers)-1]
if ss.lastMaybeNonEmptyResolveCache == len(ss.layers) {
ss.lastMaybeNonEmptyResolveCache = len(ss.layers) - 1
}
} }
func (ss *stateSnaps) mergeLastLayer() { func (ss *stateSnaps) mergeLastLayer() {
@ -86,7 +93,13 @@ func (ss *stateSnaps) mergeLastLayer() {
} }
func (ss *stateSnaps) resolveAddress(addr address.Address) (address.Address, bool) { 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] resa, ok := ss.layers[i].resolveCache[addr]
if ok { if ok {
return resa, true 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) { func (ss *stateSnaps) cacheResolveAddress(addr, resa address.Address) {
ss.layers[len(ss.layers)-1].resolveCache[addr] = resa 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) { 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 nil, err
} }
return &StateTree{ s := &StateTree{
root: root, root: root,
info: info, info: info,
version: ver, version: ver,
Store: cst, Store: cst,
snaps: newStateSnaps(), snaps: newStateSnaps(),
}, nil }
s.lookupIDFun = s.lookupIDinternal
return s, nil
} }
func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { 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 nil, err
} }
return &StateTree{ s := &StateTree{
root: nd, root: nd,
info: root.Info, info: root.Info,
version: root.Version, version: root.Version,
Store: cst, Store: cst,
snaps: newStateSnaps(), snaps: newStateSnaps(),
}, nil }
s.lookupIDFun = s.lookupIDinternal
return s, nil
default: default:
return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version) 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 return nil
} }
// LookupID gets the ID address of this actor's `addr` stored in the `InitActor`. func (st *StateTree) lookupIDinternal(addr address.Address) (address.Address, error) {
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
}
act, err := st.GetActor(init_.Address) act, err := st.GetActor(init_.Address)
if err != nil { if err != nil {
return address.Undef, xerrors.Errorf("getting init actor: %w", err) 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 { if err != nil {
return address.Undef, xerrors.Errorf("resolve address %s: %w", addr, err) 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) st.snaps.cacheResolveAddress(addr, a)

View File

@ -10,7 +10,7 @@ import (
address "github.com/filecoin-project/go-address" address "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/network" "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/build"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@ -18,7 +18,7 @@ import (
func BenchmarkStateTreeSet(b *testing.B) { func BenchmarkStateTreeSet(b *testing.B) {
cst := cbor.NewMemCborStore() cst := cbor.NewMemCborStore()
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) st, err := NewStateTree(cst, types.StateTreeVersion1)
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
@ -33,8 +33,8 @@ func BenchmarkStateTreeSet(b *testing.B) {
} }
err = st.SetActor(a, &types.Actor{ err = st.SetActor(a, &types.Actor{
Balance: types.NewInt(1258812523), Balance: types.NewInt(1258812523),
Code: builtin.StorageMinerActorCodeID, Code: builtin2.StorageMinerActorCodeID,
Head: builtin.AccountActorCodeID, Head: builtin2.AccountActorCodeID,
Nonce: uint64(i), Nonce: uint64(i),
}) })
if err != nil { if err != nil {
@ -60,8 +60,8 @@ func BenchmarkStateTreeSetFlush(b *testing.B) {
} }
err = st.SetActor(a, &types.Actor{ err = st.SetActor(a, &types.Actor{
Balance: types.NewInt(1258812523), Balance: types.NewInt(1258812523),
Code: builtin.StorageMinerActorCodeID, Code: builtin2.StorageMinerActorCodeID,
Head: builtin.AccountActorCodeID, Head: builtin2.AccountActorCodeID,
Nonce: uint64(i), Nonce: uint64(i),
}) })
if err != nil { 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) { func BenchmarkStateTree10kGetActor(b *testing.B) {
cst := cbor.NewMemCborStore() cst := cbor.NewMemCborStore()
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion)) st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
@ -86,8 +183,8 @@ func BenchmarkStateTree10kGetActor(b *testing.B) {
} }
err = st.SetActor(a, &types.Actor{ err = st.SetActor(a, &types.Actor{
Balance: types.NewInt(1258812523 + uint64(i)), Balance: types.NewInt(1258812523 + uint64(i)),
Code: builtin.StorageMinerActorCodeID, Code: builtin2.StorageMinerActorCodeID,
Head: builtin.AccountActorCodeID, Head: builtin2.AccountActorCodeID,
Nonce: uint64(i), Nonce: uint64(i),
}) })
if err != nil { if err != nil {
@ -129,8 +226,8 @@ func TestSetCache(t *testing.T) {
act := &types.Actor{ act := &types.Actor{
Balance: types.NewInt(0), Balance: types.NewInt(0),
Code: builtin.StorageMinerActorCodeID, Code: builtin2.StorageMinerActorCodeID,
Head: builtin.AccountActorCodeID, Head: builtin2.AccountActorCodeID,
Nonce: 0, Nonce: 0,
} }
@ -173,7 +270,7 @@ func TestSnapshots(t *testing.T) {
t.Fatal(err) 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) t.Fatal(err)
} }
@ -182,7 +279,7 @@ func TestSnapshots(t *testing.T) {
t.Fatal(err) 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) t.Fatal(err)
} }
@ -193,7 +290,7 @@ func TestSnapshots(t *testing.T) {
} }
// more operations in top level call... // 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) t.Fatal(err)
} }
@ -202,7 +299,7 @@ func TestSnapshots(t *testing.T) {
t.Fatal(err) 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) t.Fatal(err)
} }

View File

@ -86,6 +86,10 @@ func DefaultUpgradeSchedule() UpgradeSchedule {
Height: build.UpgradeLiftoffHeight, Height: build.UpgradeLiftoffHeight,
Network: network.Version5, Network: network.Version5,
Migration: UpgradeLiftoff, Migration: UpgradeLiftoff,
}, {
Height: build.UpgradeKumquatHeight,
Network: network.Version6,
Migration: nil,
}} }}
if build.UpgradeActorsV2Height == math.MaxInt64 { // disable actors upgrade 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) 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 { if err != nil {
return cid.Undef, xerrors.Errorf("resetting genesis msig start epochs: %w", err) 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 { if err != nil {
return cid.Undef, xerrors.Errorf("splitting first msig: %w", err) 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 { if err != nil {
return cid.Undef, xerrors.Errorf("splitting second msig: %w", err) 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) 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 { if err != nil {
return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) 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 { if err != nil {
return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) 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 { if err != nil {
return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) 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 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 { if portions < 1 {
return xerrors.Errorf("cannot split into 0 portions") 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 // 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() gb, err := sm.cs.GetGenesis()
if err != nil { if err != nil {
return xerrors.Errorf("getting genesis block: %w", err) return xerrors.Errorf("getting genesis block: %w", err)
@ -881,7 +885,7 @@ func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store,
return nil 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) act, err := tree.GetActor(addr)
if err != nil { if err != nil {
return xerrors.Errorf("getting actor: %w", err) return xerrors.Errorf("getting actor: %w", err)

View File

@ -16,14 +16,15 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor" "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" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/runtime" 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/api"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "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/actors/policy"
"github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen"
. "github.com/filecoin-project/lotus/chain/stmgr" . "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. // 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) } func (testActor) State() cbor.Er { return new(testActorState) }
type testActorState struct { 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.ValidateImmediateCallerAcceptAny()
rt.StateCreate(&testActorState{11}) rt.StateCreate(&testActorState{11})
//fmt.Println("NEW ACTOR ADDRESS IS: ", rt.Receiver()) //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 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() rt.ValidateImmediateCallerAcceptAny()
var st testActorState var st testActorState
rt.StateReadonly(&st) rt.StateReadonly(&st)
@ -175,15 +176,15 @@ func TestForkHeightTriggers(t *testing.T) {
var msgs []*types.SignedMessage 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
m := &types.Message{ m := &types.Message{
From: cg.Banker(), From: cg.Banker(),
To: lotusinit.Address, To: _init.Address,
Method: builtin.MethodsInit.Exec, Method: _init.Methods.Exec,
Params: enc, Params: enc,
GasLimit: types.TestGasLimit, GasLimit: types.TestGasLimit,
} }
@ -273,15 +274,15 @@ func TestForkRefuseCall(t *testing.T) {
cg.SetStateManager(sm) cg.SetStateManager(sm)
enc, err := actors.SerializeParams(&init0.ExecParams{CodeCID: (testActor{}).Code()}) enc, err := actors.SerializeParams(&init2.ExecParams{CodeCID: (testActor{}).Code()})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
m := &types.Message{ m := &types.Message{
From: cg.Banker(), From: cg.Banker(),
To: lotusinit.Address, To: _init.Address,
Method: builtin.MethodsInit.Exec, Method: _init.Methods.Exec,
Params: enc, Params: enc,
GasLimit: types.TestGasLimit, GasLimit: types.TestGasLimit,
Value: types.NewInt(0), Value: types.NewInt(0),

View File

@ -6,16 +6,6 @@ import (
"fmt" "fmt"
"sync" "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" "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor" cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2" 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/big"
"github.com/filecoin-project/go-state-types/network" "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/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt" "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/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/multisig"
"github.com/filecoin-project/lotus/chain/actors/builtin/paych" "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/power"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward" "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/state"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@ -48,6 +46,8 @@ const LookbackNoLimit = abi.ChainEpoch(-1)
var log = logging.Logger("statemgr") var log = logging.Logger("statemgr")
type StateManagerAPI interface { 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) 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) 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) 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 { runCron := func(epoch abi.ChainEpoch) error {
cronMsg := &types.Message{ cronMsg := &types.Message{
To: builtin0.CronActorAddr, To: cron.Address,
From: builtin0.SystemActorAddr, From: builtin.SystemActorAddr,
Nonce: uint64(epoch), Nonce: uint64(epoch),
Value: types.NewInt(0), Value: types.NewInt(0),
GasFeeCap: types.NewInt(0), GasFeeCap: types.NewInt(0),
GasPremium: types.NewInt(0), GasPremium: types.NewInt(0),
GasLimit: build.BlockGasLimit * 10000, // Make super sure this is never too little GasLimit: build.BlockGasLimit * 10000, // Make super sure this is never too little
Method: builtin0.MethodsCron.EpochTick, Method: cron.Methods.EpochTick,
Params: nil, Params: nil,
} }
ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg) ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg)
@ -350,14 +350,14 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
} }
rwMsg := &types.Message{ rwMsg := &types.Message{
From: builtin0.SystemActorAddr, From: builtin.SystemActorAddr,
To: reward.Address, To: reward.Address,
Nonce: uint64(epoch), Nonce: uint64(epoch),
Value: types.NewInt(0), Value: types.NewInt(0),
GasFeeCap: types.NewInt(0), GasFeeCap: types.NewInt(0),
GasPremium: types.NewInt(0), GasPremium: types.NewInt(0),
GasLimit: 1 << 30, GasLimit: 1 << 30,
Method: builtin0.MethodsReward.AwardBlockReward, Method: reward.Methods.AwardBlockReward,
Params: params, Params: params,
} }
ret, actErr := vmi.ApplyImplicitMessage(ctx, rwMsg) ret, actErr := vmi.ApplyImplicitMessage(ctx, rwMsg)
@ -974,7 +974,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
} else if builtin.IsAccountActor(act.Code) { } else if builtin.IsAccountActor(act.Code) {
// should exclude burnt funds actor and "remainder account actor" // should exclude burnt funds actor and "remainder account actor"
// should only ever be "faucet" accounts in testnets // should only ever be "faucet" accounts in testnets
if kaddr == builtin0.BurntFundsActorAddr { if kaddr == builtin.BurntFundsActorAddr {
return nil return nil
} }
@ -1052,24 +1052,24 @@ func (sm *StateManager) setupPreIgnitionGenesisActorsTestnet(ctx context.Context
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount) totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
// 6 months // 6 months
sixMonths := abi.ChainEpoch(183 * builtin0.EpochsInDay) sixMonths := abi.ChainEpoch(183 * builtin.EpochsInDay)
totalsByEpoch[sixMonths] = big.NewInt(49_929_341) totalsByEpoch[sixMonths] = big.NewInt(49_929_341)
totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700)) totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700))
// 1 year // 1 year
oneYear := abi.ChainEpoch(365 * builtin0.EpochsInDay) oneYear := abi.ChainEpoch(365 * builtin.EpochsInDay)
totalsByEpoch[oneYear] = big.NewInt(22_421_712) totalsByEpoch[oneYear] = big.NewInt(22_421_712)
// 2 years // 2 years
twoYears := abi.ChainEpoch(2 * 365 * builtin0.EpochsInDay) twoYears := abi.ChainEpoch(2 * 365 * builtin.EpochsInDay)
totalsByEpoch[twoYears] = big.NewInt(7_223_364) totalsByEpoch[twoYears] = big.NewInt(7_223_364)
// 3 years // 3 years
threeYears := abi.ChainEpoch(3 * 365 * builtin0.EpochsInDay) threeYears := abi.ChainEpoch(3 * 365 * builtin.EpochsInDay)
totalsByEpoch[threeYears] = big.NewInt(87_637_883) totalsByEpoch[threeYears] = big.NewInt(87_637_883)
// 6 years // 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.NewInt(100_000_000)
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_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) totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
// 6 months // 6 months
sixMonths := abi.ChainEpoch(183 * builtin0.EpochsInDay) sixMonths := abi.ChainEpoch(183 * builtin.EpochsInDay)
totalsByEpoch[sixMonths] = big.NewInt(49_929_341) totalsByEpoch[sixMonths] = big.NewInt(49_929_341)
totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700)) totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700))
// 1 year // 1 year
oneYear := abi.ChainEpoch(365 * builtin0.EpochsInDay) oneYear := abi.ChainEpoch(365 * builtin.EpochsInDay)
totalsByEpoch[oneYear] = big.NewInt(22_421_712) totalsByEpoch[oneYear] = big.NewInt(22_421_712)
// 2 years // 2 years
twoYears := abi.ChainEpoch(2 * 365 * builtin0.EpochsInDay) twoYears := abi.ChainEpoch(2 * 365 * builtin.EpochsInDay)
totalsByEpoch[twoYears] = big.NewInt(7_223_364) totalsByEpoch[twoYears] = big.NewInt(7_223_364)
// 3 years // 3 years
threeYears := abi.ChainEpoch(3 * 365 * builtin0.EpochsInDay) threeYears := abi.ChainEpoch(3 * 365 * builtin.EpochsInDay)
totalsByEpoch[threeYears] = big.NewInt(87_637_883) totalsByEpoch[threeYears] = big.NewInt(87_637_883)
// 6 years // 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.NewInt(100_000_000)
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_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) { 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 { if err != nil {
return big.Zero(), xerrors.Errorf("failed to load burnt actor: %w", err) return big.Zero(), xerrors.Errorf("failed to load burnt actor: %w", err)
} }

View File

@ -12,7 +12,6 @@ import (
"github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors/policy"
cid "github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen" 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/crypto"
"github.com/filecoin-project/go-state-types/rt" "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" 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" exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors/builtin"
init_ "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/builtin/market" "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/miner"
"github.com/filecoin-project/lotus/chain/actors/builtin/power" "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/beacon"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store" "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) 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) act, err := sm.LoadActorRaw(ctx, maddr, st)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to load miner actor: %w", err) 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) 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 { for i, sinfo := range sectors {
out[i] = proof0.SectorInfo{ out[i] = builtin.SectorInfo{
SealProof: spt, SealProof: spt,
SectorNumber: sinfo.SectorNumber, SectorNumber: sinfo.SectorNumber,
SealedCID: sinfo.SealedCID, SealedCID: sinfo.SealedCID,
@ -256,25 +255,6 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
return out, nil 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) { func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (bool, error) {
act, err := sm.LoadActor(ctx, power.Address, ts) act, err := sm.LoadActor(ctx, power.Address, ts)
if err != nil { 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) 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) lbst, _, err := sm.TipSetState(ctx, lbts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
act, err := sm.LoadActorRaw(ctx, maddr, lbst) 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 { if err != nil {
return nil, xerrors.Errorf("failed to load miner actor: %w", err) 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)) methods := make(map[abi.MethodNum]MethodMeta, len(exports))
// Explicitly add send, it's special. // Explicitly add send, it's special.
// Note that builtin2.MethodSend = builtin0.MethodSend = 0. methods[builtin.MethodSend] = MethodMeta{
methods[builtin0.MethodSend] = MethodMeta{
Name: "Send", Name: "Send",
Params: reflect.TypeOf(new(abi.EmptyValue)), Params: reflect.TypeOf(new(abi.EmptyValue)),
Ret: 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") fnName = strings.TrimSuffix(fnName[strings.LastIndexByte(fnName, '.')+1:], "-fm")
switch abi.MethodNum(number) { switch abi.MethodNum(number) {
case builtin0.MethodSend: case builtin.MethodSend:
// Note that builtin2.MethodSend = builtin0.MethodSend = 0.
panic("method 0 is reserved for Send") panic("method 0 is reserved for Send")
case builtin0.MethodConstructor: case builtin.MethodConstructor:
// Note that builtin2.MethodConstructor = builtin0.MethodConstructor = 1.
if fnName != "Constructor" { if fnName != "Constructor" {
panic("method 1 is reserved for Constructor") panic("method 1 is reserved for Constructor")
} }

View File

@ -19,12 +19,12 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/builtin" blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/adt" "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/chain/vm"
"github.com/filecoin-project/lotus/journal" "github.com/filecoin-project/lotus/journal"
bstore "github.com/filecoin-project/lotus/lib/blockstore" 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) { func (cs *ChainStore) readAMTCids(root cid.Cid) ([]cid.Cid, error) {
ctx := context.TODO() ctx := context.TODO()
// block headers use adt0, for now. // 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 { if err != nil {
return nil, xerrors.Errorf("amt load: %w", err) 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) { func (cs *ChainStore) GetParentReceipt(b *types.BlockHeader, i int) (*types.MessageReceipt, error) {
ctx := context.TODO() ctx := context.TODO()
// block headers use adt0, for now. // 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 { if err != nil {
return nil, xerrors.Errorf("amt load: %w", err) 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 var cids []cid.Cid
if !skipOldMsgs || b.Height > ts.Height()-inclRecentRoots { if !skipOldMsgs || b.Height > ts.Height()-inclRecentRoots {
mcids, err := recurseLinks(cs.bs, walked, b.Messages, []cid.Cid{b.Messages}) if walked.Visit(b.Messages) {
if err != nil { mcids, err := recurseLinks(cs.bs, walked, b.Messages, []cid.Cid{b.Messages})
return xerrors.Errorf("recursing messages failed: %w", err) if err != nil {
return xerrors.Errorf("recursing messages failed: %w", err)
}
cids = mcids
} }
cids = mcids
} }
if b.Height > 0 { if b.Height > 0 {
@ -1331,12 +1333,14 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe
out := cids out := cids
if b.Height == 0 || b.Height > ts.Height()-inclRecentRoots { if b.Height == 0 || b.Height > ts.Height()-inclRecentRoots {
cids, err := recurseLinks(cs.bs, walked, b.ParentStateRoot, []cid.Cid{b.ParentStateRoot}) if walked.Visit(b.ParentStateRoot) {
if err != nil { cids, err := recurseLinks(cs.bs, walked, b.ParentStateRoot, []cid.Cid{b.ParentStateRoot})
return xerrors.Errorf("recursing genesis state failed: %w", err) if err != nil {
} return xerrors.Errorf("recursing genesis state failed: %w", err)
}
out = append(out, cids...) out = append(out, cids...)
}
} }
for _, c := range out { for _, c := range out {

View File

@ -12,6 +12,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/gen" "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/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/blockstore" "github.com/filecoin-project/lotus/lib/blockstore"
@ -107,3 +108,60 @@ func TestChainExportImport(t *testing.T) {
t.Fatal("imported chain differed from exported chain") 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)
}
}
}

View File

@ -23,7 +23,7 @@ import (
"go.opencensus.io/stats" "go.opencensus.io/stats"
"go.opencensus.io/tag" "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/build"
"github.com/filecoin-project/lotus/chain" "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 { 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 // TODO there has to be a simpler way to do this without the blockstore dance
// block headers use adt0 // block headers use adt0
store := adt0.WrapStore(ctx, cbor.NewCborStore(blockstore.NewTemporary())) store := blockadt.WrapStore(ctx, cbor.NewCborStore(blockstore.NewTemporary()))
bmArr := adt0.MakeEmptyArray(store) bmArr := blockadt.MakeEmptyArray(store)
smArr := adt0.MakeEmptyArray(store) smArr := blockadt.MakeEmptyArray(store)
for i, m := range msg.BlsMessages { for i, m := range msg.BlsMessages {
c := cbg.CborCid(m) c := cbg.CborCid(m)

View File

@ -15,8 +15,6 @@ import (
"github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/Gurpartap/async" "github.com/Gurpartap/async"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
blocks "github.com/ipfs/go-block-format" blocks "github.com/ipfs/go-block-format"
@ -37,7 +35,11 @@ import (
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
blst "github.com/supranational/blst/bindings/go" 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/api"
"github.com/filecoin-project/lotus/build" "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) syncer.Exchange.AddPeer(from)
bestPweight := syncer.store.GetHeaviestTipSet().ParentWeight() hts := syncer.store.GetHeaviestTipSet()
bestPweight := hts.ParentWeight()
targetWeight := fts.TipSet().ParentWeight() targetWeight := fts.TipSet().ParentWeight()
if targetWeight.LessThan(bestPweight) { if targetWeight.LessThan(bestPweight) {
var miners []string var miners []string
for _, blk := range fts.TipSet().Blocks() { for _, blk := range fts.TipSet().Blocks() {
miners = append(miners, blk.Miner.String()) 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 return false
} }
@ -462,9 +465,9 @@ func zipTipSetAndMessages(bs cbor.IpldStore, ts *types.TipSet, allbmsgs []*types
// of both types (BLS and Secpk). // of both types (BLS and Secpk).
func computeMsgMeta(bs cbor.IpldStore, bmsgCids, smsgCids []cid.Cid) (cid.Cid, error) { func computeMsgMeta(bs cbor.IpldStore, bmsgCids, smsgCids []cid.Cid) (cid.Cid, error) {
// block headers use adt0 // block headers use adt0
store := adt0.WrapStore(context.TODO(), bs) store := blockadt.WrapStore(context.TODO(), bs)
bmArr := adt0.MakeEmptyArray(store) bmArr := blockadt.MakeEmptyArray(store)
smArr := adt0.MakeEmptyArray(store) smArr := blockadt.MakeEmptyArray(store)
for i, m := range bmsgCids { for i, m := range bmsgCids {
c := cbg.CborCid(m) 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) 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, Randomness: rand,
Proofs: h.WinPoStProof, Proofs: h.WinPoStProof,
ChallengedSectors: sectors, ChallengedSectors: sectors,
@ -1109,9 +1112,9 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
// Validate message arrays in a temporary blockstore. // Validate message arrays in a temporary blockstore.
tmpbs := bstore.NewTemporary() 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 { for i, m := range b.BlsMessages {
if err := checkMsg(m); err != nil { if err := checkMsg(m); err != nil {
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err) 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 { for i, m := range b.SecpkMessages {
if err := checkMsg(m); err != nil { if err := checkMsg(m); err != nil {
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err) return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
@ -1393,6 +1396,11 @@ loop:
} }
base := blockSet[len(blockSet)-1] base := blockSet[len(blockSet)-1]
if base.Equals(known) {
blockSet = blockSet[:len(blockSet)-1]
base = blockSet[len(blockSet)-1]
}
if base.IsChildOf(known) { if base.IsChildOf(known) {
// common case: receiving blocks that are building on top of our best tipset // common case: receiving blocks that are building on top of our best tipset
return blockSet, nil 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 { 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) return gen.VerifyVRF(ctx, worker, rand, evrf)
} }

View File

@ -2,7 +2,9 @@ package chain
import ( import (
"context" "context"
"os"
"sort" "sort"
"strings"
"sync" "sync"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@ -11,6 +13,14 @@ import (
const BootstrapPeerThreshold = 2 const BootstrapPeerThreshold = 2
var coalesceForksParents = false
func init() {
if os.Getenv("LOTUS_SYNC_REL_PARENT") == "yes" {
coalesceForksParents = true
}
}
const ( const (
BSStateInit = 0 BSStateInit = 0
BSStateSelected = 1 BSStateSelected = 1
@ -152,6 +162,19 @@ func newSyncTargetBucket(tipsets ...*types.TipSet) *syncTargetBucket {
return &stb 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 { func (sbs *syncBucketSet) RelatedToAny(ts *types.TipSet) bool {
for _, b := range sbs.buckets { for _, b := range sbs.buckets {
if b.sameChainAs(ts) { if b.sameChainAs(ts) {
@ -198,13 +221,17 @@ func (sbs *syncBucketSet) removeBucket(toremove *syncTargetBucket) {
} }
func (sbs *syncBucketSet) PopRelated(ts *types.TipSet) *syncTargetBucket { func (sbs *syncBucketSet) PopRelated(ts *types.TipSet) *syncTargetBucket {
var bOut *syncTargetBucket
for _, b := range sbs.buckets { for _, b := range sbs.buckets {
if b.sameChainAs(ts) { if b.sameChainAs(ts) {
sbs.removeBucket(b) 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 { func (sbs *syncBucketSet) Heaviest() *types.TipSet {
@ -224,8 +251,7 @@ func (sbs *syncBucketSet) Empty() bool {
} }
type syncTargetBucket struct { type syncTargetBucket struct {
tips []*types.TipSet tips []*types.TipSet
count int
} }
func (stb *syncTargetBucket) sameChainAs(ts *types.TipSet) bool { 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() { if ts.Parents() == t.Key() {
return true return true
} }
if coalesceForksParents && ts.Parents() == t.Parents() {
return true
}
} }
return false return false
} }
func (stb *syncTargetBucket) add(ts *types.TipSet) { func (stb *syncTargetBucket) add(ts *types.TipSet) {
stb.count++
for _, t := range stb.tips { for _, t := range stb.tips {
if t.Equals(ts) { if t.Equals(ts) {
@ -294,7 +322,6 @@ func (sm *syncManager) selectSyncTarget() (*types.TipSet, error) {
} }
func (sm *syncManager) syncScheduler() { func (sm *syncManager) syncScheduler() {
for { for {
select { select {
case ts, ok := <-sm.incomingTipSets: case ts, ok := <-sm.incomingTipSets:
@ -326,7 +353,8 @@ func (sm *syncManager) scheduleIncoming(ts *types.TipSet) {
var relatedToActiveSync bool var relatedToActiveSync bool
for _, acts := range sm.activeSyncs { for _, acts := range sm.activeSyncs {
if ts.Equals(acts) { if ts.Equals(acts) {
break // ignore, we are already syncing it
return
} }
if ts.Parents() == acts.Key() { if ts.Parents() == acts.Key() {
@ -376,7 +404,9 @@ func (sm *syncManager) scheduleProcessResult(res *syncResult) {
sm.nextSyncTarget = relbucket sm.nextSyncTarget = relbucket
sm.workerChan = sm.syncTargets sm.workerChan = sm.syncTargets
} else { } else {
sm.syncQueue.buckets = append(sm.syncQueue.buckets, relbucket) for _, t := range relbucket.tips {
sm.syncQueue.Insert(t)
}
} }
return return
} }

View File

@ -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) { func TestSyncManager(t *testing.T) {
ctx := context.Background() ctx := context.Background()

View File

@ -7,8 +7,6 @@ import (
"testing" "testing"
"time" "time"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ds "github.com/ipfs/go-datastore" ds "github.com/ipfs/go-datastore"
@ -20,6 +18,8 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "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/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/policy" "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 return []uint64{1}, nil
} }
func (wpp badWpp) ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error) { func (wpp badWpp) ComputeProof(context.Context, []proof2.SectorInfo, abi.PoStRandomness) ([]proof2.PoStProof, error) {
return []proof.PoStProof{ return []proof2.PoStProof{
{ {
PoStProof: abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, PoStProof: abi.RegisteredPoStProof_StackedDrgWinning2KiBV1,
ProofBytes: []byte("evil"), ProofBytes: []byte("evil"),

View File

@ -4,7 +4,7 @@ import (
"bytes" "bytes"
"math/big" "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" "github.com/minio/blake2b-simd"
@ -55,7 +55,7 @@ type BlockHeader struct {
BeaconEntries []BeaconEntry // 3 BeaconEntries []BeaconEntry // 3
WinPoStProof []proof.PoStProof // 4 WinPoStProof []proof2.PoStProof // 4
Parents []cid.Cid // 5 Parents []cid.Cid // 5

View File

@ -7,7 +7,7 @@ import (
"reflect" "reflect"
"testing" "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" cid "github.com/ipfs/go-cid"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -82,7 +82,7 @@ func TestInteropBH(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
posts := []proof.PoStProof{ posts := []proof2.PoStProof{
{PoStProof: abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, ProofBytes: []byte{0x07}}, {PoStProof: abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, ProofBytes: []byte{0x07}},
} }

View File

@ -3,6 +3,7 @@ package types
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"regexp"
"runtime" "runtime"
"strings" "strings"
"time" "time"
@ -68,11 +69,10 @@ func (l Loc) String() string {
return fmt.Sprintf("%s@%s:%d", fnpkg, file[len(file)-1], l.Line) 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 { func (l Loc) Important() bool {
if strings.HasPrefix(l.Function, "github.com/filecoin-project/specs-actors/actors/builtin") { return importantRegex.MatchString(l.Function)
return true
}
return false
} }
func (gt *GasTrace) MarshalJSON() ([]byte, error) { func (gt *GasTrace) MarshalJSON() ([]byte, error) {

View File

@ -9,13 +9,15 @@ import (
"github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto" "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) { func TestEqualCall(t *testing.T) {
m1 := &Message{ m1 := &Message{
To: builtin.StoragePowerActorAddr, To: builtin2.StoragePowerActorAddr,
From: builtin.SystemActorAddr, From: builtin2.SystemActorAddr,
Nonce: 34, Nonce: 34,
Value: big.Zero(), Value: big.Zero(),
@ -28,8 +30,8 @@ func TestEqualCall(t *testing.T) {
} }
m2 := &Message{ m2 := &Message{
To: builtin.StoragePowerActorAddr, To: builtin2.StoragePowerActorAddr,
From: builtin.SystemActorAddr, From: builtin2.SystemActorAddr,
Nonce: 34, Nonce: 34,
Value: big.Zero(), Value: big.Zero(),
@ -42,8 +44,8 @@ func TestEqualCall(t *testing.T) {
} }
m3 := &Message{ m3 := &Message{
To: builtin.StoragePowerActorAddr, To: builtin2.StoragePowerActorAddr,
From: builtin.SystemActorAddr, From: builtin2.SystemActorAddr,
Nonce: 34, Nonce: 34,
Value: big.Zero(), Value: big.Zero(),
@ -56,8 +58,8 @@ func TestEqualCall(t *testing.T) {
} }
m4 := &Message{ m4 := &Message{
To: builtin.StoragePowerActorAddr, To: builtin2.StoragePowerActorAddr,
From: builtin.SystemActorAddr, From: builtin2.SystemActorAddr,
Nonce: 34, Nonce: 34,
Value: big.Zero(), Value: big.Zero(),
@ -76,8 +78,8 @@ func TestEqualCall(t *testing.T) {
func TestMessageJson(t *testing.T) { func TestMessageJson(t *testing.T) {
m := &Message{ m := &Message{
To: builtin.StoragePowerActorAddr, To: builtin2.StoragePowerActorAddr,
From: builtin.SystemActorAddr, From: builtin2.SystemActorAddr,
Nonce: 34, Nonce: 34,
Value: big.Zero(), Value: big.Zero(),
@ -105,8 +107,8 @@ func TestMessageJson(t *testing.T) {
func TestSignedMessageJson(t *testing.T) { func TestSignedMessageJson(t *testing.T) {
m := Message{ m := Message{
To: builtin.StoragePowerActorAddr, To: builtin2.StoragePowerActorAddr,
From: builtin.SystemActorAddr, From: builtin2.SystemActorAddr,
Nonce: 34, Nonce: 34,
Value: big.Zero(), Value: big.Zero(),

View File

@ -3,13 +3,13 @@ package vm
import ( import (
"fmt" "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" "github.com/filecoin-project/go-address"
addr "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/abi"
"github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/crypto"
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
) )
@ -78,8 +78,8 @@ type Pricelist interface {
OnVerifySignature(sigType crypto.SigType, planTextSize int) (GasCharge, error) OnVerifySignature(sigType crypto.SigType, planTextSize int) (GasCharge, error)
OnHashing(dataSize int) GasCharge OnHashing(dataSize int) GasCharge
OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge
OnVerifySeal(info proof.SealVerifyInfo) GasCharge OnVerifySeal(info proof2.SealVerifyInfo) GasCharge
OnVerifyPost(info proof.WindowPoStVerifyInfo) GasCharge OnVerifyPost(info proof2.WindowPoStVerifyInfo) GasCharge
OnVerifyConsensusFault() GasCharge OnVerifyConsensusFault() GasCharge
} }
@ -150,7 +150,7 @@ func PricelistByEpoch(epoch abi.ChainEpoch) Pricelist {
} }
type pricedSyscalls struct { type pricedSyscalls struct {
under vmr.Syscalls under vmr2.Syscalls
pl Pricelist pl Pricelist
chargeGas func(GasCharge) chargeGas func(GasCharge)
} }
@ -184,7 +184,7 @@ func (ps pricedSyscalls) ComputeUnsealedSectorCID(reg abi.RegisteredSealProof, p
} }
// Verifies a sector seal proof. // 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)) ps.chargeGas(ps.pl.OnVerifySeal(vi))
defer ps.chargeGas(gasOnActorExec) defer ps.chargeGas(gasOnActorExec)
@ -192,7 +192,7 @@ func (ps pricedSyscalls) VerifySeal(vi proof.SealVerifyInfo) error {
} }
// Verifies a proof of spacetime. // 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)) ps.chargeGas(ps.pl.OnVerifyPost(vi))
defer ps.chargeGas(gasOnActorExec) 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 // 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). // blocks in the parent of h2 (i.e. h2's grandparent).
// Returns nil and an error if the headers don't prove a fault. // 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()) ps.chargeGas(ps.pl.OnVerifyConsensusFault())
defer ps.chargeGas(gasOnActorExec) defer ps.chargeGas(gasOnActorExec)
return ps.under.VerifyConsensusFault(h1, h2, extra) 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) count := int64(0)
for _, svis := range inp { for _, svis := range inp {
count += int64(len(svis)) count += int64(len(svis))

View File

@ -3,12 +3,13 @@ package vm
import ( import (
"fmt" "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/abi"
"github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto" "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 { 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 { if big.Cmp(value, abi.NewTokenAmount(0)) != 0 {
ret += pl.sendTransferFunds ret += pl.sendTransferFunds
if methodNum == builtin0.MethodSend { if methodNum == builtin.MethodSend {
// transfer only // transfer only
ret += pl.sendTransferOnlyPremium ret += pl.sendTransferOnlyPremium
} }
extra += "t" extra += "t"
} }
if methodNum != builtin0.MethodSend { if methodNum != builtin.MethodSend {
extra += "i" extra += "i"
// running actors is cheaper becase we hand over to actors // running actors is cheaper becase we hand over to actors
ret += pl.sendInvokeMethod ret += pl.sendInvokeMethod
@ -175,14 +176,14 @@ func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredSealPr
} }
// OnVerifySeal // 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 // TODO: this needs more cost tunning, check with @lotus
// this is not used // this is not used
return newGasCharge("OnVerifySeal", pl.verifySealBase, 0) return newGasCharge("OnVerifySeal", pl.verifySealBase, 0)
} }
// OnVerifyPost // OnVerifyPost
func (pl *pricelistV0) OnVerifyPost(info proof.WindowPoStVerifyInfo) GasCharge { func (pl *pricelistV0) OnVerifyPost(info proof2.WindowPoStVerifyInfo) GasCharge {
sectorSize := "unknown" sectorSize := "unknown"
var proofType abi.RegisteredPoStProof var proofType abi.RegisteredPoStProof

View File

@ -5,16 +5,17 @@ import (
"io" "io"
"testing" "testing"
"github.com/filecoin-project/go-state-types/abi"
cbor "github.com/ipfs/go-ipld-cbor" cbor "github.com/ipfs/go-ipld-cbor"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/exitcode" "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"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/specs-actors/actors/runtime"
) )
type basicContract struct{} 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") rt.Abortf(exitcode.ExitCode(params.B), "params.B")
return nil 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") rt.Abortf(255, "bad params")
return nil 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") rt.Abortf(exitcode.ExitCode(params.B+10), "params.B")
return nil return nil
} }

View File

@ -15,6 +15,8 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "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" "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 // 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 { if aerr != nil {
return nil, address.Undef, aerrors.Wrap(aerr, "failed to invoke account constructor") return nil, address.Undef, aerrors.Wrap(aerr, "failed to invoke account constructor")
} }

View File

@ -53,8 +53,8 @@ func (m *Message) ValueReceived() abi.TokenAmount {
var EnableGasTracing = false var EnableGasTracing = false
type Runtime struct { type Runtime struct {
rt0.Message rt2.Message
rt0.Syscalls rt2.Syscalls
ctx context.Context ctx context.Context
@ -72,6 +72,7 @@ type Runtime struct {
originNonce uint64 originNonce uint64
executionTrace types.ExecutionTrace executionTrace types.ExecutionTrace
depth uint64
numActorsCreated uint64 numActorsCreated uint64
allowInternal bool allowInternal bool
callerValidated bool callerValidated bool

View File

@ -7,8 +7,6 @@ import (
goruntime "runtime" goruntime "runtime"
"sync" "sync"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor" 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/state"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sigs" "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" "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 // 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 { 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{ return &syscallShim{
ctx: ctx, 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 // 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). // and an optional extra one to check common ancestry (as needed).
// Note that the blocks are ordered: the method requires a.Epoch() <= b.Epoch(). // 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. // 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. // 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 // 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 // (2) check for the consensus faults themselves
var consensusFault *runtime.ConsensusFault var consensusFault *runtime2.ConsensusFault
// (a) double-fork mining fault // (a) double-fork mining fault
if blockA.Height == blockB.Height { if blockA.Height == blockB.Height {
consensusFault = &runtime.ConsensusFault{ consensusFault = &runtime2.ConsensusFault{
Target: blockA.Miner, Target: blockA.Miner,
Epoch: blockB.Height, 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, // strictly speaking no need to compare heights based on double fork mining check above,
// but at same height this would be a different fault. // but at same height this would be a different fault.
if types.CidArrsEqual(blockA.Parents, blockB.Parents) && blockA.Height != blockB.Height { if types.CidArrsEqual(blockA.Parents, blockB.Parents) && blockA.Height != blockB.Height {
consensusFault = &runtime.ConsensusFault{ consensusFault = &runtime2.ConsensusFault{
Target: blockA.Miner, Target: blockA.Miner,
Epoch: blockB.Height, 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 && if types.CidArrsEqual(blockA.Parents, blockC.Parents) && blockA.Height == blockC.Height &&
types.CidArrsContains(blockB.Parents, blockC.Cid()) && !types.CidArrsContains(blockB.Parents, blockA.Cid()) { types.CidArrsContains(blockB.Parents, blockC.Cid()) && !types.CidArrsContains(blockB.Parents, blockA.Cid()) {
consensusFault = &runtime.ConsensusFault{ consensusFault = &runtime2.ConsensusFault{
Target: blockA.Miner, Target: blockA.Miner,
Epoch: blockB.Height, Epoch: blockB.Height,
Type: runtime.ConsensusFaultParentGrinding, Type: runtime2.ConsensusFaultParentGrinding,
} }
} }
} }
@ -215,7 +215,7 @@ func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error {
return nil 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) ok, err := ss.verifier.VerifyWindowPoSt(context.TODO(), proof)
if err != nil { if err != nil {
return err return err
@ -226,7 +226,7 @@ func (ss *syscallShim) VerifyPoSt(proof proof.WindowPoStVerifyInfo) error {
return nil return nil
} }
func (ss *syscallShim) VerifySeal(info proof.SealVerifyInfo) error { func (ss *syscallShim) VerifySeal(info proof2.SealVerifyInfo) error {
//_, span := trace.StartSpan(ctx, "ValidatePoRep") //_, span := trace.StartSpan(ctx, "ValidatePoRep")
//defer span.End() //defer span.End()
@ -266,7 +266,7 @@ func (ss *syscallShim) VerifySignature(sig crypto.Signature, addr address.Addres
var BatchSealVerifyParallelism = goruntime.NumCPU() 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) out := make(map[address.Address][]bool)
sema := make(chan struct{}, BatchSealVerifyParallelism) sema := make(chan struct{}, BatchSealVerifyParallelism)
@ -278,7 +278,7 @@ func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]proof.SealVeri
for i, s := range seals { for i, s := range seals {
wg.Add(1) 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() defer wg.Done()
sema <- struct{}{} sema <- struct{}{}

View File

@ -38,6 +38,8 @@ import (
"github.com/filecoin-project/lotus/lib/bufbstore" "github.com/filecoin-project/lotus/lib/bufbstore"
) )
const MaxCallDepth = 4096
var log = logging.Logger("vm") var log = logging.Logger("vm")
var actorLog = logging.Logger("actors") var actorLog = logging.Logger("actors")
var gasOnActorExec = newGasCharge("OnActorExec", 0, 0) var gasOnActorExec = newGasCharge("OnActorExec", 0, 0)
@ -97,24 +99,37 @@ func (bs *gasChargingBlocks) Put(blk block.Block) error {
return nil 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{ rt := &Runtime{
ctx: ctx, ctx: ctx,
vm: vm, vm: vm,
state: vm.cstate, state: vm.cstate,
origin: origin, origin: msg.From,
originNonce: originNonce, originNonce: msg.Nonce,
height: vm.blockHeight, height: vm.blockHeight,
gasUsed: usedGas, gasUsed: 0,
gasAvailable: msg.GasLimit, gasAvailable: msg.GasLimit,
numActorsCreated: nac, depth: 0,
numActorsCreated: 0,
pricelist: PricelistByEpoch(vm.blockHeight), pricelist: PricelistByEpoch(vm.blockHeight),
allowInternal: true, allowInternal: true,
callerValidated: false, callerValidated: false,
executionTrace: types.ExecutionTrace{Msg: msg}, 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{ rt.cst = &cbor.BasicIpldStore{
Blocks: &gasChargingBlocks{rt.chargeGasFunc(2), rt.pricelist, vm.cst.Blocks}, Blocks: &gasChargingBlocks{rt.chargeGasFunc(2), rt.pricelist, vm.cst.Blocks},
Atlas: vm.cst.Atlas, Atlas: vm.cst.Atlas,
@ -148,8 +163,8 @@ type UnsafeVM struct {
VM *VM VM *VM
} }
func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message, origin address.Address, originNonce uint64, usedGas int64, nac uint64) *Runtime { func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message) *Runtime {
return vm.VM.makeRuntime(ctx, msg, origin, originNonce, usedGas, nac) return vm.VM.makeRuntime(ctx, msg, nil)
} }
type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) 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 st := vm.cstate
origin := msg.From rt := vm.makeRuntime(ctx, msg, parent)
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)
if EnableGasTracing { if EnableGasTracing {
rt.lastGasChargeTime = start rt.lastGasChargeTime = start
if parent != nil { if parent != nil {

View File

@ -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 { func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) error {
k, err := w.findKey(addr) k, err := w.findKey(addr)
if err != nil { if err != nil {
return xerrors.Errorf("failed to delete key %s : %w", addr, err) 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 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 { 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) 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. // TODO: Does this always error in the not-found case? Just ignoring an error return for now.
_ = w.keystore.Delete(KNamePrefix + tAddr) _ = w.keystore.Delete(KNamePrefix + tAddr)
delete(w.keys, addr)
return nil return nil
} }

View File

@ -1291,7 +1291,7 @@ var chainDecodeParamsCmd = &cli.Command{
return xerrors.Errorf("getting actor: %w", err) 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 { if err != nil {
return err return err
} }

View File

@ -1,24 +1,29 @@
package cli package cli
import ( import (
"bufio"
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
"math/rand"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
"strconv" "strconv"
"strings"
"sync"
"sync/atomic"
"text/tabwriter" "text/tabwriter"
"time" "time"
tm "github.com/buger/goterm" tm "github.com/buger/goterm"
"github.com/chzyer/readline"
"github.com/docker/go-units" "github.com/docker/go-units"
"github.com/fatih/color" "github.com/fatih/color"
datatransfer "github.com/filecoin-project/go-data-transfer" datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-fil-markets/retrievalmarket" "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-cid"
"github.com/ipfs/go-cidutil/cidenc" "github.com/ipfs/go-cidutil/cidenc"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
@ -35,6 +40,7 @@ import (
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
lapi "github.com/filecoin-project/lotus/api" lapi "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "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/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/tablewriter" "github.com/filecoin-project/lotus/lib/tablewriter"
@ -74,6 +80,7 @@ var clientCmd = &cli.Command{
WithCategory("storage", clientQueryAskCmd), WithCategory("storage", clientQueryAskCmd),
WithCategory("storage", clientListDeals), WithCategory("storage", clientListDeals),
WithCategory("storage", clientGetDealCmd), WithCategory("storage", clientGetDealCmd),
WithCategory("storage", clientListAsksCmd),
WithCategory("data", clientImportCmd), WithCategory("data", clientImportCmd),
WithCategory("data", clientDropCmd), WithCategory("data", clientDropCmd),
WithCategory("data", clientLocalCmd), WithCategory("data", clientLocalCmd),
@ -336,6 +343,7 @@ var clientDealCmd = &cli.Command{
} }
defer closer() defer closer()
ctx := ReqContext(cctx) ctx := ReqContext(cctx)
afmt := NewAppFmt(cctx.App)
if cctx.NArg() != 4 { if cctx.NArg() != 4 {
return xerrors.New("expected 4 args: dataCid, miner, price, duration") return xerrors.New("expected 4 args: dataCid, miner, price, duration")
@ -455,7 +463,7 @@ var clientDealCmd = &cli.Command{
return err return err
} }
fmt.Println(encoder.Encode(*proposal)) afmt.Println(encoder.Encode(*proposal))
return nil return nil
}, },
@ -468,16 +476,27 @@ func interactiveDeal(cctx *cli.Context) error {
} }
defer closer() defer closer()
ctx := ReqContext(cctx) ctx := ReqContext(cctx)
ctx, cancel := context.WithCancel(ctx)
defer cancel()
afmt := NewAppFmt(cctx.App)
state := "import" state := "import"
gib := types.NewInt(1 << 30)
var data cid.Cid var data cid.Cid
var days int var days int
var maddr address.Address var maddrs []address.Address
var ask storagemarket.StorageAsk var ask []storagemarket.StorageAsk
var epochPrice big.Int var epochPrices []big.Int
var dur time.Duration
var epochs abi.ChainEpoch var epochs abi.ChainEpoch
var verified bool var verified bool
var ds lapi.DataSize
// find
var candidateAsks []*storagemarket.StorageAsk
var budget types.FIL
var dealCount int64
var a address.Address var a address.Address
if from := cctx.String("from"); from != "" { if from := cctx.String("from"); from != "" {
@ -494,10 +513,24 @@ func interactiveDeal(cctx *cli.Context) error {
a = def a = def
} }
printErr := func(err error) { fromBal, err := api.WalletBalance(ctx, a)
fmt.Printf("%s %s\n", color.RedString("Error:"), err.Error()) 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 { for {
// TODO: better exit handling // TODO: better exit handling
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
@ -506,10 +539,10 @@ func interactiveDeal(cctx *cli.Context) error {
switch state { switch state {
case "import": 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 _cidStr, _, err := rl.ReadLine()
_, err := fmt.Scan(&cidStr) cidStr := string(_cidStr)
if err != nil { if err != nil {
printErr(xerrors.Errorf("reading cid string: %w", err)) printErr(xerrors.Errorf("reading cid string: %w", err))
continue continue
@ -521,11 +554,23 @@ func interactiveDeal(cctx *cli.Context) error {
continue continue
} }
color.Blue(".. calculating data size\n")
ds, err = api.ClientDealSize(ctx, data)
if err != nil {
return err
}
state = "duration" state = "duration"
case "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 { if err != nil {
printErr(xerrors.Errorf("parsing duration: %w", err)) printErr(xerrors.Errorf("parsing duration: %w", err))
continue continue
@ -536,44 +581,9 @@ func interactiveDeal(cctx *cli.Context) error {
continue continue
} }
state = "miner" dur = 24 * time.Hour * time.Duration(days)
case "miner": epochs = abi.ChainEpoch(dur / (time.Duration(build.BlockDelaySecs) * time.Second))
fmt.Print("Miner Address (f0..): ")
var maddrStr string
_, 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" state = "verified"
case "verified": case "verified":
ts, err := api.ChainHead(ctx) ts, err := api.ChainHead(ctx)
@ -587,26 +597,20 @@ func interactiveDeal(cctx *cli.Context) error {
} }
if dcap == nil { if dcap == nil {
state = "confirm" state = "miner"
continue 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) { if dcap.Uint64() < uint64(ds.PieceSize) {
color.Yellow(".. not enough DataCap available for a verified deal\n") color.Yellow(".. not enough DataCap available for a verified deal\n")
state = "confirm" state = "miner"
continue continue
} }
fmt.Print("\nMake this a verified deal? (yes/no): ") afmt.Print("\nMake this a verified deal? (yes/no): ")
var yn string _yn, _, err := rl.ReadLine()
_, err = fmt.Scan(&yn) yn := string(_yn)
if err != nil { if err != nil {
return err return err
} }
@ -617,54 +621,208 @@ func interactiveDeal(cctx *cli.Context) error {
case "no": case "no":
verified = false verified = false
default: default:
fmt.Println("Type in full 'yes' or 'no'") afmt.Println("Type in full 'yes' or 'no'")
continue continue
} }
state = "confirm" state = "miner"
case "confirm": case "miner":
fromBal, err := api.WalletBalance(ctx, a) afmt.Print("Miner Addresses (f0.. f0..), none to find: ")
_maddrsStr, _, err := rl.ReadLine()
maddrsStr := string(_maddrsStr)
if err != nil { 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") for _, s := range strings.Fields(maddrsStr) {
ds, err := api.ClientDealSize(ctx, data) 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 { if err != nil {
return err return err
} }
dur := 24 * time.Hour * time.Duration(days) for _, ask := range asks {
if ask.MinPieceSize > ds.PieceSize {
epochs = abi.ChainEpoch(dur / (time.Duration(build.BlockDelaySecs) * time.Second)) continue
// TODO: do some more or epochs math (round to miner PP, deal start buffer) }
if ask.MaxPieceSize < ds.PieceSize {
pricePerGib := ask.Price continue
if verified { }
pricePerGib = ask.VerifiedPrice 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? // 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))) totalPrice := types.BigMul(epochPrice, types.NewInt(uint64(epochs)))
fmt.Printf("-----\n") afmt.Printf("Total price: ~%s (%s per epoch)\n", color.CyanString(types.FIL(totalPrice).String()), types.FIL(epochPrice))
fmt.Printf("Proposing from %s\n", a) afmt.Printf("Verified: %v\n", verified)
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)
state = "accept" state = "accept"
case "accept": case "accept":
fmt.Print("\nAccept (yes/no): ") afmt.Print("\nAccept (yes/no): ")
var yn string _yn, _, err := rl.ReadLine()
_, err := fmt.Scan(&yn) yn := string(_yn)
if err != nil { if err != nil {
return err return err
} }
@ -674,36 +832,40 @@ func interactiveDeal(cctx *cli.Context) error {
} }
if yn != "yes" { if yn != "yes" {
fmt.Println("Type in full 'yes' or 'no'") afmt.Println("Type in full 'yes' or 'no'")
continue continue
} }
state = "execute" state = "execute"
case "execute": case "execute":
color.Blue(".. executing") color.Blue(".. executing\n")
proposal, err := api.ClientStartDeal(ctx, &lapi.StartDealParams{
Data: &storagemarket.DataRef{ for i, maddr := range maddrs {
TransferType: storagemarket.TTGraphsync, proposal, err := api.ClientStartDeal(ctx, &lapi.StartDealParams{
Root: data, Data: &storagemarket.DataRef{
}, TransferType: storagemarket.TTGraphsync,
Wallet: a, Root: data,
Miner: maddr, },
EpochPrice: epochPrice, Wallet: a,
MinBlocksDuration: uint64(epochs), Miner: maddr,
DealStartEpoch: abi.ChainEpoch(cctx.Int64("start-epoch")), EpochPrice: epochPrices[i],
FastRetrieval: cctx.Bool("fast-retrieval"), MinBlocksDuration: uint64(epochs),
VerifiedDeal: verified, DealStartEpoch: abi.ChainEpoch(cctx.Int64("start-epoch")),
}) FastRetrieval: cctx.Bool("fast-retrieval"),
if err != nil { VerifiedDeal: verified,
return err })
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 return nil
default: default:
return xerrors.Errorf("unknown state: %s", state) return xerrors.Errorf("unknown state: %s", state)
@ -815,6 +977,7 @@ var clientRetrieveCmd = &cli.Command{
} }
defer closer() defer closer()
ctx := ReqContext(cctx) ctx := ReqContext(cctx)
afmt := NewAppFmt(cctx.App)
var payer address.Address var payer address.Address
if cctx.String("from") != "" { if cctx.String("from") != "" {
@ -923,14 +1086,14 @@ var clientRetrieveCmd = &cli.Command{
select { select {
case evt, ok := <-updates: case evt, ok := <-updates:
if ok { 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.SizeStr(types.NewInt(evt.BytesReceived)),
types.FIL(evt.FundsSpent), types.FIL(evt.FundsSpent),
retrievalmarket.ClientEvents[evt.Event], retrievalmarket.ClientEvents[evt.Event],
retrievalmarket.DealStatuses[evt.Status], retrievalmarket.DealStatuses[evt.Status],
) )
} else { } else {
fmt.Println("Success") afmt.Println("Success")
return nil 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{ var clientQueryAskCmd = &cli.Command{
Name: "query-ask", Name: "query-ask",
Usage: "Find a miners ask", Usage: "Find a miners ask",
@ -963,8 +1272,9 @@ var clientQueryAskCmd = &cli.Command{
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
afmt := NewAppFmt(cctx.App)
if cctx.NArg() != 1 { if cctx.NArg() != 1 {
fmt.Println("Usage: query-ask [minerAddress]") afmt.Println("Usage: query-ask [minerAddress]")
return nil return nil
} }
@ -1005,23 +1315,23 @@ var clientQueryAskCmd = &cli.Command{
return err return err
} }
fmt.Printf("Ask: %s\n", maddr) afmt.Printf("Ask: %s\n", maddr)
fmt.Printf("Price per GiB: %s\n", types.FIL(ask.Price)) afmt.Printf("Price per GiB: %s\n", types.FIL(ask.Price))
fmt.Printf("Verified Price per GiB: %s\n", types.FIL(ask.VerifiedPrice)) afmt.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("Max Piece size: %s\n", types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))))
size := cctx.Int64("size") size := cctx.Int64("size")
if size == 0 { if size == 0 {
return nil return nil
} }
perEpoch := types.BigDiv(types.BigMul(ask.Price, types.NewInt(uint64(size))), types.NewInt(1<<30)) 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") duration := cctx.Int64("duration")
if duration == 0 { if duration == 0 {
return nil 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 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)
}, },
} }

22
cli/client_test.go Normal file
View File

@ -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)
}

View File

@ -2,15 +2,16 @@ package cli
import ( import (
"fmt" "fmt"
"io"
"os" "os"
"github.com/urfave/cli/v2" ufcli "github.com/urfave/cli/v2"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
type PrintHelpErr struct { type PrintHelpErr struct {
Err error Err error
Ctx *cli.Context Ctx *ufcli.Context
} }
func (e *PrintHelpErr) Error() string { func (e *PrintHelpErr) Error() string {
@ -26,11 +27,11 @@ func (e *PrintHelpErr) Is(o error) bool {
return ok return ok
} }
func ShowHelp(cctx *cli.Context, err error) error { func ShowHelp(cctx *ufcli.Context, err error) error {
return &PrintHelpErr{Err: err, Ctx: cctx} 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 err := app.Run(os.Args); err != nil {
if os.Getenv("LOTUS_DEV") != "" { if os.Getenv("LOTUS_DEV") != "" {
log.Warnf("%+v", err) log.Warnf("%+v", err)
@ -39,8 +40,40 @@ func RunApp(app *cli.App) {
} }
var phe *PrintHelpErr var phe *PrintHelpErr
if xerrors.As(err, &phe) { if xerrors.As(err, &phe) {
_ = cli.ShowCommandHelp(phe.Ctx, phe.Ctx.Command.Name) _ = ufcli.ShowCommandHelp(phe.Ctx, phe.Ctx.Command.Name)
} }
os.Exit(1) 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...)
}

View File

@ -10,8 +10,6 @@ import (
"strconv" "strconv"
"text/tabwriter" "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/builtin"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
@ -28,8 +26,8 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"golang.org/x/xerrors" "golang.org/x/xerrors"
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init"
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" msig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
"github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
@ -167,7 +165,7 @@ var msigCreateCmd = &cli.Command{
// get address of newly created miner // 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 { if err := execreturn.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil {
return err return err
} }
@ -427,7 +425,7 @@ var msigProposeCmd = &cli.Command{
return fmt.Errorf("proposal returned exit %d", wait.Receipt.ExitCode) 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 { if err := retval.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil {
return fmt.Errorf("failed to unmarshal propose return value: %w", err) return fmt.Errorf("failed to unmarshal propose return value: %w", err)
} }
@ -1160,7 +1158,7 @@ var msigLockProposeCmd = &cli.Command{
from = defaddr from = defaddr
} }
params, actErr := actors.SerializeParams(&msig0.LockBalanceParams{ params, actErr := actors.SerializeParams(&msig2.LockBalanceParams{
StartEpoch: abi.ChainEpoch(start), StartEpoch: abi.ChainEpoch(start),
UnlockDuration: abi.ChainEpoch(duration), UnlockDuration: abi.ChainEpoch(duration),
Amount: abi.NewTokenAmount(amount.Int64()), Amount: abi.NewTokenAmount(amount.Int64()),
@ -1170,7 +1168,7 @@ var msigLockProposeCmd = &cli.Command{
return actErr 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 { if err != nil {
return err return err
} }
@ -1257,7 +1255,7 @@ var msigLockApproveCmd = &cli.Command{
from = defaddr from = defaddr
} }
params, actErr := actors.SerializeParams(&msig0.LockBalanceParams{ params, actErr := actors.SerializeParams(&msig2.LockBalanceParams{
StartEpoch: abi.ChainEpoch(start), StartEpoch: abi.ChainEpoch(start),
UnlockDuration: abi.ChainEpoch(duration), UnlockDuration: abi.ChainEpoch(duration),
Amount: abi.NewTokenAmount(amount.Int64()), Amount: abi.NewTokenAmount(amount.Int64()),
@ -1267,7 +1265,7 @@ var msigLockApproveCmd = &cli.Command{
return actErr 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 { if err != nil {
return err return err
} }
@ -1349,7 +1347,7 @@ var msigLockCancelCmd = &cli.Command{
from = defaddr from = defaddr
} }
params, actErr := actors.SerializeParams(&msig0.LockBalanceParams{ params, actErr := actors.SerializeParams(&msig2.LockBalanceParams{
StartEpoch: abi.ChainEpoch(start), StartEpoch: abi.ChainEpoch(start),
UnlockDuration: abi.ChainEpoch(duration), UnlockDuration: abi.ChainEpoch(duration),
Amount: abi.NewTokenAmount(amount.Int64()), Amount: abi.NewTokenAmount(amount.Int64()),
@ -1359,7 +1357,7 @@ var msigLockCancelCmd = &cli.Command{
return actErr 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 { if err != nil {
return err return err
} }
@ -1488,7 +1486,7 @@ var msigProposeThresholdCmd = &cli.Command{
from = defaddr from = defaddr
} }
params, actErr := actors.SerializeParams(&msig0.ChangeNumApprovalsThresholdParams{ params, actErr := actors.SerializeParams(&msig2.ChangeNumApprovalsThresholdParams{
NewThreshold: newM, NewThreshold: newM,
}) })
@ -1496,7 +1494,7 @@ var msigProposeThresholdCmd = &cli.Command{
return actErr 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 { if err != nil {
return fmt.Errorf("failed to propose change of threshold: %w", err) return fmt.Errorf("failed to propose change of threshold: %w", err)
} }

View File

@ -6,50 +6,17 @@ import (
"testing" "testing"
"time" "time"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api/test"
clitest "github.com/filecoin-project/lotus/cli/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 // TestMultisig does a basic test to exercise the multisig CLI
// commands // commands
func TestMultisig(t *testing.T) { func TestMultisig(t *testing.T) {
_ = os.Setenv("BELLMAN_NO_GPU", "1") _ = os.Setenv("BELLMAN_NO_GPU", "1")
clitest.QuietMiningLogs()
blocktime := 5 * time.Millisecond blocktime := 5 * time.Millisecond
ctx := context.Background() ctx := context.Background()
nodes, _ := startNodes(ctx, t, blocktime) clientNode, _ := clitest.StartOneNodeOneMiner(ctx, t, blocktime)
clientNode := nodes[0]
clitest.RunMultisigTest(t, Commands, clientNode) 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}
}

View File

@ -1211,7 +1211,7 @@ func ComputeStateHTMLTempl(w io.Writer, ts *types.TipSet, o *api.ComputeStateOut
"GetCode": getCode, "GetCode": getCode,
"GetMethod": getMethod, "GetMethod": getMethod,
"ToFil": toFil, "ToFil": toFil,
"JsonParams": jsonParams, "JsonParams": JsonParams,
"JsonReturn": jsonReturn, "JsonReturn": jsonReturn,
"IsSlow": isSlow, "IsSlow": isSlow,
"IsVerySlow": isVerySlow, "IsVerySlow": isVerySlow,
@ -1298,7 +1298,7 @@ func sumGas(changes []*types.GasTrace) types.GasTrace {
return out 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] methodMeta, found := stmgr.MethodsMap[code][method]
if !found { if !found {
return "", fmt.Errorf("method %d not found on actor %s", method, code) return "", fmt.Errorf("method %d not found on actor %s", method, code)

115
cli/test/client.go Normal file
View File

@ -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 <miner addr>
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 <cid> <miner addr> 1000000attofil <duration>
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
// <cid>
// <duration> (in days)
// <miner addr>
// "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 <cid> <file path>
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)
}

View File

@ -122,3 +122,12 @@ func (c *mockCLIClient) flagSet(cmd *lcli.Command) *flag.FlagSet {
} }
return fs 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)
}

View File

@ -10,19 +10,10 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api/test" "github.com/filecoin-project/lotus/api/test"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
logging "github.com/ipfs/go-log/v2"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
lcli "github.com/urfave/cli/v2" 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) { func RunMultisigTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode) {
ctx := context.Background() ctx := context.Background()

41
cli/test/net.go Normal file
View File

@ -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
}

12
cli/test/util.go Normal file
View File

@ -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")
}

View File

@ -13,9 +13,13 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address" "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/big"
"github.com/filecoin-project/go-state-types/crypto" "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" types "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/tablewriter" "github.com/filecoin-project/lotus/lib/tablewriter"
) )
@ -34,6 +38,7 @@ var walletCmd = &cli.Command{
walletSign, walletSign,
walletVerify, walletVerify,
walletDelete, walletDelete,
walletMarket,
}, },
} }
@ -74,6 +79,16 @@ var walletList = &cli.Command{
Usage: "Only print addresses", Usage: "Only print addresses",
Aliases: []string{"a"}, 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 { Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx) api, closer, err := GetFullNodeAPI(cctx)
@ -93,7 +108,10 @@ var walletList = &cli.Command{
tw := tablewriter.New( tw := tablewriter.New(
tablewriter.Col("Address"), tablewriter.Col("Address"),
tablewriter.Col("ID"),
tablewriter.Col("Balance"), tablewriter.Col("Balance"),
tablewriter.Col("Market(Avail)"),
tablewriter.Col("Market(Locked)"),
tablewriter.Col("Nonce"), tablewriter.Col("Nonce"),
tablewriter.Col("Default"), tablewriter.Col("Default"),
tablewriter.NewLineCol("Error")) tablewriter.NewLineCol("Error"))
@ -126,6 +144,23 @@ var walletList = &cli.Command{
row["Default"] = "X" 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) tw.Write(row)
} }
} }
@ -471,3 +506,107 @@ var walletDelete = &cli.Command{
return api.WalletDelete(ctx, addr) 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
},
}

View File

@ -7,7 +7,7 @@ import (
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "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/ipfs/go-datastore"
"github.com/minio/blake2b-simd" "github.com/minio/blake2b-simd"
cbg "github.com/whyrusleeping/cbor-gen" 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.withCache(func() (bool, error) {
return cv.backend.VerifySeal(svi) return cv.backend.VerifySeal(svi)
}, &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) 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.withCache(func() (bool, error) {
return cv.backend.VerifyWindowPoSt(ctx, info) return cv.backend.VerifyWindowPoSt(ctx, info)
}, &info) }, &info)

View File

@ -26,7 +26,9 @@ import (
"github.com/filecoin-project/lotus/lib/blockstore" "github.com/filecoin-project/lotus/lib/blockstore"
_ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp" _ "github.com/filecoin-project/lotus/lib/sigs/secp"
metricsprometheus "github.com/ipfs/go-metrics-prometheus"
"github.com/ipld/go-car" "github.com/ipld/go-car"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
@ -34,6 +36,7 @@ import (
bdg "github.com/dgraph-io/badger/v2" bdg "github.com/dgraph-io/badger/v2"
"github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore"
badger "github.com/ipfs/go-ds-badger2" badger "github.com/ipfs/go-ds-badger2"
measure "github.com/ipfs/go-ds-measure"
pebbleds "github.com/ipfs/go-ds-pebble" pebbleds "github.com/ipfs/go-ds-pebble"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
@ -89,8 +92,12 @@ var importBenchCmd = &cli.Command{
&cli.BoolFlag{ &cli.BoolFlag{
Name: "only-import", Name: "only-import",
}, },
&cli.BoolFlag{
Name: "use-pebble",
},
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
metricsprometheus.Inject() //nolint:errcheck
vm.BatchSealVerifyParallelism = cctx.Int("batch-seal-verify-threads") vm.BatchSealVerifyParallelism = cctx.Int("batch-seal-verify-threads")
if !cctx.Args().Present() { if !cctx.Args().Present() {
fmt.Println("must pass car file of chain to benchmark importing") 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 defer cfi.Close() //nolint:errcheck // read only file
go func() { go func() {
http.Handle("/debug/metrics/prometheus", promhttp.Handler())
http.ListenAndServe("localhost:6060", nil) //nolint:errcheck http.ListenAndServe("localhost:6060", nil) //nolint:errcheck
}() }()
@ -126,7 +134,7 @@ var importBenchCmd = &cli.Command{
bdgOpt.Options.DetectConflicts = false bdgOpt.Options.DetectConflicts = false
var bds datastore.Batching var bds datastore.Batching
if false { if cctx.Bool("use-pebble") {
cache := 512 cache := 512
bds, err = pebbleds.NewDatastore(tdir, &pebble.Options{ bds, err = pebbleds.NewDatastore(tdir, &pebble.Options{
// Pebble has a single combined cache area and the write // Pebble has a single combined cache area and the write
@ -155,6 +163,8 @@ var importBenchCmd = &cli.Command{
} }
defer bds.Close() //nolint:errcheck defer bds.Close() //nolint:errcheck
bds = measure.New("dsbench", bds)
bs := blockstore.NewBlockstore(bds) bs := blockstore.NewBlockstore(bds)
cacheOpts := blockstore.DefaultCacheOpts() cacheOpts := blockstore.DefaultCacheOpts()
cacheOpts.HasBloomFilterSize = 0 cacheOpts.HasBloomFilterSize = 0
@ -310,6 +320,21 @@ var importBenchCmd = &cli.Command{
pprof.StopCPUProfile() 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 return nil
}, },

View File

@ -11,7 +11,7 @@ import (
"path/filepath" "path/filepath"
"time" "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" "github.com/docker/go-units"
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
@ -237,7 +237,7 @@ var sealBenchCmd = &cli.Command{
} }
var sealTimings []SealingResult var sealTimings []SealingResult
var sealedSectors []saproof.SectorInfo var sealedSectors []saproof2.SectorInfo
if robench == "" { if robench == "" {
var err error var err error
@ -280,7 +280,7 @@ var sealBenchCmd = &cli.Command{
} }
for _, s := range genm.Sectors { for _, s := range genm.Sectors {
sealedSectors = append(sealedSectors, saproof.SectorInfo{ sealedSectors = append(sealedSectors, saproof2.SectorInfo{
SealedCID: s.CommR, SealedCID: s.CommR,
SectorNumber: s.SectorID, SectorNumber: s.SectorID,
SealProof: s.ProofType, SealProof: s.ProofType,
@ -305,7 +305,7 @@ var sealBenchCmd = &cli.Command{
return err return err
} }
candidates := make([]saproof.SectorInfo, len(fcandidates)) candidates := make([]saproof2.SectorInfo, len(fcandidates))
for i, fcandidate := range fcandidates { for i, fcandidate := range fcandidates {
candidates[i] = sealedSectors[fcandidate] candidates[i] = sealedSectors[fcandidate]
} }
@ -328,7 +328,7 @@ var sealBenchCmd = &cli.Command{
winnningpost2 := time.Now() winnningpost2 := time.Now()
pvi1 := saproof.WinningPoStVerifyInfo{ pvi1 := saproof2.WinningPoStVerifyInfo{
Randomness: abi.PoStRandomness(challenge[:]), Randomness: abi.PoStRandomness(challenge[:]),
Proofs: proof1, Proofs: proof1,
ChallengedSectors: candidates, ChallengedSectors: candidates,
@ -344,7 +344,7 @@ var sealBenchCmd = &cli.Command{
verifyWinningPost1 := time.Now() verifyWinningPost1 := time.Now()
pvi2 := saproof.WinningPoStVerifyInfo{ pvi2 := saproof2.WinningPoStVerifyInfo{
Randomness: abi.PoStRandomness(challenge[:]), Randomness: abi.PoStRandomness(challenge[:]),
Proofs: proof2, Proofs: proof2,
ChallengedSectors: candidates, ChallengedSectors: candidates,
@ -376,7 +376,7 @@ var sealBenchCmd = &cli.Command{
windowpost2 := time.Now() windowpost2 := time.Now()
wpvi1 := saproof.WindowPoStVerifyInfo{ wpvi1 := saproof2.WindowPoStVerifyInfo{
Randomness: challenge[:], Randomness: challenge[:],
Proofs: wproof1, Proofs: wproof1,
ChallengedSectors: sealedSectors, ChallengedSectors: sealedSectors,
@ -392,7 +392,7 @@ var sealBenchCmd = &cli.Command{
verifyWindowpost1 := time.Now() verifyWindowpost1 := time.Now()
wpvi2 := saproof.WindowPoStVerifyInfo{ wpvi2 := saproof2.WindowPoStVerifyInfo{
Randomness: challenge[:], Randomness: challenge[:],
Proofs: wproof2, Proofs: wproof2,
ChallengedSectors: sealedSectors, ChallengedSectors: sealedSectors,
@ -464,10 +464,10 @@ type ParCfg struct {
Commit int 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 var pieces []abi.PieceInfo
sealTimings := make([]SealingResult, numSectors) sealTimings := make([]SealingResult, numSectors)
sealedSectors := make([]saproof.SectorInfo, numSectors) sealedSectors := make([]saproof2.SectorInfo, numSectors)
preCommit2Sema := make(chan struct{}, par.PreCommit2) preCommit2Sema := make(chan struct{}, par.PreCommit2)
commitSema := make(chan struct{}, par.Commit) commitSema := make(chan struct{}, par.Commit)
@ -537,7 +537,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
precommit2 := time.Now() precommit2 := time.Now()
<-preCommit2Sema <-preCommit2Sema
sealedSectors[ix] = saproof.SectorInfo{ sealedSectors[ix] = saproof2.SectorInfo{
SealProof: sb.SealProofType(), SealProof: sb.SealProofType(),
SectorNumber: i, SectorNumber: i,
SealedCID: cids.Sealed, SealedCID: cids.Sealed,
@ -589,7 +589,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
<-commitSema <-commitSema
if !skipc2 { if !skipc2 {
svi := saproof.SealVerifyInfo{ svi := saproof2.SealVerifyInfo{
SectorID: abi.SectorID{Miner: mid, Number: i}, SectorID: abi.SectorID{Miner: mid, Number: i},
SealedCID: cids.Sealed, SealedCID: cids.Sealed,
SealProof: sb.SealProofType(), SealProof: sb.SealProofType(),

View File

@ -15,7 +15,7 @@ import (
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
"github.com/filecoin-project/go-state-types/abi" "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/api"
"github.com/filecoin-project/lotus/chain/types" "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.Fatalw("Failed to collect actor changes", "error", err)
} }
log.Infow("Collected Actor Changes", log.Infow("Collected Actor Changes",
"MarketChanges", len(actorChanges[builtin.StorageMarketActorCodeID]), "MarketChanges", len(actorChanges[builtin2.StorageMarketActorCodeID]),
"MinerChanges", len(actorChanges[builtin.StorageMinerActorCodeID]), "MinerChanges", len(actorChanges[builtin2.StorageMinerActorCodeID]),
"RewardChanges", len(actorChanges[builtin.RewardActorCodeID]), "RewardChanges", len(actorChanges[builtin2.RewardActorCodeID]),
"AccountChanges", len(actorChanges[builtin.AccountActorCodeID]), "AccountChanges", len(actorChanges[builtin2.AccountActorCodeID]),
"nullRounds", len(nullRounds)) "nullRounds", len(nullRounds))
grp := sync.WaitGroup{} grp := sync.WaitGroup{}
@ -145,7 +145,7 @@ func (p *Processor) Start(ctx context.Context) {
grp.Add(1) grp.Add(1)
go func() { go func() {
defer grp.Done() 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) log.Errorf("Failed to handle market changes: %w", err)
return return
} }
@ -154,7 +154,7 @@ func (p *Processor) Start(ctx context.Context) {
grp.Add(1) grp.Add(1)
go func() { go func() {
defer grp.Done() 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) log.Errorf("Failed to handle miner changes: %w", err)
return return
} }
@ -163,7 +163,7 @@ func (p *Processor) Start(ctx context.Context) {
grp.Add(1) grp.Add(1)
go func() { go func() {
defer grp.Done() 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) log.Errorf("Failed to handle reward changes: %w", err)
return return
} }
@ -172,7 +172,7 @@ func (p *Processor) Start(ctx context.Context) {
grp.Add(1) grp.Add(1)
go func() { go func() {
defer grp.Done() 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) log.Errorf("Failed to handle power actor changes: %w", err)
return return
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/dline" "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/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
@ -22,8 +23,8 @@ import (
) )
const ( const (
LookbackCap = time.Hour * 12 LookbackCap = time.Hour * 24
stateWaitLookbackLimit = abi.ChainEpoch(20) StateWaitLookbackLimit = abi.ChainEpoch(20)
) )
var ( var (
@ -33,19 +34,29 @@ var (
// gatewayDepsAPI defines the API methods that the GatewayAPI depends on // gatewayDepsAPI defines the API methods that the GatewayAPI depends on
// (to make it easy to mock for tests) // (to make it easy to mock for tests)
type gatewayDepsAPI interface { type gatewayDepsAPI interface {
ChainHasObj(context.Context, cid.Cid) (bool, error) Version(context.Context) (api.Version, error)
ChainHead(ctx context.Context) (*types.TipSet, 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) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, 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) 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) 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) MpoolPushUntrusted(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, 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) 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) 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) 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) 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) 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) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error)
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, 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) StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, 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) StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error)
} }
type GatewayAPI struct { type GatewayAPI struct {
api gatewayDepsAPI api gatewayDepsAPI
lookbackCap time.Duration lookbackCap time.Duration
stateWaitLookbackLimit abi.ChainEpoch
} }
// NewGatewayAPI creates a new GatewayAPI with the default lookback cap // NewGatewayAPI creates a new GatewayAPI with the default lookback cap
func NewGatewayAPI(api gatewayDepsAPI) *GatewayAPI { func NewGatewayAPI(api gatewayDepsAPI) *GatewayAPI {
return newGatewayAPI(api, LookbackCap) return newGatewayAPI(api, LookbackCap, StateWaitLookbackLimit)
} }
// used by the tests // used by the tests
func newGatewayAPI(api gatewayDepsAPI, lookbackCap time.Duration) *GatewayAPI { func newGatewayAPI(api gatewayDepsAPI, lookbackCap time.Duration, stateWaitLookbackLimit abi.ChainEpoch) *GatewayAPI {
return &GatewayAPI{api: api, lookbackCap: lookbackCap} return &GatewayAPI{api: api, lookbackCap: lookbackCap, stateWaitLookbackLimit: stateWaitLookbackLimit}
} }
func (a *GatewayAPI) checkTipsetKey(ctx context.Context, tsk types.TipSetKey) error { 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 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) { func (a *GatewayAPI) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) {
return a.api.ChainHasObj(ctx, c) 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) 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) { func (a *GatewayAPI) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
return a.api.ChainGetTipSet(ctx, tsk) 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) 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) { func (a *GatewayAPI) ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) {
return a.api.ChainGetNode(ctx, p) 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) { 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 { if err := a.checkTipsetKey(ctx, tsk); err != nil {
return nil, err return nil, err
@ -205,6 +234,14 @@ func (a *GatewayAPI) StateAccountKey(ctx context.Context, addr address.Address,
return a.api.StateAccountKey(ctx, addr, tsk) 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) { func (a *GatewayAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
if err := a.checkTipsetKey(ctx, tsk); err != nil { if err := a.checkTipsetKey(ctx, tsk); err != nil {
return nil, err 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) 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) { func (a *GatewayAPI) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
if err := a.checkTipsetKey(ctx, tsk); err != nil { if err := a.checkTipsetKey(ctx, tsk); err != nil {
return address.Undef, err 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) 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) { 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) { 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) { func (a *GatewayAPI) StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
if err := a.checkTipsetKey(ctx, tsk); err != nil { if err := a.checkTipsetKey(ctx, tsk); err != nil {
return api.CirculatingSupply{}, err return api.CirculatingSupply{}, err

View File

@ -6,6 +6,9 @@ import (
"testing" "testing"
"time" "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/filecoin-project/lotus/build"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -116,6 +119,38 @@ func (m *mockGatewayDepsAPI) ChainHasObj(context.Context, cid.Cid) (bool, error)
panic("implement me") 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) { func (m *mockGatewayDepsAPI) ChainHead(ctx context.Context) (*types.TipSet, error) {
m.lk.RLock() m.lk.RLock()
defer m.lk.RUnlock() defer m.lk.RUnlock()
@ -165,10 +200,6 @@ func (m *mockGatewayDepsAPI) ChainGetTipSetByHeight(ctx context.Context, h abi.C
return m.tipsets[h], nil 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) { func (m *mockGatewayDepsAPI) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) {
panic("implement me") panic("implement me")
} }

View File

@ -12,8 +12,8 @@ import (
"github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/cli"
clitest "github.com/filecoin-project/lotus/cli/test" clitest "github.com/filecoin-project/lotus/cli/test"
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init"
"github.com/filecoin-project/specs-actors/actors/builtin/multisig" multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@ -25,12 +25,14 @@ import (
"github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/api/client"
"github.com/filecoin-project/lotus/api/test" "github.com/filecoin-project/lotus/api/test"
"github.com/filecoin-project/lotus/chain/actors/policy" "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/chain/types"
"github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node"
builder "github.com/filecoin-project/lotus/node/test" builder "github.com/filecoin-project/lotus/node/test"
) )
const maxLookbackCap = time.Duration(math.MaxInt64) const maxLookbackCap = time.Duration(math.MaxInt64)
const maxStateWaitLookbackLimit = stmgr.LookbackNoLimit
func init() { func init() {
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
@ -38,15 +40,19 @@ func init() {
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
} }
// TestEndToEndWalletMsig tests that wallet and msig API calls can be made // TestWalletMsig tests that API calls to wallet and msig can be made on a lite
// on a lite node that is connected through a gateway to a full API node // node that is connected through a gateway to a full API node
func TestEndToEndWalletMsig(t *testing.T) { func TestWalletMsig(t *testing.T) {
_ = os.Setenv("BELLMAN_NO_GPU", "1") _ = os.Setenv("BELLMAN_NO_GPU", "1")
clitest.QuietMiningLogs()
blocktime := 5 * time.Millisecond blocktime := 5 * time.Millisecond
ctx := context.Background() ctx := context.Background()
full, lite, closer := startNodes(ctx, t, blocktime, maxLookbackCap) nodes := startNodes(ctx, t, blocktime, maxLookbackCap, maxStateWaitLookbackLimit)
defer closer() defer nodes.closer()
lite := nodes.lite
full := nodes.full
// The full node starts with a wallet // The full node starts with a wallet
fullWalletAddr, err := full.WalletDefaultAddress(ctx) fullWalletAddr, err := full.WalletDefaultAddress(ctx)
@ -101,7 +107,7 @@ func TestEndToEndWalletMsig(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, 0, res.Receipt.ExitCode) require.EqualValues(t, 0, res.Receipt.ExitCode)
var execReturn init0.ExecReturn var execReturn init2.ExecReturn
err = execReturn.UnmarshalCBOR(bytes.NewReader(res.Receipt.Return)) err = execReturn.UnmarshalCBOR(bytes.NewReader(res.Receipt.Return))
require.NoError(t, err) require.NoError(t, err)
@ -121,7 +127,7 @@ func TestEndToEndWalletMsig(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, 0, res.Receipt.ExitCode) require.EqualValues(t, 0, res.Receipt.ExitCode)
var proposeReturn multisig.ProposeReturn var proposeReturn multisig2.ProposeReturn
err = proposeReturn.UnmarshalCBOR(bytes.NewReader(res.Receipt.Return)) err = proposeReturn.UnmarshalCBOR(bytes.NewReader(res.Receipt.Return))
require.NoError(t, err) require.NoError(t, err)
@ -135,62 +141,89 @@ func TestEndToEndWalletMsig(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, 0, res.Receipt.ExitCode) require.EqualValues(t, 0, res.Receipt.ExitCode)
var approveReturn multisig.ApproveReturn var approveReturn multisig2.ApproveReturn
err = approveReturn.UnmarshalCBOR(bytes.NewReader(res.Receipt.Return)) err = approveReturn.UnmarshalCBOR(bytes.NewReader(res.Receipt.Return))
require.NoError(t, err) require.NoError(t, err)
require.True(t, approveReturn.Applied) 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 // 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") _ = os.Setenv("BELLMAN_NO_GPU", "1")
clitest.QuietMiningLogs() clitest.QuietMiningLogs()
blocktime := 5 * time.Millisecond blocktime := 5 * time.Millisecond
ctx := context.Background() ctx := context.Background()
full, lite, closer := startNodes(ctx, t, blocktime, maxLookbackCap) nodes := startNodesWithFunds(ctx, t, blocktime, maxLookbackCap, maxStateWaitLookbackLimit)
defer closer() defer nodes.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)
lite := nodes.lite
clitest.RunMultisigTest(t, cli.Commands, 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 { func TestDealFlow(t *testing.T) {
msg := &types.Message{ _ = os.Setenv("BELLMAN_NO_GPU", "1")
From: fromAddr, clitest.QuietMiningLogs()
To: toAddr,
Value: amt,
}
sm, err := fromNode.MpoolPushMessage(ctx, msg, nil) blocktime := 5 * time.Millisecond
if err != nil { ctx := context.Background()
return err nodes := startNodesWithFunds(ctx, t, blocktime, maxLookbackCap, maxStateWaitLookbackLimit)
} defer nodes.closer()
res, err := fromNode.StateWaitMsg(ctx, sm.Cid(), 1) test.MakeDeal(t, ctx, 6, nodes.lite, nodes.miner, false, false)
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
} }
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 var closer jsonrpc.ClientCloser
// Create one miner and two full nodes. // 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] fullNode := nodes[0]
// Create a gateway server in front of the full node // 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) require.NoError(t, err)
// Create a gateway client API that connects to the gateway server // 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) err = miner.NetConnect(ctx, fullAddr)
require.NoError(t, err) 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 // Start mining blocks
bm := test.NewBlockMiner(ctx, t, miner, blocktime) bm := test.NewBlockMiner(ctx, t, miner, blocktime)
bm.MineBlocks() 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
} }

View File

@ -7,10 +7,15 @@ import (
"os" "os"
"github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc"
"go.opencensus.io/tag"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
lcli "github.com/filecoin-project/lotus/cli" lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/lib/lotuslog" "github.com/filecoin-project/lotus/lib/lotuslog"
"github.com/filecoin-project/lotus/metrics"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"go.opencensus.io/stats/view"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
@ -64,6 +69,13 @@ var runCmd = &cli.Command{
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
defer cancel() 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) api, closer, err := lcli.GetFullNodeAPI(cctx)
if err != nil { if err != nil {
return err return err
@ -76,7 +88,7 @@ var runCmd = &cli.Command{
log.Info("Setting up API endpoint at " + address) log.Info("Setting up API endpoint at " + address)
rpcServer := jsonrpc.NewServer() rpcServer := jsonrpc.NewServer()
rpcServer.Register("Filecoin", NewGatewayAPI(api)) rpcServer.Register("Filecoin", metrics.MetricedGatewayAPI(NewGatewayAPI(api)))
mux.Handle("/rpc/v0", rpcServer) mux.Handle("/rpc/v0", rpcServer)
mux.PathPrefix("/").Handler(http.DefaultServeMux) mux.PathPrefix("/").Handler(http.DefaultServeMux)
@ -89,6 +101,7 @@ var runCmd = &cli.Command{
srv := &http.Server{ srv := &http.Server{
Handler: mux, Handler: mux,
BaseContext: func(listener net.Listener) context.Context { BaseContext: func(listener net.Listener) context.Context {
ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "lotus-gateway"))
return ctx return ctx
}, },
} }

View File

@ -6,19 +6,19 @@ import (
"context" "context"
"encoding/csv" "encoding/csv"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
_ "net/http/pprof" _ "net/http/pprof"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/go-state-types/network"
@ -251,6 +251,15 @@ var recoverMinersCmd = &cli.Command{
} }
defer closer() 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")) from, err := address.NewFromString(cctx.String("from"))
if err != nil { if err != nil {
return xerrors.Errorf("parsing source address (provide correct --from flag!): %w", err) 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")) minerRecoveryCutoff := uint64(cctx.Int("miner-recovery-cutoff"))
minerRecoveryBonus := uint64(cctx.Int("miner-recovery-bonus")) minerRecoveryBonus := uint64(cctx.Int("miner-recovery-bonus"))
blockmap := make(map[address.Address]struct{})
for _, addr := range r.Blocklist() {
blockmap[addr] = struct{}{}
}
rf := &refunder{ rf := &refunder{
api: api, api: api,
wallet: from, wallet: from,
@ -274,6 +289,7 @@ var recoverMinersCmd = &cli.Command{
minerRecoveryRefundPercent: minerRecoveryRefundPercent, minerRecoveryRefundPercent: minerRecoveryRefundPercent,
minerRecoveryCutoff: types.FromFil(minerRecoveryCutoff), minerRecoveryCutoff: types.FromFil(minerRecoveryCutoff),
minerRecoveryBonus: types.FromFil(minerRecoveryBonus), minerRecoveryBonus: types.FromFil(minerRecoveryBonus),
blockmap: blockmap,
} }
refundTipset, err := api.ChainHead(ctx) refundTipset, err := api.ChainHead(ctx)
@ -466,6 +482,12 @@ var runCmd = &cli.Command{
return err return err
} }
blockmap := make(map[address.Address]struct{})
for _, addr := range r.Blocklist() {
blockmap[addr] = struct{}{}
}
rf := &refunder{ rf := &refunder{
api: api, api: api,
wallet: from, wallet: from,
@ -480,13 +502,18 @@ var runCmd = &cli.Command{
publishStorageDealsEnabled: publishStorageDealsEnabled, publishStorageDealsEnabled: publishStorageDealsEnabled,
preFeeCapMax: types.BigInt(preFeeCapMax), preFeeCapMax: types.BigInt(preFeeCapMax),
proveFeeCapMax: types.BigInt(proveFeeCapMax), proveFeeCapMax: types.BigInt(proveFeeCapMax),
blockmap: blockmap,
} }
var refunds *MinersRefund = NewMinersRefund() var refunds = NewMinersRefund()
var rounds int = 0 var rounds = 0
nextMinerRecovery := r.MinerRecoveryHeight() + minerRecoveryPeriod nextMinerRecovery := r.MinerRecoveryHeight() + minerRecoveryPeriod
for tipset := range tipsetsCh { for tipset := range tipsetsCh {
for k := range rf.blockmap {
fmt.Printf("%s\n", k)
}
refunds, err = rf.ProcessTipset(ctx, tipset, refunds) refunds, err = rf.ProcessTipset(ctx, tipset, refunds)
if err != nil { if err != nil {
return err return err
@ -634,6 +661,7 @@ type refunder struct {
windowedPoStEnabled bool windowedPoStEnabled bool
publishStorageDealsEnabled bool publishStorageDealsEnabled bool
threshold big.Int threshold big.Int
blockmap map[address.Address]struct{}
preFeeCapMax big.Int preFeeCapMax big.Int
proveFeeCapMax big.Int proveFeeCapMax big.Int
@ -738,6 +766,11 @@ func (r *refunder) EnsureMinerMinimums(ctx context.Context, tipset *types.TipSet
} }
for _, maddr := range miners { 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) mact, err := r.api.StateGetActor(ctx, maddr, types.EmptyTSK)
if err != nil { if err != nil {
log.Errorw("failed", "err", err, "height", tipset.Height(), "key", tipset.Key(), "miner", maddr) 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 var messageMethod string
switch m.Method { switch m.Method {
case builtin0.MethodsMarket.PublishStorageDeals: case market.Methods.PublishStorageDeals:
if !r.publishStorageDealsEnabled { if !r.publishStorageDealsEnabled {
return false, messageMethod, types.NewInt(0), nil return false, messageMethod, types.NewInt(0), nil
} }
@ -897,8 +930,13 @@ func (r *refunder) processTipsetStorageMinerActor(ctx context.Context, tipset *t
refundValue := types.NewInt(0) refundValue := types.NewInt(0)
var messageMethod string 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 { switch m.Method {
case builtin0.MethodsMiner.SubmitWindowedPoSt: case miner.Methods.SubmitWindowedPoSt:
if !r.windowedPoStEnabled { if !r.windowedPoStEnabled {
return false, messageMethod, types.NewInt(0), nil 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) refundValue = types.BigMul(types.NewInt(uint64(recp.GasUsed)), tipset.Blocks()[0].ParentBaseFee)
case builtin0.MethodsMiner.ProveCommitSector: case miner.Methods.ProveCommitSector:
if !r.proveCommitEnabled { if !r.proveCommitEnabled {
return false, messageMethod, types.NewInt(0), nil 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 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 sn abi.SectorNumber
var proveCommitSector miner0.ProveCommitSectorParams var proveCommitSector miner2.ProveCommitSectorParams
if err := proveCommitSector.UnmarshalCBOR(bytes.NewBuffer(m.Params)); err != nil { 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) log.Warnw("failed to decode provecommit params", "err", err, "method", messageMethod, "cid", msg.Cid, "miner", m.To)
return false, messageMethod, types.NewInt(0), nil return false, messageMethod, types.NewInt(0), nil
@ -967,7 +1010,7 @@ func (r *refunder) processTipsetStorageMinerActor(ctx context.Context, tipset *t
if r.refundPercent > 0 { if r.refundPercent > 0 {
refundValue = types.BigMul(types.BigDiv(refundValue, types.NewInt(100)), types.NewInt(uint64(r.refundPercent))) 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 { if !r.preCommitEnabled {
return false, messageMethod, types.NewInt(0), nil 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 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 var precommitInfo miner.SectorPreCommitInfo
if err := precommitInfo.UnmarshalCBOR(bytes.NewBuffer(m.Params)); err != nil { 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) 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 lastHeight abi.ChainEpoch
lastMinerRecoveryHeight abi.ChainEpoch lastMinerRecoveryHeight abi.ChainEpoch
path string path string
blocklist []address.Address
} }
func NewRepo(path string) (*Repo, error) { func NewRepo(path string) (*Repo, error) {
@ -1222,6 +1271,10 @@ func (r *Repo) Open() error {
return err return err
} }
if err := r.loadBlockList(); err != nil {
return err
}
return nil return nil
} }
@ -1247,6 +1300,51 @@ func loadChainEpoch(fn string) (abi.ChainEpoch, error) {
return abi.ChainEpoch(height), nil 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 { func (r *Repo) loadHeight() error {
var err error var err error
r.lastHeight, err = loadChainEpoch(filepath.Join(r.path, "height")) r.lastHeight, err = loadChainEpoch(filepath.Join(r.path, "height"))
@ -1259,6 +1357,10 @@ func (r *Repo) loadMinerRecoveryHeight() error {
return err return err
} }
func (r *Repo) Blocklist() []address.Address {
return r.blocklist
}
func (r *Repo) Height() abi.ChainEpoch { func (r *Repo) Height() abi.ChainEpoch {
return r.lastHeight return r.lastHeight
} }

View File

@ -18,6 +18,8 @@ import (
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
manet "github.com/multiformats/go-multiaddr/net" manet "github.com/multiformats/go-multiaddr/net"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"go.opencensus.io/stats/view"
"go.opencensus.io/tag"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-jsonrpc" "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/extern/sector-storage/stores"
"github.com/filecoin-project/lotus/lib/lotuslog" "github.com/filecoin-project/lotus/lib/lotuslog"
"github.com/filecoin-project/lotus/lib/rpcenc" "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/modules"
"github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/node/repo"
) )
@ -194,6 +197,13 @@ var runCmd = &cli.Command{
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
defer cancel() 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) v, err := nodeApi.Version(ctx)
if err != nil { if err != nil {
return err return err
@ -376,7 +386,7 @@ var runCmd = &cli.Command{
readerHandler, readerServerOpt := rpcenc.ReaderParamDecoder() readerHandler, readerServerOpt := rpcenc.ReaderParamDecoder()
rpcServer := jsonrpc.NewServer(readerServerOpt) 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/v0", rpcServer)
mux.Handle("/rpc/streams/v0/push/{uuid}", readerHandler) mux.Handle("/rpc/streams/v0/push/{uuid}", readerHandler)
@ -391,6 +401,7 @@ var runCmd = &cli.Command{
srv := &http.Server{ srv := &http.Server{
Handler: ah, Handler: ah,
BaseContext: func(listener net.Listener) context.Context { BaseContext: func(listener net.Listener) context.Context {
ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "lotus-worker"))
return ctx return ctx
}, },
} }

View File

@ -22,7 +22,8 @@ import (
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/extern/sector-storage/zerocomm" "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/types"
"github.com/filecoin-project/lotus/chain/wallet" "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 { func createDeals(m *genesis.Miner, k *wallet.Key, maddr address.Address, ssize abi.SectorSize) error {
for i, sector := range m.Sectors { for i, sector := range m.Sectors {
proposal := &market.DealProposal{ proposal := &market2.DealProposal{
PieceCID: sector.CommD, PieceCID: sector.CommD,
PieceSize: abi.PaddedPieceSize(ssize), PieceSize: abi.PaddedPieceSize(ssize),
Client: k.Address, Client: k.Address,

View File

@ -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
},
}

View File

@ -7,9 +7,9 @@ import (
"strings" "strings"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
ledgerfil "github.com/whyrusleeping/ledger-filecoin-go" ledgerfil "github.com/whyrusleeping/ledger-filecoin-go"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/types" "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 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 { if err != nil {
return xerrors.Errorf("getting balance: %w", err) if strings.Contains(err.Error(), "actor not found") {
} a = nil
if !b.IsZero() { } else {
end = i + 21 // BIP32 spec, stop after 20 empty addresses 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 { } else {
fmt.Printf("%s %s\n", addr, printHDPath(p)) fmt.Printf("%s %s\n", addr, printHDPath(p))
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"fmt"
"os" "os"
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
@ -18,6 +19,7 @@ func main() {
base32Cmd, base32Cmd,
base16Cmd, base16Cmd,
bitFieldCmd, bitFieldCmd,
frozenMinersCmd,
keyinfoCmd, keyinfoCmd,
jwtCmd, jwtCmd,
noncefix, noncefix,
@ -42,6 +44,8 @@ func main() {
stateTreePruneCmd, stateTreePruneCmd,
datastoreCmd, datastoreCmd,
ledgerCmd, ledgerCmd,
sectorsCmd,
msgCmd,
} }
app := &cli.App{ app := &cli.App{
@ -56,6 +60,13 @@ func main() {
Hidden: true, Hidden: true,
Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME 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{ &cli.StringFlag{
Name: "log-level", Name: "log-level",
Value: "info", Value: "info",

View File

@ -14,11 +14,10 @@ import (
"go.opencensus.io/stats/view" "go.opencensus.io/stats/view"
"go.opencensus.io/tag" "go.opencensus.io/tag"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
lapi "github.com/filecoin-project/lotus/api" lapi "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli" lcli "github.com/filecoin-project/lotus/cli"
) )
@ -145,7 +144,7 @@ var mpoolStatsCmd = &cli.Command{
seen: time.Now(), 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) miner, err := isMiner(u.Message.Message.To)
if err != nil { if err != nil {

280
cmd/lotus-shed/msg.go Normal file
View File

@ -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)
}

Some files were not shown because too many files have changed in this diff Show More