From 571114bc44811c416f1dbeeddcfdcda72c13aced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Mar 2021 16:40:22 +0100 Subject: [PATCH 01/60] Scaffolding for API versioning --- api/v0api/full.go | 679 ++++++++++++++++++++++++++++++++++++++ api/v0api/v1_wrapper.go | 32 ++ api/v1api/latest.go | 9 + cmd/lotus-gateway/main.go | 2 +- cmd/lotus/rpc.go | 25 +- 5 files changed, 737 insertions(+), 10 deletions(-) create mode 100644 api/v0api/full.go create mode 100644 api/v0api/v1_wrapper.go create mode 100644 api/v1api/latest.go diff --git a/api/v0api/full.go b/api/v0api/full.go new file mode 100644 index 00000000000..aad8531a091 --- /dev/null +++ b/api/v0api/full.go @@ -0,0 +1,679 @@ +package v0api + +import ( + "context" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + datatransfer "github.com/filecoin-project/go-data-transfer" + "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/go-multistore" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/dline" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p-core/peer" + + "github.com/filecoin-project/lotus/api" + apitypes "github.com/filecoin-project/lotus/api/types" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" + "github.com/filecoin-project/lotus/chain/types" + marketevents "github.com/filecoin-project/lotus/markets/loggers" + "github.com/filecoin-project/lotus/node/modules/dtypes" +) + +// FullNode API is a low-level interface to the Filecoin network full node +type FullNode interface { + api.Common + + // MethodGroup: Chain + // The Chain method group contains methods for interacting with the + // blockchain, but that do not require any form of state computation. + + // ChainNotify returns channel with chain head updates. + // First message is guaranteed to be of len == 1, and type == 'current'. + ChainNotify(context.Context) (<-chan []*api.HeadChange, error) //perm:read + + // ChainHead returns the current head of the chain. + ChainHead(context.Context) (*types.TipSet, error) //perm:read + + // ChainGetRandomnessFromTickets is used to sample the chain for randomness. + ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) //perm:read + + // ChainGetRandomnessFromBeacon is used to sample the beacon for randomness. + ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) //perm:read + + // ChainGetBlock returns the block specified by the given CID. + ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) //perm:read + // ChainGetTipSet returns the tipset specified by the given TipSetKey. + ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error) //perm:read + + // ChainGetBlockMessages returns messages stored in the specified block. + // + // Note: If there are multiple blocks in a tipset, it's likely that some + // messages will be duplicated. It's also possible for blocks in a tipset to have + // different messages from the same sender at the same nonce. When that happens, + // only the first message (in a block with lowest ticket) will be considered + // for execution + // + // NOTE: THIS METHOD SHOULD ONLY BE USED FOR GETTING MESSAGES IN A SPECIFIC BLOCK + // + // DO NOT USE THIS METHOD TO GET MESSAGES INCLUDED IN A TIPSET + // Use ChainGetParentMessages, which will perform correct message deduplication + ChainGetBlockMessages(ctx context.Context, blockCid cid.Cid) (*api.BlockMessages, error) //perm:read + + // ChainGetParentReceipts returns receipts for messages in parent tipset of + // the specified block. The receipts in the list returned is one-to-one with the + // messages returned by a call to ChainGetParentMessages with the same blockCid. + ChainGetParentReceipts(ctx context.Context, blockCid cid.Cid) ([]*types.MessageReceipt, error) //perm:read + + // ChainGetParentMessages returns messages stored in parent tipset of the + // specified block. + ChainGetParentMessages(ctx context.Context, blockCid cid.Cid) ([]api.Message, error) //perm:read + + // ChainGetTipSetByHeight looks back for a tipset at the specified epoch. + // If there are no blocks at the specified epoch, a tipset at an earlier epoch + // will be returned. + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) //perm:read + + // ChainReadObj reads ipld nodes referenced by the specified CID from chain + // blockstore and returns raw bytes. + ChainReadObj(context.Context, cid.Cid) ([]byte, error) //perm:read + + // ChainDeleteObj deletes node referenced by the given CID + ChainDeleteObj(context.Context, cid.Cid) error //perm:admin + + // ChainHasObj checks if a given CID exists in the chain blockstore. + ChainHasObj(context.Context, cid.Cid) (bool, error) //perm:read + + // ChainStatObj returns statistics about the graph referenced by 'obj'. + // If 'base' is also specified, then the returned stat will be a diff + // between the two objects. + ChainStatObj(ctx context.Context, obj cid.Cid, base cid.Cid) (api.ObjStat, error) //perm:read + + // ChainSetHead forcefully sets current chain head. Use with caution. + ChainSetHead(context.Context, types.TipSetKey) error //perm:admin + + // ChainGetGenesis returns the genesis tipset. + ChainGetGenesis(context.Context) (*types.TipSet, error) //perm:read + + // ChainTipSetWeight computes weight for the specified tipset. + ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error) //perm:read + ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) //perm:read + + // ChainGetMessage reads a message referenced by the specified CID from the + // chain blockstore. + ChainGetMessage(context.Context, cid.Cid) (*types.Message, error) //perm:read + + // ChainGetPath returns a set of revert/apply operations needed to get from + // one tipset to another, for example: + //``` + // to + // ^ + // from tAA + // ^ ^ + // tBA tAB + // ^---*--^ + // ^ + // tRR + //``` + // Would return `[revert(tBA), apply(tAB), apply(tAA)]` + ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*api.HeadChange, error) //perm:read + + // ChainExport returns a stream of bytes with CAR dump of chain data. + // The exported chain data includes the header chain from the given tipset + // back to genesis, the entire genesis state, and the most recent 'nroots' + // state trees. + // If oldmsgskip is set, messages from before the requested roots are also not included. + ChainExport(ctx context.Context, nroots abi.ChainEpoch, oldmsgskip bool, tsk types.TipSetKey) (<-chan []byte, error) //perm:read + + // MethodGroup: Beacon + // The Beacon method group contains methods for interacting with the random beacon (DRAND) + + // BeaconGetEntry returns the beacon entry for the given filecoin epoch. If + // the entry has not yet been produced, the call will block until the entry + // becomes available + BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) //perm:read + + // GasEstimateFeeCap estimates gas fee cap + GasEstimateFeeCap(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error) //perm:read + + // GasEstimateGasLimit estimates gas used by the message and returns it. + // It fails if message fails to execute. + GasEstimateGasLimit(context.Context, *types.Message, types.TipSetKey) (int64, error) //perm:read + + // GasEstimateGasPremium estimates what gas price should be used for a + // message to have high likelihood of inclusion in `nblocksincl` epochs. + + GasEstimateGasPremium(_ context.Context, nblocksincl uint64, + sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) //perm:read + + // GasEstimateMessageGas estimates gas values for unset message gas fields + GasEstimateMessageGas(context.Context, *types.Message, *api.MessageSendSpec, types.TipSetKey) (*types.Message, error) //perm:read + + // MethodGroup: Sync + // The Sync method group contains methods for interacting with and + // observing the lotus sync service. + + // SyncState returns the current status of the lotus sync system. + SyncState(context.Context) (*api.SyncState, error) //perm:read + + // SyncSubmitBlock can be used to submit a newly created block to the. + // network through this node + SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error //perm:write + + // SyncIncomingBlocks returns a channel streaming incoming, potentially not + // yet synced block headers. + SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) //perm:read + + // SyncCheckpoint marks a blocks as checkpointed, meaning that it won't ever fork away from it. + SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error //perm:admin + + // SyncMarkBad marks a blocks as bad, meaning that it won't ever by synced. + // Use with extreme caution. + SyncMarkBad(ctx context.Context, bcid cid.Cid) error //perm:admin + + // SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again. + SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error //perm:admin + + // SyncUnmarkAllBad purges bad block cache, making it possible to sync to chains previously marked as bad + SyncUnmarkAllBad(ctx context.Context) error //perm:admin + + // SyncCheckBad checks if a block was marked as bad, and if it was, returns + // the reason. + SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) //perm:read + + // SyncValidateTipset indicates whether the provided tipset is valid or not + SyncValidateTipset(ctx context.Context, tsk types.TipSetKey) (bool, error) //perm:read + + // MethodGroup: Mpool + // The Mpool methods are for interacting with the message pool. The message pool + // manages all incoming and outgoing 'messages' going over the network. + + // MpoolPending returns pending mempool messages. + MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) //perm:read + + // MpoolSelect returns a list of pending messages for inclusion in the next block + MpoolSelect(context.Context, types.TipSetKey, float64) ([]*types.SignedMessage, error) //perm:read + + // MpoolPush pushes a signed message to mempool. + MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error) //perm:write + + // MpoolPushUntrusted pushes a signed message to mempool from untrusted sources. + MpoolPushUntrusted(context.Context, *types.SignedMessage) (cid.Cid, error) //perm:write + + // MpoolPushMessage atomically assigns a nonce, signs, and pushes a message + // to mempool. + // maxFee is only used when GasFeeCap/GasPremium fields aren't specified + // + // When maxFee is set to 0, MpoolPushMessage will guess appropriate fee + // based on current chain conditions + MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) //perm:sign + + // MpoolBatchPush batch pushes a signed message to mempool. + MpoolBatchPush(context.Context, []*types.SignedMessage) ([]cid.Cid, error) //perm:write + + // MpoolBatchPushUntrusted batch pushes a signed message to mempool from untrusted sources. + MpoolBatchPushUntrusted(context.Context, []*types.SignedMessage) ([]cid.Cid, error) //perm:write + + // MpoolBatchPushMessage batch pushes a unsigned message to mempool. + MpoolBatchPushMessage(context.Context, []*types.Message, *api.MessageSendSpec) ([]*types.SignedMessage, error) //perm:sign + + // MpoolGetNonce gets next nonce for the specified sender. + // Note that this method may not be atomic. Use MpoolPushMessage instead. + MpoolGetNonce(context.Context, address.Address) (uint64, error) //perm:read + MpoolSub(context.Context) (<-chan api.MpoolUpdate, error) //perm:read + + // MpoolClear clears pending messages from the mpool + MpoolClear(context.Context, bool) error //perm:write + + // MpoolGetConfig returns (a copy of) the current mpool config + MpoolGetConfig(context.Context) (*types.MpoolConfig, error) //perm:read + // MpoolSetConfig sets the mpool config to (a copy of) the supplied config + MpoolSetConfig(context.Context, *types.MpoolConfig) error //perm:admin + + // MethodGroup: Miner + + MinerGetBaseInfo(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error) //perm:read + MinerCreateBlock(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) //perm:write + + // // UX ? + + // MethodGroup: Wallet + + // WalletNew creates a new address in the wallet with the given sigType. + // Available key types: bls, secp256k1, secp256k1-ledger + // Support for numerical types: 1 - secp256k1, 2 - BLS is deprecated + WalletNew(context.Context, types.KeyType) (address.Address, error) //perm:write + // WalletHas indicates whether the given address is in the wallet. + WalletHas(context.Context, address.Address) (bool, error) //perm:write + // WalletList lists all the addresses in the wallet. + WalletList(context.Context) ([]address.Address, error) //perm:write + // WalletBalance returns the balance of the given address at the current head of the chain. + WalletBalance(context.Context, address.Address) (types.BigInt, error) //perm:read + // WalletSign signs the given bytes using the given address. + WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) //perm:sign + // WalletSignMessage signs the given message using the given address. + WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) //perm:sign + // WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid. + // The address does not have to be in the wallet. + WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) (bool, error) //perm:read + // WalletDefaultAddress returns the address marked as default in the wallet. + WalletDefaultAddress(context.Context) (address.Address, error) //perm:write + // WalletSetDefault marks the given address as as the default one. + WalletSetDefault(context.Context, address.Address) error //perm:write + // WalletExport returns the private key of an address in the wallet. + WalletExport(context.Context, address.Address) (*types.KeyInfo, error) //perm:admin + // WalletImport receives a KeyInfo, which includes a private key, and imports it into the wallet. + WalletImport(context.Context, *types.KeyInfo) (address.Address, error) //perm:admin + // WalletDelete deletes an address from the wallet. + WalletDelete(context.Context, address.Address) error //perm:admin + // WalletValidateAddress validates whether a given string can be decoded as a well-formed address + WalletValidateAddress(context.Context, string) (address.Address, error) //perm:read + + // Other + + // MethodGroup: Client + // The Client methods all have to do with interacting with the storage and + // retrieval markets as a client + + // ClientImport imports file under the specified path into filestore. + ClientImport(ctx context.Context, ref api.FileRef) (*api.ImportRes, error) //perm:admin + // ClientRemoveImport removes file import + ClientRemoveImport(ctx context.Context, importID multistore.StoreID) error //perm:admin + // ClientStartDeal proposes a deal with a miner. + ClientStartDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) //perm:admin + // ClientGetDealInfo returns the latest information about a given deal. + ClientGetDealInfo(context.Context, cid.Cid) (*api.DealInfo, error) //perm:read + // ClientListDeals returns information about the deals made by the local client. + ClientListDeals(ctx context.Context) ([]api.DealInfo, error) //perm:write + // ClientGetDealUpdates returns the status of updated deals + ClientGetDealUpdates(ctx context.Context) (<-chan api.DealInfo, error) //perm:write + // ClientGetDealStatus returns status given a code + ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error) //perm:read + // ClientHasLocal indicates whether a certain CID is locally stored. + ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) //perm:write + // ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer). + ClientFindData(ctx context.Context, root cid.Cid, piece *cid.Cid) ([]api.QueryOffer, error) //perm:read + // ClientMinerQueryOffer returns a QueryOffer for the specific miner and file. + ClientMinerQueryOffer(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (api.QueryOffer, error) //perm:read + // ClientRetrieve initiates the retrieval of a file, as specified in the order. + ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error //perm:admin + // ClientRetrieveWithEvents initiates the retrieval of a file, as specified in the order, and provides a channel + // of status updates. + ClientRetrieveWithEvents(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) //perm:admin + // ClientQueryAsk returns a signed StorageAsk from the specified miner. + ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) //perm:read + // ClientCalcCommP calculates the CommP and data size of the specified CID + ClientDealPieceCID(ctx context.Context, root cid.Cid) (api.DataCIDSize, error) //perm:read + // ClientCalcCommP calculates the CommP for a specified file + ClientCalcCommP(ctx context.Context, inpath string) (*api.CommPRet, error) //perm:write + // ClientGenCar generates a CAR file for the specified file. + ClientGenCar(ctx context.Context, ref api.FileRef, outpath string) error //perm:write + // ClientDealSize calculates real deal data size + ClientDealSize(ctx context.Context, root cid.Cid) (api.DataSize, error) //perm:read + // ClientListTransfers returns the status of all ongoing transfers of data + ClientListDataTransfers(ctx context.Context) ([]api.DataTransferChannel, error) //perm:write + ClientDataTransferUpdates(ctx context.Context) (<-chan api.DataTransferChannel, error) //perm:write + // ClientRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer + ClientRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error //perm:write + // ClientCancelDataTransfer cancels a data transfer with the given transfer ID and other peer + ClientCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error //perm:write + // ClientRetrieveTryRestartInsufficientFunds attempts to restart stalled retrievals on a given payment channel + // which are stuck due to insufficient funds + ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error //perm:write + + // ClientUnimport removes references to the specified file from filestore + //ClientUnimport(path string) + + // ClientListImports lists imported files and their root CIDs + ClientListImports(ctx context.Context) ([]api.Import, error) //perm:write + + //ClientListAsks() []Ask + + // MethodGroup: State + // The State methods are used to query, inspect, and interact with chain state. + // Most methods take a TipSetKey as a parameter. The state looked up is the parent state of the tipset. + // A nil TipSetKey can be provided as a param, this will cause the heaviest tipset in the chain to be used. + + // StateCall runs the given message and returns its result without any persisted changes. + // + // StateCall applies the message to the tipset's parent state. The + // message is not applied on-top-of the messages in the passed-in + // tipset. + StateCall(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) //perm:read + // StateReplay replays a given message, assuming it was included in a block in the specified tipset. + // + // If a tipset key is provided, and a replacing message is found on chain, + // the method will return an error saying that the message wasn't found + // + // If no tipset key is provided, the appropriate tipset is looked up, and if + // the message was gas-repriced, the on-chain message will be replayed - in + // that case the returned InvocResult.MsgCid will not match the Cid param + // + // If the caller wants to ensure that exactly the requested message was executed, + // they MUST check that InvocResult.MsgCid is equal to the provided Cid. + // Without this check both the requested and original message may appear as + // successfully executed on-chain, which may look like a double-spend. + // + // A replacing message is a message with a different CID, any of Gas values, and + // different signature, but with all other parameters matching (source/destination, + // nonce, params, etc.) + StateReplay(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) //perm:read + // StateGetActor returns the indicated actor's nonce and balance. + StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) //perm:read + // StateReadState returns the indicated actor's state. + StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) //perm:read + // StateListMessages looks back and returns all messages with a matching to or from address, stopping at the given height. + StateListMessages(ctx context.Context, match *api.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) //perm:read + // StateDecodeParams attempts to decode the provided params, based on the recipient actor address and method number. + StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error) //perm:read + + // StateNetworkName returns the name of the network the node is synced to + StateNetworkName(context.Context) (dtypes.NetworkName, error) //perm:read + // StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included. + StateMinerSectors(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) //perm:read + // StateMinerActiveSectors returns info about sectors that a given miner is actively proving. + StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) //perm:read + // StateMinerProvingDeadline calculates the deadline at some epoch for a proving period + // and returns the deadline-related calculations. + StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) //perm:read + // StateMinerPower returns the power of the indicated miner + StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) //perm:read + // StateMinerInfo returns info about the indicated miner + StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) //perm:read + // StateMinerDeadlines returns all the proving deadlines for the given miner + StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]api.Deadline, error) //perm:read + // StateMinerPartitions returns all partitions in the specified deadline + StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]api.Partition, error) //perm:read + // StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner + StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) //perm:read + // StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset + StateAllMinerFaults(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*api.Fault, error) //perm:read + // StateMinerRecoveries returns a bitfield indicating the recovering sectors of the given miner + StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) //perm:read + // StateMinerInitialPledgeCollateral returns the precommit deposit for the specified miner's sector + StateMinerPreCommitDepositForPower(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) //perm:read + // StateMinerInitialPledgeCollateral returns the initial pledge collateral for the specified miner's sector + StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) //perm:read + // StateMinerAvailableBalance returns the portion of a miner's balance that can be withdrawn or spent + StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) //perm:read + // StateMinerSectorAllocated checks if a sector is allocated + StateMinerSectorAllocated(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error) //perm:read + // StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector + StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) //perm:read + // StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found + // NOTE: returned info.Expiration may not be accurate in some cases, use StateSectorExpiration to get accurate + // expiration epoch + StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) //perm:read + // StateSectorExpiration returns epoch at which given sector will expire + StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) //perm:read + // StateSectorPartition finds deadline/partition with the specified sector + StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error) //perm:read + // StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed + // + // NOTE: If a replacing message is found on chain, this method will return + // a MsgLookup for the replacing message - the MsgLookup.Message will be a different + // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the + // result of the execution of the replacing message. + // + // If the caller wants to ensure that exactly the requested message was executed, + // they MUST check that MsgLookup.Message is equal to the provided 'cid'. + // Without this check both the requested and original message may appear as + // successfully executed on-chain, which may look like a double-spend. + // + // A replacing message is a message with a different CID, any of Gas values, and + // different signature, but with all other parameters matching (source/destination, + // nonce, params, etc.) + StateSearchMsg(context.Context, cid.Cid) (*api.MsgLookup, error) //perm:read + // StateSearchMsgLimited looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed + // + // NOTE: If a replacing message is found on chain, this method will return + // a MsgLookup for the replacing message - the MsgLookup.Message will be a different + // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the + // result of the execution of the replacing message. + // + // If the caller wants to ensure that exactly the requested message was executed, + // they MUST check that MsgLookup.Message is equal to the provided 'cid'. + // Without this check both the requested and original message may appear as + // successfully executed on-chain, which may look like a double-spend. + // + // A replacing message is a message with a different CID, any of Gas values, and + // different signature, but with all other parameters matching (source/destination, + // nonce, params, etc.) + StateSearchMsgLimited(ctx context.Context, msg cid.Cid, limit abi.ChainEpoch) (*api.MsgLookup, error) //perm:read + // StateWaitMsg looks back in the chain for a message. If not found, it blocks until the + // message arrives on chain, and gets to the indicated confidence depth. + // + // NOTE: If a replacing message is found on chain, this method will return + // a MsgLookup for the replacing message - the MsgLookup.Message will be a different + // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the + // result of the execution of the replacing message. + // + // If the caller wants to ensure that exactly the requested message was executed, + // they MUST check that MsgLookup.Message is equal to the provided 'cid'. + // Without this check both the requested and original message may appear as + // successfully executed on-chain, which may look like a double-spend. + // + // A replacing message is a message with a different CID, any of Gas values, and + // different signature, but with all other parameters matching (source/destination, + // nonce, params, etc.) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) //perm:read + // StateWaitMsgLimited looks back up to limit epochs in the chain for a message. + // If not found, it blocks until the message arrives on chain, and gets to the + // indicated confidence depth. + // + // NOTE: If a replacing message is found on chain, this method will return + // a MsgLookup for the replacing message - the MsgLookup.Message will be a different + // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the + // result of the execution of the replacing message. + // + // If the caller wants to ensure that exactly the requested message was executed, + // they MUST check that MsgLookup.Message is equal to the provided 'cid'. + // Without this check both the requested and original message may appear as + // successfully executed on-chain, which may look like a double-spend. + // + // A replacing message is a message with a different CID, any of Gas values, and + // different signature, but with all other parameters matching (source/destination, + // nonce, params, etc.) + StateWaitMsgLimited(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch) (*api.MsgLookup, error) //perm:read + // StateListMiners returns the addresses of every miner that has claimed power in the Power Actor + StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error) //perm:read + // StateListActors returns the addresses of every actor in the state + StateListActors(context.Context, types.TipSetKey) ([]address.Address, error) //perm:read + // StateMarketBalance looks up the Escrow and Locked balances of the given address in the Storage Market + StateMarketBalance(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error) //perm:read + // StateMarketParticipants returns the Escrow and Locked balances of every participant in the Storage Market + StateMarketParticipants(context.Context, types.TipSetKey) (map[string]api.MarketBalance, error) //perm:read + // StateMarketDeals returns information about every deal in the Storage Market + StateMarketDeals(context.Context, types.TipSetKey) (map[string]api.MarketDeal, error) //perm:read + // StateMarketStorageDeal returns information about the indicated deal + StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) //perm:read + // StateLookupID retrieves the ID address of the given address + StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error) //perm:read + // StateAccountKey returns the public key address of the given ID address + StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error) //perm:read + // StateChangedActors returns all the actors whose states change between the two given state CIDs + // TODO: Should this take tipset keys instead? + StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) //perm:read + // StateGetReceipt returns the message receipt for the given message or for a + // matching gas-repriced replacing message + // + // NOTE: If the requested message was replaced, this method will return the receipt + // for the replacing message - if the caller needs the receipt for exactly the + // requested message, use StateSearchMsg().Receipt, and check that MsgLookup.Message + // is matching the requested CID + // + // DEPRECATED: Use StateSearchMsg, this method won't be supported in v1 API + StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) //perm:read + // StateMinerSectorCount returns the number of sectors in a miner's sector set and proving set + StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) //perm:read + // StateCompute is a flexible command that applies the given messages on the given tipset. + // The messages are run as though the VM were at the provided height. + // + // When called, StateCompute will: + // - Load the provided tipset, or use the current chain head if not provided + // - Compute the tipset state of the provided tipset on top of the parent state + // - (note that this step runs before vmheight is applied to the execution) + // - Execute state upgrade if any were scheduled at the epoch, or in null + // blocks preceding the tipset + // - Call the cron actor on null blocks preceding the tipset + // - For each block in the tipset + // - Apply messages in blocks in the specified + // - Award block reward by calling the reward actor + // - Call the cron actor for the current epoch + // - If the specified vmheight is higher than the current epoch, apply any + // needed state upgrades to the state + // - Apply the specified messages to the state + // + // The vmheight parameter sets VM execution epoch, and can be used to simulate + // message execution in different network versions. If the specified vmheight + // epoch is higher than the epoch of the specified tipset, any state upgrades + // until the vmheight will be executed on the state before applying messages + // specified by the user. + // + // Note that the initial tipset state computation is not affected by the + // vmheight parameter - only the messages in the `apply` set are + // + // If the caller wants to simply compute the state, vmheight should be set to + // the epoch of the specified tipset. + // + // Messages in the `apply` parameter must have the correct nonces, and gas + // values set. + StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*api.ComputeStateOutput, error) //perm:read + // StateVerifierStatus returns the data cap for the given address. + // Returns nil if there is no entry in the data cap table for the + // address. + StateVerifierStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) //perm:read + // StateVerifiedClientStatus returns the data cap for the given address. + // Returns nil if there is no entry in the data cap table for the + // address. + StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) //perm:read + // StateVerifiedClientStatus returns the address of the Verified Registry's root key + StateVerifiedRegistryRootKey(ctx context.Context, tsk types.TipSetKey) (address.Address, error) //perm:read + // StateDealProviderCollateralBounds returns the min and max collateral a storage provider + // can issue. It takes the deal size and verified status as parameters. + StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (api.DealCollateralBounds, error) //perm:read + + // StateCirculatingSupply returns the exact circulating supply of Filecoin at the given tipset. + // This is not used anywhere in the protocol itself, and is only for external consumption. + StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error) //perm:read + // StateVMCirculatingSupplyInternal returns an approximation of the circulating supply of Filecoin at the given tipset. + // This is the value reported by the runtime interface to actors code. + StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error) //perm:read + // StateNetworkVersion returns the network version at the given tipset + StateNetworkVersion(context.Context, types.TipSetKey) (apitypes.NetworkVersion, error) //perm:read + + // MethodGroup: Msig + // The Msig methods are used to interact with multisig wallets on the + // filecoin network + + // MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent + MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) //perm:read + // MsigGetVestingSchedule returns the vesting details of a given multisig. + MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (api.MsigVesting, error) //perm:read + // MsigGetVested returns the amount of FIL that vested in a multisig in a certain period. + // It takes the following params: , , + MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error) //perm:read + + //MsigGetPending returns pending transactions for the given multisig + //wallet. Once pending transactions are fully approved, they will no longer + //appear here. + MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*api.MsigTransaction, error) //perm:read + + // MsigCreate creates a multisig wallet + // It takes the following params: , , + //, , + MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) //perm:sign + // MsigPropose proposes a multisig message + // It takes the following params: , , , + // , , + MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign + + // MsigApprove approves a previously-proposed multisig message by transaction ID + // It takes the following params: , + MsigApprove(context.Context, address.Address, uint64, address.Address) (cid.Cid, error) //perm:sign + + // MsigApproveTxnHash approves a previously-proposed multisig message, specified + // using both transaction ID and a hash of the parameters used in the + // proposal. This method of approval can be used to ensure you only approve + // exactly the transaction you think you are. + // It takes the following params: , , , , , + // , , + MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign + + // MsigCancel cancels a previously-proposed multisig message + // It takes the following params: , , , , + // , , + MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign + // MsigAddPropose proposes adding a signer in the multisig + // It takes the following params: , , + // , + MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign + // MsigAddApprove approves a previously proposed AddSigner message + // It takes the following params: , , , + // , , + MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign + // MsigAddCancel cancels a previously proposed AddSigner message + // It takes the following params: , , , + // , + MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error) //perm:sign + // MsigSwapPropose proposes swapping 2 signers in the multisig + // It takes the following params: , , + // , + MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign + // MsigSwapApprove approves a previously proposed SwapSigner + // It takes the following params: , , , + // , , + MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign + // MsigSwapCancel cancels a previously proposed SwapSigner message + // It takes the following params: , , , + // , + MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) //perm:sign + + // MsigRemoveSigner proposes the removal of a signer from the multisig. + // It accepts the multisig to make the change on, the proposer address to + // send the message from, the address to be removed, and a boolean + // indicating whether or not the signing threshold should be lowered by one + // along with the address removal. + MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) //perm:sign + + // MarketAddBalance adds funds to the market actor + MarketAddBalance(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign + // MarketGetReserved gets the amount of funds that are currently reserved for the address + MarketGetReserved(ctx context.Context, addr address.Address) (types.BigInt, error) //perm:sign + // MarketReserveFunds reserves funds for a deal + MarketReserveFunds(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign + // MarketReleaseFunds releases funds reserved by MarketReserveFunds + MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error //perm:sign + // MarketWithdraw withdraws unlocked funds from the market actor + MarketWithdraw(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign + + // MethodGroup: Paych + // The Paych methods are for interacting with and managing payment channels + + PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) //perm:sign + PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error) //perm:sign + PaychAvailableFunds(ctx context.Context, ch address.Address) (*api.ChannelAvailableFunds, error) //perm:sign + PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*api.ChannelAvailableFunds, error) //perm:sign + PaychList(context.Context) ([]address.Address, error) //perm:read + PaychStatus(context.Context, address.Address) (*api.PaychStatus, error) //perm:read + PaychSettle(context.Context, address.Address) (cid.Cid, error) //perm:sign + PaychCollect(context.Context, address.Address) (cid.Cid, error) //perm:sign + PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error) //perm:sign + PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []api.VoucherSpec) (*api.PaymentInfo, error) //perm:sign + PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error //perm:read + PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) //perm:read + PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*api.VoucherCreateResult, error) //perm:sign + PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) //perm:write + PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) //perm:write + PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) //perm:sign + + // CreateBackup creates node backup onder the specified file name. The + // method requires that the lotus daemon is running with the + // LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that + // the path specified when calling CreateBackup is within the base path + CreateBackup(ctx context.Context, fpath string) error //perm:admin +} + diff --git a/api/v0api/v1_wrapper.go b/api/v0api/v1_wrapper.go new file mode 100644 index 00000000000..89130160d7a --- /dev/null +++ b/api/v0api/v1_wrapper.go @@ -0,0 +1,32 @@ +package v0api + +import ( + "github.com/filecoin-project/lotus/api/v1api" +) + +type WrapperV1 struct { + v1api.FullNode +} + +/* example: +- dropped StateGetReceipt +- tsk param for StateSearchMsg + +func (w *WrapperV1) StateSearchMsg(ctx context.Context, c cid.Cid) (*api.MsgLookup, error) { + return w.FullNode.StateSearchMsg(ctx, c, types.EmptyTSK) +} + +func (w *WrapperV1) StateGetReceipt(ctx context.Context, cid cid.Cid, key types.TipSetKey) (*types.MessageReceipt, error) { + m, err := w.FullNode.StateSearchMsg(ctx, cid, key) + if err != nil { + return nil, err + } + + if m == nil { + return nil, nil + } + + return &m.Receipt, nil +}*/ + +var _ FullNode = &WrapperV1{} diff --git a/api/v1api/latest.go b/api/v1api/latest.go new file mode 100644 index 00000000000..eb67e1e363a --- /dev/null +++ b/api/v1api/latest.go @@ -0,0 +1,9 @@ +package v1api + +import ( + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/apistruct" +) + +type FullNode = api.FullNode +type FullNodeStruct = apistruct.FullNodeStruct diff --git a/cmd/lotus-gateway/main.go b/cmd/lotus-gateway/main.go index 23b743d7392..05fa62c7501 100644 --- a/cmd/lotus-gateway/main.go +++ b/cmd/lotus-gateway/main.go @@ -100,7 +100,7 @@ var runCmd = &cli.Command{ rpcServer := jsonrpc.NewServer(serverOptions...) rpcServer.Register("Filecoin", metrics.MetricedGatewayAPI(NewGatewayAPI(api))) - mux.Handle("/rpc/v0", rpcServer) + mux.Handle("/rpc/v0", rpcServer) // todo: v1 support registry := promclient.DefaultRegisterer.(*promclient.Registry) exporter, err := prometheus.NewExporter(prometheus.Options{ diff --git a/cmd/lotus/rpc.go b/cmd/lotus/rpc.go index abadfd20c8f..0f0d1225d82 100644 --- a/cmd/lotus/rpc.go +++ b/cmd/lotus/rpc.go @@ -21,8 +21,9 @@ import ( "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc/auth" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/metrics" "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/impl" @@ -30,21 +31,27 @@ import ( var log = logging.Logger("main") -func serveRPC(a api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, shutdownCh <-chan struct{}, maxRequestSize int64) error { +func serveRPC(a v1api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, shutdownCh <-chan struct{}, maxRequestSize int64) error { serverOptions := make([]jsonrpc.ServerOption, 0) if maxRequestSize != 0 { // config set serverOptions = append(serverOptions, jsonrpc.WithMaxRequestSize(maxRequestSize)) } - rpcServer := jsonrpc.NewServer(serverOptions...) - rpcServer.Register("Filecoin", apistruct.PermissionedFullAPI(metrics.MetricedFullAPI(a))) - rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover") + serveRpc := func(path string, hnd interface{}) { + rpcServer := jsonrpc.NewServer(serverOptions...) + rpcServer.Register("Filecoin", hnd) - ah := &auth.Handler{ - Verify: a.AuthVerify, - Next: rpcServer.ServeHTTP, + ah := &auth.Handler{ + Verify: a.AuthVerify, + Next: rpcServer.ServeHTTP, + } + + http.Handle(path, ah) } - http.Handle("/rpc/v0", ah) + pma := apistruct.PermissionedFullAPI(metrics.MetricedFullAPI(a)) + + serveRpc("/rpc/v1", pma) + serveRpc("/rpc/v0", &v0api.WrapperV1{FullNode: pma}) importAH := &auth.Handler{ Verify: a.AuthVerify, From 3fe4b50a13354d3ea9422e3471cef75617036aea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Mar 2021 17:01:56 +0100 Subject: [PATCH 02/60] apigen: Work with versioned apis --- Makefile | 6 +- api/apistruct/struct.go | 20 +- api/apistruct/types.go | 12 + api/v0api/common.go | 77 +++ api/v0api/full.go | 39 +- api/v0api/struct.go | 1231 +++++++++++++++++++++++++++++++++++++++ gen/api/proxygen.go | 34 +- 7 files changed, 1378 insertions(+), 41 deletions(-) create mode 100644 api/apistruct/types.go create mode 100644 api/v0api/common.go create mode 100644 api/v0api/struct.go diff --git a/Makefile b/Makefile index 16269e13393..5d7781b1da1 100644 --- a/Makefile +++ b/Makefile @@ -326,9 +326,9 @@ method-gen: (cd ./lotuspond/front/src/chain && go run ./methodgen.go) api-gen: - go run ./gen/api > api/apistruct/struct.go - goimports -w api/apistruct - goimports -w api/apistruct + go run ./gen/api + goimports -w api/apistruct api/v0api + goimports -w api/apistruct api/v0api .PHONY: api-gen docsgen: docsgen-md docsgen-openrpc diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 34cf52fce07..63dbb51b00e 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -32,10 +32,10 @@ import ( "github.com/filecoin-project/specs-storage/storage" "github.com/google/uuid" "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p-core/metrics" + metrics "github.com/libp2p/go-libp2p-core/metrics" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + protocol "github.com/libp2p/go-libp2p-core/protocol" ) type ChainIOStruct struct { @@ -2162,11 +2162,11 @@ func (s *WorkerStruct) WaitQuiet(p0 context.Context) error { return s.Internal.WaitQuiet(p0) } -var _ api.ChainIO = new(ChainIOStruct) -var _ api.Common = new(CommonStruct) -var _ api.FullNode = new(FullNodeStruct) -var _ api.Gateway = new(GatewayStruct) -var _ api.Signable = new(SignableStruct) -var _ api.StorageMiner = new(StorageMinerStruct) -var _ api.Wallet = new(WalletStruct) -var _ api.Worker = new(WorkerStruct) +var _ ChainIO = new(ChainIOStruct) +var _ Common = new(CommonStruct) +var _ FullNode = new(FullNodeStruct) +var _ Gateway = new(GatewayStruct) +var _ Signable = new(SignableStruct) +var _ StorageMiner = new(StorageMinerStruct) +var _ Wallet = new(WalletStruct) +var _ Worker = new(WorkerStruct) diff --git a/api/apistruct/types.go b/api/apistruct/types.go new file mode 100644 index 00000000000..57c89cdaaf2 --- /dev/null +++ b/api/apistruct/types.go @@ -0,0 +1,12 @@ +package apistruct + +import "github.com/filecoin-project/lotus/api" + +type ChainIO = api.ChainIO +type Common = api.Common +type FullNode = api.FullNode +type Gateway = api.Gateway +type Signable = api.Signable +type StorageMiner = api.StorageMiner +type Wallet = api.Wallet +type Worker = api.Worker diff --git a/api/v0api/common.go b/api/v0api/common.go new file mode 100644 index 00000000000..6848fa6a880 --- /dev/null +++ b/api/v0api/common.go @@ -0,0 +1,77 @@ +package v0api + +import ( + "context" + + "github.com/filecoin-project/lotus/api" + + "github.com/google/uuid" + + "github.com/filecoin-project/go-jsonrpc/auth" + metrics "github.com/libp2p/go-libp2p-core/metrics" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + protocol "github.com/libp2p/go-libp2p-core/protocol" + + apitypes "github.com/filecoin-project/lotus/api/types" +) + +type Common interface { + + // MethodGroup: Auth + + AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) //perm:read + AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error) //perm:admin + + // MethodGroup: Net + + NetConnectedness(context.Context, peer.ID) (network.Connectedness, error) //perm:read + NetPeers(context.Context) ([]peer.AddrInfo, error) //perm:read + NetConnect(context.Context, peer.AddrInfo) error //perm:write + NetAddrsListen(context.Context) (peer.AddrInfo, error) //perm:read + NetDisconnect(context.Context, peer.ID) error //perm:write + NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error) //perm:read + NetPubsubScores(context.Context) ([]api.PubsubScore, error) //perm:read + NetAutoNatStatus(context.Context) (api.NatInfo, error) //perm:read + NetAgentVersion(ctx context.Context, p peer.ID) (string, error) //perm:read + NetPeerInfo(context.Context, peer.ID) (*api.ExtendedPeerInfo, error) //perm:read + + // NetBandwidthStats returns statistics about the nodes total bandwidth + // usage and current rate across all peers and protocols. + NetBandwidthStats(ctx context.Context) (metrics.Stats, error) //perm:read + + // NetBandwidthStatsByPeer returns statistics about the nodes bandwidth + // usage and current rate per peer + NetBandwidthStatsByPeer(ctx context.Context) (map[string]metrics.Stats, error) //perm:read + + // NetBandwidthStatsByProtocol returns statistics about the nodes bandwidth + // usage and current rate per protocol + NetBandwidthStatsByProtocol(ctx context.Context) (map[protocol.ID]metrics.Stats, error) //perm:read + + // ConnectionGater API + NetBlockAdd(ctx context.Context, acl api.NetBlockList) error //perm:admin + NetBlockRemove(ctx context.Context, acl api.NetBlockList) error //perm:admin + NetBlockList(ctx context.Context) (api.NetBlockList, error) //perm:read + + // MethodGroup: Common + + // Discover returns an OpenRPC document describing an RPC API. + Discover(ctx context.Context) (apitypes.OpenRPCDocument, error) //perm:read + + // ID returns peerID of libp2p node backing this API + ID(context.Context) (peer.ID, error) //perm:read + + // Version provides information about API provider + Version(context.Context) (api.APIVersion, error) //perm:read + + LogList(context.Context) ([]string, error) //perm:write + LogSetLevel(context.Context, string, string) error //perm:write + + // trigger graceful shutdown + Shutdown(context.Context) error //perm:admin + + // Session returns a random UUID of api provider session + Session(context.Context) (uuid.UUID, error) //perm:read + + Closing(context.Context) (<-chan struct{}, error) //perm:read +} diff --git a/api/v0api/full.go b/api/v0api/full.go index aad8531a091..8e370de5180 100644 --- a/api/v0api/full.go +++ b/api/v0api/full.go @@ -25,7 +25,7 @@ import ( // FullNode API is a low-level interface to the Filecoin network full node type FullNode interface { - api.Common + Common // MethodGroup: Chain // The Chain method group contains methods for interacting with the @@ -100,7 +100,7 @@ type FullNode interface { // ChainTipSetWeight computes weight for the specified tipset. ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error) //perm:read - ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) //perm:read + ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) //perm:read // ChainGetMessage reads a message referenced by the specified CID from the // chain blockstore. @@ -223,7 +223,7 @@ type FullNode interface { // MpoolGetNonce gets next nonce for the specified sender. // Note that this method may not be atomic. Use MpoolPushMessage instead. MpoolGetNonce(context.Context, address.Address) (uint64, error) //perm:read - MpoolSub(context.Context) (<-chan api.MpoolUpdate, error) //perm:read + MpoolSub(context.Context) (<-chan api.MpoolUpdate, error) //perm:read // MpoolClear clears pending messages from the mpool MpoolClear(context.Context, bool) error //perm:write @@ -653,22 +653,22 @@ type FullNode interface { // MethodGroup: Paych // The Paych methods are for interacting with and managing payment channels - PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) //perm:sign - PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error) //perm:sign - PaychAvailableFunds(ctx context.Context, ch address.Address) (*api.ChannelAvailableFunds, error) //perm:sign - PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*api.ChannelAvailableFunds, error) //perm:sign - PaychList(context.Context) ([]address.Address, error) //perm:read - PaychStatus(context.Context, address.Address) (*api.PaychStatus, error) //perm:read - PaychSettle(context.Context, address.Address) (cid.Cid, error) //perm:sign - PaychCollect(context.Context, address.Address) (cid.Cid, error) //perm:sign - PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error) //perm:sign - PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []api.VoucherSpec) (*api.PaymentInfo, error) //perm:sign - PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error //perm:read - PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) //perm:read - PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*api.VoucherCreateResult, error) //perm:sign - PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) //perm:write - PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) //perm:write - PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) //perm:sign + PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) //perm:sign + PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error) //perm:sign + PaychAvailableFunds(ctx context.Context, ch address.Address) (*api.ChannelAvailableFunds, error) //perm:sign + PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*api.ChannelAvailableFunds, error) //perm:sign + PaychList(context.Context) ([]address.Address, error) //perm:read + PaychStatus(context.Context, address.Address) (*api.PaychStatus, error) //perm:read + PaychSettle(context.Context, address.Address) (cid.Cid, error) //perm:sign + PaychCollect(context.Context, address.Address) (cid.Cid, error) //perm:sign + PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error) //perm:sign + PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []api.VoucherSpec) (*api.PaymentInfo, error) //perm:sign + PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error //perm:read + PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) //perm:read + PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*api.VoucherCreateResult, error) //perm:sign + PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) //perm:write + PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) //perm:write + PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) //perm:sign // CreateBackup creates node backup onder the specified file name. The // method requires that the lotus daemon is running with the @@ -676,4 +676,3 @@ type FullNode interface { // the path specified when calling CreateBackup is within the base path CreateBackup(ctx context.Context, fpath string) error //perm:admin } - diff --git a/api/v0api/struct.go b/api/v0api/struct.go new file mode 100644 index 00000000000..e5550814f38 --- /dev/null +++ b/api/v0api/struct.go @@ -0,0 +1,1231 @@ +// Code generated by github.com/filecoin-project/lotus/gen/api. DO NOT EDIT. + +package v0api + +import ( + "context" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + datatransfer "github.com/filecoin-project/go-data-transfer" + "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/go-jsonrpc/auth" + "github.com/filecoin-project/go-multistore" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/lotus/api" + apitypes "github.com/filecoin-project/lotus/api/types" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" + "github.com/filecoin-project/lotus/chain/types" + marketevents "github.com/filecoin-project/lotus/markets/loggers" + "github.com/filecoin-project/lotus/node/modules/dtypes" + "github.com/google/uuid" + "github.com/ipfs/go-cid" + metrics "github.com/libp2p/go-libp2p-core/metrics" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + protocol "github.com/libp2p/go-libp2p-core/protocol" +) + +type CommonStruct struct { + Internal struct { + AuthNew func(p0 context.Context, p1 []auth.Permission) ([]byte, error) `perm:"admin"` + + AuthVerify func(p0 context.Context, p1 string) ([]auth.Permission, error) `perm:"read"` + + Closing func(p0 context.Context) (<-chan struct{}, error) `perm:"read"` + + Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) `perm:"read"` + + ID func(p0 context.Context) (peer.ID, error) `perm:"read"` + + LogList func(p0 context.Context) ([]string, error) `perm:"write"` + + LogSetLevel func(p0 context.Context, p1 string, p2 string) error `perm:"write"` + + NetAddrsListen func(p0 context.Context) (peer.AddrInfo, error) `perm:"read"` + + NetAgentVersion func(p0 context.Context, p1 peer.ID) (string, error) `perm:"read"` + + NetAutoNatStatus func(p0 context.Context) (api.NatInfo, error) `perm:"read"` + + NetBandwidthStats func(p0 context.Context) (metrics.Stats, error) `perm:"read"` + + NetBandwidthStatsByPeer func(p0 context.Context) (map[string]metrics.Stats, error) `perm:"read"` + + NetBandwidthStatsByProtocol func(p0 context.Context) (map[protocol.ID]metrics.Stats, error) `perm:"read"` + + NetBlockAdd func(p0 context.Context, p1 api.NetBlockList) error `perm:"admin"` + + NetBlockList func(p0 context.Context) (api.NetBlockList, error) `perm:"read"` + + NetBlockRemove func(p0 context.Context, p1 api.NetBlockList) error `perm:"admin"` + + NetConnect func(p0 context.Context, p1 peer.AddrInfo) error `perm:"write"` + + NetConnectedness func(p0 context.Context, p1 peer.ID) (network.Connectedness, error) `perm:"read"` + + NetDisconnect func(p0 context.Context, p1 peer.ID) error `perm:"write"` + + NetFindPeer func(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) `perm:"read"` + + NetPeerInfo func(p0 context.Context, p1 peer.ID) (*api.ExtendedPeerInfo, error) `perm:"read"` + + NetPeers func(p0 context.Context) ([]peer.AddrInfo, error) `perm:"read"` + + NetPubsubScores func(p0 context.Context) ([]api.PubsubScore, error) `perm:"read"` + + Session func(p0 context.Context) (uuid.UUID, error) `perm:"read"` + + Shutdown func(p0 context.Context) error `perm:"admin"` + + Version func(p0 context.Context) (api.APIVersion, error) `perm:"read"` + } +} + +type FullNodeStruct struct { + CommonStruct + + Internal struct { + BeaconGetEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"` + + ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + + ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"` + + ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"` + + ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `perm:"read"` + + ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `perm:"read"` + + ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"` + + ChainGetNode func(p0 context.Context, p1 string) (*api.IpldObject, error) `perm:"read"` + + ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]api.Message, error) `perm:"read"` + + ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` + + ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) `perm:"read"` + + ChainGetRandomnessFromBeacon func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"` + + ChainGetRandomnessFromTickets func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"` + + ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `perm:"read"` + + ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `perm:"read"` + + ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"read"` + + ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"` + + ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `perm:"read"` + + ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"` + + ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` + + ChainStatObj func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) `perm:"read"` + + ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + ClientCalcCommP func(p0 context.Context, p1 string) (*api.CommPRet, error) `perm:"write"` + + ClientCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + + ClientDataTransferUpdates func(p0 context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"` + + ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) `perm:"read"` + + ClientDealSize func(p0 context.Context, p1 cid.Cid) (api.DataSize, error) `perm:"read"` + + ClientFindData func(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) `perm:"read"` + + ClientGenCar func(p0 context.Context, p1 api.FileRef, p2 string) error `perm:"write"` + + ClientGetDealInfo func(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) `perm:"read"` + + ClientGetDealStatus func(p0 context.Context, p1 uint64) (string, error) `perm:"read"` + + ClientGetDealUpdates func(p0 context.Context) (<-chan api.DealInfo, error) `perm:"write"` + + ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"` + + ClientImport func(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) `perm:"admin"` + + ClientListDataTransfers func(p0 context.Context) ([]api.DataTransferChannel, error) `perm:"write"` + + ClientListDeals func(p0 context.Context) ([]api.DealInfo, error) `perm:"write"` + + ClientListImports func(p0 context.Context) ([]api.Import, error) `perm:"write"` + + ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) `perm:"read"` + + ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"` + + ClientRemoveImport func(p0 context.Context, p1 multistore.StoreID) error `perm:"admin"` + + ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + + ClientRetrieve func(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error `perm:"admin"` + + ClientRetrieveTryRestartInsufficientFunds func(p0 context.Context, p1 address.Address) error `perm:"write"` + + ClientRetrieveWithEvents func(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"` + + ClientStartDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"admin"` + + CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` + + GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"` + + GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `perm:"read"` + + MarketAddBalance func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + + MarketGetReserved func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"sign"` + + MarketReleaseFunds func(p0 context.Context, p1 address.Address, p2 types.BigInt) error `perm:"sign"` + + MarketReserveFunds func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + + MarketWithdraw func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + + MinerCreateBlock func(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"` + + MinerGetBaseInfo func(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"` + + MpoolBatchPush func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` + + MpoolBatchPushMessage func(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"` + + MpoolBatchPushUntrusted func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` + + MpoolClear func(p0 context.Context, p1 bool) error `perm:"write"` + + MpoolGetConfig func(p0 context.Context) (*types.MpoolConfig, error) `perm:"read"` + + MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"read"` + + MpoolPending func(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"` + + MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` + + MpoolPushMessage func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"` + + MpoolPushUntrusted func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` + + MpoolSelect func(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) `perm:"read"` + + MpoolSetConfig func(p0 context.Context, p1 *types.MpoolConfig) error `perm:"admin"` + + MpoolSub func(p0 context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"` + + MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) `perm:"sign"` + + MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) `perm:"sign"` + + MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"` + + MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) `perm:"sign"` + + MsigApproveTxnHash func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) `perm:"sign"` + + MsigCancel func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) `perm:"sign"` + + MsigCreate func(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) `perm:"sign"` + + MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) `perm:"read"` + + MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) `perm:"read"` + + MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) `perm:"sign"` + + MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"` + + MsigSwapApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) `perm:"sign"` + + MsigSwapCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) `perm:"sign"` + + MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) `perm:"sign"` + + PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"` + + PaychAvailableFunds func(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"` + + PaychAvailableFundsByFromTo func(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"` + + PaychCollect func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` + + PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) `perm:"sign"` + + PaychGetWaitReady func(p0 context.Context, p1 cid.Cid) (address.Address, error) `perm:"sign"` + + PaychList func(p0 context.Context) ([]address.Address, error) `perm:"read"` + + PaychNewPayment func(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"` + + PaychSettle func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` + + PaychStatus func(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) `perm:"read"` + + PaychVoucherAdd func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) `perm:"write"` + + PaychVoucherCheckSpendable func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) `perm:"read"` + + PaychVoucherCheckValid func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error `perm:"read"` + + PaychVoucherCreate func(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) `perm:"sign"` + + PaychVoucherList func(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) `perm:"write"` + + PaychVoucherSubmit func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) `perm:"sign"` + + StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` + + StateAllMinerFaults func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) `perm:"read"` + + StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) `perm:"read"` + + StateChangedActors func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) `perm:"read"` + + StateCirculatingSupply func(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) `perm:"read"` + + StateCompute func(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"` + + StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"` + + StateDecodeParams func(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) `perm:"read"` + + StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"` + + StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"` + + StateListActors func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` + + StateListMessages func(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` + + StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` + + StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` + + StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) `perm:"read"` + + StateMarketDeals func(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) `perm:"read"` + + StateMarketParticipants func(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) `perm:"read"` + + StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) `perm:"read"` + + StateMinerActiveSectors func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` + + StateMinerAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + StateMinerDeadlines func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) `perm:"read"` + + StateMinerFaults func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` + + StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) `perm:"read"` + + StateMinerInitialPledgeCollateral func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + StateMinerPartitions func(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) `perm:"read"` + + StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) `perm:"read"` + + StateMinerPreCommitDepositForPower func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `perm:"read"` + + StateMinerRecoveries func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` + + StateMinerSectorAllocated func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) `perm:"read"` + + StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) `perm:"read"` + + StateMinerSectors func(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` + + StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) `perm:"read"` + + StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `perm:"read"` + + StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) `perm:"read"` + + StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) `perm:"read"` + + StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `perm:"read"` + + StateSearchMsgLimited func(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"` + + StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"` + + StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"` + + StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) `perm:"read"` + + StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"` + + StateVMCirculatingSupplyInternal func(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"` + + StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` + + StateVerifiedRegistryRootKey func(p0 context.Context, p1 types.TipSetKey) (address.Address, error) `perm:"read"` + + StateVerifierStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` + + StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `perm:"read"` + + StateWaitMsgLimited func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"` + + SyncCheckBad func(p0 context.Context, p1 cid.Cid) (string, error) `perm:"read"` + + SyncCheckpoint func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` + + SyncIncomingBlocks func(p0 context.Context) (<-chan *types.BlockHeader, error) `perm:"read"` + + SyncMarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + + SyncState func(p0 context.Context) (*api.SyncState, error) `perm:"read"` + + SyncSubmitBlock func(p0 context.Context, p1 *types.BlockMsg) error `perm:"write"` + + SyncUnmarkAllBad func(p0 context.Context) error `perm:"admin"` + + SyncUnmarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + + SyncValidateTipset func(p0 context.Context, p1 types.TipSetKey) (bool, error) `perm:"read"` + + WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"read"` + + WalletDefaultAddress func(p0 context.Context) (address.Address, error) `perm:"write"` + + WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"` + + WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"` + + WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"write"` + + WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"` + + WalletList func(p0 context.Context) ([]address.Address, error) `perm:"write"` + + WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"write"` + + WalletSetDefault func(p0 context.Context, p1 address.Address) error `perm:"write"` + + WalletSign func(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) `perm:"sign"` + + WalletSignMessage func(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) `perm:"sign"` + + WalletValidateAddress func(p0 context.Context, p1 string) (address.Address, error) `perm:"read"` + + WalletVerify func(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) `perm:"read"` + } +} + +func (s *CommonStruct) AuthNew(p0 context.Context, p1 []auth.Permission) ([]byte, error) { + return s.Internal.AuthNew(p0, p1) +} + +func (s *CommonStruct) AuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { + return s.Internal.AuthVerify(p0, p1) +} + +func (s *CommonStruct) Closing(p0 context.Context) (<-chan struct{}, error) { + return s.Internal.Closing(p0) +} + +func (s *CommonStruct) Discover(p0 context.Context) (apitypes.OpenRPCDocument, error) { + return s.Internal.Discover(p0) +} + +func (s *CommonStruct) ID(p0 context.Context) (peer.ID, error) { + return s.Internal.ID(p0) +} + +func (s *CommonStruct) LogList(p0 context.Context) ([]string, error) { + return s.Internal.LogList(p0) +} + +func (s *CommonStruct) LogSetLevel(p0 context.Context, p1 string, p2 string) error { + return s.Internal.LogSetLevel(p0, p1, p2) +} + +func (s *CommonStruct) NetAddrsListen(p0 context.Context) (peer.AddrInfo, error) { + return s.Internal.NetAddrsListen(p0) +} + +func (s *CommonStruct) NetAgentVersion(p0 context.Context, p1 peer.ID) (string, error) { + return s.Internal.NetAgentVersion(p0, p1) +} + +func (s *CommonStruct) NetAutoNatStatus(p0 context.Context) (api.NatInfo, error) { + return s.Internal.NetAutoNatStatus(p0) +} + +func (s *CommonStruct) NetBandwidthStats(p0 context.Context) (metrics.Stats, error) { + return s.Internal.NetBandwidthStats(p0) +} + +func (s *CommonStruct) NetBandwidthStatsByPeer(p0 context.Context) (map[string]metrics.Stats, error) { + return s.Internal.NetBandwidthStatsByPeer(p0) +} + +func (s *CommonStruct) NetBandwidthStatsByProtocol(p0 context.Context) (map[protocol.ID]metrics.Stats, error) { + return s.Internal.NetBandwidthStatsByProtocol(p0) +} + +func (s *CommonStruct) NetBlockAdd(p0 context.Context, p1 api.NetBlockList) error { + return s.Internal.NetBlockAdd(p0, p1) +} + +func (s *CommonStruct) NetBlockList(p0 context.Context) (api.NetBlockList, error) { + return s.Internal.NetBlockList(p0) +} + +func (s *CommonStruct) NetBlockRemove(p0 context.Context, p1 api.NetBlockList) error { + return s.Internal.NetBlockRemove(p0, p1) +} + +func (s *CommonStruct) NetConnect(p0 context.Context, p1 peer.AddrInfo) error { + return s.Internal.NetConnect(p0, p1) +} + +func (s *CommonStruct) NetConnectedness(p0 context.Context, p1 peer.ID) (network.Connectedness, error) { + return s.Internal.NetConnectedness(p0, p1) +} + +func (s *CommonStruct) NetDisconnect(p0 context.Context, p1 peer.ID) error { + return s.Internal.NetDisconnect(p0, p1) +} + +func (s *CommonStruct) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) { + return s.Internal.NetFindPeer(p0, p1) +} + +func (s *CommonStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*api.ExtendedPeerInfo, error) { + return s.Internal.NetPeerInfo(p0, p1) +} + +func (s *CommonStruct) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) { + return s.Internal.NetPeers(p0) +} + +func (s *CommonStruct) NetPubsubScores(p0 context.Context) ([]api.PubsubScore, error) { + return s.Internal.NetPubsubScores(p0) +} + +func (s *CommonStruct) Session(p0 context.Context) (uuid.UUID, error) { + return s.Internal.Session(p0) +} + +func (s *CommonStruct) Shutdown(p0 context.Context) error { + return s.Internal.Shutdown(p0) +} + +func (s *CommonStruct) Version(p0 context.Context) (api.APIVersion, error) { + return s.Internal.Version(p0) +} + +func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + return s.Internal.BeaconGetEntry(p0, p1) +} + +func (s *FullNodeStruct) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { + return s.Internal.ChainDeleteObj(p0, p1) +} + +func (s *FullNodeStruct) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { + return s.Internal.ChainExport(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { + return s.Internal.ChainGetBlock(p0, p1) +} + +func (s *FullNodeStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { + return s.Internal.ChainGetBlockMessages(p0, p1) +} + +func (s *FullNodeStruct) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { + return s.Internal.ChainGetGenesis(p0) +} + +func (s *FullNodeStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return s.Internal.ChainGetMessage(p0, p1) +} + +func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*api.IpldObject, error) { + return s.Internal.ChainGetNode(p0, p1) +} + +func (s *FullNodeStruct) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]api.Message, error) { + return s.Internal.ChainGetParentMessages(p0, p1) +} + +func (s *FullNodeStruct) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { + return s.Internal.ChainGetParentReceipts(p0, p1) +} + +func (s *FullNodeStruct) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) { + return s.Internal.ChainGetPath(p0, p1, p2) +} + +func (s *FullNodeStruct) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return s.Internal.ChainGetRandomnessFromBeacon(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStruct) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return s.Internal.ChainGetRandomnessFromTickets(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSet(p0, p1) +} + +func (s *FullNodeStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) +} + +func (s *FullNodeStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return s.Internal.ChainHasObj(p0, p1) +} + +func (s *FullNodeStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { + return s.Internal.ChainHead(p0) +} + +func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { + return s.Internal.ChainNotify(p0) +} + +func (s *FullNodeStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return s.Internal.ChainReadObj(p0, p1) +} + +func (s *FullNodeStruct) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { + return s.Internal.ChainSetHead(p0, p1) +} + +func (s *FullNodeStruct) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) { + return s.Internal.ChainStatObj(p0, p1, p2) +} + +func (s *FullNodeStruct) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { + return s.Internal.ChainTipSetWeight(p0, p1) +} + +func (s *FullNodeStruct) ClientCalcCommP(p0 context.Context, p1 string) (*api.CommPRet, error) { + return s.Internal.ClientCalcCommP(p0, p1) +} + +func (s *FullNodeStruct) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return s.Internal.ClientCancelDataTransfer(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) ClientDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { + return s.Internal.ClientDataTransferUpdates(p0) +} + +func (s *FullNodeStruct) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) { + return s.Internal.ClientDealPieceCID(p0, p1) +} + +func (s *FullNodeStruct) ClientDealSize(p0 context.Context, p1 cid.Cid) (api.DataSize, error) { + return s.Internal.ClientDealSize(p0, p1) +} + +func (s *FullNodeStruct) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) { + return s.Internal.ClientFindData(p0, p1, p2) +} + +func (s *FullNodeStruct) ClientGenCar(p0 context.Context, p1 api.FileRef, p2 string) error { + return s.Internal.ClientGenCar(p0, p1, p2) +} + +func (s *FullNodeStruct) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) { + return s.Internal.ClientGetDealInfo(p0, p1) +} + +func (s *FullNodeStruct) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { + return s.Internal.ClientGetDealStatus(p0, p1) +} + +func (s *FullNodeStruct) ClientGetDealUpdates(p0 context.Context) (<-chan api.DealInfo, error) { + return s.Internal.ClientGetDealUpdates(p0) +} + +func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { + return s.Internal.ClientHasLocal(p0, p1) +} + +func (s *FullNodeStruct) ClientImport(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) { + return s.Internal.ClientImport(p0, p1) +} + +func (s *FullNodeStruct) ClientListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { + return s.Internal.ClientListDataTransfers(p0) +} + +func (s *FullNodeStruct) ClientListDeals(p0 context.Context) ([]api.DealInfo, error) { + return s.Internal.ClientListDeals(p0) +} + +func (s *FullNodeStruct) ClientListImports(p0 context.Context) ([]api.Import, error) { + return s.Internal.ClientListImports(p0) +} + +func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) { + return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { + return s.Internal.ClientQueryAsk(p0, p1, p2) +} + +func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { + return s.Internal.ClientRemoveImport(p0, p1) +} + +func (s *FullNodeStruct) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return s.Internal.ClientRestartDataTransfer(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) ClientRetrieve(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error { + return s.Internal.ClientRetrieve(p0, p1, p2) +} + +func (s *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { + return s.Internal.ClientRetrieveTryRestartInsufficientFunds(p0, p1) +} + +func (s *FullNodeStruct) ClientRetrieveWithEvents(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { + return s.Internal.ClientRetrieveWithEvents(p0, p1, p2) +} + +func (s *FullNodeStruct) ClientStartDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) { + return s.Internal.ClientStartDeal(p0, p1) +} + +func (s *FullNodeStruct) CreateBackup(p0 context.Context, p1 string) error { + return s.Internal.CreateBackup(p0, p1) +} + +func (s *FullNodeStruct) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.GasEstimateFeeCap(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { + return s.Internal.GasEstimateGasLimit(p0, p1, p2) +} + +func (s *FullNodeStruct) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { + return s.Internal.GasEstimateGasPremium(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return s.Internal.MarketAddBalance(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return s.Internal.MarketGetReserved(p0, p1) +} + +func (s *FullNodeStruct) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { + return s.Internal.MarketReleaseFunds(p0, p1, p2) +} + +func (s *FullNodeStruct) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return s.Internal.MarketReserveFunds(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return s.Internal.MarketWithdraw(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) MinerCreateBlock(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) { + return s.Internal.MinerCreateBlock(p0, p1) +} + +func (s *FullNodeStruct) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) { + return s.Internal.MinerGetBaseInfo(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return s.Internal.MpoolBatchPush(p0, p1) +} + +func (s *FullNodeStruct) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { + return s.Internal.MpoolBatchPushMessage(p0, p1, p2) +} + +func (s *FullNodeStruct) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return s.Internal.MpoolBatchPushUntrusted(p0, p1) +} + +func (s *FullNodeStruct) MpoolClear(p0 context.Context, p1 bool) error { + return s.Internal.MpoolClear(p0, p1) +} + +func (s *FullNodeStruct) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { + return s.Internal.MpoolGetConfig(p0) +} + +func (s *FullNodeStruct) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { + return s.Internal.MpoolGetNonce(p0, p1) +} + +func (s *FullNodeStruct) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { + return s.Internal.MpoolPending(p0, p1) +} + +func (s *FullNodeStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return s.Internal.MpoolPush(p0, p1) +} + +func (s *FullNodeStruct) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) { + return s.Internal.MpoolPushMessage(p0, p1, p2) +} + +func (s *FullNodeStruct) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return s.Internal.MpoolPushUntrusted(p0, p1) +} + +func (s *FullNodeStruct) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { + return s.Internal.MpoolSelect(p0, p1, p2) +} + +func (s *FullNodeStruct) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { + return s.Internal.MpoolSetConfig(p0, p1) +} + +func (s *FullNodeStruct) MpoolSub(p0 context.Context) (<-chan api.MpoolUpdate, error) { + return s.Internal.MpoolSub(p0) +} + +func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) { + return s.Internal.MsigAddApprove(p0, p1, p2, p3, p4, p5, p6) +} + +func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) { + return s.Internal.MsigAddCancel(p0, p1, p2, p3, p4, p5) +} + +func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { + return s.Internal.MsigAddPropose(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) { + return s.Internal.MsigApprove(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) { + return s.Internal.MsigApproveTxnHash(p0, p1, p2, p3, p4, p5, p6, p7, p8) +} + +func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) { + return s.Internal.MsigCancel(p0, p1, p2, p3, p4, p5, p6, p7) +} + +func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) { + return s.Internal.MsigCreate(p0, p1, p2, p3, p4, p5, p6) +} + +func (s *FullNodeStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return s.Internal.MsigGetAvailableBalance(p0, p1, p2) +} + +func (s *FullNodeStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { + return s.Internal.MsigGetPending(p0, p1, p2) +} + +func (s *FullNodeStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.MsigGetVested(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) { + return s.Internal.MsigGetVestingSchedule(p0, p1, p2) +} + +func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) { + return s.Internal.MsigPropose(p0, p1, p2, p3, p4, p5, p6) +} + +func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { + return s.Internal.MsigRemoveSigner(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) { + return s.Internal.MsigSwapApprove(p0, p1, p2, p3, p4, p5, p6) +} + +func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) { + return s.Internal.MsigSwapCancel(p0, p1, p2, p3, p4, p5) +} + +func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) { + return s.Internal.MsigSwapPropose(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStruct) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { + return s.Internal.PaychAllocateLane(p0, p1) +} + +func (s *FullNodeStruct) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) { + return s.Internal.PaychAvailableFunds(p0, p1) +} + +func (s *FullNodeStruct) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) { + return s.Internal.PaychAvailableFundsByFromTo(p0, p1, p2) +} + +func (s *FullNodeStruct) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return s.Internal.PaychCollect(p0, p1) +} + +func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) { + return s.Internal.PaychGet(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { + return s.Internal.PaychGetWaitReady(p0, p1) +} + +func (s *FullNodeStruct) PaychList(p0 context.Context) ([]address.Address, error) { + return s.Internal.PaychList(p0) +} + +func (s *FullNodeStruct) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) { + return s.Internal.PaychNewPayment(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return s.Internal.PaychSettle(p0, p1) +} + +func (s *FullNodeStruct) PaychStatus(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) { + return s.Internal.PaychStatus(p0, p1) +} + +func (s *FullNodeStruct) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { + return s.Internal.PaychVoucherAdd(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStruct) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { + return s.Internal.PaychVoucherCheckSpendable(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStruct) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { + return s.Internal.PaychVoucherCheckValid(p0, p1, p2) +} + +func (s *FullNodeStruct) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) { + return s.Internal.PaychVoucherCreate(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { + return s.Internal.PaychVoucherList(p0, p1) +} + +func (s *FullNodeStruct) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { + return s.Internal.PaychVoucherSubmit(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateAccountKey(p0, p1, p2) +} + +func (s *FullNodeStruct) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) { + return s.Internal.StateAllMinerFaults(p0, p1, p2) +} + +func (s *FullNodeStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) { + return s.Internal.StateCall(p0, p1, p2) +} + +func (s *FullNodeStruct) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { + return s.Internal.StateChangedActors(p0, p1, p2) +} + +func (s *FullNodeStruct) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { + return s.Internal.StateCirculatingSupply(p0, p1) +} + +func (s *FullNodeStruct) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) { + return s.Internal.StateCompute(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { + return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { + return s.Internal.StateDecodeParams(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return s.Internal.StateGetActor(p0, p1, p2) +} + +func (s *FullNodeStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + return s.Internal.StateGetReceipt(p0, p1, p2) +} + +func (s *FullNodeStruct) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return s.Internal.StateListActors(p0, p1) +} + +func (s *FullNodeStruct) StateListMessages(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { + return s.Internal.StateListMessages(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return s.Internal.StateListMiners(p0, p1) +} + +func (s *FullNodeStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateLookupID(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { + return s.Internal.StateMarketBalance(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) { + return s.Internal.StateMarketDeals(p0, p1) +} + +func (s *FullNodeStruct) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) { + return s.Internal.StateMarketParticipants(p0, p1) +} + +func (s *FullNodeStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { + return s.Internal.StateMarketStorageDeal(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return s.Internal.StateMinerActiveSectors(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return s.Internal.StateMinerAvailableBalance(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) { + return s.Internal.StateMinerDeadlines(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return s.Internal.StateMinerFaults(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return s.Internal.StateMinerInfo(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.StateMinerInitialPledgeCollateral(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) { + return s.Internal.StateMinerPartitions(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { + return s.Internal.StateMinerPower(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.StateMinerPreCommitDepositForPower(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return s.Internal.StateMinerProvingDeadline(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return s.Internal.StateMinerRecoveries(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { + return s.Internal.StateMinerSectorAllocated(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) { + return s.Internal.StateMinerSectorCount(p0, p1, p2) +} + +func (s *FullNodeStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return s.Internal.StateMinerSectors(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { + return s.Internal.StateNetworkName(p0) +} + +func (s *FullNodeStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + return s.Internal.StateNetworkVersion(p0, p1) +} + +func (s *FullNodeStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) { + return s.Internal.StateReadState(p0, p1, p2) +} + +func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) { + return s.Internal.StateReplay(p0, p1, p2) +} + +func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { + return s.Internal.StateSearchMsg(p0, p1) +} + +func (s *FullNodeStruct) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) { + return s.Internal.StateSearchMsgLimited(p0, p1, p2) +} + +func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { + return s.Internal.StateSectorExpiration(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { + return s.Internal.StateSectorPartition(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + return s.Internal.StateSectorPreCommitInfo(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) { + return s.Internal.StateVMCirculatingSupplyInternal(p0, p1) +} + +func (s *FullNodeStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return s.Internal.StateVerifiedClientStatus(p0, p1, p2) +} + +func (s *FullNodeStruct) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { + return s.Internal.StateVerifiedRegistryRootKey(p0, p1) +} + +func (s *FullNodeStruct) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return s.Internal.StateVerifierStatus(p0, p1, p2) +} + +func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { + return s.Internal.StateWaitMsg(p0, p1, p2) +} + +func (s *FullNodeStruct) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) { + return s.Internal.StateWaitMsgLimited(p0, p1, p2, p3) +} + +func (s *FullNodeStruct) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { + return s.Internal.SyncCheckBad(p0, p1) +} + +func (s *FullNodeStruct) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { + return s.Internal.SyncCheckpoint(p0, p1) +} + +func (s *FullNodeStruct) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { + return s.Internal.SyncIncomingBlocks(p0) +} + +func (s *FullNodeStruct) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { + return s.Internal.SyncMarkBad(p0, p1) +} + +func (s *FullNodeStruct) SyncState(p0 context.Context) (*api.SyncState, error) { + return s.Internal.SyncState(p0) +} + +func (s *FullNodeStruct) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { + return s.Internal.SyncSubmitBlock(p0, p1) +} + +func (s *FullNodeStruct) SyncUnmarkAllBad(p0 context.Context) error { + return s.Internal.SyncUnmarkAllBad(p0) +} + +func (s *FullNodeStruct) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { + return s.Internal.SyncUnmarkBad(p0, p1) +} + +func (s *FullNodeStruct) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { + return s.Internal.SyncValidateTipset(p0, p1) +} + +func (s *FullNodeStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return s.Internal.WalletBalance(p0, p1) +} + +func (s *FullNodeStruct) WalletDefaultAddress(p0 context.Context) (address.Address, error) { + return s.Internal.WalletDefaultAddress(p0) +} + +func (s *FullNodeStruct) WalletDelete(p0 context.Context, p1 address.Address) error { + return s.Internal.WalletDelete(p0, p1) +} + +func (s *FullNodeStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + return s.Internal.WalletExport(p0, p1) +} + +func (s *FullNodeStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + return s.Internal.WalletHas(p0, p1) +} + +func (s *FullNodeStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + return s.Internal.WalletImport(p0, p1) +} + +func (s *FullNodeStruct) WalletList(p0 context.Context) ([]address.Address, error) { + return s.Internal.WalletList(p0) +} + +func (s *FullNodeStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + return s.Internal.WalletNew(p0, p1) +} + +func (s *FullNodeStruct) WalletSetDefault(p0 context.Context, p1 address.Address) error { + return s.Internal.WalletSetDefault(p0, p1) +} + +func (s *FullNodeStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { + return s.Internal.WalletSign(p0, p1, p2) +} + +func (s *FullNodeStruct) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { + return s.Internal.WalletSignMessage(p0, p1, p2) +} + +func (s *FullNodeStruct) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { + return s.Internal.WalletValidateAddress(p0, p1) +} + +func (s *FullNodeStruct) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { + return s.Internal.WalletVerify(p0, p1, p2, p3) +} + +var _ Common = new(CommonStruct) +var _ FullNode = new(FullNodeStruct) diff --git a/gen/api/proxygen.go b/gen/api/proxygen.go index 42aed096536..64859380f84 100644 --- a/gen/api/proxygen.go +++ b/gen/api/proxygen.go @@ -53,7 +53,13 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor { return v } func main() { - if err := runMain(); err != nil { + // latest (v1) + if err := generate("./api", "api", "apistruct", "./api/apistruct/struct.go"); err != nil { + fmt.Println("error: ", err) + } + + // v0 + if err := generate("./api/v0api", "v0api", "v0api", "./api/v0api/struct.go"); err != nil { fmt.Println("error: ", err) } } @@ -116,9 +122,13 @@ func typeName(e ast.Expr) (string, error) { } } -func runMain() error { +func generate(path, pkg, outpkg, outfile string) error { fset := token.NewFileSet() - apiDir, err := filepath.Abs("./api") + apiDir, err := filepath.Abs(path) + if err != nil { + return err + } + outfile, err = filepath.Abs(outfile) if err != nil { return err } @@ -127,7 +137,7 @@ func runMain() error { return err } - ap := pkgs["api"] + ap := pkgs[pkg] v := &Visitor{make(map[string]map[string]*methodMeta), map[string][]string{}} ast.Walk(v, ap) @@ -148,9 +158,11 @@ func runMain() error { type meta struct { Infos map[string]*strinfo Imports map[string]string + OutPkg string } m := &meta{ + OutPkg: outpkg, Infos: map[string]*strinfo{}, Imports: map[string]string{}, } @@ -165,6 +177,9 @@ func runMain() error { for _, im := range f.Imports { m.Imports[im.Path.Value] = im.Path.Value + if im.Name != nil { + m.Imports[im.Path.Value] = im.Name.Name + " " + m.Imports[im.Path.Value] + } } for ifname, methods := range v.Methods { @@ -244,14 +259,17 @@ func runMain() error { } fmt.Println(string(jb))*/ - w := os.Stdout + w, err := os.OpenFile(outfile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) + if err != nil { + return err + } err = doTemplate(w, m, `// Code generated by github.com/filecoin-project/lotus/gen/api. DO NOT EDIT. -package apistruct +package {{.OutPkg}} import ( -{{range .Imports}}{{.}} +{{range .Imports}} {{.}} {{end}} ) `) @@ -282,7 +300,7 @@ func (s *{{$name}}Struct) {{.Name}}({{.NamedParams}}) ({{.Results}}) { {{end}} {{end}} -{{range .Infos}}var _ api.{{.Name}} = new({{.Name}}Struct) +{{range .Infos}}var _ {{.Name}} = new({{.Name}}Struct) {{end}} `) From d198cf456ead4d6b500f800e4b80e0b284de27b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Mar 2021 17:20:56 +0100 Subject: [PATCH 03/60] make docsgen work with versioned api --- Makefile | 13 +- api/docgen-openrpc/cmd/docgen_openrpc.go | 2 +- api/docgen-openrpc/openrpc.go | 2 +- api/docgen/cmd/docgen.go | 2 +- api/docgen/docgen.go | 8 +- api/v0api/v1_wrapper.go | 8 +- cmd/lotus/rpc.go | 2 +- ...thods-miner.md => api-v0-methods-miner.md} | 0 ...ods-worker.md => api-v0-methods-worker.md} | 0 .../en/{api-methods.md => api-v0-methods.md} | 0 documentation/en/api-v1-unstable-methods.md | 5583 +++++++++++++++++ 11 files changed, 5602 insertions(+), 18 deletions(-) rename documentation/en/{api-methods-miner.md => api-v0-methods-miner.md} (100%) rename documentation/en/{api-methods-worker.md => api-v0-methods-worker.md} (100%) rename documentation/en/{api-methods.md => api-v0-methods.md} (100%) create mode 100644 documentation/en/api-v1-unstable-methods.md diff --git a/Makefile b/Makefile index 5d7781b1da1..02fe23b4a10 100644 --- a/Makefile +++ b/Makefile @@ -341,20 +341,21 @@ docsgen-openrpc-bin: docsgen-md: docsgen-md-full docsgen-md-storage docsgen-md-worker docsgen-md-full: docsgen-md-bin - ./docgen-md "api/api_full.go" "FullNode" > documentation/en/api-methods.md + ./docgen-md "api/api_full.go" "FullNode" "api" "./api" > documentation/en/api-v1-unstable-methods.md + ./docgen-md "api/v0api/full.go" "FullNode" "v0api" "./api/v0api" > documentation/en/api-v0-methods.md docsgen-md-storage: docsgen-md-bin - ./docgen-md "api/api_storage.go" "StorageMiner" > documentation/en/api-methods-miner.md + ./docgen-md "api/api_storage.go" "StorageMiner" "api" "./api" > documentation/en/api-v0-methods-miner.md docsgen-md-worker: docsgen-md-bin - ./docgen-md "api/api_worker.go" "Worker" > documentation/en/api-methods-worker.md + ./docgen-md "api/api_worker.go" "Worker" "api" "./api" > documentation/en/api-v0-methods-worker.md docsgen-openrpc: docsgen-openrpc-full docsgen-openrpc-storage docsgen-openrpc-worker docsgen-openrpc-full: docsgen-openrpc-bin - ./docgen-openrpc "api/api_full.go" "FullNode" -gzip > build/openrpc/full.json.gz + ./docgen-openrpc "api/api_full.go" "FullNode" "api" "./api" -gzip > build/openrpc/full.json.gz docsgen-openrpc-storage: docsgen-openrpc-bin - ./docgen-openrpc "api/api_storage.go" "StorageMiner" -gzip > build/openrpc/miner.json.gz + ./docgen-openrpc "api/api_storage.go" "StorageMiner" "api" "./api" -gzip > build/openrpc/miner.json.gz docsgen-openrpc-worker: docsgen-openrpc-bin - ./docgen-openrpc "api/api_worker.go" "Worker" -gzip > build/openrpc/worker.json.gz + ./docgen-openrpc "api/api_worker.go" "Worker" "api" "./api" -gzip > build/openrpc/worker.json.gz .PHONY: docsgen docsgen-md-bin docsgen-openrpc-bin diff --git a/api/docgen-openrpc/cmd/docgen_openrpc.go b/api/docgen-openrpc/cmd/docgen_openrpc.go index 81683e04d58..b1322257c8f 100644 --- a/api/docgen-openrpc/cmd/docgen_openrpc.go +++ b/api/docgen-openrpc/cmd/docgen_openrpc.go @@ -52,7 +52,7 @@ func main() { // Could use flags package to handle this more cleanly, but that requires changes elsewhere // the scope of which just isn't warranted by this one use case which will usually be run // programmatically anyways. - if len(os.Args) > 3 && os.Args[3] == "-gzip" { + if len(os.Args) > 5 && os.Args[5] == "-gzip" { jsonOut, err = json.Marshal(out) if err != nil { log.Fatalln(err) diff --git a/api/docgen-openrpc/openrpc.go b/api/docgen-openrpc/openrpc.go index 507ad3cb113..e2cd9ce53a7 100644 --- a/api/docgen-openrpc/openrpc.go +++ b/api/docgen-openrpc/openrpc.go @@ -22,7 +22,7 @@ var Comments map[string]string var GroupDocs map[string]string func init() { - Comments, GroupDocs = docgen.ParseApiASTInfo(os.Args[1], os.Args[2]) + Comments, GroupDocs = docgen.ParseApiASTInfo(os.Args[1], os.Args[2], os.Args[3], os.Args[4]) } // schemaDictEntry represents a type association passed to the jsonschema reflector. diff --git a/api/docgen/cmd/docgen.go b/api/docgen/cmd/docgen.go index c47d4420873..57182d4004b 100644 --- a/api/docgen/cmd/docgen.go +++ b/api/docgen/cmd/docgen.go @@ -14,7 +14,7 @@ import ( ) func main() { - comments, groupComments := docgen.ParseApiASTInfo(os.Args[1], os.Args[2]) + comments, groupComments := docgen.ParseApiASTInfo(os.Args[1], os.Args[2], os.Args[3], os.Args[4]) groups := make(map[string]*docgen.MethodGroup) diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index e17238d887a..49f83895974 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -342,9 +342,9 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor { const NoComment = "There are not yet any comments for this method." -func ParseApiASTInfo(apiFile, iface string) (comments map[string]string, groupDocs map[string]string) { //nolint:golint +func ParseApiASTInfo(apiFile, iface, pkg, dir string) (comments map[string]string, groupDocs map[string]string) { //nolint:golint fset := token.NewFileSet() - apiDir, err := filepath.Abs("./api") + apiDir, err := filepath.Abs(dir) if err != nil { fmt.Println("./api filepath absolute error: ", err) return @@ -360,14 +360,14 @@ func ParseApiASTInfo(apiFile, iface string) (comments map[string]string, groupDo return } - ap := pkgs["api"] + ap := pkgs[pkg] f := ap.Files[apiFile] cmap := ast.NewCommentMap(fset, f, f.Comments) v := &Visitor{iface, make(map[string]ast.Node)} - ast.Walk(v, pkgs["api"]) + ast.Walk(v, ap) comments = make(map[string]string) groupDocs = make(map[string]string) diff --git a/api/v0api/v1_wrapper.go b/api/v0api/v1_wrapper.go index 89130160d7a..92b223390b1 100644 --- a/api/v0api/v1_wrapper.go +++ b/api/v0api/v1_wrapper.go @@ -4,7 +4,7 @@ import ( "github.com/filecoin-project/lotus/api/v1api" ) -type WrapperV1 struct { +type WrapperV1Full struct { v1api.FullNode } @@ -12,11 +12,11 @@ type WrapperV1 struct { - dropped StateGetReceipt - tsk param for StateSearchMsg -func (w *WrapperV1) StateSearchMsg(ctx context.Context, c cid.Cid) (*api.MsgLookup, error) { +func (w *WrapperV1Full) StateSearchMsg(ctx context.Context, c cid.Cid) (*api.MsgLookup, error) { return w.FullNode.StateSearchMsg(ctx, c, types.EmptyTSK) } -func (w *WrapperV1) StateGetReceipt(ctx context.Context, cid cid.Cid, key types.TipSetKey) (*types.MessageReceipt, error) { +func (w *WrapperV1Full) StateGetReceipt(ctx context.Context, cid cid.Cid, key types.TipSetKey) (*types.MessageReceipt, error) { m, err := w.FullNode.StateSearchMsg(ctx, cid, key) if err != nil { return nil, err @@ -29,4 +29,4 @@ func (w *WrapperV1) StateGetReceipt(ctx context.Context, cid cid.Cid, key types. return &m.Receipt, nil }*/ -var _ FullNode = &WrapperV1{} +var _ FullNode = &WrapperV1Full{} diff --git a/cmd/lotus/rpc.go b/cmd/lotus/rpc.go index 0f0d1225d82..00de0fddb08 100644 --- a/cmd/lotus/rpc.go +++ b/cmd/lotus/rpc.go @@ -51,7 +51,7 @@ func serveRPC(a v1api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, sh pma := apistruct.PermissionedFullAPI(metrics.MetricedFullAPI(a)) serveRpc("/rpc/v1", pma) - serveRpc("/rpc/v0", &v0api.WrapperV1{FullNode: pma}) + serveRpc("/rpc/v0", &v0api.WrapperV1Full{FullNode: pma}) importAH := &auth.Handler{ Verify: a.AuthVerify, diff --git a/documentation/en/api-methods-miner.md b/documentation/en/api-v0-methods-miner.md similarity index 100% rename from documentation/en/api-methods-miner.md rename to documentation/en/api-v0-methods-miner.md diff --git a/documentation/en/api-methods-worker.md b/documentation/en/api-v0-methods-worker.md similarity index 100% rename from documentation/en/api-methods-worker.md rename to documentation/en/api-v0-methods-worker.md diff --git a/documentation/en/api-methods.md b/documentation/en/api-v0-methods.md similarity index 100% rename from documentation/en/api-methods.md rename to documentation/en/api-v0-methods.md diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md new file mode 100644 index 00000000000..b8764d5b1fb --- /dev/null +++ b/documentation/en/api-v1-unstable-methods.md @@ -0,0 +1,5583 @@ +# Groups +* [](#) + * [Closing](#Closing) + * [Discover](#Discover) + * [Session](#Session) + * [Shutdown](#Shutdown) + * [Version](#Version) +* [Auth](#Auth) + * [AuthNew](#AuthNew) + * [AuthVerify](#AuthVerify) +* [Beacon](#Beacon) + * [BeaconGetEntry](#BeaconGetEntry) +* [Chain](#Chain) + * [ChainDeleteObj](#ChainDeleteObj) + * [ChainExport](#ChainExport) + * [ChainGetBlock](#ChainGetBlock) + * [ChainGetBlockMessages](#ChainGetBlockMessages) + * [ChainGetGenesis](#ChainGetGenesis) + * [ChainGetMessage](#ChainGetMessage) + * [ChainGetNode](#ChainGetNode) + * [ChainGetParentMessages](#ChainGetParentMessages) + * [ChainGetParentReceipts](#ChainGetParentReceipts) + * [ChainGetPath](#ChainGetPath) + * [ChainGetRandomnessFromBeacon](#ChainGetRandomnessFromBeacon) + * [ChainGetRandomnessFromTickets](#ChainGetRandomnessFromTickets) + * [ChainGetTipSet](#ChainGetTipSet) + * [ChainGetTipSetByHeight](#ChainGetTipSetByHeight) + * [ChainHasObj](#ChainHasObj) + * [ChainHead](#ChainHead) + * [ChainNotify](#ChainNotify) + * [ChainReadObj](#ChainReadObj) + * [ChainSetHead](#ChainSetHead) + * [ChainStatObj](#ChainStatObj) + * [ChainTipSetWeight](#ChainTipSetWeight) +* [Client](#Client) + * [ClientCalcCommP](#ClientCalcCommP) + * [ClientCancelDataTransfer](#ClientCancelDataTransfer) + * [ClientDataTransferUpdates](#ClientDataTransferUpdates) + * [ClientDealPieceCID](#ClientDealPieceCID) + * [ClientDealSize](#ClientDealSize) + * [ClientFindData](#ClientFindData) + * [ClientGenCar](#ClientGenCar) + * [ClientGetDealInfo](#ClientGetDealInfo) + * [ClientGetDealStatus](#ClientGetDealStatus) + * [ClientGetDealUpdates](#ClientGetDealUpdates) + * [ClientHasLocal](#ClientHasLocal) + * [ClientImport](#ClientImport) + * [ClientListDataTransfers](#ClientListDataTransfers) + * [ClientListDeals](#ClientListDeals) + * [ClientListImports](#ClientListImports) + * [ClientMinerQueryOffer](#ClientMinerQueryOffer) + * [ClientQueryAsk](#ClientQueryAsk) + * [ClientRemoveImport](#ClientRemoveImport) + * [ClientRestartDataTransfer](#ClientRestartDataTransfer) + * [ClientRetrieve](#ClientRetrieve) + * [ClientRetrieveTryRestartInsufficientFunds](#ClientRetrieveTryRestartInsufficientFunds) + * [ClientRetrieveWithEvents](#ClientRetrieveWithEvents) + * [ClientStartDeal](#ClientStartDeal) +* [Create](#Create) + * [CreateBackup](#CreateBackup) +* [Gas](#Gas) + * [GasEstimateFeeCap](#GasEstimateFeeCap) + * [GasEstimateGasLimit](#GasEstimateGasLimit) + * [GasEstimateGasPremium](#GasEstimateGasPremium) + * [GasEstimateMessageGas](#GasEstimateMessageGas) +* [I](#I) + * [ID](#ID) +* [Log](#Log) + * [LogList](#LogList) + * [LogSetLevel](#LogSetLevel) +* [Market](#Market) + * [MarketAddBalance](#MarketAddBalance) + * [MarketGetReserved](#MarketGetReserved) + * [MarketReleaseFunds](#MarketReleaseFunds) + * [MarketReserveFunds](#MarketReserveFunds) + * [MarketWithdraw](#MarketWithdraw) +* [Miner](#Miner) + * [MinerCreateBlock](#MinerCreateBlock) + * [MinerGetBaseInfo](#MinerGetBaseInfo) +* [Mpool](#Mpool) + * [MpoolBatchPush](#MpoolBatchPush) + * [MpoolBatchPushMessage](#MpoolBatchPushMessage) + * [MpoolBatchPushUntrusted](#MpoolBatchPushUntrusted) + * [MpoolClear](#MpoolClear) + * [MpoolGetConfig](#MpoolGetConfig) + * [MpoolGetNonce](#MpoolGetNonce) + * [MpoolPending](#MpoolPending) + * [MpoolPush](#MpoolPush) + * [MpoolPushMessage](#MpoolPushMessage) + * [MpoolPushUntrusted](#MpoolPushUntrusted) + * [MpoolSelect](#MpoolSelect) + * [MpoolSetConfig](#MpoolSetConfig) + * [MpoolSub](#MpoolSub) +* [Msig](#Msig) + * [MsigAddApprove](#MsigAddApprove) + * [MsigAddCancel](#MsigAddCancel) + * [MsigAddPropose](#MsigAddPropose) + * [MsigApprove](#MsigApprove) + * [MsigApproveTxnHash](#MsigApproveTxnHash) + * [MsigCancel](#MsigCancel) + * [MsigCreate](#MsigCreate) + * [MsigGetAvailableBalance](#MsigGetAvailableBalance) + * [MsigGetPending](#MsigGetPending) + * [MsigGetVested](#MsigGetVested) + * [MsigGetVestingSchedule](#MsigGetVestingSchedule) + * [MsigPropose](#MsigPropose) + * [MsigRemoveSigner](#MsigRemoveSigner) + * [MsigSwapApprove](#MsigSwapApprove) + * [MsigSwapCancel](#MsigSwapCancel) + * [MsigSwapPropose](#MsigSwapPropose) +* [Net](#Net) + * [NetAddrsListen](#NetAddrsListen) + * [NetAgentVersion](#NetAgentVersion) + * [NetAutoNatStatus](#NetAutoNatStatus) + * [NetBandwidthStats](#NetBandwidthStats) + * [NetBandwidthStatsByPeer](#NetBandwidthStatsByPeer) + * [NetBandwidthStatsByProtocol](#NetBandwidthStatsByProtocol) + * [NetBlockAdd](#NetBlockAdd) + * [NetBlockList](#NetBlockList) + * [NetBlockRemove](#NetBlockRemove) + * [NetConnect](#NetConnect) + * [NetConnectedness](#NetConnectedness) + * [NetDisconnect](#NetDisconnect) + * [NetFindPeer](#NetFindPeer) + * [NetPeerInfo](#NetPeerInfo) + * [NetPeers](#NetPeers) + * [NetPubsubScores](#NetPubsubScores) +* [Paych](#Paych) + * [PaychAllocateLane](#PaychAllocateLane) + * [PaychAvailableFunds](#PaychAvailableFunds) + * [PaychAvailableFundsByFromTo](#PaychAvailableFundsByFromTo) + * [PaychCollect](#PaychCollect) + * [PaychGet](#PaychGet) + * [PaychGetWaitReady](#PaychGetWaitReady) + * [PaychList](#PaychList) + * [PaychNewPayment](#PaychNewPayment) + * [PaychSettle](#PaychSettle) + * [PaychStatus](#PaychStatus) + * [PaychVoucherAdd](#PaychVoucherAdd) + * [PaychVoucherCheckSpendable](#PaychVoucherCheckSpendable) + * [PaychVoucherCheckValid](#PaychVoucherCheckValid) + * [PaychVoucherCreate](#PaychVoucherCreate) + * [PaychVoucherList](#PaychVoucherList) + * [PaychVoucherSubmit](#PaychVoucherSubmit) +* [State](#State) + * [StateAccountKey](#StateAccountKey) + * [StateAllMinerFaults](#StateAllMinerFaults) + * [StateCall](#StateCall) + * [StateChangedActors](#StateChangedActors) + * [StateCirculatingSupply](#StateCirculatingSupply) + * [StateCompute](#StateCompute) + * [StateDealProviderCollateralBounds](#StateDealProviderCollateralBounds) + * [StateDecodeParams](#StateDecodeParams) + * [StateGetActor](#StateGetActor) + * [StateGetReceipt](#StateGetReceipt) + * [StateListActors](#StateListActors) + * [StateListMessages](#StateListMessages) + * [StateListMiners](#StateListMiners) + * [StateLookupID](#StateLookupID) + * [StateMarketBalance](#StateMarketBalance) + * [StateMarketDeals](#StateMarketDeals) + * [StateMarketParticipants](#StateMarketParticipants) + * [StateMarketStorageDeal](#StateMarketStorageDeal) + * [StateMinerActiveSectors](#StateMinerActiveSectors) + * [StateMinerAvailableBalance](#StateMinerAvailableBalance) + * [StateMinerDeadlines](#StateMinerDeadlines) + * [StateMinerFaults](#StateMinerFaults) + * [StateMinerInfo](#StateMinerInfo) + * [StateMinerInitialPledgeCollateral](#StateMinerInitialPledgeCollateral) + * [StateMinerPartitions](#StateMinerPartitions) + * [StateMinerPower](#StateMinerPower) + * [StateMinerPreCommitDepositForPower](#StateMinerPreCommitDepositForPower) + * [StateMinerProvingDeadline](#StateMinerProvingDeadline) + * [StateMinerRecoveries](#StateMinerRecoveries) + * [StateMinerSectorAllocated](#StateMinerSectorAllocated) + * [StateMinerSectorCount](#StateMinerSectorCount) + * [StateMinerSectors](#StateMinerSectors) + * [StateNetworkName](#StateNetworkName) + * [StateNetworkVersion](#StateNetworkVersion) + * [StateReadState](#StateReadState) + * [StateReplay](#StateReplay) + * [StateSearchMsg](#StateSearchMsg) + * [StateSearchMsgLimited](#StateSearchMsgLimited) + * [StateSectorExpiration](#StateSectorExpiration) + * [StateSectorGetInfo](#StateSectorGetInfo) + * [StateSectorPartition](#StateSectorPartition) + * [StateSectorPreCommitInfo](#StateSectorPreCommitInfo) + * [StateVMCirculatingSupplyInternal](#StateVMCirculatingSupplyInternal) + * [StateVerifiedClientStatus](#StateVerifiedClientStatus) + * [StateVerifiedRegistryRootKey](#StateVerifiedRegistryRootKey) + * [StateVerifierStatus](#StateVerifierStatus) + * [StateWaitMsg](#StateWaitMsg) + * [StateWaitMsgLimited](#StateWaitMsgLimited) +* [Sync](#Sync) + * [SyncCheckBad](#SyncCheckBad) + * [SyncCheckpoint](#SyncCheckpoint) + * [SyncIncomingBlocks](#SyncIncomingBlocks) + * [SyncMarkBad](#SyncMarkBad) + * [SyncState](#SyncState) + * [SyncSubmitBlock](#SyncSubmitBlock) + * [SyncUnmarkAllBad](#SyncUnmarkAllBad) + * [SyncUnmarkBad](#SyncUnmarkBad) + * [SyncValidateTipset](#SyncValidateTipset) +* [Wallet](#Wallet) + * [WalletBalance](#WalletBalance) + * [WalletDefaultAddress](#WalletDefaultAddress) + * [WalletDelete](#WalletDelete) + * [WalletExport](#WalletExport) + * [WalletHas](#WalletHas) + * [WalletImport](#WalletImport) + * [WalletList](#WalletList) + * [WalletNew](#WalletNew) + * [WalletSetDefault](#WalletSetDefault) + * [WalletSign](#WalletSign) + * [WalletSignMessage](#WalletSignMessage) + * [WalletValidateAddress](#WalletValidateAddress) + * [WalletVerify](#WalletVerify) +## + + +### Closing + + +Perms: read + +Inputs: `null` + +Response: `{}` + +### Discover + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "info": { + "title": "Lotus RPC API", + "version": "1.2.1/generated=2020-11-22T08:22:42-06:00" + }, + "methods": [], + "openrpc": "1.2.6" +} +``` + +### Session + + +Perms: read + +Inputs: `null` + +Response: `"07070707-0707-0707-0707-070707070707"` + +### Shutdown + + +Perms: admin + +Inputs: `null` + +Response: `{}` + +### Version + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Version": "string value", + "APIVersion": 65792, + "BlockDelay": 42 +} +``` + +## Auth + + +### AuthNew + + +Perms: admin + +Inputs: +```json +[ + null +] +``` + +Response: `"Ynl0ZSBhcnJheQ=="` + +### AuthVerify + + +Perms: read + +Inputs: +```json +[ + "string value" +] +``` + +Response: `null` + +## Beacon +The Beacon method group contains methods for interacting with the random beacon (DRAND) + + +### BeaconGetEntry +BeaconGetEntry returns the beacon entry for the given filecoin epoch. If +the entry has not yet been produced, the call will block until the entry +becomes available + + +Perms: read + +Inputs: +```json +[ + 10101 +] +``` + +Response: +```json +{ + "Round": 42, + "Data": "Ynl0ZSBhcnJheQ==" +} +``` + +## Chain +The Chain method group contains methods for interacting with the +blockchain, but that do not require any form of state computation. + + +### ChainDeleteObj +ChainDeleteObj deletes node referenced by the given CID + + +Perms: admin + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `{}` + +### ChainExport +ChainExport returns a stream of bytes with CAR dump of chain data. +The exported chain data includes the header chain from the given tipset +back to genesis, the entire genesis state, and the most recent 'nroots' +state trees. +If oldmsgskip is set, messages from before the requested roots are also not included. + + +Perms: read + +Inputs: +```json +[ + 10101, + true, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"Ynl0ZSBhcnJheQ=="` + +### ChainGetBlock +ChainGetBlock returns the block specified by the given CID. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "Miner": "f01234", + "Ticket": { + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "ElectionProof": { + "WinCount": 9, + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "BeaconEntries": null, + "WinPoStProof": null, + "Parents": null, + "ParentWeight": "0", + "Height": 10101, + "ParentStateRoot": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Messages": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "BLSAggregate": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Timestamp": 42, + "BlockSig": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "ForkSignaling": 42, + "ParentBaseFee": "0" +} +``` + +### ChainGetBlockMessages +ChainGetBlockMessages returns messages stored in the specified block. + +Note: If there are multiple blocks in a tipset, it's likely that some +messages will be duplicated. It's also possible for blocks in a tipset to have +different messages from the same sender at the same nonce. When that happens, +only the first message (in a block with lowest ticket) will be considered +for execution + +NOTE: THIS METHOD SHOULD ONLY BE USED FOR GETTING MESSAGES IN A SPECIFIC BLOCK + +DO NOT USE THIS METHOD TO GET MESSAGES INCLUDED IN A TIPSET +Use ChainGetParentMessages, which will perform correct message deduplication + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "BlsMessages": null, + "SecpkMessages": null, + "Cids": null +} +``` + +### ChainGetGenesis +ChainGetGenesis returns the genesis tipset. + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Cids": null, + "Blocks": null, + "Height": 0 +} +``` + +### ChainGetMessage +ChainGetMessage reads a message referenced by the specified CID from the +chain blockstore. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } +} +``` + +### ChainGetNode + + +Perms: read + +Inputs: +```json +[ + "string value" +] +``` + +Response: +```json +{ + "Cid": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Obj": {} +} +``` + +### ChainGetParentMessages +ChainGetParentMessages returns messages stored in parent tipset of the +specified block. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `null` + +### ChainGetParentReceipts +ChainGetParentReceipts returns receipts for messages in parent tipset of +the specified block. The receipts in the list returned is one-to-one with the +messages returned by a call to ChainGetParentMessages with the same blockCid. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `null` + +### ChainGetPath +ChainGetPath returns a set of revert/apply operations needed to get from +one tipset to another, for example: +``` + to + ^ +from tAA + ^ ^ +tBA tAB + ^---*--^ + ^ + tRR +``` +Would return `[revert(tBA), apply(tAB), apply(tAA)]` + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### ChainGetRandomnessFromBeacon +ChainGetRandomnessFromBeacon is used to sample the beacon for randomness. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + 2, + 10101, + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: `null` + +### ChainGetRandomnessFromTickets +ChainGetRandomnessFromTickets is used to sample the chain for randomness. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + 2, + 10101, + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: `null` + +### ChainGetTipSet +ChainGetTipSet returns the tipset specified by the given TipSetKey. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Cids": null, + "Blocks": null, + "Height": 0 +} +``` + +### ChainGetTipSetByHeight +ChainGetTipSetByHeight looks back for a tipset at the specified epoch. +If there are no blocks at the specified epoch, a tipset at an earlier epoch +will be returned. + + +Perms: read + +Inputs: +```json +[ + 10101, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Cids": null, + "Blocks": null, + "Height": 0 +} +``` + +### ChainHasObj +ChainHasObj checks if a given CID exists in the chain blockstore. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `true` + +### ChainHead +ChainHead returns the current head of the chain. + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Cids": null, + "Blocks": null, + "Height": 0 +} +``` + +### ChainNotify +ChainNotify returns channel with chain head updates. +First message is guaranteed to be of len == 1, and type == 'current'. + + +Perms: read + +Inputs: `null` + +Response: `null` + +### ChainReadObj +ChainReadObj reads ipld nodes referenced by the specified CID from chain +blockstore and returns raw bytes. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `"Ynl0ZSBhcnJheQ=="` + +### ChainSetHead +ChainSetHead forcefully sets current chain head. Use with caution. + + +Perms: admin + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `{}` + +### ChainStatObj +ChainStatObj returns statistics about the graph referenced by 'obj'. +If 'base' is also specified, then the returned stat will be a diff +between the two objects. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "Size": 42, + "Links": 42 +} +``` + +### ChainTipSetWeight +ChainTipSetWeight computes weight for the specified tipset. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +## Client +The Client methods all have to do with interacting with the storage and +retrieval markets as a client + + +### ClientCalcCommP +ClientCalcCommP calculates the CommP for a specified file + + +Perms: write + +Inputs: +```json +[ + "string value" +] +``` + +Response: +```json +{ + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Size": 1024 +} +``` + +### ClientCancelDataTransfer +ClientCancelDataTransfer cancels a data transfer with the given transfer ID and other peer + + +Perms: write + +Inputs: +```json +[ + 3, + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + true +] +``` + +Response: `{}` + +### ClientDataTransferUpdates + + +Perms: write + +Inputs: `null` + +Response: +```json +{ + "TransferID": 3, + "Status": 1, + "BaseCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "IsInitiator": true, + "IsSender": true, + "Voucher": "string value", + "Message": "string value", + "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Transferred": 42 +} +``` + +### ClientDealPieceCID +ClientCalcCommP calculates the CommP and data size of the specified CID + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "PayloadSize": 9, + "PieceSize": 1032, + "PieceCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +} +``` + +### ClientDealSize +ClientDealSize calculates real deal data size + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "PayloadSize": 9, + "PieceSize": 1032 +} +``` + +### ClientFindData +ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer). + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + null +] +``` + +Response: `null` + +### ClientGenCar +ClientGenCar generates a CAR file for the specified file. + + +Perms: write + +Inputs: +```json +[ + { + "Path": "string value", + "IsCAR": true + }, + "string value" +] +``` + +Response: `{}` + +### ClientGetDealInfo +ClientGetDealInfo returns the latest information about a given deal. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "ProposalCid": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "State": 42, + "Message": "string value", + "Provider": "f01234", + "DataRef": { + "TransferType": "string value", + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceCid": null, + "PieceSize": 1024, + "RawBlockSize": 42 + }, + "PieceCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Size": 42, + "PricePerEpoch": "0", + "Duration": 42, + "DealID": 5432, + "CreationTime": "0001-01-01T00:00:00Z", + "Verified": true, + "TransferChannelID": { + "Initiator": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Responder": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "ID": 3 + }, + "DataTransfer": { + "TransferID": 3, + "Status": 1, + "BaseCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "IsInitiator": true, + "IsSender": true, + "Voucher": "string value", + "Message": "string value", + "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Transferred": 42 + } +} +``` + +### ClientGetDealStatus +ClientGetDealStatus returns status given a code + + +Perms: read + +Inputs: +```json +[ + 42 +] +``` + +Response: `"string value"` + +### ClientGetDealUpdates +ClientGetDealUpdates returns the status of updated deals + + +Perms: write + +Inputs: `null` + +Response: +```json +{ + "ProposalCid": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "State": 42, + "Message": "string value", + "Provider": "f01234", + "DataRef": { + "TransferType": "string value", + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceCid": null, + "PieceSize": 1024, + "RawBlockSize": 42 + }, + "PieceCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Size": 42, + "PricePerEpoch": "0", + "Duration": 42, + "DealID": 5432, + "CreationTime": "0001-01-01T00:00:00Z", + "Verified": true, + "TransferChannelID": { + "Initiator": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Responder": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "ID": 3 + }, + "DataTransfer": { + "TransferID": 3, + "Status": 1, + "BaseCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "IsInitiator": true, + "IsSender": true, + "Voucher": "string value", + "Message": "string value", + "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Transferred": 42 + } +} +``` + +### ClientHasLocal +ClientHasLocal indicates whether a certain CID is locally stored. + + +Perms: write + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `true` + +### ClientImport +ClientImport imports file under the specified path into filestore. + + +Perms: admin + +Inputs: +```json +[ + { + "Path": "string value", + "IsCAR": true + } +] +``` + +Response: +```json +{ + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ImportID": 50 +} +``` + +### ClientListDataTransfers +ClientListTransfers returns the status of all ongoing transfers of data + + +Perms: write + +Inputs: `null` + +Response: `null` + +### ClientListDeals +ClientListDeals returns information about the deals made by the local client. + + +Perms: write + +Inputs: `null` + +Response: `null` + +### ClientListImports +ClientListImports lists imported files and their root CIDs + + +Perms: write + +Inputs: `null` + +Response: `null` + +### ClientMinerQueryOffer +ClientMinerQueryOffer returns a QueryOffer for the specific miner and file. + + +Perms: read + +Inputs: +```json +[ + "f01234", + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + null +] +``` + +Response: +```json +{ + "Err": "string value", + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Piece": null, + "Size": 42, + "MinPrice": "0", + "UnsealPrice": "0", + "PaymentInterval": 42, + "PaymentIntervalIncrease": 42, + "Miner": "f01234", + "MinerPeer": { + "Address": "f01234", + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "PieceCID": null + } +} +``` + +### ClientQueryAsk +ClientQueryAsk returns a signed StorageAsk from the specified miner. + + +Perms: read + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "f01234" +] +``` + +Response: +```json +{ + "Price": "0", + "VerifiedPrice": "0", + "MinPieceSize": 1032, + "MaxPieceSize": 1032, + "Miner": "f01234", + "Timestamp": 10101, + "Expiry": 10101, + "SeqNo": 42 +} +``` + +### ClientRemoveImport +ClientRemoveImport removes file import + + +Perms: admin + +Inputs: +```json +[ + 50 +] +``` + +Response: `{}` + +### ClientRestartDataTransfer +ClientRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer + + +Perms: write + +Inputs: +```json +[ + 3, + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + true +] +``` + +Response: `{}` + +### ClientRetrieve +ClientRetrieve initiates the retrieval of a file, as specified in the order. + + +Perms: admin + +Inputs: +```json +[ + { + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Piece": null, + "Size": 42, + "Total": "0", + "UnsealPrice": "0", + "PaymentInterval": 42, + "PaymentIntervalIncrease": 42, + "Client": "f01234", + "Miner": "f01234", + "MinerPeer": { + "Address": "f01234", + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "PieceCID": null + } + }, + { + "Path": "string value", + "IsCAR": true + } +] +``` + +Response: `{}` + +### ClientRetrieveTryRestartInsufficientFunds +ClientRetrieveTryRestartInsufficientFunds attempts to restart stalled retrievals on a given payment channel +which are stuck due to insufficient funds + + +Perms: write + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `{}` + +### ClientRetrieveWithEvents +ClientRetrieveWithEvents initiates the retrieval of a file, as specified in the order, and provides a channel +of status updates. + + +Perms: admin + +Inputs: +```json +[ + { + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Piece": null, + "Size": 42, + "Total": "0", + "UnsealPrice": "0", + "PaymentInterval": 42, + "PaymentIntervalIncrease": 42, + "Client": "f01234", + "Miner": "f01234", + "MinerPeer": { + "Address": "f01234", + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "PieceCID": null + } + }, + { + "Path": "string value", + "IsCAR": true + } +] +``` + +Response: +```json +{ + "Event": 5, + "Status": 0, + "BytesReceived": 42, + "FundsSpent": "0", + "Err": "string value" +} +``` + +### ClientStartDeal +ClientStartDeal proposes a deal with a miner. + + +Perms: admin + +Inputs: +```json +[ + { + "Data": { + "TransferType": "string value", + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceCid": null, + "PieceSize": 1024, + "RawBlockSize": 42 + }, + "Wallet": "f01234", + "Miner": "f01234", + "EpochPrice": "0", + "MinBlocksDuration": 42, + "ProviderCollateral": "0", + "DealStartEpoch": 10101, + "FastRetrieval": true, + "VerifiedDeal": true + } +] +``` + +Response: `null` + +## Create + + +### CreateBackup +CreateBackup creates node backup onder the specified file name. The +method requires that the lotus daemon is running with the +LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that +the path specified when calling CreateBackup is within the base path + + +Perms: admin + +Inputs: +```json +[ + "string value" +] +``` + +Response: `{}` + +## Gas + + +### GasEstimateFeeCap +GasEstimateFeeCap estimates gas fee cap + + +Perms: read + +Inputs: +```json +[ + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### GasEstimateGasLimit +GasEstimateGasLimit estimates gas used by the message and returns it. +It fails if message fails to execute. + + +Perms: read + +Inputs: +```json +[ + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `9` + +### GasEstimateGasPremium +GasEstimateGasPremium estimates what gas price should be used for a +message to have high likelihood of inclusion in `nblocksincl` epochs. + + +Perms: read + +Inputs: +```json +[ + 42, + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### GasEstimateMessageGas +GasEstimateMessageGas estimates gas values for unset message gas fields + + +Perms: read + +Inputs: +```json +[ + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + { + "MaxFee": "0" + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } +} +``` + +## I + + +### ID + + +Perms: read + +Inputs: `null` + +Response: `"12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf"` + +## Log + + +### LogList + + +Perms: write + +Inputs: `null` + +Response: `null` + +### LogSetLevel + + +Perms: write + +Inputs: +```json +[ + "string value", + "string value" +] +``` + +Response: `{}` + +## Market + + +### MarketAddBalance +MarketAddBalance adds funds to the market actor + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MarketGetReserved +MarketGetReserved gets the amount of funds that are currently reserved for the address + + +Perms: sign + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `"0"` + +### MarketReleaseFunds +MarketReleaseFunds releases funds reserved by MarketReserveFunds + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "0" +] +``` + +Response: `{}` + +### MarketReserveFunds +MarketReserveFunds reserves funds for a deal + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MarketWithdraw +MarketWithdraw withdraws unlocked funds from the market actor + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +## Miner + + +### MinerCreateBlock + + +Perms: write + +Inputs: +```json +[ + { + "Miner": "f01234", + "Parents": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + "Ticket": { + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "Eproof": { + "WinCount": 9, + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "BeaconValues": null, + "Messages": null, + "Epoch": 10101, + "Timestamp": 42, + "WinningPoStProof": null + } +] +``` + +Response: +```json +{ + "Header": { + "Miner": "f01234", + "Ticket": { + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "ElectionProof": { + "WinCount": 9, + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "BeaconEntries": null, + "WinPoStProof": null, + "Parents": null, + "ParentWeight": "0", + "Height": 10101, + "ParentStateRoot": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Messages": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "BLSAggregate": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Timestamp": 42, + "BlockSig": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "ForkSignaling": 42, + "ParentBaseFee": "0" + }, + "BlsMessages": null, + "SecpkMessages": null +} +``` + +### MinerGetBaseInfo +There are not yet any comments for this method. + +Perms: read + +Inputs: +```json +[ + "f01234", + 10101, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "MinerPower": "0", + "NetworkPower": "0", + "Sectors": null, + "WorkerKey": "f01234", + "SectorSize": 34359738368, + "PrevBeaconEntry": { + "Round": 42, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "BeaconEntries": null, + "EligibleForMining": true +} +``` + +## Mpool +The Mpool methods are for interacting with the message pool. The message pool +manages all incoming and outgoing 'messages' going over the network. + + +### MpoolBatchPush +MpoolBatchPush batch pushes a signed message to mempool. + + +Perms: write + +Inputs: +```json +[ + null +] +``` + +Response: `null` + +### MpoolBatchPushMessage +MpoolBatchPushMessage batch pushes a unsigned message to mempool. + + +Perms: sign + +Inputs: +```json +[ + null, + { + "MaxFee": "0" + } +] +``` + +Response: `null` + +### MpoolBatchPushUntrusted +MpoolBatchPushUntrusted batch pushes a signed message to mempool from untrusted sources. + + +Perms: write + +Inputs: +```json +[ + null +] +``` + +Response: `null` + +### MpoolClear +MpoolClear clears pending messages from the mpool + + +Perms: write + +Inputs: +```json +[ + true +] +``` + +Response: `{}` + +### MpoolGetConfig +MpoolGetConfig returns (a copy of) the current mpool config + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "PriorityAddrs": null, + "SizeLimitHigh": 123, + "SizeLimitLow": 123, + "ReplaceByFeeRatio": 12.3, + "PruneCooldown": 60000000000, + "GasLimitOverestimation": 12.3 +} +``` + +### MpoolGetNonce +MpoolGetNonce gets next nonce for the specified sender. +Note that this method may not be atomic. Use MpoolPushMessage instead. + + +Perms: read + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `42` + +### MpoolPending +MpoolPending returns pending mempool messages. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### MpoolPush +MpoolPush pushes a signed message to mempool. + + +Perms: write + +Inputs: +```json +[ + { + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + } +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MpoolPushMessage +MpoolPushMessage atomically assigns a nonce, signs, and pushes a message +to mempool. +maxFee is only used when GasFeeCap/GasPremium fields aren't specified + +When maxFee is set to 0, MpoolPushMessage will guess appropriate fee +based on current chain conditions + + +Perms: sign + +Inputs: +```json +[ + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + { + "MaxFee": "0" + } +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } +} +``` + +### MpoolPushUntrusted +MpoolPushUntrusted pushes a signed message to mempool from untrusted sources. + + +Perms: write + +Inputs: +```json +[ + { + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + } +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MpoolSelect +MpoolSelect returns a list of pending messages for inclusion in the next block + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + 12.3 +] +``` + +Response: `null` + +### MpoolSetConfig +MpoolSetConfig sets the mpool config to (a copy of) the supplied config + + +Perms: admin + +Inputs: +```json +[ + { + "PriorityAddrs": null, + "SizeLimitHigh": 123, + "SizeLimitLow": 123, + "ReplaceByFeeRatio": 12.3, + "PruneCooldown": 60000000000, + "GasLimitOverestimation": 12.3 + } +] +``` + +Response: `{}` + +### MpoolSub + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Type": 0, + "Message": { + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + } +} +``` + +## Msig +The Msig methods are used to interact with multisig wallets on the +filecoin network + + +### MsigAddApprove +MsigAddApprove approves a previously proposed AddSigner message +It takes the following params: , , , +, , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + 42, + "f01234", + "f01234", + true +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigAddCancel +MsigAddCancel cancels a previously proposed AddSigner message +It takes the following params: , , , +, + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + 42, + "f01234", + true +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigAddPropose +MsigAddPropose proposes adding a signer in the multisig +It takes the following params: , , +, + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "f01234", + true +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigApprove +MsigApprove approves a previously-proposed multisig message by transaction ID +It takes the following params: , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + 42, + "f01234" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigApproveTxnHash +MsigApproveTxnHash approves a previously-proposed multisig message, specified +using both transaction ID and a hash of the parameters used in the +proposal. This method of approval can be used to ensure you only approve +exactly the transaction you think you are. +It takes the following params: , , , , , +, , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + 42, + "f01234", + "f01234", + "0", + "f01234", + 42, + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigCancel +MsigCancel cancels a previously-proposed multisig message +It takes the following params: , , , , +, , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + 42, + "f01234", + "0", + "f01234", + 42, + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigCreate +MsigCreate creates a multisig wallet +It takes the following params: , , +, , + + +Perms: sign + +Inputs: +```json +[ + 42, + null, + 10101, + "0", + "f01234", + "0" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigGetAvailableBalance +MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### MsigGetPending +MsigGetPending returns pending transactions for the given multisig +wallet. Once pending transactions are fully approved, they will no longer +appear here. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### MsigGetVested +MsigGetVested returns the amount of FIL that vested in a multisig in a certain period. +It takes the following params: , , + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### MsigGetVestingSchedule +MsigGetVestingSchedule returns the vesting details of a given multisig. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "InitialBalance": "0", + "StartEpoch": 10101, + "UnlockDuration": 10101 +} +``` + +### MsigPropose +MsigPropose proposes a multisig message +It takes the following params: , , , +, , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0", + "f01234", + 42, + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigRemoveSigner +MsigRemoveSigner proposes the removal of a signer from the multisig. +It accepts the multisig to make the change on, the proposer address to +send the message from, the address to be removed, and a boolean +indicating whether or not the signing threshold should be lowered by one +along with the address removal. + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "f01234", + true +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigSwapApprove +MsigSwapApprove approves a previously proposed SwapSigner +It takes the following params: , , , +, , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + 42, + "f01234", + "f01234", + "f01234" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigSwapCancel +MsigSwapCancel cancels a previously proposed SwapSigner message +It takes the following params: , , , +, + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + 42, + "f01234", + "f01234" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MsigSwapPropose +MsigSwapPropose proposes swapping 2 signers in the multisig +It takes the following params: , , +, + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "f01234", + "f01234" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +## Net + + +### NetAddrsListen + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +} +``` + +### NetAgentVersion + + +Perms: read + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +] +``` + +Response: `"string value"` + +### NetAutoNatStatus + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Reachability": 1, + "PublicAddr": "string value" +} +``` + +### NetBandwidthStats + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "TotalIn": 9, + "TotalOut": 9, + "RateIn": 12.3, + "RateOut": 12.3 +} +``` + +### NetBandwidthStatsByPeer + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "12D3KooWSXmXLJmBR1M7i9RW9GQPNUhZSzXKzxDHWtAgNuJAbyEJ": { + "TotalIn": 174000, + "TotalOut": 12500, + "RateIn": 100, + "RateOut": 50 + } +} +``` + +### NetBandwidthStatsByProtocol + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "/fil/hello/1.0.0": { + "TotalIn": 174000, + "TotalOut": 12500, + "RateIn": 100, + "RateOut": 50 + } +} +``` + +### NetBlockAdd + + +Perms: admin + +Inputs: +```json +[ + { + "Peers": null, + "IPAddrs": null, + "IPSubnets": null + } +] +``` + +Response: `{}` + +### NetBlockList + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Peers": null, + "IPAddrs": null, + "IPSubnets": null +} +``` + +### NetBlockRemove + + +Perms: admin + +Inputs: +```json +[ + { + "Peers": null, + "IPAddrs": null, + "IPSubnets": null + } +] +``` + +Response: `{}` + +### NetConnect + + +Perms: write + +Inputs: +```json +[ + { + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + } +] +``` + +Response: `{}` + +### NetConnectedness + + +Perms: read + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +] +``` + +Response: `1` + +### NetDisconnect + + +Perms: write + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +] +``` + +Response: `{}` + +### NetFindPeer + + +Perms: read + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +] +``` + +Response: +```json +{ + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +} +``` + +### NetPeerInfo + + +Perms: read + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +] +``` + +Response: +```json +{ + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Agent": "string value", + "Addrs": null, + "Protocols": null, + "ConnMgrMeta": { + "FirstSeen": "0001-01-01T00:00:00Z", + "Value": 123, + "Tags": { + "name": 42 + }, + "Conns": { + "name": "2021-03-08T22:52:18Z" + } + } +} +``` + +### NetPeers + + +Perms: read + +Inputs: `null` + +Response: `null` + +### NetPubsubScores + + +Perms: read + +Inputs: `null` + +Response: `null` + +## Paych +The Paych methods are for interacting with and managing payment channels + + +### PaychAllocateLane + + +Perms: sign + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `42` + +### PaychAvailableFunds + + +Perms: sign + +Inputs: +```json +[ + "f01234" +] +``` + +Response: +```json +{ + "Channel": "\u003cempty\u003e", + "From": "f01234", + "To": "f01234", + "ConfirmedAmt": "0", + "PendingAmt": "0", + "PendingWaitSentinel": null, + "QueuedAmt": "0", + "VoucherReedeemedAmt": "0" +} +``` + +### PaychAvailableFundsByFromTo + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234" +] +``` + +Response: +```json +{ + "Channel": "\u003cempty\u003e", + "From": "f01234", + "To": "f01234", + "ConfirmedAmt": "0", + "PendingAmt": "0", + "PendingWaitSentinel": null, + "QueuedAmt": "0", + "VoucherReedeemedAmt": "0" +} +``` + +### PaychCollect + + +Perms: sign + +Inputs: +```json +[ + "f01234" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### PaychGet +There are not yet any comments for this method. + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0" +] +``` + +Response: +```json +{ + "Channel": "f01234", + "WaitSentinel": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +} +``` + +### PaychGetWaitReady + + +Perms: sign + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `"f01234"` + +### PaychList + + +Perms: read + +Inputs: `null` + +Response: `null` + +### PaychNewPayment + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + null +] +``` + +Response: +```json +{ + "Channel": "f01234", + "WaitSentinel": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Vouchers": null +} +``` + +### PaychSettle + + +Perms: sign + +Inputs: +```json +[ + "f01234" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### PaychStatus + + +Perms: read + +Inputs: +```json +[ + "f01234" +] +``` + +Response: +```json +{ + "ControlAddr": "f01234", + "Direction": 1 +} +``` + +### PaychVoucherAdd + + +Perms: write + +Inputs: +```json +[ + "f01234", + { + "ChannelAddr": "f01234", + "TimeLockMin": 10101, + "TimeLockMax": 10101, + "SecretPreimage": "Ynl0ZSBhcnJheQ==", + "Extra": { + "Actor": "f01234", + "Method": 1, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Lane": 42, + "Nonce": 42, + "Amount": "0", + "MinSettleHeight": 10101, + "Merges": null, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } + }, + "Ynl0ZSBhcnJheQ==", + "0" +] +``` + +Response: `"0"` + +### PaychVoucherCheckSpendable + + +Perms: read + +Inputs: +```json +[ + "f01234", + { + "ChannelAddr": "f01234", + "TimeLockMin": 10101, + "TimeLockMax": 10101, + "SecretPreimage": "Ynl0ZSBhcnJheQ==", + "Extra": { + "Actor": "f01234", + "Method": 1, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Lane": 42, + "Nonce": 42, + "Amount": "0", + "MinSettleHeight": 10101, + "Merges": null, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } + }, + "Ynl0ZSBhcnJheQ==", + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: `true` + +### PaychVoucherCheckValid + + +Perms: read + +Inputs: +```json +[ + "f01234", + { + "ChannelAddr": "f01234", + "TimeLockMin": 10101, + "TimeLockMax": 10101, + "SecretPreimage": "Ynl0ZSBhcnJheQ==", + "Extra": { + "Actor": "f01234", + "Method": 1, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Lane": 42, + "Nonce": 42, + "Amount": "0", + "MinSettleHeight": 10101, + "Merges": null, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } + } +] +``` + +Response: `{}` + +### PaychVoucherCreate + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "0", + 42 +] +``` + +Response: +```json +{ + "Voucher": { + "ChannelAddr": "f01234", + "TimeLockMin": 10101, + "TimeLockMax": 10101, + "SecretPreimage": "Ynl0ZSBhcnJheQ==", + "Extra": { + "Actor": "f01234", + "Method": 1, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Lane": 42, + "Nonce": 42, + "Amount": "0", + "MinSettleHeight": 10101, + "Merges": null, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } + }, + "Shortfall": "0" +} +``` + +### PaychVoucherList + + +Perms: write + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `null` + +### PaychVoucherSubmit + + +Perms: sign + +Inputs: +```json +[ + "f01234", + { + "ChannelAddr": "f01234", + "TimeLockMin": 10101, + "TimeLockMax": 10101, + "SecretPreimage": "Ynl0ZSBhcnJheQ==", + "Extra": { + "Actor": "f01234", + "Method": 1, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Lane": 42, + "Nonce": 42, + "Amount": "0", + "MinSettleHeight": 10101, + "Merges": null, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } + }, + "Ynl0ZSBhcnJheQ==", + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +## State +The State methods are used to query, inspect, and interact with chain state. +Most methods take a TipSetKey as a parameter. The state looked up is the parent state of the tipset. +A nil TipSetKey can be provided as a param, this will cause the heaviest tipset in the chain to be used. + + +### StateAccountKey +StateAccountKey returns the public key address of the given ID address + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"f01234"` + +### StateAllMinerFaults +StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset + + +Perms: read + +Inputs: +```json +[ + 10101, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateCall +StateCall runs the given message and returns its result without any persisted changes. + +StateCall applies the message to the tipset's parent state. The +message is not applied on-top-of the messages in the passed-in +tipset. + + +Perms: read + +Inputs: +```json +[ + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "MsgCid": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Msg": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "MsgRct": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "GasCost": { + "Message": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "GasUsed": "0", + "BaseFeeBurn": "0", + "OverEstimationBurn": "0", + "MinerPenalty": "0", + "MinerTip": "0", + "Refund": "0", + "TotalCost": "0" + }, + "ExecutionTrace": { + "Msg": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "MsgRct": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "Error": "string value", + "Duration": 60000000000, + "GasCharges": null, + "Subcalls": null + }, + "Error": "string value", + "Duration": 60000000000 +} +``` + +### StateChangedActors +StateChangedActors returns all the actors whose states change between the two given state CIDs +TODO: Should this take tipset keys instead? + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "t01236": { + "Code": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Head": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Nonce": 42, + "Balance": "0" + } +} +``` + +### StateCirculatingSupply +StateCirculatingSupply returns the exact circulating supply of Filecoin at the given tipset. +This is not used anywhere in the protocol itself, and is only for external consumption. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateCompute +StateCompute is a flexible command that applies the given messages on the given tipset. +The messages are run as though the VM were at the provided height. + +When called, StateCompute will: +- Load the provided tipset, or use the current chain head if not provided +- Compute the tipset state of the provided tipset on top of the parent state + - (note that this step runs before vmheight is applied to the execution) + - Execute state upgrade if any were scheduled at the epoch, or in null + blocks preceding the tipset + - Call the cron actor on null blocks preceding the tipset + - For each block in the tipset + - Apply messages in blocks in the specified + - Award block reward by calling the reward actor + - Call the cron actor for the current epoch +- If the specified vmheight is higher than the current epoch, apply any + needed state upgrades to the state +- Apply the specified messages to the state + +The vmheight parameter sets VM execution epoch, and can be used to simulate +message execution in different network versions. If the specified vmheight +epoch is higher than the epoch of the specified tipset, any state upgrades +until the vmheight will be executed on the state before applying messages +specified by the user. + +Note that the initial tipset state computation is not affected by the +vmheight parameter - only the messages in the `apply` set are + +If the caller wants to simply compute the state, vmheight should be set to +the epoch of the specified tipset. + +Messages in the `apply` parameter must have the correct nonces, and gas +values set. + + +Perms: read + +Inputs: +```json +[ + 10101, + null, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Trace": null +} +``` + +### StateDealProviderCollateralBounds +StateDealProviderCollateralBounds returns the min and max collateral a storage provider +can issue. It takes the deal size and verified status as parameters. + + +Perms: read + +Inputs: +```json +[ + 1032, + true, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Min": "0", + "Max": "0" +} +``` + +### StateDecodeParams +StateDecodeParams attempts to decode the provided params, based on the recipient actor address and method number. + + +Perms: read + +Inputs: +```json +[ + "f01234", + 1, + "Ynl0ZSBhcnJheQ==", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `{}` + +### StateGetActor +StateGetActor returns the indicated actor's nonce and balance. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Code": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Head": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Nonce": 42, + "Balance": "0" +} +``` + +### StateGetReceipt +StateGetReceipt returns the message receipt for the given message or for a +matching gas-repriced replacing message + +NOTE: If the requested message was replaced, this method will return the receipt +for the replacing message - if the caller needs the receipt for exactly the +requested message, use StateSearchMsg().Receipt, and check that MsgLookup.Message +is matching the requested CID + +DEPRECATED: Use StateSearchMsg, this method won't be supported in v1 API + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 +} +``` + +### StateListActors +StateListActors returns the addresses of every actor in the state + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateListMessages +StateListMessages looks back and returns all messages with a matching to or from address, stopping at the given height. + + +Perms: read + +Inputs: +```json +[ + { + "To": "f01234", + "From": "f01234" + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + 10101 +] +``` + +Response: `null` + +### StateListMiners +StateListMiners returns the addresses of every miner that has claimed power in the Power Actor + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateLookupID +StateLookupID retrieves the ID address of the given address + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"f01234"` + +### StateMarketBalance +StateMarketBalance looks up the Escrow and Locked balances of the given address in the Storage Market + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Escrow": "0", + "Locked": "0" +} +``` + +### StateMarketDeals +StateMarketDeals returns information about every deal in the Storage Market + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "t026363": { + "Proposal": { + "PieceCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceSize": 1032, + "VerifiedDeal": true, + "Client": "f01234", + "Provider": "f01234", + "Label": "string value", + "StartEpoch": 10101, + "EndEpoch": 10101, + "StoragePricePerEpoch": "0", + "ProviderCollateral": "0", + "ClientCollateral": "0" + }, + "State": { + "SectorStartEpoch": 10101, + "LastUpdatedEpoch": 10101, + "SlashEpoch": 10101 + } + } +} +``` + +### StateMarketParticipants +StateMarketParticipants returns the Escrow and Locked balances of every participant in the Storage Market + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "t026363": { + "Escrow": "0", + "Locked": "0" + } +} +``` + +### StateMarketStorageDeal +StateMarketStorageDeal returns information about the indicated deal + + +Perms: read + +Inputs: +```json +[ + 5432, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Proposal": { + "PieceCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceSize": 1032, + "VerifiedDeal": true, + "Client": "f01234", + "Provider": "f01234", + "Label": "string value", + "StartEpoch": 10101, + "EndEpoch": 10101, + "StoragePricePerEpoch": "0", + "ProviderCollateral": "0", + "ClientCollateral": "0" + }, + "State": { + "SectorStartEpoch": 10101, + "LastUpdatedEpoch": 10101, + "SlashEpoch": 10101 + } +} +``` + +### StateMinerActiveSectors +StateMinerActiveSectors returns info about sectors that a given miner is actively proving. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateMinerAvailableBalance +StateMinerAvailableBalance returns the portion of a miner's balance that can be withdrawn or spent + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateMinerDeadlines +StateMinerDeadlines returns all the proving deadlines for the given miner + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateMinerFaults +StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +[ + 5, + 1 +] +``` + +### StateMinerInfo +StateMinerInfo returns info about the indicated miner + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Owner": "f01234", + "Worker": "f01234", + "NewWorker": "f01234", + "ControlAddresses": null, + "WorkerChangeEpoch": 10101, + "PeerId": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Multiaddrs": null, + "WindowPoStProofType": 8, + "SectorSize": 34359738368, + "WindowPoStPartitionSectors": 42, + "ConsensusFaultElapsed": 10101 +} +``` + +### StateMinerInitialPledgeCollateral +StateMinerInitialPledgeCollateral returns the initial pledge collateral for the specified miner's sector + + +Perms: read + +Inputs: +```json +[ + "f01234", + { + "SealProof": 8, + "SectorNumber": 9, + "SealedCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "SealRandEpoch": 10101, + "DealIDs": null, + "Expiration": 10101, + "ReplaceCapacity": true, + "ReplaceSectorDeadline": 42, + "ReplaceSectorPartition": 42, + "ReplaceSectorNumber": 9 + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateMinerPartitions +StateMinerPartitions returns all partitions in the specified deadline + + +Perms: read + +Inputs: +```json +[ + "f01234", + 42, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateMinerPower +StateMinerPower returns the power of the indicated miner + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "MinerPower": { + "RawBytePower": "0", + "QualityAdjPower": "0" + }, + "TotalPower": { + "RawBytePower": "0", + "QualityAdjPower": "0" + }, + "HasMinPower": true +} +``` + +### StateMinerPreCommitDepositForPower +StateMinerInitialPledgeCollateral returns the precommit deposit for the specified miner's sector + + +Perms: read + +Inputs: +```json +[ + "f01234", + { + "SealProof": 8, + "SectorNumber": 9, + "SealedCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "SealRandEpoch": 10101, + "DealIDs": null, + "Expiration": 10101, + "ReplaceCapacity": true, + "ReplaceSectorDeadline": 42, + "ReplaceSectorPartition": 42, + "ReplaceSectorNumber": 9 + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateMinerProvingDeadline +StateMinerProvingDeadline calculates the deadline at some epoch for a proving period +and returns the deadline-related calculations. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "CurrentEpoch": 10101, + "PeriodStart": 10101, + "Index": 42, + "Open": 10101, + "Close": 10101, + "Challenge": 10101, + "FaultCutoff": 10101, + "WPoStPeriodDeadlines": 42, + "WPoStProvingPeriod": 10101, + "WPoStChallengeWindow": 10101, + "WPoStChallengeLookback": 10101, + "FaultDeclarationCutoff": 10101 +} +``` + +### StateMinerRecoveries +StateMinerRecoveries returns a bitfield indicating the recovering sectors of the given miner + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +[ + 5, + 1 +] +``` + +### StateMinerSectorAllocated +StateMinerSectorAllocated checks if a sector is allocated + + +Perms: read + +Inputs: +```json +[ + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `true` + +### StateMinerSectorCount +StateMinerSectorCount returns the number of sectors in a miner's sector set and proving set + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Live": 42, + "Active": 42, + "Faulty": 42 +} +``` + +### StateMinerSectors +StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + 0 + ], + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateNetworkName +StateNetworkName returns the name of the network the node is synced to + + +Perms: read + +Inputs: `null` + +Response: `"lotus"` + +### StateNetworkVersion +StateNetworkVersion returns the network version at the given tipset + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `9` + +### StateReadState +StateReadState returns the indicated actor's state. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Balance": "0", + "Code": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "State": {} +} +``` + +### StateReplay +StateReplay replays a given message, assuming it was included in a block in the specified tipset. + +If a tipset key is provided, and a replacing message is found on chain, +the method will return an error saying that the message wasn't found + +If no tipset key is provided, the appropriate tipset is looked up, and if +the message was gas-repriced, the on-chain message will be replayed - in +that case the returned InvocResult.MsgCid will not match the Cid param + +If the caller wants to ensure that exactly the requested message was executed, +they MUST check that InvocResult.MsgCid is equal to the provided Cid. +Without this check both the requested and original message may appear as +successfully executed on-chain, which may look like a double-spend. + +A replacing message is a message with a different CID, any of Gas values, and +different signature, but with all other parameters matching (source/destination, +nonce, params, etc.) + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "MsgCid": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Msg": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "MsgRct": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "GasCost": { + "Message": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "GasUsed": "0", + "BaseFeeBurn": "0", + "OverEstimationBurn": "0", + "MinerPenalty": "0", + "MinerTip": "0", + "Refund": "0", + "TotalCost": "0" + }, + "ExecutionTrace": { + "Msg": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "MsgRct": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "Error": "string value", + "Duration": 60000000000, + "GasCharges": null, + "Subcalls": null + }, + "Error": "string value", + "Duration": 60000000000 +} +``` + +### StateSearchMsg +StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed + +NOTE: If a replacing message is found on chain, this method will return +a MsgLookup for the replacing message - the MsgLookup.Message will be a different +CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the +result of the execution of the replacing message. + +If the caller wants to ensure that exactly the requested message was executed, +they MUST check that MsgLookup.Message is equal to the provided 'cid'. +Without this check both the requested and original message may appear as +successfully executed on-chain, which may look like a double-spend. + +A replacing message is a message with a different CID, any of Gas values, and +different signature, but with all other parameters matching (source/destination, +nonce, params, etc.) + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "Message": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Receipt": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "ReturnDec": {}, + "TipSet": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + "Height": 10101 +} +``` + +### StateSearchMsgLimited +StateSearchMsgLimited looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed + +NOTE: If a replacing message is found on chain, this method will return +a MsgLookup for the replacing message - the MsgLookup.Message will be a different +CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the +result of the execution of the replacing message. + +If the caller wants to ensure that exactly the requested message was executed, +they MUST check that MsgLookup.Message is equal to the provided 'cid'. +Without this check both the requested and original message may appear as +successfully executed on-chain, which may look like a double-spend. + +A replacing message is a message with a different CID, any of Gas values, and +different signature, but with all other parameters matching (source/destination, +nonce, params, etc.) + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + 10101 +] +``` + +Response: +```json +{ + "Message": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Receipt": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "ReturnDec": {}, + "TipSet": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + "Height": 10101 +} +``` + +### StateSectorExpiration +StateSectorExpiration returns epoch at which given sector will expire + + +Perms: read + +Inputs: +```json +[ + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "OnTime": 10101, + "Early": 10101 +} +``` + +### StateSectorGetInfo +StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found +NOTE: returned info.Expiration may not be accurate in some cases, use StateSectorExpiration to get accurate +expiration epoch + + +Perms: read + +Inputs: +```json +[ + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "SectorNumber": 9, + "SealProof": 8, + "SealedCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "DealIDs": null, + "Activation": 10101, + "Expiration": 10101, + "DealWeight": "0", + "VerifiedDealWeight": "0", + "InitialPledge": "0", + "ExpectedDayReward": "0", + "ExpectedStoragePledge": "0" +} +``` + +### StateSectorPartition +StateSectorPartition finds deadline/partition with the specified sector + + +Perms: read + +Inputs: +```json +[ + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Deadline": 42, + "Partition": 42 +} +``` + +### StateSectorPreCommitInfo +StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector + + +Perms: read + +Inputs: +```json +[ + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Info": { + "SealProof": 8, + "SectorNumber": 9, + "SealedCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "SealRandEpoch": 10101, + "DealIDs": null, + "Expiration": 10101, + "ReplaceCapacity": true, + "ReplaceSectorDeadline": 42, + "ReplaceSectorPartition": 42, + "ReplaceSectorNumber": 9 + }, + "PreCommitDeposit": "0", + "PreCommitEpoch": 10101, + "DealWeight": "0", + "VerifiedDealWeight": "0" +} +``` + +### StateVMCirculatingSupplyInternal +StateVMCirculatingSupplyInternal returns an approximation of the circulating supply of Filecoin at the given tipset. +This is the value reported by the runtime interface to actors code. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "FilVested": "0", + "FilMined": "0", + "FilBurnt": "0", + "FilLocked": "0", + "FilCirculating": "0" +} +``` + +### StateVerifiedClientStatus +StateVerifiedClientStatus returns the data cap for the given address. +Returns nil if there is no entry in the data cap table for the +address. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateVerifiedRegistryRootKey +StateVerifiedClientStatus returns the address of the Verified Registry's root key + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"f01234"` + +### StateVerifierStatus +StateVerifierStatus returns the data cap for the given address. +Returns nil if there is no entry in the data cap table for the +address. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateWaitMsg +StateWaitMsg looks back in the chain for a message. If not found, it blocks until the +message arrives on chain, and gets to the indicated confidence depth. + +NOTE: If a replacing message is found on chain, this method will return +a MsgLookup for the replacing message - the MsgLookup.Message will be a different +CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the +result of the execution of the replacing message. + +If the caller wants to ensure that exactly the requested message was executed, +they MUST check that MsgLookup.Message is equal to the provided 'cid'. +Without this check both the requested and original message may appear as +successfully executed on-chain, which may look like a double-spend. + +A replacing message is a message with a different CID, any of Gas values, and +different signature, but with all other parameters matching (source/destination, +nonce, params, etc.) + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + 42 +] +``` + +Response: +```json +{ + "Message": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Receipt": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "ReturnDec": {}, + "TipSet": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + "Height": 10101 +} +``` + +### StateWaitMsgLimited +StateWaitMsgLimited looks back up to limit epochs in the chain for a message. +If not found, it blocks until the message arrives on chain, and gets to the +indicated confidence depth. + +NOTE: If a replacing message is found on chain, this method will return +a MsgLookup for the replacing message - the MsgLookup.Message will be a different +CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the +result of the execution of the replacing message. + +If the caller wants to ensure that exactly the requested message was executed, +they MUST check that MsgLookup.Message is equal to the provided 'cid'. +Without this check both the requested and original message may appear as +successfully executed on-chain, which may look like a double-spend. + +A replacing message is a message with a different CID, any of Gas values, and +different signature, but with all other parameters matching (source/destination, +nonce, params, etc.) + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + 42, + 10101 +] +``` + +Response: +```json +{ + "Message": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Receipt": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "ReturnDec": {}, + "TipSet": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + "Height": 10101 +} +``` + +## Sync +The Sync method group contains methods for interacting with and +observing the lotus sync service. + + +### SyncCheckBad +SyncCheckBad checks if a block was marked as bad, and if it was, returns +the reason. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `"string value"` + +### SyncCheckpoint +SyncCheckpoint marks a blocks as checkpointed, meaning that it won't ever fork away from it. + + +Perms: admin + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `{}` + +### SyncIncomingBlocks +SyncIncomingBlocks returns a channel streaming incoming, potentially not +yet synced block headers. + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Miner": "f01234", + "Ticket": { + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "ElectionProof": { + "WinCount": 9, + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "BeaconEntries": null, + "WinPoStProof": null, + "Parents": null, + "ParentWeight": "0", + "Height": 10101, + "ParentStateRoot": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Messages": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "BLSAggregate": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Timestamp": 42, + "BlockSig": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "ForkSignaling": 42, + "ParentBaseFee": "0" +} +``` + +### SyncMarkBad +SyncMarkBad marks a blocks as bad, meaning that it won't ever by synced. +Use with extreme caution. + + +Perms: admin + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `{}` + +### SyncState +SyncState returns the current status of the lotus sync system. + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "ActiveSyncs": null, + "VMApplied": 42 +} +``` + +### SyncSubmitBlock +SyncSubmitBlock can be used to submit a newly created block to the. +network through this node + + +Perms: write + +Inputs: +```json +[ + { + "Header": { + "Miner": "f01234", + "Ticket": { + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "ElectionProof": { + "WinCount": 9, + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "BeaconEntries": null, + "WinPoStProof": null, + "Parents": null, + "ParentWeight": "0", + "Height": 10101, + "ParentStateRoot": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Messages": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "BLSAggregate": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Timestamp": 42, + "BlockSig": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "ForkSignaling": 42, + "ParentBaseFee": "0" + }, + "BlsMessages": null, + "SecpkMessages": null + } +] +``` + +Response: `{}` + +### SyncUnmarkAllBad +SyncUnmarkAllBad purges bad block cache, making it possible to sync to chains previously marked as bad + + +Perms: admin + +Inputs: `null` + +Response: `{}` + +### SyncUnmarkBad +SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again. + + +Perms: admin + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `{}` + +### SyncValidateTipset +SyncValidateTipset indicates whether the provided tipset is valid or not + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `true` + +## Wallet + + +### WalletBalance +WalletBalance returns the balance of the given address at the current head of the chain. + + +Perms: read + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `"0"` + +### WalletDefaultAddress +WalletDefaultAddress returns the address marked as default in the wallet. + + +Perms: write + +Inputs: `null` + +Response: `"f01234"` + +### WalletDelete +WalletDelete deletes an address from the wallet. + + +Perms: admin + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `{}` + +### WalletExport +WalletExport returns the private key of an address in the wallet. + + +Perms: admin + +Inputs: +```json +[ + "f01234" +] +``` + +Response: +```json +{ + "Type": "bls", + "PrivateKey": "Ynl0ZSBhcnJheQ==" +} +``` + +### WalletHas +WalletHas indicates whether the given address is in the wallet. + + +Perms: write + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `true` + +### WalletImport +WalletImport receives a KeyInfo, which includes a private key, and imports it into the wallet. + + +Perms: admin + +Inputs: +```json +[ + { + "Type": "bls", + "PrivateKey": "Ynl0ZSBhcnJheQ==" + } +] +``` + +Response: `"f01234"` + +### WalletList +WalletList lists all the addresses in the wallet. + + +Perms: write + +Inputs: `null` + +Response: `null` + +### WalletNew +WalletNew creates a new address in the wallet with the given sigType. +Available key types: bls, secp256k1, secp256k1-ledger +Support for numerical types: 1 - secp256k1, 2 - BLS is deprecated + + +Perms: write + +Inputs: +```json +[ + "bls" +] +``` + +Response: `"f01234"` + +### WalletSetDefault +WalletSetDefault marks the given address as as the default one. + + +Perms: write + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `{}` + +### WalletSign +WalletSign signs the given bytes using the given address. + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: +```json +{ + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" +} +``` + +### WalletSignMessage +WalletSignMessage signs the given message using the given address. + + +Perms: sign + +Inputs: +```json +[ + "f01234", + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + } +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } +} +``` + +### WalletValidateAddress +WalletValidateAddress validates whether a given string can be decoded as a well-formed address + + +Perms: read + +Inputs: +```json +[ + "string value" +] +``` + +Response: `"f01234"` + +### WalletVerify +WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid. +The address does not have to be in the wallet. + + +Perms: read + +Inputs: +```json +[ + "f01234", + "Ynl0ZSBhcnJheQ==", + { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } +] +``` + +Response: `true` + From efccf7d73032df4f107244072a5c8ef97852cd59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Mar 2021 17:23:01 +0100 Subject: [PATCH 04/60] Generate v0 mocks --- api/v0api/full.go | 2 + api/v0api/v0mocks/mock_full.go | 3004 ++++++++++++++++++++++++++++++++ 2 files changed, 3006 insertions(+) create mode 100644 api/v0api/v0mocks/mock_full.go diff --git a/api/v0api/full.go b/api/v0api/full.go index 8e370de5180..ec1ee9a4a21 100644 --- a/api/v0api/full.go +++ b/api/v0api/full.go @@ -23,6 +23,8 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" ) +//go:generate go run github.com/golang/mock/mockgen -destination=v0mocks/mock_full.go -package=v0mocks . FullNode + // FullNode API is a low-level interface to the Filecoin network full node type FullNode interface { Common diff --git a/api/v0api/v0mocks/mock_full.go b/api/v0api/v0mocks/mock_full.go new file mode 100644 index 00000000000..ff391a0bb1b --- /dev/null +++ b/api/v0api/v0mocks/mock_full.go @@ -0,0 +1,3004 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/filecoin-project/lotus/api/v0api (interfaces: FullNode) + +// Package v0mocks is a generated GoMock package. +package v0mocks + +import ( + context "context" + reflect "reflect" + + address "github.com/filecoin-project/go-address" + bitfield "github.com/filecoin-project/go-bitfield" + datatransfer "github.com/filecoin-project/go-data-transfer" + storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket" + auth "github.com/filecoin-project/go-jsonrpc/auth" + multistore "github.com/filecoin-project/go-multistore" + abi "github.com/filecoin-project/go-state-types/abi" + big "github.com/filecoin-project/go-state-types/big" + crypto "github.com/filecoin-project/go-state-types/crypto" + dline "github.com/filecoin-project/go-state-types/dline" + network "github.com/filecoin-project/go-state-types/network" + api "github.com/filecoin-project/lotus/api" + apitypes "github.com/filecoin-project/lotus/api/types" + miner "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + types "github.com/filecoin-project/lotus/chain/types" + marketevents "github.com/filecoin-project/lotus/markets/loggers" + dtypes "github.com/filecoin-project/lotus/node/modules/dtypes" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + paych "github.com/filecoin-project/specs-actors/actors/builtin/paych" + gomock "github.com/golang/mock/gomock" + uuid "github.com/google/uuid" + cid "github.com/ipfs/go-cid" + metrics "github.com/libp2p/go-libp2p-core/metrics" + network0 "github.com/libp2p/go-libp2p-core/network" + peer "github.com/libp2p/go-libp2p-core/peer" + protocol "github.com/libp2p/go-libp2p-core/protocol" +) + +// MockFullNode is a mock of FullNode interface +type MockFullNode struct { + ctrl *gomock.Controller + recorder *MockFullNodeMockRecorder +} + +// MockFullNodeMockRecorder is the mock recorder for MockFullNode +type MockFullNodeMockRecorder struct { + mock *MockFullNode +} + +// NewMockFullNode creates a new mock instance +func NewMockFullNode(ctrl *gomock.Controller) *MockFullNode { + mock := &MockFullNode{ctrl: ctrl} + mock.recorder = &MockFullNodeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockFullNode) EXPECT() *MockFullNodeMockRecorder { + return m.recorder +} + +// AuthNew mocks base method +func (m *MockFullNode) AuthNew(arg0 context.Context, arg1 []auth.Permission) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthNew", arg0, arg1) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AuthNew indicates an expected call of AuthNew +func (mr *MockFullNodeMockRecorder) AuthNew(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthNew", reflect.TypeOf((*MockFullNode)(nil).AuthNew), arg0, arg1) +} + +// AuthVerify mocks base method +func (m *MockFullNode) AuthVerify(arg0 context.Context, arg1 string) ([]auth.Permission, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthVerify", arg0, arg1) + ret0, _ := ret[0].([]auth.Permission) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AuthVerify indicates an expected call of AuthVerify +func (mr *MockFullNodeMockRecorder) AuthVerify(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthVerify", reflect.TypeOf((*MockFullNode)(nil).AuthVerify), arg0, arg1) +} + +// BeaconGetEntry mocks base method +func (m *MockFullNode) BeaconGetEntry(arg0 context.Context, arg1 abi.ChainEpoch) (*types.BeaconEntry, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeaconGetEntry", arg0, arg1) + ret0, _ := ret[0].(*types.BeaconEntry) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BeaconGetEntry indicates an expected call of BeaconGetEntry +func (mr *MockFullNodeMockRecorder) BeaconGetEntry(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconGetEntry", reflect.TypeOf((*MockFullNode)(nil).BeaconGetEntry), arg0, arg1) +} + +// ChainDeleteObj mocks base method +func (m *MockFullNode) ChainDeleteObj(arg0 context.Context, arg1 cid.Cid) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainDeleteObj", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ChainDeleteObj indicates an expected call of ChainDeleteObj +func (mr *MockFullNodeMockRecorder) ChainDeleteObj(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainDeleteObj", reflect.TypeOf((*MockFullNode)(nil).ChainDeleteObj), arg0, arg1) +} + +// ChainExport mocks base method +func (m *MockFullNode) ChainExport(arg0 context.Context, arg1 abi.ChainEpoch, arg2 bool, arg3 types.TipSetKey) (<-chan []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainExport", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(<-chan []byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainExport indicates an expected call of ChainExport +func (mr *MockFullNodeMockRecorder) ChainExport(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainExport", reflect.TypeOf((*MockFullNode)(nil).ChainExport), arg0, arg1, arg2, arg3) +} + +// ChainGetBlock mocks base method +func (m *MockFullNode) ChainGetBlock(arg0 context.Context, arg1 cid.Cid) (*types.BlockHeader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetBlock", arg0, arg1) + ret0, _ := ret[0].(*types.BlockHeader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetBlock indicates an expected call of ChainGetBlock +func (mr *MockFullNodeMockRecorder) ChainGetBlock(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetBlock", reflect.TypeOf((*MockFullNode)(nil).ChainGetBlock), arg0, arg1) +} + +// ChainGetBlockMessages mocks base method +func (m *MockFullNode) ChainGetBlockMessages(arg0 context.Context, arg1 cid.Cid) (*api.BlockMessages, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetBlockMessages", arg0, arg1) + ret0, _ := ret[0].(*api.BlockMessages) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetBlockMessages indicates an expected call of ChainGetBlockMessages +func (mr *MockFullNodeMockRecorder) ChainGetBlockMessages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetBlockMessages", reflect.TypeOf((*MockFullNode)(nil).ChainGetBlockMessages), arg0, arg1) +} + +// ChainGetGenesis mocks base method +func (m *MockFullNode) ChainGetGenesis(arg0 context.Context) (*types.TipSet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetGenesis", arg0) + ret0, _ := ret[0].(*types.TipSet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetGenesis indicates an expected call of ChainGetGenesis +func (mr *MockFullNodeMockRecorder) ChainGetGenesis(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetGenesis", reflect.TypeOf((*MockFullNode)(nil).ChainGetGenesis), arg0) +} + +// ChainGetMessage mocks base method +func (m *MockFullNode) ChainGetMessage(arg0 context.Context, arg1 cid.Cid) (*types.Message, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetMessage", arg0, arg1) + ret0, _ := ret[0].(*types.Message) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetMessage indicates an expected call of ChainGetMessage +func (mr *MockFullNodeMockRecorder) ChainGetMessage(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetMessage", reflect.TypeOf((*MockFullNode)(nil).ChainGetMessage), arg0, arg1) +} + +// ChainGetNode mocks base method +func (m *MockFullNode) ChainGetNode(arg0 context.Context, arg1 string) (*api.IpldObject, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetNode", arg0, arg1) + ret0, _ := ret[0].(*api.IpldObject) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetNode indicates an expected call of ChainGetNode +func (mr *MockFullNodeMockRecorder) ChainGetNode(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetNode", reflect.TypeOf((*MockFullNode)(nil).ChainGetNode), arg0, arg1) +} + +// ChainGetParentMessages mocks base method +func (m *MockFullNode) ChainGetParentMessages(arg0 context.Context, arg1 cid.Cid) ([]api.Message, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetParentMessages", arg0, arg1) + ret0, _ := ret[0].([]api.Message) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetParentMessages indicates an expected call of ChainGetParentMessages +func (mr *MockFullNodeMockRecorder) ChainGetParentMessages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetParentMessages", reflect.TypeOf((*MockFullNode)(nil).ChainGetParentMessages), arg0, arg1) +} + +// ChainGetParentReceipts mocks base method +func (m *MockFullNode) ChainGetParentReceipts(arg0 context.Context, arg1 cid.Cid) ([]*types.MessageReceipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetParentReceipts", arg0, arg1) + ret0, _ := ret[0].([]*types.MessageReceipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetParentReceipts indicates an expected call of ChainGetParentReceipts +func (mr *MockFullNodeMockRecorder) ChainGetParentReceipts(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetParentReceipts", reflect.TypeOf((*MockFullNode)(nil).ChainGetParentReceipts), arg0, arg1) +} + +// ChainGetPath mocks base method +func (m *MockFullNode) ChainGetPath(arg0 context.Context, arg1, arg2 types.TipSetKey) ([]*api.HeadChange, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetPath", arg0, arg1, arg2) + ret0, _ := ret[0].([]*api.HeadChange) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetPath indicates an expected call of ChainGetPath +func (mr *MockFullNodeMockRecorder) ChainGetPath(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetPath", reflect.TypeOf((*MockFullNode)(nil).ChainGetPath), arg0, arg1, arg2) +} + +// ChainGetRandomnessFromBeacon mocks base method +func (m *MockFullNode) ChainGetRandomnessFromBeacon(arg0 context.Context, arg1 types.TipSetKey, arg2 crypto.DomainSeparationTag, arg3 abi.ChainEpoch, arg4 []byte) (abi.Randomness, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetRandomnessFromBeacon", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(abi.Randomness) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetRandomnessFromBeacon indicates an expected call of ChainGetRandomnessFromBeacon +func (mr *MockFullNodeMockRecorder) ChainGetRandomnessFromBeacon(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetRandomnessFromBeacon", reflect.TypeOf((*MockFullNode)(nil).ChainGetRandomnessFromBeacon), arg0, arg1, arg2, arg3, arg4) +} + +// ChainGetRandomnessFromTickets mocks base method +func (m *MockFullNode) ChainGetRandomnessFromTickets(arg0 context.Context, arg1 types.TipSetKey, arg2 crypto.DomainSeparationTag, arg3 abi.ChainEpoch, arg4 []byte) (abi.Randomness, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetRandomnessFromTickets", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(abi.Randomness) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetRandomnessFromTickets indicates an expected call of ChainGetRandomnessFromTickets +func (mr *MockFullNodeMockRecorder) ChainGetRandomnessFromTickets(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetRandomnessFromTickets", reflect.TypeOf((*MockFullNode)(nil).ChainGetRandomnessFromTickets), arg0, arg1, arg2, arg3, arg4) +} + +// ChainGetTipSet mocks base method +func (m *MockFullNode) ChainGetTipSet(arg0 context.Context, arg1 types.TipSetKey) (*types.TipSet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetTipSet", arg0, arg1) + ret0, _ := ret[0].(*types.TipSet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetTipSet indicates an expected call of ChainGetTipSet +func (mr *MockFullNodeMockRecorder) ChainGetTipSet(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetTipSet", reflect.TypeOf((*MockFullNode)(nil).ChainGetTipSet), arg0, arg1) +} + +// ChainGetTipSetByHeight mocks base method +func (m *MockFullNode) ChainGetTipSetByHeight(arg0 context.Context, arg1 abi.ChainEpoch, arg2 types.TipSetKey) (*types.TipSet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetTipSetByHeight", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.TipSet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetTipSetByHeight indicates an expected call of ChainGetTipSetByHeight +func (mr *MockFullNodeMockRecorder) ChainGetTipSetByHeight(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetTipSetByHeight", reflect.TypeOf((*MockFullNode)(nil).ChainGetTipSetByHeight), arg0, arg1, arg2) +} + +// ChainHasObj mocks base method +func (m *MockFullNode) ChainHasObj(arg0 context.Context, arg1 cid.Cid) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainHasObj", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainHasObj indicates an expected call of ChainHasObj +func (mr *MockFullNodeMockRecorder) ChainHasObj(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHasObj", reflect.TypeOf((*MockFullNode)(nil).ChainHasObj), arg0, arg1) +} + +// ChainHead mocks base method +func (m *MockFullNode) ChainHead(arg0 context.Context) (*types.TipSet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainHead", arg0) + ret0, _ := ret[0].(*types.TipSet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainHead indicates an expected call of ChainHead +func (mr *MockFullNodeMockRecorder) ChainHead(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHead", reflect.TypeOf((*MockFullNode)(nil).ChainHead), arg0) +} + +// ChainNotify mocks base method +func (m *MockFullNode) ChainNotify(arg0 context.Context) (<-chan []*api.HeadChange, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainNotify", arg0) + ret0, _ := ret[0].(<-chan []*api.HeadChange) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainNotify indicates an expected call of ChainNotify +func (mr *MockFullNodeMockRecorder) ChainNotify(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainNotify", reflect.TypeOf((*MockFullNode)(nil).ChainNotify), arg0) +} + +// ChainReadObj mocks base method +func (m *MockFullNode) ChainReadObj(arg0 context.Context, arg1 cid.Cid) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainReadObj", arg0, arg1) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainReadObj indicates an expected call of ChainReadObj +func (mr *MockFullNodeMockRecorder) ChainReadObj(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainReadObj", reflect.TypeOf((*MockFullNode)(nil).ChainReadObj), arg0, arg1) +} + +// ChainSetHead mocks base method +func (m *MockFullNode) ChainSetHead(arg0 context.Context, arg1 types.TipSetKey) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainSetHead", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ChainSetHead indicates an expected call of ChainSetHead +func (mr *MockFullNodeMockRecorder) ChainSetHead(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainSetHead", reflect.TypeOf((*MockFullNode)(nil).ChainSetHead), arg0, arg1) +} + +// ChainStatObj mocks base method +func (m *MockFullNode) ChainStatObj(arg0 context.Context, arg1, arg2 cid.Cid) (api.ObjStat, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainStatObj", arg0, arg1, arg2) + ret0, _ := ret[0].(api.ObjStat) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainStatObj indicates an expected call of ChainStatObj +func (mr *MockFullNodeMockRecorder) ChainStatObj(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainStatObj", reflect.TypeOf((*MockFullNode)(nil).ChainStatObj), arg0, arg1, arg2) +} + +// ChainTipSetWeight mocks base method +func (m *MockFullNode) ChainTipSetWeight(arg0 context.Context, arg1 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainTipSetWeight", arg0, arg1) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainTipSetWeight indicates an expected call of ChainTipSetWeight +func (mr *MockFullNodeMockRecorder) ChainTipSetWeight(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainTipSetWeight", reflect.TypeOf((*MockFullNode)(nil).ChainTipSetWeight), arg0, arg1) +} + +// ClientCalcCommP mocks base method +func (m *MockFullNode) ClientCalcCommP(arg0 context.Context, arg1 string) (*api.CommPRet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientCalcCommP", arg0, arg1) + ret0, _ := ret[0].(*api.CommPRet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientCalcCommP indicates an expected call of ClientCalcCommP +func (mr *MockFullNodeMockRecorder) ClientCalcCommP(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCalcCommP", reflect.TypeOf((*MockFullNode)(nil).ClientCalcCommP), arg0, arg1) +} + +// ClientCancelDataTransfer mocks base method +func (m *MockFullNode) ClientCancelDataTransfer(arg0 context.Context, arg1 datatransfer.TransferID, arg2 peer.ID, arg3 bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientCancelDataTransfer", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientCancelDataTransfer indicates an expected call of ClientCancelDataTransfer +func (mr *MockFullNodeMockRecorder) ClientCancelDataTransfer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelDataTransfer", reflect.TypeOf((*MockFullNode)(nil).ClientCancelDataTransfer), arg0, arg1, arg2, arg3) +} + +// ClientDataTransferUpdates mocks base method +func (m *MockFullNode) ClientDataTransferUpdates(arg0 context.Context) (<-chan api.DataTransferChannel, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientDataTransferUpdates", arg0) + ret0, _ := ret[0].(<-chan api.DataTransferChannel) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientDataTransferUpdates indicates an expected call of ClientDataTransferUpdates +func (mr *MockFullNodeMockRecorder) ClientDataTransferUpdates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDataTransferUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientDataTransferUpdates), arg0) +} + +// ClientDealPieceCID mocks base method +func (m *MockFullNode) ClientDealPieceCID(arg0 context.Context, arg1 cid.Cid) (api.DataCIDSize, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientDealPieceCID", arg0, arg1) + ret0, _ := ret[0].(api.DataCIDSize) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientDealPieceCID indicates an expected call of ClientDealPieceCID +func (mr *MockFullNodeMockRecorder) ClientDealPieceCID(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDealPieceCID", reflect.TypeOf((*MockFullNode)(nil).ClientDealPieceCID), arg0, arg1) +} + +// ClientDealSize mocks base method +func (m *MockFullNode) ClientDealSize(arg0 context.Context, arg1 cid.Cid) (api.DataSize, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientDealSize", arg0, arg1) + ret0, _ := ret[0].(api.DataSize) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientDealSize indicates an expected call of ClientDealSize +func (mr *MockFullNodeMockRecorder) ClientDealSize(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDealSize", reflect.TypeOf((*MockFullNode)(nil).ClientDealSize), arg0, arg1) +} + +// ClientFindData mocks base method +func (m *MockFullNode) ClientFindData(arg0 context.Context, arg1 cid.Cid, arg2 *cid.Cid) ([]api.QueryOffer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientFindData", arg0, arg1, arg2) + ret0, _ := ret[0].([]api.QueryOffer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientFindData indicates an expected call of ClientFindData +func (mr *MockFullNodeMockRecorder) ClientFindData(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientFindData", reflect.TypeOf((*MockFullNode)(nil).ClientFindData), arg0, arg1, arg2) +} + +// ClientGenCar mocks base method +func (m *MockFullNode) ClientGenCar(arg0 context.Context, arg1 api.FileRef, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGenCar", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientGenCar indicates an expected call of ClientGenCar +func (mr *MockFullNodeMockRecorder) ClientGenCar(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGenCar", reflect.TypeOf((*MockFullNode)(nil).ClientGenCar), arg0, arg1, arg2) +} + +// ClientGetDealInfo mocks base method +func (m *MockFullNode) ClientGetDealInfo(arg0 context.Context, arg1 cid.Cid) (*api.DealInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGetDealInfo", arg0, arg1) + ret0, _ := ret[0].(*api.DealInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientGetDealInfo indicates an expected call of ClientGetDealInfo +func (mr *MockFullNodeMockRecorder) ClientGetDealInfo(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealInfo", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealInfo), arg0, arg1) +} + +// ClientGetDealStatus mocks base method +func (m *MockFullNode) ClientGetDealStatus(arg0 context.Context, arg1 uint64) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGetDealStatus", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientGetDealStatus indicates an expected call of ClientGetDealStatus +func (mr *MockFullNodeMockRecorder) ClientGetDealStatus(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealStatus", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealStatus), arg0, arg1) +} + +// ClientGetDealUpdates mocks base method +func (m *MockFullNode) ClientGetDealUpdates(arg0 context.Context) (<-chan api.DealInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGetDealUpdates", arg0) + ret0, _ := ret[0].(<-chan api.DealInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientGetDealUpdates indicates an expected call of ClientGetDealUpdates +func (mr *MockFullNodeMockRecorder) ClientGetDealUpdates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealUpdates), arg0) +} + +// ClientHasLocal mocks base method +func (m *MockFullNode) ClientHasLocal(arg0 context.Context, arg1 cid.Cid) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientHasLocal", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientHasLocal indicates an expected call of ClientHasLocal +func (mr *MockFullNodeMockRecorder) ClientHasLocal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientHasLocal", reflect.TypeOf((*MockFullNode)(nil).ClientHasLocal), arg0, arg1) +} + +// ClientImport mocks base method +func (m *MockFullNode) ClientImport(arg0 context.Context, arg1 api.FileRef) (*api.ImportRes, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientImport", arg0, arg1) + ret0, _ := ret[0].(*api.ImportRes) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientImport indicates an expected call of ClientImport +func (mr *MockFullNodeMockRecorder) ClientImport(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientImport", reflect.TypeOf((*MockFullNode)(nil).ClientImport), arg0, arg1) +} + +// ClientListDataTransfers mocks base method +func (m *MockFullNode) ClientListDataTransfers(arg0 context.Context) ([]api.DataTransferChannel, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientListDataTransfers", arg0) + ret0, _ := ret[0].([]api.DataTransferChannel) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientListDataTransfers indicates an expected call of ClientListDataTransfers +func (mr *MockFullNodeMockRecorder) ClientListDataTransfers(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListDataTransfers", reflect.TypeOf((*MockFullNode)(nil).ClientListDataTransfers), arg0) +} + +// ClientListDeals mocks base method +func (m *MockFullNode) ClientListDeals(arg0 context.Context) ([]api.DealInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientListDeals", arg0) + ret0, _ := ret[0].([]api.DealInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientListDeals indicates an expected call of ClientListDeals +func (mr *MockFullNodeMockRecorder) ClientListDeals(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListDeals", reflect.TypeOf((*MockFullNode)(nil).ClientListDeals), arg0) +} + +// ClientListImports mocks base method +func (m *MockFullNode) ClientListImports(arg0 context.Context) ([]api.Import, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientListImports", arg0) + ret0, _ := ret[0].([]api.Import) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientListImports indicates an expected call of ClientListImports +func (mr *MockFullNodeMockRecorder) ClientListImports(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListImports", reflect.TypeOf((*MockFullNode)(nil).ClientListImports), arg0) +} + +// ClientMinerQueryOffer mocks base method +func (m *MockFullNode) ClientMinerQueryOffer(arg0 context.Context, arg1 address.Address, arg2 cid.Cid, arg3 *cid.Cid) (api.QueryOffer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientMinerQueryOffer", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(api.QueryOffer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientMinerQueryOffer indicates an expected call of ClientMinerQueryOffer +func (mr *MockFullNodeMockRecorder) ClientMinerQueryOffer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientMinerQueryOffer", reflect.TypeOf((*MockFullNode)(nil).ClientMinerQueryOffer), arg0, arg1, arg2, arg3) +} + +// ClientQueryAsk mocks base method +func (m *MockFullNode) ClientQueryAsk(arg0 context.Context, arg1 peer.ID, arg2 address.Address) (*storagemarket.StorageAsk, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientQueryAsk", arg0, arg1, arg2) + ret0, _ := ret[0].(*storagemarket.StorageAsk) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientQueryAsk indicates an expected call of ClientQueryAsk +func (mr *MockFullNodeMockRecorder) ClientQueryAsk(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientQueryAsk", reflect.TypeOf((*MockFullNode)(nil).ClientQueryAsk), arg0, arg1, arg2) +} + +// ClientRemoveImport mocks base method +func (m *MockFullNode) ClientRemoveImport(arg0 context.Context, arg1 multistore.StoreID) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientRemoveImport", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientRemoveImport indicates an expected call of ClientRemoveImport +func (mr *MockFullNodeMockRecorder) ClientRemoveImport(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRemoveImport", reflect.TypeOf((*MockFullNode)(nil).ClientRemoveImport), arg0, arg1) +} + +// ClientRestartDataTransfer mocks base method +func (m *MockFullNode) ClientRestartDataTransfer(arg0 context.Context, arg1 datatransfer.TransferID, arg2 peer.ID, arg3 bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientRestartDataTransfer", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientRestartDataTransfer indicates an expected call of ClientRestartDataTransfer +func (mr *MockFullNodeMockRecorder) ClientRestartDataTransfer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRestartDataTransfer", reflect.TypeOf((*MockFullNode)(nil).ClientRestartDataTransfer), arg0, arg1, arg2, arg3) +} + +// ClientRetrieve mocks base method +func (m *MockFullNode) ClientRetrieve(arg0 context.Context, arg1 api.RetrievalOrder, arg2 *api.FileRef) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientRetrieve", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientRetrieve indicates an expected call of ClientRetrieve +func (mr *MockFullNodeMockRecorder) ClientRetrieve(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieve", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieve), arg0, arg1, arg2) +} + +// ClientRetrieveTryRestartInsufficientFunds mocks base method +func (m *MockFullNode) ClientRetrieveTryRestartInsufficientFunds(arg0 context.Context, arg1 address.Address) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientRetrieveTryRestartInsufficientFunds", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientRetrieveTryRestartInsufficientFunds indicates an expected call of ClientRetrieveTryRestartInsufficientFunds +func (mr *MockFullNodeMockRecorder) ClientRetrieveTryRestartInsufficientFunds(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieveTryRestartInsufficientFunds", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieveTryRestartInsufficientFunds), arg0, arg1) +} + +// ClientRetrieveWithEvents mocks base method +func (m *MockFullNode) ClientRetrieveWithEvents(arg0 context.Context, arg1 api.RetrievalOrder, arg2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientRetrieveWithEvents", arg0, arg1, arg2) + ret0, _ := ret[0].(<-chan marketevents.RetrievalEvent) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientRetrieveWithEvents indicates an expected call of ClientRetrieveWithEvents +func (mr *MockFullNodeMockRecorder) ClientRetrieveWithEvents(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieveWithEvents", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieveWithEvents), arg0, arg1, arg2) +} + +// ClientStartDeal mocks base method +func (m *MockFullNode) ClientStartDeal(arg0 context.Context, arg1 *api.StartDealParams) (*cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientStartDeal", arg0, arg1) + ret0, _ := ret[0].(*cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientStartDeal indicates an expected call of ClientStartDeal +func (mr *MockFullNodeMockRecorder) ClientStartDeal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStartDeal", reflect.TypeOf((*MockFullNode)(nil).ClientStartDeal), arg0, arg1) +} + +// Closing mocks base method +func (m *MockFullNode) Closing(arg0 context.Context) (<-chan struct{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Closing", arg0) + ret0, _ := ret[0].(<-chan struct{}) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Closing indicates an expected call of Closing +func (mr *MockFullNodeMockRecorder) Closing(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Closing", reflect.TypeOf((*MockFullNode)(nil).Closing), arg0) +} + +// CreateBackup mocks base method +func (m *MockFullNode) CreateBackup(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateBackup", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateBackup indicates an expected call of CreateBackup +func (mr *MockFullNodeMockRecorder) CreateBackup(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBackup", reflect.TypeOf((*MockFullNode)(nil).CreateBackup), arg0, arg1) +} + +// Discover mocks base method +func (m *MockFullNode) Discover(arg0 context.Context) (apitypes.OpenRPCDocument, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Discover", arg0) + ret0, _ := ret[0].(apitypes.OpenRPCDocument) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Discover indicates an expected call of Discover +func (mr *MockFullNodeMockRecorder) Discover(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Discover", reflect.TypeOf((*MockFullNode)(nil).Discover), arg0) +} + +// GasEstimateFeeCap mocks base method +func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Message, arg2 int64, arg3 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GasEstimateFeeCap", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GasEstimateFeeCap indicates an expected call of GasEstimateFeeCap +func (mr *MockFullNodeMockRecorder) GasEstimateFeeCap(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateFeeCap", reflect.TypeOf((*MockFullNode)(nil).GasEstimateFeeCap), arg0, arg1, arg2, arg3) +} + +// GasEstimateGasLimit mocks base method +func (m *MockFullNode) GasEstimateGasLimit(arg0 context.Context, arg1 *types.Message, arg2 types.TipSetKey) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GasEstimateGasLimit", arg0, arg1, arg2) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GasEstimateGasLimit indicates an expected call of GasEstimateGasLimit +func (mr *MockFullNodeMockRecorder) GasEstimateGasLimit(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateGasLimit", reflect.TypeOf((*MockFullNode)(nil).GasEstimateGasLimit), arg0, arg1, arg2) +} + +// GasEstimateGasPremium mocks base method +func (m *MockFullNode) GasEstimateGasPremium(arg0 context.Context, arg1 uint64, arg2 address.Address, arg3 int64, arg4 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GasEstimateGasPremium", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GasEstimateGasPremium indicates an expected call of GasEstimateGasPremium +func (mr *MockFullNodeMockRecorder) GasEstimateGasPremium(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateGasPremium", reflect.TypeOf((*MockFullNode)(nil).GasEstimateGasPremium), arg0, arg1, arg2, arg3, arg4) +} + +// GasEstimateMessageGas mocks base method +func (m *MockFullNode) GasEstimateMessageGas(arg0 context.Context, arg1 *types.Message, arg2 *api.MessageSendSpec, arg3 types.TipSetKey) (*types.Message, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GasEstimateMessageGas", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*types.Message) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GasEstimateMessageGas indicates an expected call of GasEstimateMessageGas +func (mr *MockFullNodeMockRecorder) GasEstimateMessageGas(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateMessageGas", reflect.TypeOf((*MockFullNode)(nil).GasEstimateMessageGas), arg0, arg1, arg2, arg3) +} + +// ID mocks base method +func (m *MockFullNode) ID(arg0 context.Context) (peer.ID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ID", arg0) + ret0, _ := ret[0].(peer.ID) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ID indicates an expected call of ID +func (mr *MockFullNodeMockRecorder) ID(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockFullNode)(nil).ID), arg0) +} + +// LogList mocks base method +func (m *MockFullNode) LogList(arg0 context.Context) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LogList", arg0) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// LogList indicates an expected call of LogList +func (mr *MockFullNodeMockRecorder) LogList(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogList", reflect.TypeOf((*MockFullNode)(nil).LogList), arg0) +} + +// LogSetLevel mocks base method +func (m *MockFullNode) LogSetLevel(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LogSetLevel", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// LogSetLevel indicates an expected call of LogSetLevel +func (mr *MockFullNodeMockRecorder) LogSetLevel(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogSetLevel", reflect.TypeOf((*MockFullNode)(nil).LogSetLevel), arg0, arg1, arg2) +} + +// MarketAddBalance mocks base method +func (m *MockFullNode) MarketAddBalance(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarketAddBalance", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MarketAddBalance indicates an expected call of MarketAddBalance +func (mr *MockFullNodeMockRecorder) MarketAddBalance(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketAddBalance", reflect.TypeOf((*MockFullNode)(nil).MarketAddBalance), arg0, arg1, arg2, arg3) +} + +// MarketGetReserved mocks base method +func (m *MockFullNode) MarketGetReserved(arg0 context.Context, arg1 address.Address) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarketGetReserved", arg0, arg1) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MarketGetReserved indicates an expected call of MarketGetReserved +func (mr *MockFullNodeMockRecorder) MarketGetReserved(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketGetReserved", reflect.TypeOf((*MockFullNode)(nil).MarketGetReserved), arg0, arg1) +} + +// MarketReleaseFunds mocks base method +func (m *MockFullNode) MarketReleaseFunds(arg0 context.Context, arg1 address.Address, arg2 big.Int) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarketReleaseFunds", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// MarketReleaseFunds indicates an expected call of MarketReleaseFunds +func (mr *MockFullNodeMockRecorder) MarketReleaseFunds(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketReleaseFunds", reflect.TypeOf((*MockFullNode)(nil).MarketReleaseFunds), arg0, arg1, arg2) +} + +// MarketReserveFunds mocks base method +func (m *MockFullNode) MarketReserveFunds(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarketReserveFunds", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MarketReserveFunds indicates an expected call of MarketReserveFunds +func (mr *MockFullNodeMockRecorder) MarketReserveFunds(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketReserveFunds", reflect.TypeOf((*MockFullNode)(nil).MarketReserveFunds), arg0, arg1, arg2, arg3) +} + +// MarketWithdraw mocks base method +func (m *MockFullNode) MarketWithdraw(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarketWithdraw", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MarketWithdraw indicates an expected call of MarketWithdraw +func (mr *MockFullNodeMockRecorder) MarketWithdraw(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketWithdraw", reflect.TypeOf((*MockFullNode)(nil).MarketWithdraw), arg0, arg1, arg2, arg3) +} + +// MinerCreateBlock mocks base method +func (m *MockFullNode) MinerCreateBlock(arg0 context.Context, arg1 *api.BlockTemplate) (*types.BlockMsg, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MinerCreateBlock", arg0, arg1) + ret0, _ := ret[0].(*types.BlockMsg) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MinerCreateBlock indicates an expected call of MinerCreateBlock +func (mr *MockFullNodeMockRecorder) MinerCreateBlock(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinerCreateBlock", reflect.TypeOf((*MockFullNode)(nil).MinerCreateBlock), arg0, arg1) +} + +// MinerGetBaseInfo mocks base method +func (m *MockFullNode) MinerGetBaseInfo(arg0 context.Context, arg1 address.Address, arg2 abi.ChainEpoch, arg3 types.TipSetKey) (*api.MiningBaseInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MinerGetBaseInfo", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.MiningBaseInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MinerGetBaseInfo indicates an expected call of MinerGetBaseInfo +func (mr *MockFullNodeMockRecorder) MinerGetBaseInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinerGetBaseInfo", reflect.TypeOf((*MockFullNode)(nil).MinerGetBaseInfo), arg0, arg1, arg2, arg3) +} + +// MpoolBatchPush mocks base method +func (m *MockFullNode) MpoolBatchPush(arg0 context.Context, arg1 []*types.SignedMessage) ([]cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolBatchPush", arg0, arg1) + ret0, _ := ret[0].([]cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolBatchPush indicates an expected call of MpoolBatchPush +func (mr *MockFullNodeMockRecorder) MpoolBatchPush(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPush", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPush), arg0, arg1) +} + +// MpoolBatchPushMessage mocks base method +func (m *MockFullNode) MpoolBatchPushMessage(arg0 context.Context, arg1 []*types.Message, arg2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolBatchPushMessage", arg0, arg1, arg2) + ret0, _ := ret[0].([]*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolBatchPushMessage indicates an expected call of MpoolBatchPushMessage +func (mr *MockFullNodeMockRecorder) MpoolBatchPushMessage(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPushMessage", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPushMessage), arg0, arg1, arg2) +} + +// MpoolBatchPushUntrusted mocks base method +func (m *MockFullNode) MpoolBatchPushUntrusted(arg0 context.Context, arg1 []*types.SignedMessage) ([]cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolBatchPushUntrusted", arg0, arg1) + ret0, _ := ret[0].([]cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolBatchPushUntrusted indicates an expected call of MpoolBatchPushUntrusted +func (mr *MockFullNodeMockRecorder) MpoolBatchPushUntrusted(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPushUntrusted", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPushUntrusted), arg0, arg1) +} + +// MpoolClear mocks base method +func (m *MockFullNode) MpoolClear(arg0 context.Context, arg1 bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolClear", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// MpoolClear indicates an expected call of MpoolClear +func (mr *MockFullNodeMockRecorder) MpoolClear(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolClear", reflect.TypeOf((*MockFullNode)(nil).MpoolClear), arg0, arg1) +} + +// MpoolGetConfig mocks base method +func (m *MockFullNode) MpoolGetConfig(arg0 context.Context) (*types.MpoolConfig, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolGetConfig", arg0) + ret0, _ := ret[0].(*types.MpoolConfig) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolGetConfig indicates an expected call of MpoolGetConfig +func (mr *MockFullNodeMockRecorder) MpoolGetConfig(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolGetConfig", reflect.TypeOf((*MockFullNode)(nil).MpoolGetConfig), arg0) +} + +// MpoolGetNonce mocks base method +func (m *MockFullNode) MpoolGetNonce(arg0 context.Context, arg1 address.Address) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolGetNonce", arg0, arg1) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolGetNonce indicates an expected call of MpoolGetNonce +func (mr *MockFullNodeMockRecorder) MpoolGetNonce(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolGetNonce", reflect.TypeOf((*MockFullNode)(nil).MpoolGetNonce), arg0, arg1) +} + +// MpoolPending mocks base method +func (m *MockFullNode) MpoolPending(arg0 context.Context, arg1 types.TipSetKey) ([]*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolPending", arg0, arg1) + ret0, _ := ret[0].([]*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolPending indicates an expected call of MpoolPending +func (mr *MockFullNodeMockRecorder) MpoolPending(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPending", reflect.TypeOf((*MockFullNode)(nil).MpoolPending), arg0, arg1) +} + +// MpoolPush mocks base method +func (m *MockFullNode) MpoolPush(arg0 context.Context, arg1 *types.SignedMessage) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolPush", arg0, arg1) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolPush indicates an expected call of MpoolPush +func (mr *MockFullNodeMockRecorder) MpoolPush(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPush", reflect.TypeOf((*MockFullNode)(nil).MpoolPush), arg0, arg1) +} + +// MpoolPushMessage mocks base method +func (m *MockFullNode) MpoolPushMessage(arg0 context.Context, arg1 *types.Message, arg2 *api.MessageSendSpec) (*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolPushMessage", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolPushMessage indicates an expected call of MpoolPushMessage +func (mr *MockFullNodeMockRecorder) MpoolPushMessage(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPushMessage", reflect.TypeOf((*MockFullNode)(nil).MpoolPushMessage), arg0, arg1, arg2) +} + +// MpoolPushUntrusted mocks base method +func (m *MockFullNode) MpoolPushUntrusted(arg0 context.Context, arg1 *types.SignedMessage) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolPushUntrusted", arg0, arg1) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolPushUntrusted indicates an expected call of MpoolPushUntrusted +func (mr *MockFullNodeMockRecorder) MpoolPushUntrusted(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPushUntrusted", reflect.TypeOf((*MockFullNode)(nil).MpoolPushUntrusted), arg0, arg1) +} + +// MpoolSelect mocks base method +func (m *MockFullNode) MpoolSelect(arg0 context.Context, arg1 types.TipSetKey, arg2 float64) ([]*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolSelect", arg0, arg1, arg2) + ret0, _ := ret[0].([]*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolSelect indicates an expected call of MpoolSelect +func (mr *MockFullNodeMockRecorder) MpoolSelect(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSelect", reflect.TypeOf((*MockFullNode)(nil).MpoolSelect), arg0, arg1, arg2) +} + +// MpoolSetConfig mocks base method +func (m *MockFullNode) MpoolSetConfig(arg0 context.Context, arg1 *types.MpoolConfig) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolSetConfig", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// MpoolSetConfig indicates an expected call of MpoolSetConfig +func (mr *MockFullNodeMockRecorder) MpoolSetConfig(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSetConfig", reflect.TypeOf((*MockFullNode)(nil).MpoolSetConfig), arg0, arg1) +} + +// MpoolSub mocks base method +func (m *MockFullNode) MpoolSub(arg0 context.Context) (<-chan api.MpoolUpdate, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolSub", arg0) + ret0, _ := ret[0].(<-chan api.MpoolUpdate) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolSub indicates an expected call of MpoolSub +func (mr *MockFullNodeMockRecorder) MpoolSub(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSub", reflect.TypeOf((*MockFullNode)(nil).MpoolSub), arg0) +} + +// MsigAddApprove mocks base method +func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address, arg6 bool) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigAddApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigAddApprove indicates an expected call of MsigAddApprove +func (mr *MockFullNodeMockRecorder) MsigAddApprove(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddApprove", reflect.TypeOf((*MockFullNode)(nil).MsigAddApprove), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// MsigAddCancel mocks base method +func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4 address.Address, arg5 bool) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigAddCancel", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigAddCancel indicates an expected call of MsigAddCancel +func (mr *MockFullNodeMockRecorder) MsigAddCancel(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddCancel", reflect.TypeOf((*MockFullNode)(nil).MsigAddCancel), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// MsigAddPropose mocks base method +func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigAddPropose", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigAddPropose indicates an expected call of MsigAddPropose +func (mr *MockFullNodeMockRecorder) MsigAddPropose(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddPropose", reflect.TypeOf((*MockFullNode)(nil).MsigAddPropose), arg0, arg1, arg2, arg3, arg4) +} + +// MsigApprove mocks base method +func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigApprove", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigApprove indicates an expected call of MsigApprove +func (mr *MockFullNodeMockRecorder) MsigApprove(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigApprove", reflect.TypeOf((*MockFullNode)(nil).MsigApprove), arg0, arg1, arg2, arg3) +} + +// MsigApproveTxnHash mocks base method +func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3, arg4 address.Address, arg5 big.Int, arg6 address.Address, arg7 uint64, arg8 []byte) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigApproveTxnHash", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigApproveTxnHash indicates an expected call of MsigApproveTxnHash +func (mr *MockFullNodeMockRecorder) MsigApproveTxnHash(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigApproveTxnHash", reflect.TypeOf((*MockFullNode)(nil).MsigApproveTxnHash), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) +} + +// MsigCancel mocks base method +func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address, arg4 big.Int, arg5 address.Address, arg6 uint64, arg7 []byte) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigCancel", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigCancel indicates an expected call of MsigCancel +func (mr *MockFullNodeMockRecorder) MsigCancel(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigCancel", reflect.TypeOf((*MockFullNode)(nil).MsigCancel), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +} + +// MsigCreate mocks base method +func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []address.Address, arg3 abi.ChainEpoch, arg4 big.Int, arg5 address.Address, arg6 big.Int) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigCreate", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigCreate indicates an expected call of MsigCreate +func (mr *MockFullNodeMockRecorder) MsigCreate(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigCreate", reflect.TypeOf((*MockFullNode)(nil).MsigCreate), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// MsigGetAvailableBalance mocks base method +func (m *MockFullNode) MsigGetAvailableBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigGetAvailableBalance", arg0, arg1, arg2) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigGetAvailableBalance indicates an expected call of MsigGetAvailableBalance +func (mr *MockFullNodeMockRecorder) MsigGetAvailableBalance(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetAvailableBalance", reflect.TypeOf((*MockFullNode)(nil).MsigGetAvailableBalance), arg0, arg1, arg2) +} + +// MsigGetPending mocks base method +func (m *MockFullNode) MsigGetPending(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]*api.MsigTransaction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigGetPending", arg0, arg1, arg2) + ret0, _ := ret[0].([]*api.MsigTransaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigGetPending indicates an expected call of MsigGetPending +func (mr *MockFullNodeMockRecorder) MsigGetPending(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetPending", reflect.TypeOf((*MockFullNode)(nil).MsigGetPending), arg0, arg1, arg2) +} + +// MsigGetVested mocks base method +func (m *MockFullNode) MsigGetVested(arg0 context.Context, arg1 address.Address, arg2, arg3 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigGetVested", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigGetVested indicates an expected call of MsigGetVested +func (mr *MockFullNodeMockRecorder) MsigGetVested(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetVested", reflect.TypeOf((*MockFullNode)(nil).MsigGetVested), arg0, arg1, arg2, arg3) +} + +// MsigGetVestingSchedule mocks base method +func (m *MockFullNode) MsigGetVestingSchedule(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MsigVesting, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigGetVestingSchedule", arg0, arg1, arg2) + ret0, _ := ret[0].(api.MsigVesting) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigGetVestingSchedule indicates an expected call of MsigGetVestingSchedule +func (mr *MockFullNodeMockRecorder) MsigGetVestingSchedule(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetVestingSchedule", reflect.TypeOf((*MockFullNode)(nil).MsigGetVestingSchedule), arg0, arg1, arg2) +} + +// MsigPropose mocks base method +func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int, arg4 address.Address, arg5 uint64, arg6 []byte) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigPropose", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigPropose indicates an expected call of MsigPropose +func (mr *MockFullNodeMockRecorder) MsigPropose(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigPropose", reflect.TypeOf((*MockFullNode)(nil).MsigPropose), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// MsigRemoveSigner mocks base method +func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigRemoveSigner", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigRemoveSigner indicates an expected call of MsigRemoveSigner +func (mr *MockFullNodeMockRecorder) MsigRemoveSigner(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigRemoveSigner", reflect.TypeOf((*MockFullNode)(nil).MsigRemoveSigner), arg0, arg1, arg2, arg3, arg4) +} + +// MsigSwapApprove mocks base method +func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5, arg6 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigSwapApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigSwapApprove indicates an expected call of MsigSwapApprove +func (mr *MockFullNodeMockRecorder) MsigSwapApprove(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapApprove", reflect.TypeOf((*MockFullNode)(nil).MsigSwapApprove), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// MsigSwapCancel mocks base method +func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigSwapCancel", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigSwapCancel indicates an expected call of MsigSwapCancel +func (mr *MockFullNodeMockRecorder) MsigSwapCancel(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapCancel", reflect.TypeOf((*MockFullNode)(nil).MsigSwapCancel), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// MsigSwapPropose mocks base method +func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, arg4 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigSwapPropose", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigSwapPropose indicates an expected call of MsigSwapPropose +func (mr *MockFullNodeMockRecorder) MsigSwapPropose(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapPropose", reflect.TypeOf((*MockFullNode)(nil).MsigSwapPropose), arg0, arg1, arg2, arg3, arg4) +} + +// NetAddrsListen mocks base method +func (m *MockFullNode) NetAddrsListen(arg0 context.Context) (peer.AddrInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetAddrsListen", arg0) + ret0, _ := ret[0].(peer.AddrInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetAddrsListen indicates an expected call of NetAddrsListen +func (mr *MockFullNodeMockRecorder) NetAddrsListen(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAddrsListen", reflect.TypeOf((*MockFullNode)(nil).NetAddrsListen), arg0) +} + +// NetAgentVersion mocks base method +func (m *MockFullNode) NetAgentVersion(arg0 context.Context, arg1 peer.ID) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetAgentVersion", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetAgentVersion indicates an expected call of NetAgentVersion +func (mr *MockFullNodeMockRecorder) NetAgentVersion(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAgentVersion", reflect.TypeOf((*MockFullNode)(nil).NetAgentVersion), arg0, arg1) +} + +// NetAutoNatStatus mocks base method +func (m *MockFullNode) NetAutoNatStatus(arg0 context.Context) (api.NatInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetAutoNatStatus", arg0) + ret0, _ := ret[0].(api.NatInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetAutoNatStatus indicates an expected call of NetAutoNatStatus +func (mr *MockFullNodeMockRecorder) NetAutoNatStatus(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAutoNatStatus", reflect.TypeOf((*MockFullNode)(nil).NetAutoNatStatus), arg0) +} + +// NetBandwidthStats mocks base method +func (m *MockFullNode) NetBandwidthStats(arg0 context.Context) (metrics.Stats, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBandwidthStats", arg0) + ret0, _ := ret[0].(metrics.Stats) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetBandwidthStats indicates an expected call of NetBandwidthStats +func (mr *MockFullNodeMockRecorder) NetBandwidthStats(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStats", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStats), arg0) +} + +// NetBandwidthStatsByPeer mocks base method +func (m *MockFullNode) NetBandwidthStatsByPeer(arg0 context.Context) (map[string]metrics.Stats, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBandwidthStatsByPeer", arg0) + ret0, _ := ret[0].(map[string]metrics.Stats) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetBandwidthStatsByPeer indicates an expected call of NetBandwidthStatsByPeer +func (mr *MockFullNodeMockRecorder) NetBandwidthStatsByPeer(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStatsByPeer", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStatsByPeer), arg0) +} + +// NetBandwidthStatsByProtocol mocks base method +func (m *MockFullNode) NetBandwidthStatsByProtocol(arg0 context.Context) (map[protocol.ID]metrics.Stats, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBandwidthStatsByProtocol", arg0) + ret0, _ := ret[0].(map[protocol.ID]metrics.Stats) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetBandwidthStatsByProtocol indicates an expected call of NetBandwidthStatsByProtocol +func (mr *MockFullNodeMockRecorder) NetBandwidthStatsByProtocol(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStatsByProtocol", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStatsByProtocol), arg0) +} + +// NetBlockAdd mocks base method +func (m *MockFullNode) NetBlockAdd(arg0 context.Context, arg1 api.NetBlockList) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBlockAdd", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetBlockAdd indicates an expected call of NetBlockAdd +func (mr *MockFullNodeMockRecorder) NetBlockAdd(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockAdd", reflect.TypeOf((*MockFullNode)(nil).NetBlockAdd), arg0, arg1) +} + +// NetBlockList mocks base method +func (m *MockFullNode) NetBlockList(arg0 context.Context) (api.NetBlockList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBlockList", arg0) + ret0, _ := ret[0].(api.NetBlockList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetBlockList indicates an expected call of NetBlockList +func (mr *MockFullNodeMockRecorder) NetBlockList(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockList", reflect.TypeOf((*MockFullNode)(nil).NetBlockList), arg0) +} + +// NetBlockRemove mocks base method +func (m *MockFullNode) NetBlockRemove(arg0 context.Context, arg1 api.NetBlockList) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBlockRemove", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetBlockRemove indicates an expected call of NetBlockRemove +func (mr *MockFullNodeMockRecorder) NetBlockRemove(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockRemove", reflect.TypeOf((*MockFullNode)(nil).NetBlockRemove), arg0, arg1) +} + +// NetConnect mocks base method +func (m *MockFullNode) NetConnect(arg0 context.Context, arg1 peer.AddrInfo) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetConnect", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetConnect indicates an expected call of NetConnect +func (mr *MockFullNodeMockRecorder) NetConnect(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetConnect", reflect.TypeOf((*MockFullNode)(nil).NetConnect), arg0, arg1) +} + +// NetConnectedness mocks base method +func (m *MockFullNode) NetConnectedness(arg0 context.Context, arg1 peer.ID) (network0.Connectedness, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetConnectedness", arg0, arg1) + ret0, _ := ret[0].(network0.Connectedness) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetConnectedness indicates an expected call of NetConnectedness +func (mr *MockFullNodeMockRecorder) NetConnectedness(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetConnectedness", reflect.TypeOf((*MockFullNode)(nil).NetConnectedness), arg0, arg1) +} + +// NetDisconnect mocks base method +func (m *MockFullNode) NetDisconnect(arg0 context.Context, arg1 peer.ID) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetDisconnect", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetDisconnect indicates an expected call of NetDisconnect +func (mr *MockFullNodeMockRecorder) NetDisconnect(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetDisconnect", reflect.TypeOf((*MockFullNode)(nil).NetDisconnect), arg0, arg1) +} + +// NetFindPeer mocks base method +func (m *MockFullNode) NetFindPeer(arg0 context.Context, arg1 peer.ID) (peer.AddrInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetFindPeer", arg0, arg1) + ret0, _ := ret[0].(peer.AddrInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetFindPeer indicates an expected call of NetFindPeer +func (mr *MockFullNodeMockRecorder) NetFindPeer(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetFindPeer", reflect.TypeOf((*MockFullNode)(nil).NetFindPeer), arg0, arg1) +} + +// NetPeerInfo mocks base method +func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetPeerInfo", arg0, arg1) + ret0, _ := ret[0].(*api.ExtendedPeerInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetPeerInfo indicates an expected call of NetPeerInfo +func (mr *MockFullNodeMockRecorder) NetPeerInfo(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeerInfo", reflect.TypeOf((*MockFullNode)(nil).NetPeerInfo), arg0, arg1) +} + +// NetPeers mocks base method +func (m *MockFullNode) NetPeers(arg0 context.Context) ([]peer.AddrInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetPeers", arg0) + ret0, _ := ret[0].([]peer.AddrInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetPeers indicates an expected call of NetPeers +func (mr *MockFullNodeMockRecorder) NetPeers(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeers", reflect.TypeOf((*MockFullNode)(nil).NetPeers), arg0) +} + +// NetPubsubScores mocks base method +func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetPubsubScores", arg0) + ret0, _ := ret[0].([]api.PubsubScore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetPubsubScores indicates an expected call of NetPubsubScores +func (mr *MockFullNodeMockRecorder) NetPubsubScores(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0) +} + +// PaychAllocateLane mocks base method +func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Address) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychAllocateLane", arg0, arg1) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychAllocateLane indicates an expected call of PaychAllocateLane +func (mr *MockFullNodeMockRecorder) PaychAllocateLane(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAllocateLane", reflect.TypeOf((*MockFullNode)(nil).PaychAllocateLane), arg0, arg1) +} + +// PaychAvailableFunds mocks base method +func (m *MockFullNode) PaychAvailableFunds(arg0 context.Context, arg1 address.Address) (*api.ChannelAvailableFunds, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychAvailableFunds", arg0, arg1) + ret0, _ := ret[0].(*api.ChannelAvailableFunds) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychAvailableFunds indicates an expected call of PaychAvailableFunds +func (mr *MockFullNodeMockRecorder) PaychAvailableFunds(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAvailableFunds", reflect.TypeOf((*MockFullNode)(nil).PaychAvailableFunds), arg0, arg1) +} + +// PaychAvailableFundsByFromTo mocks base method +func (m *MockFullNode) PaychAvailableFundsByFromTo(arg0 context.Context, arg1, arg2 address.Address) (*api.ChannelAvailableFunds, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychAvailableFundsByFromTo", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.ChannelAvailableFunds) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychAvailableFundsByFromTo indicates an expected call of PaychAvailableFundsByFromTo +func (mr *MockFullNodeMockRecorder) PaychAvailableFundsByFromTo(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAvailableFundsByFromTo", reflect.TypeOf((*MockFullNode)(nil).PaychAvailableFundsByFromTo), arg0, arg1, arg2) +} + +// PaychCollect mocks base method +func (m *MockFullNode) PaychCollect(arg0 context.Context, arg1 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychCollect", arg0, arg1) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychCollect indicates an expected call of PaychCollect +func (mr *MockFullNodeMockRecorder) PaychCollect(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychCollect", reflect.TypeOf((*MockFullNode)(nil).PaychCollect), arg0, arg1) +} + +// PaychGet mocks base method +func (m *MockFullNode) PaychGet(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (*api.ChannelInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychGet", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.ChannelInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychGet indicates an expected call of PaychGet +func (mr *MockFullNodeMockRecorder) PaychGet(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychGet", reflect.TypeOf((*MockFullNode)(nil).PaychGet), arg0, arg1, arg2, arg3) +} + +// PaychGetWaitReady mocks base method +func (m *MockFullNode) PaychGetWaitReady(arg0 context.Context, arg1 cid.Cid) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychGetWaitReady", arg0, arg1) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychGetWaitReady indicates an expected call of PaychGetWaitReady +func (mr *MockFullNodeMockRecorder) PaychGetWaitReady(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychGetWaitReady", reflect.TypeOf((*MockFullNode)(nil).PaychGetWaitReady), arg0, arg1) +} + +// PaychList mocks base method +func (m *MockFullNode) PaychList(arg0 context.Context) ([]address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychList", arg0) + ret0, _ := ret[0].([]address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychList indicates an expected call of PaychList +func (mr *MockFullNodeMockRecorder) PaychList(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychList", reflect.TypeOf((*MockFullNode)(nil).PaychList), arg0) +} + +// PaychNewPayment mocks base method +func (m *MockFullNode) PaychNewPayment(arg0 context.Context, arg1, arg2 address.Address, arg3 []api.VoucherSpec) (*api.PaymentInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychNewPayment", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.PaymentInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychNewPayment indicates an expected call of PaychNewPayment +func (mr *MockFullNodeMockRecorder) PaychNewPayment(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychNewPayment", reflect.TypeOf((*MockFullNode)(nil).PaychNewPayment), arg0, arg1, arg2, arg3) +} + +// PaychSettle mocks base method +func (m *MockFullNode) PaychSettle(arg0 context.Context, arg1 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychSettle", arg0, arg1) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychSettle indicates an expected call of PaychSettle +func (mr *MockFullNodeMockRecorder) PaychSettle(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychSettle", reflect.TypeOf((*MockFullNode)(nil).PaychSettle), arg0, arg1) +} + +// PaychStatus mocks base method +func (m *MockFullNode) PaychStatus(arg0 context.Context, arg1 address.Address) (*api.PaychStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychStatus", arg0, arg1) + ret0, _ := ret[0].(*api.PaychStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychStatus indicates an expected call of PaychStatus +func (mr *MockFullNodeMockRecorder) PaychStatus(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychStatus", reflect.TypeOf((*MockFullNode)(nil).PaychStatus), arg0, arg1) +} + +// PaychVoucherAdd mocks base method +func (m *MockFullNode) PaychVoucherAdd(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3 []byte, arg4 big.Int) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherAdd", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychVoucherAdd indicates an expected call of PaychVoucherAdd +func (mr *MockFullNodeMockRecorder) PaychVoucherAdd(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherAdd", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherAdd), arg0, arg1, arg2, arg3, arg4) +} + +// PaychVoucherCheckSpendable mocks base method +func (m *MockFullNode) PaychVoucherCheckSpendable(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3, arg4 []byte) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherCheckSpendable", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychVoucherCheckSpendable indicates an expected call of PaychVoucherCheckSpendable +func (mr *MockFullNodeMockRecorder) PaychVoucherCheckSpendable(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCheckSpendable", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCheckSpendable), arg0, arg1, arg2, arg3, arg4) +} + +// PaychVoucherCheckValid mocks base method +func (m *MockFullNode) PaychVoucherCheckValid(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherCheckValid", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// PaychVoucherCheckValid indicates an expected call of PaychVoucherCheckValid +func (mr *MockFullNodeMockRecorder) PaychVoucherCheckValid(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCheckValid", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCheckValid), arg0, arg1, arg2) +} + +// PaychVoucherCreate mocks base method +func (m *MockFullNode) PaychVoucherCreate(arg0 context.Context, arg1 address.Address, arg2 big.Int, arg3 uint64) (*api.VoucherCreateResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherCreate", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.VoucherCreateResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychVoucherCreate indicates an expected call of PaychVoucherCreate +func (mr *MockFullNodeMockRecorder) PaychVoucherCreate(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCreate", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCreate), arg0, arg1, arg2, arg3) +} + +// PaychVoucherList mocks base method +func (m *MockFullNode) PaychVoucherList(arg0 context.Context, arg1 address.Address) ([]*paych.SignedVoucher, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherList", arg0, arg1) + ret0, _ := ret[0].([]*paych.SignedVoucher) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychVoucherList indicates an expected call of PaychVoucherList +func (mr *MockFullNodeMockRecorder) PaychVoucherList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherList", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherList), arg0, arg1) +} + +// PaychVoucherSubmit mocks base method +func (m *MockFullNode) PaychVoucherSubmit(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3, arg4 []byte) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherSubmit", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychVoucherSubmit indicates an expected call of PaychVoucherSubmit +func (mr *MockFullNodeMockRecorder) PaychVoucherSubmit(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherSubmit", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherSubmit), arg0, arg1, arg2, arg3, arg4) +} + +// Session mocks base method +func (m *MockFullNode) Session(arg0 context.Context) (uuid.UUID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Session", arg0) + ret0, _ := ret[0].(uuid.UUID) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Session indicates an expected call of Session +func (mr *MockFullNodeMockRecorder) Session(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Session", reflect.TypeOf((*MockFullNode)(nil).Session), arg0) +} + +// Shutdown mocks base method +func (m *MockFullNode) Shutdown(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Shutdown", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Shutdown indicates an expected call of Shutdown +func (mr *MockFullNodeMockRecorder) Shutdown(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shutdown", reflect.TypeOf((*MockFullNode)(nil).Shutdown), arg0) +} + +// StateAccountKey mocks base method +func (m *MockFullNode) StateAccountKey(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateAccountKey", arg0, arg1, arg2) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateAccountKey indicates an expected call of StateAccountKey +func (mr *MockFullNodeMockRecorder) StateAccountKey(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateAccountKey", reflect.TypeOf((*MockFullNode)(nil).StateAccountKey), arg0, arg1, arg2) +} + +// StateAllMinerFaults mocks base method +func (m *MockFullNode) StateAllMinerFaults(arg0 context.Context, arg1 abi.ChainEpoch, arg2 types.TipSetKey) ([]*api.Fault, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateAllMinerFaults", arg0, arg1, arg2) + ret0, _ := ret[0].([]*api.Fault) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateAllMinerFaults indicates an expected call of StateAllMinerFaults +func (mr *MockFullNodeMockRecorder) StateAllMinerFaults(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateAllMinerFaults", reflect.TypeOf((*MockFullNode)(nil).StateAllMinerFaults), arg0, arg1, arg2) +} + +// StateCall mocks base method +func (m *MockFullNode) StateCall(arg0 context.Context, arg1 *types.Message, arg2 types.TipSetKey) (*api.InvocResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateCall", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.InvocResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateCall indicates an expected call of StateCall +func (mr *MockFullNodeMockRecorder) StateCall(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCall", reflect.TypeOf((*MockFullNode)(nil).StateCall), arg0, arg1, arg2) +} + +// StateChangedActors mocks base method +func (m *MockFullNode) StateChangedActors(arg0 context.Context, arg1, arg2 cid.Cid) (map[string]types.Actor, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateChangedActors", arg0, arg1, arg2) + ret0, _ := ret[0].(map[string]types.Actor) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateChangedActors indicates an expected call of StateChangedActors +func (mr *MockFullNodeMockRecorder) StateChangedActors(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateChangedActors", reflect.TypeOf((*MockFullNode)(nil).StateChangedActors), arg0, arg1, arg2) +} + +// StateCirculatingSupply mocks base method +func (m *MockFullNode) StateCirculatingSupply(arg0 context.Context, arg1 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateCirculatingSupply", arg0, arg1) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateCirculatingSupply indicates an expected call of StateCirculatingSupply +func (mr *MockFullNodeMockRecorder) StateCirculatingSupply(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCirculatingSupply", reflect.TypeOf((*MockFullNode)(nil).StateCirculatingSupply), arg0, arg1) +} + +// StateCompute mocks base method +func (m *MockFullNode) StateCompute(arg0 context.Context, arg1 abi.ChainEpoch, arg2 []*types.Message, arg3 types.TipSetKey) (*api.ComputeStateOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateCompute", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.ComputeStateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateCompute indicates an expected call of StateCompute +func (mr *MockFullNodeMockRecorder) StateCompute(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCompute", reflect.TypeOf((*MockFullNode)(nil).StateCompute), arg0, arg1, arg2, arg3) +} + +// StateDealProviderCollateralBounds mocks base method +func (m *MockFullNode) StateDealProviderCollateralBounds(arg0 context.Context, arg1 abi.PaddedPieceSize, arg2 bool, arg3 types.TipSetKey) (api.DealCollateralBounds, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateDealProviderCollateralBounds", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(api.DealCollateralBounds) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateDealProviderCollateralBounds indicates an expected call of StateDealProviderCollateralBounds +func (mr *MockFullNodeMockRecorder) StateDealProviderCollateralBounds(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateDealProviderCollateralBounds", reflect.TypeOf((*MockFullNode)(nil).StateDealProviderCollateralBounds), arg0, arg1, arg2, arg3) +} + +// StateDecodeParams mocks base method +func (m *MockFullNode) StateDecodeParams(arg0 context.Context, arg1 address.Address, arg2 abi.MethodNum, arg3 []byte, arg4 types.TipSetKey) (interface{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateDecodeParams", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(interface{}) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateDecodeParams indicates an expected call of StateDecodeParams +func (mr *MockFullNodeMockRecorder) StateDecodeParams(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateDecodeParams", reflect.TypeOf((*MockFullNode)(nil).StateDecodeParams), arg0, arg1, arg2, arg3, arg4) +} + +// StateGetActor mocks base method +func (m *MockFullNode) StateGetActor(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*types.Actor, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateGetActor", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.Actor) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateGetActor indicates an expected call of StateGetActor +func (mr *MockFullNodeMockRecorder) StateGetActor(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetActor", reflect.TypeOf((*MockFullNode)(nil).StateGetActor), arg0, arg1, arg2) +} + +// StateGetReceipt mocks base method +func (m *MockFullNode) StateGetReceipt(arg0 context.Context, arg1 cid.Cid, arg2 types.TipSetKey) (*types.MessageReceipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateGetReceipt", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.MessageReceipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateGetReceipt indicates an expected call of StateGetReceipt +func (mr *MockFullNodeMockRecorder) StateGetReceipt(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetReceipt", reflect.TypeOf((*MockFullNode)(nil).StateGetReceipt), arg0, arg1, arg2) +} + +// StateListActors mocks base method +func (m *MockFullNode) StateListActors(arg0 context.Context, arg1 types.TipSetKey) ([]address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateListActors", arg0, arg1) + ret0, _ := ret[0].([]address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateListActors indicates an expected call of StateListActors +func (mr *MockFullNodeMockRecorder) StateListActors(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListActors", reflect.TypeOf((*MockFullNode)(nil).StateListActors), arg0, arg1) +} + +// StateListMessages mocks base method +func (m *MockFullNode) StateListMessages(arg0 context.Context, arg1 *api.MessageMatch, arg2 types.TipSetKey, arg3 abi.ChainEpoch) ([]cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateListMessages", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].([]cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateListMessages indicates an expected call of StateListMessages +func (mr *MockFullNodeMockRecorder) StateListMessages(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListMessages", reflect.TypeOf((*MockFullNode)(nil).StateListMessages), arg0, arg1, arg2, arg3) +} + +// StateListMiners mocks base method +func (m *MockFullNode) StateListMiners(arg0 context.Context, arg1 types.TipSetKey) ([]address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateListMiners", arg0, arg1) + ret0, _ := ret[0].([]address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateListMiners indicates an expected call of StateListMiners +func (mr *MockFullNodeMockRecorder) StateListMiners(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListMiners", reflect.TypeOf((*MockFullNode)(nil).StateListMiners), arg0, arg1) +} + +// StateLookupID mocks base method +func (m *MockFullNode) StateLookupID(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateLookupID", arg0, arg1, arg2) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateLookupID indicates an expected call of StateLookupID +func (mr *MockFullNodeMockRecorder) StateLookupID(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateLookupID", reflect.TypeOf((*MockFullNode)(nil).StateLookupID), arg0, arg1, arg2) +} + +// StateMarketBalance mocks base method +func (m *MockFullNode) StateMarketBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MarketBalance, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMarketBalance", arg0, arg1, arg2) + ret0, _ := ret[0].(api.MarketBalance) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMarketBalance indicates an expected call of StateMarketBalance +func (mr *MockFullNodeMockRecorder) StateMarketBalance(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketBalance", reflect.TypeOf((*MockFullNode)(nil).StateMarketBalance), arg0, arg1, arg2) +} + +// StateMarketDeals mocks base method +func (m *MockFullNode) StateMarketDeals(arg0 context.Context, arg1 types.TipSetKey) (map[string]api.MarketDeal, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMarketDeals", arg0, arg1) + ret0, _ := ret[0].(map[string]api.MarketDeal) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMarketDeals indicates an expected call of StateMarketDeals +func (mr *MockFullNodeMockRecorder) StateMarketDeals(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketDeals", reflect.TypeOf((*MockFullNode)(nil).StateMarketDeals), arg0, arg1) +} + +// StateMarketParticipants mocks base method +func (m *MockFullNode) StateMarketParticipants(arg0 context.Context, arg1 types.TipSetKey) (map[string]api.MarketBalance, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMarketParticipants", arg0, arg1) + ret0, _ := ret[0].(map[string]api.MarketBalance) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMarketParticipants indicates an expected call of StateMarketParticipants +func (mr *MockFullNodeMockRecorder) StateMarketParticipants(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketParticipants", reflect.TypeOf((*MockFullNode)(nil).StateMarketParticipants), arg0, arg1) +} + +// StateMarketStorageDeal mocks base method +func (m *MockFullNode) StateMarketStorageDeal(arg0 context.Context, arg1 abi.DealID, arg2 types.TipSetKey) (*api.MarketDeal, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMarketStorageDeal", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.MarketDeal) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMarketStorageDeal indicates an expected call of StateMarketStorageDeal +func (mr *MockFullNodeMockRecorder) StateMarketStorageDeal(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketStorageDeal", reflect.TypeOf((*MockFullNode)(nil).StateMarketStorageDeal), arg0, arg1, arg2) +} + +// StateMinerActiveSectors mocks base method +func (m *MockFullNode) StateMinerActiveSectors(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerActiveSectors", arg0, arg1, arg2) + ret0, _ := ret[0].([]*miner.SectorOnChainInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerActiveSectors indicates an expected call of StateMinerActiveSectors +func (mr *MockFullNodeMockRecorder) StateMinerActiveSectors(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerActiveSectors", reflect.TypeOf((*MockFullNode)(nil).StateMinerActiveSectors), arg0, arg1, arg2) +} + +// StateMinerAvailableBalance mocks base method +func (m *MockFullNode) StateMinerAvailableBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerAvailableBalance", arg0, arg1, arg2) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerAvailableBalance indicates an expected call of StateMinerAvailableBalance +func (mr *MockFullNodeMockRecorder) StateMinerAvailableBalance(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerAvailableBalance", reflect.TypeOf((*MockFullNode)(nil).StateMinerAvailableBalance), arg0, arg1, arg2) +} + +// StateMinerDeadlines mocks base method +func (m *MockFullNode) StateMinerDeadlines(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]api.Deadline, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerDeadlines", arg0, arg1, arg2) + ret0, _ := ret[0].([]api.Deadline) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerDeadlines indicates an expected call of StateMinerDeadlines +func (mr *MockFullNodeMockRecorder) StateMinerDeadlines(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerDeadlines", reflect.TypeOf((*MockFullNode)(nil).StateMinerDeadlines), arg0, arg1, arg2) +} + +// StateMinerFaults mocks base method +func (m *MockFullNode) StateMinerFaults(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (bitfield.BitField, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerFaults", arg0, arg1, arg2) + ret0, _ := ret[0].(bitfield.BitField) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerFaults indicates an expected call of StateMinerFaults +func (mr *MockFullNodeMockRecorder) StateMinerFaults(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerFaults", reflect.TypeOf((*MockFullNode)(nil).StateMinerFaults), arg0, arg1, arg2) +} + +// StateMinerInfo mocks base method +func (m *MockFullNode) StateMinerInfo(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (miner.MinerInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerInfo", arg0, arg1, arg2) + ret0, _ := ret[0].(miner.MinerInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerInfo indicates an expected call of StateMinerInfo +func (mr *MockFullNodeMockRecorder) StateMinerInfo(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInfo", reflect.TypeOf((*MockFullNode)(nil).StateMinerInfo), arg0, arg1, arg2) +} + +// StateMinerInitialPledgeCollateral mocks base method +func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerInitialPledgeCollateral", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerInitialPledgeCollateral indicates an expected call of StateMinerInitialPledgeCollateral +func (mr *MockFullNodeMockRecorder) StateMinerInitialPledgeCollateral(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInitialPledgeCollateral", reflect.TypeOf((*MockFullNode)(nil).StateMinerInitialPledgeCollateral), arg0, arg1, arg2, arg3) +} + +// StateMinerPartitions mocks base method +func (m *MockFullNode) StateMinerPartitions(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 types.TipSetKey) ([]api.Partition, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerPartitions", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].([]api.Partition) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerPartitions indicates an expected call of StateMinerPartitions +func (mr *MockFullNodeMockRecorder) StateMinerPartitions(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPartitions", reflect.TypeOf((*MockFullNode)(nil).StateMinerPartitions), arg0, arg1, arg2, arg3) +} + +// StateMinerPower mocks base method +func (m *MockFullNode) StateMinerPower(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*api.MinerPower, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerPower", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.MinerPower) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerPower indicates an expected call of StateMinerPower +func (mr *MockFullNodeMockRecorder) StateMinerPower(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPower", reflect.TypeOf((*MockFullNode)(nil).StateMinerPower), arg0, arg1, arg2) +} + +// StateMinerPreCommitDepositForPower mocks base method +func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerPreCommitDepositForPower", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerPreCommitDepositForPower indicates an expected call of StateMinerPreCommitDepositForPower +func (mr *MockFullNodeMockRecorder) StateMinerPreCommitDepositForPower(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPreCommitDepositForPower", reflect.TypeOf((*MockFullNode)(nil).StateMinerPreCommitDepositForPower), arg0, arg1, arg2, arg3) +} + +// StateMinerProvingDeadline mocks base method +func (m *MockFullNode) StateMinerProvingDeadline(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*dline.Info, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerProvingDeadline", arg0, arg1, arg2) + ret0, _ := ret[0].(*dline.Info) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerProvingDeadline indicates an expected call of StateMinerProvingDeadline +func (mr *MockFullNodeMockRecorder) StateMinerProvingDeadline(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerProvingDeadline", reflect.TypeOf((*MockFullNode)(nil).StateMinerProvingDeadline), arg0, arg1, arg2) +} + +// StateMinerRecoveries mocks base method +func (m *MockFullNode) StateMinerRecoveries(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (bitfield.BitField, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerRecoveries", arg0, arg1, arg2) + ret0, _ := ret[0].(bitfield.BitField) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerRecoveries indicates an expected call of StateMinerRecoveries +func (mr *MockFullNodeMockRecorder) StateMinerRecoveries(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerRecoveries", reflect.TypeOf((*MockFullNode)(nil).StateMinerRecoveries), arg0, arg1, arg2) +} + +// StateMinerSectorAllocated mocks base method +func (m *MockFullNode) StateMinerSectorAllocated(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerSectorAllocated", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerSectorAllocated indicates an expected call of StateMinerSectorAllocated +func (mr *MockFullNodeMockRecorder) StateMinerSectorAllocated(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectorAllocated", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectorAllocated), arg0, arg1, arg2, arg3) +} + +// StateMinerSectorCount mocks base method +func (m *MockFullNode) StateMinerSectorCount(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MinerSectors, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerSectorCount", arg0, arg1, arg2) + ret0, _ := ret[0].(api.MinerSectors) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerSectorCount indicates an expected call of StateMinerSectorCount +func (mr *MockFullNodeMockRecorder) StateMinerSectorCount(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectorCount", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectorCount), arg0, arg1, arg2) +} + +// StateMinerSectors mocks base method +func (m *MockFullNode) StateMinerSectors(arg0 context.Context, arg1 address.Address, arg2 *bitfield.BitField, arg3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerSectors", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].([]*miner.SectorOnChainInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerSectors indicates an expected call of StateMinerSectors +func (mr *MockFullNodeMockRecorder) StateMinerSectors(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectors", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectors), arg0, arg1, arg2, arg3) +} + +// StateNetworkName mocks base method +func (m *MockFullNode) StateNetworkName(arg0 context.Context) (dtypes.NetworkName, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateNetworkName", arg0) + ret0, _ := ret[0].(dtypes.NetworkName) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateNetworkName indicates an expected call of StateNetworkName +func (mr *MockFullNodeMockRecorder) StateNetworkName(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateNetworkName", reflect.TypeOf((*MockFullNode)(nil).StateNetworkName), arg0) +} + +// StateNetworkVersion mocks base method +func (m *MockFullNode) StateNetworkVersion(arg0 context.Context, arg1 types.TipSetKey) (network.Version, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateNetworkVersion", arg0, arg1) + ret0, _ := ret[0].(network.Version) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateNetworkVersion indicates an expected call of StateNetworkVersion +func (mr *MockFullNodeMockRecorder) StateNetworkVersion(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateNetworkVersion", reflect.TypeOf((*MockFullNode)(nil).StateNetworkVersion), arg0, arg1) +} + +// StateReadState mocks base method +func (m *MockFullNode) StateReadState(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*api.ActorState, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateReadState", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.ActorState) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateReadState indicates an expected call of StateReadState +func (mr *MockFullNodeMockRecorder) StateReadState(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateReadState", reflect.TypeOf((*MockFullNode)(nil).StateReadState), arg0, arg1, arg2) +} + +// StateReplay mocks base method +func (m *MockFullNode) StateReplay(arg0 context.Context, arg1 types.TipSetKey, arg2 cid.Cid) (*api.InvocResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateReplay", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.InvocResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateReplay indicates an expected call of StateReplay +func (mr *MockFullNodeMockRecorder) StateReplay(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateReplay", reflect.TypeOf((*MockFullNode)(nil).StateReplay), arg0, arg1, arg2) +} + +// StateSearchMsg mocks base method +func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 cid.Cid) (*api.MsgLookup, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSearchMsg", arg0, arg1) + ret0, _ := ret[0].(*api.MsgLookup) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSearchMsg indicates an expected call of StateSearchMsg +func (mr *MockFullNodeMockRecorder) StateSearchMsg(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsg", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsg), arg0, arg1) +} + +// StateSearchMsgLimited mocks base method +func (m *MockFullNode) StateSearchMsgLimited(arg0 context.Context, arg1 cid.Cid, arg2 abi.ChainEpoch) (*api.MsgLookup, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSearchMsgLimited", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.MsgLookup) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSearchMsgLimited indicates an expected call of StateSearchMsgLimited +func (mr *MockFullNodeMockRecorder) StateSearchMsgLimited(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsgLimited", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsgLimited), arg0, arg1, arg2) +} + +// StateSectorExpiration mocks base method +func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorExpiration, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSectorExpiration", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*miner.SectorExpiration) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSectorExpiration indicates an expected call of StateSectorExpiration +func (mr *MockFullNodeMockRecorder) StateSectorExpiration(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorExpiration", reflect.TypeOf((*MockFullNode)(nil).StateSectorExpiration), arg0, arg1, arg2, arg3) +} + +// StateSectorGetInfo mocks base method +func (m *MockFullNode) StateSectorGetInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSectorGetInfo", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*miner.SectorOnChainInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSectorGetInfo indicates an expected call of StateSectorGetInfo +func (mr *MockFullNodeMockRecorder) StateSectorGetInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorGetInfo", reflect.TypeOf((*MockFullNode)(nil).StateSectorGetInfo), arg0, arg1, arg2, arg3) +} + +// StateSectorPartition mocks base method +func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorLocation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSectorPartition", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*miner.SectorLocation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSectorPartition indicates an expected call of StateSectorPartition +func (mr *MockFullNodeMockRecorder) StateSectorPartition(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorPartition", reflect.TypeOf((*MockFullNode)(nil).StateSectorPartition), arg0, arg1, arg2, arg3) +} + +// StateSectorPreCommitInfo mocks base method +func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSectorPreCommitInfo", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(miner.SectorPreCommitOnChainInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSectorPreCommitInfo indicates an expected call of StateSectorPreCommitInfo +func (mr *MockFullNodeMockRecorder) StateSectorPreCommitInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorPreCommitInfo", reflect.TypeOf((*MockFullNode)(nil).StateSectorPreCommitInfo), arg0, arg1, arg2, arg3) +} + +// StateVMCirculatingSupplyInternal mocks base method +func (m *MockFullNode) StateVMCirculatingSupplyInternal(arg0 context.Context, arg1 types.TipSetKey) (api.CirculatingSupply, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateVMCirculatingSupplyInternal", arg0, arg1) + ret0, _ := ret[0].(api.CirculatingSupply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateVMCirculatingSupplyInternal indicates an expected call of StateVMCirculatingSupplyInternal +func (mr *MockFullNodeMockRecorder) StateVMCirculatingSupplyInternal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVMCirculatingSupplyInternal", reflect.TypeOf((*MockFullNode)(nil).StateVMCirculatingSupplyInternal), arg0, arg1) +} + +// StateVerifiedClientStatus mocks base method +func (m *MockFullNode) StateVerifiedClientStatus(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateVerifiedClientStatus", arg0, arg1, arg2) + ret0, _ := ret[0].(*big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateVerifiedClientStatus indicates an expected call of StateVerifiedClientStatus +func (mr *MockFullNodeMockRecorder) StateVerifiedClientStatus(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifiedClientStatus", reflect.TypeOf((*MockFullNode)(nil).StateVerifiedClientStatus), arg0, arg1, arg2) +} + +// StateVerifiedRegistryRootKey mocks base method +func (m *MockFullNode) StateVerifiedRegistryRootKey(arg0 context.Context, arg1 types.TipSetKey) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateVerifiedRegistryRootKey", arg0, arg1) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateVerifiedRegistryRootKey indicates an expected call of StateVerifiedRegistryRootKey +func (mr *MockFullNodeMockRecorder) StateVerifiedRegistryRootKey(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifiedRegistryRootKey", reflect.TypeOf((*MockFullNode)(nil).StateVerifiedRegistryRootKey), arg0, arg1) +} + +// StateVerifierStatus mocks base method +func (m *MockFullNode) StateVerifierStatus(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateVerifierStatus", arg0, arg1, arg2) + ret0, _ := ret[0].(*big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateVerifierStatus indicates an expected call of StateVerifierStatus +func (mr *MockFullNodeMockRecorder) StateVerifierStatus(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifierStatus", reflect.TypeOf((*MockFullNode)(nil).StateVerifierStatus), arg0, arg1, arg2) +} + +// StateWaitMsg mocks base method +func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uint64) (*api.MsgLookup, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateWaitMsg", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.MsgLookup) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateWaitMsg indicates an expected call of StateWaitMsg +func (mr *MockFullNodeMockRecorder) StateWaitMsg(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsg", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsg), arg0, arg1, arg2) +} + +// StateWaitMsgLimited mocks base method +func (m *MockFullNode) StateWaitMsgLimited(arg0 context.Context, arg1 cid.Cid, arg2 uint64, arg3 abi.ChainEpoch) (*api.MsgLookup, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateWaitMsgLimited", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.MsgLookup) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateWaitMsgLimited indicates an expected call of StateWaitMsgLimited +func (mr *MockFullNodeMockRecorder) StateWaitMsgLimited(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsgLimited", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsgLimited), arg0, arg1, arg2, arg3) +} + +// SyncCheckBad mocks base method +func (m *MockFullNode) SyncCheckBad(arg0 context.Context, arg1 cid.Cid) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncCheckBad", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SyncCheckBad indicates an expected call of SyncCheckBad +func (mr *MockFullNodeMockRecorder) SyncCheckBad(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncCheckBad", reflect.TypeOf((*MockFullNode)(nil).SyncCheckBad), arg0, arg1) +} + +// SyncCheckpoint mocks base method +func (m *MockFullNode) SyncCheckpoint(arg0 context.Context, arg1 types.TipSetKey) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncCheckpoint", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SyncCheckpoint indicates an expected call of SyncCheckpoint +func (mr *MockFullNodeMockRecorder) SyncCheckpoint(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncCheckpoint", reflect.TypeOf((*MockFullNode)(nil).SyncCheckpoint), arg0, arg1) +} + +// SyncIncomingBlocks mocks base method +func (m *MockFullNode) SyncIncomingBlocks(arg0 context.Context) (<-chan *types.BlockHeader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncIncomingBlocks", arg0) + ret0, _ := ret[0].(<-chan *types.BlockHeader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SyncIncomingBlocks indicates an expected call of SyncIncomingBlocks +func (mr *MockFullNodeMockRecorder) SyncIncomingBlocks(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncIncomingBlocks", reflect.TypeOf((*MockFullNode)(nil).SyncIncomingBlocks), arg0) +} + +// SyncMarkBad mocks base method +func (m *MockFullNode) SyncMarkBad(arg0 context.Context, arg1 cid.Cid) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncMarkBad", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SyncMarkBad indicates an expected call of SyncMarkBad +func (mr *MockFullNodeMockRecorder) SyncMarkBad(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncMarkBad", reflect.TypeOf((*MockFullNode)(nil).SyncMarkBad), arg0, arg1) +} + +// SyncState mocks base method +func (m *MockFullNode) SyncState(arg0 context.Context) (*api.SyncState, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncState", arg0) + ret0, _ := ret[0].(*api.SyncState) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SyncState indicates an expected call of SyncState +func (mr *MockFullNodeMockRecorder) SyncState(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncState", reflect.TypeOf((*MockFullNode)(nil).SyncState), arg0) +} + +// SyncSubmitBlock mocks base method +func (m *MockFullNode) SyncSubmitBlock(arg0 context.Context, arg1 *types.BlockMsg) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncSubmitBlock", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SyncSubmitBlock indicates an expected call of SyncSubmitBlock +func (mr *MockFullNodeMockRecorder) SyncSubmitBlock(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncSubmitBlock", reflect.TypeOf((*MockFullNode)(nil).SyncSubmitBlock), arg0, arg1) +} + +// SyncUnmarkAllBad mocks base method +func (m *MockFullNode) SyncUnmarkAllBad(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncUnmarkAllBad", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SyncUnmarkAllBad indicates an expected call of SyncUnmarkAllBad +func (mr *MockFullNodeMockRecorder) SyncUnmarkAllBad(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncUnmarkAllBad", reflect.TypeOf((*MockFullNode)(nil).SyncUnmarkAllBad), arg0) +} + +// SyncUnmarkBad mocks base method +func (m *MockFullNode) SyncUnmarkBad(arg0 context.Context, arg1 cid.Cid) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncUnmarkBad", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SyncUnmarkBad indicates an expected call of SyncUnmarkBad +func (mr *MockFullNodeMockRecorder) SyncUnmarkBad(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncUnmarkBad", reflect.TypeOf((*MockFullNode)(nil).SyncUnmarkBad), arg0, arg1) +} + +// SyncValidateTipset mocks base method +func (m *MockFullNode) SyncValidateTipset(arg0 context.Context, arg1 types.TipSetKey) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncValidateTipset", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SyncValidateTipset indicates an expected call of SyncValidateTipset +func (mr *MockFullNodeMockRecorder) SyncValidateTipset(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncValidateTipset", reflect.TypeOf((*MockFullNode)(nil).SyncValidateTipset), arg0, arg1) +} + +// Version mocks base method +func (m *MockFullNode) Version(arg0 context.Context) (api.APIVersion, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Version", arg0) + ret0, _ := ret[0].(api.APIVersion) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Version indicates an expected call of Version +func (mr *MockFullNodeMockRecorder) Version(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockFullNode)(nil).Version), arg0) +} + +// WalletBalance mocks base method +func (m *MockFullNode) WalletBalance(arg0 context.Context, arg1 address.Address) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletBalance", arg0, arg1) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletBalance indicates an expected call of WalletBalance +func (mr *MockFullNodeMockRecorder) WalletBalance(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletBalance", reflect.TypeOf((*MockFullNode)(nil).WalletBalance), arg0, arg1) +} + +// WalletDefaultAddress mocks base method +func (m *MockFullNode) WalletDefaultAddress(arg0 context.Context) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletDefaultAddress", arg0) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletDefaultAddress indicates an expected call of WalletDefaultAddress +func (mr *MockFullNodeMockRecorder) WalletDefaultAddress(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletDefaultAddress", reflect.TypeOf((*MockFullNode)(nil).WalletDefaultAddress), arg0) +} + +// WalletDelete mocks base method +func (m *MockFullNode) WalletDelete(arg0 context.Context, arg1 address.Address) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletDelete", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// WalletDelete indicates an expected call of WalletDelete +func (mr *MockFullNodeMockRecorder) WalletDelete(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletDelete", reflect.TypeOf((*MockFullNode)(nil).WalletDelete), arg0, arg1) +} + +// WalletExport mocks base method +func (m *MockFullNode) WalletExport(arg0 context.Context, arg1 address.Address) (*types.KeyInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletExport", arg0, arg1) + ret0, _ := ret[0].(*types.KeyInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletExport indicates an expected call of WalletExport +func (mr *MockFullNodeMockRecorder) WalletExport(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletExport", reflect.TypeOf((*MockFullNode)(nil).WalletExport), arg0, arg1) +} + +// WalletHas mocks base method +func (m *MockFullNode) WalletHas(arg0 context.Context, arg1 address.Address) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletHas", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletHas indicates an expected call of WalletHas +func (mr *MockFullNodeMockRecorder) WalletHas(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletHas", reflect.TypeOf((*MockFullNode)(nil).WalletHas), arg0, arg1) +} + +// WalletImport mocks base method +func (m *MockFullNode) WalletImport(arg0 context.Context, arg1 *types.KeyInfo) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletImport", arg0, arg1) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletImport indicates an expected call of WalletImport +func (mr *MockFullNodeMockRecorder) WalletImport(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletImport", reflect.TypeOf((*MockFullNode)(nil).WalletImport), arg0, arg1) +} + +// WalletList mocks base method +func (m *MockFullNode) WalletList(arg0 context.Context) ([]address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletList", arg0) + ret0, _ := ret[0].([]address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletList indicates an expected call of WalletList +func (mr *MockFullNodeMockRecorder) WalletList(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletList", reflect.TypeOf((*MockFullNode)(nil).WalletList), arg0) +} + +// WalletNew mocks base method +func (m *MockFullNode) WalletNew(arg0 context.Context, arg1 types.KeyType) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletNew", arg0, arg1) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletNew indicates an expected call of WalletNew +func (mr *MockFullNodeMockRecorder) WalletNew(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletNew", reflect.TypeOf((*MockFullNode)(nil).WalletNew), arg0, arg1) +} + +// WalletSetDefault mocks base method +func (m *MockFullNode) WalletSetDefault(arg0 context.Context, arg1 address.Address) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletSetDefault", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// WalletSetDefault indicates an expected call of WalletSetDefault +func (mr *MockFullNodeMockRecorder) WalletSetDefault(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSetDefault", reflect.TypeOf((*MockFullNode)(nil).WalletSetDefault), arg0, arg1) +} + +// WalletSign mocks base method +func (m *MockFullNode) WalletSign(arg0 context.Context, arg1 address.Address, arg2 []byte) (*crypto.Signature, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletSign", arg0, arg1, arg2) + ret0, _ := ret[0].(*crypto.Signature) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletSign indicates an expected call of WalletSign +func (mr *MockFullNodeMockRecorder) WalletSign(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSign", reflect.TypeOf((*MockFullNode)(nil).WalletSign), arg0, arg1, arg2) +} + +// WalletSignMessage mocks base method +func (m *MockFullNode) WalletSignMessage(arg0 context.Context, arg1 address.Address, arg2 *types.Message) (*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletSignMessage", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletSignMessage indicates an expected call of WalletSignMessage +func (mr *MockFullNodeMockRecorder) WalletSignMessage(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSignMessage", reflect.TypeOf((*MockFullNode)(nil).WalletSignMessage), arg0, arg1, arg2) +} + +// WalletValidateAddress mocks base method +func (m *MockFullNode) WalletValidateAddress(arg0 context.Context, arg1 string) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletValidateAddress", arg0, arg1) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletValidateAddress indicates an expected call of WalletValidateAddress +func (mr *MockFullNodeMockRecorder) WalletValidateAddress(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletValidateAddress", reflect.TypeOf((*MockFullNode)(nil).WalletValidateAddress), arg0, arg1) +} + +// WalletVerify mocks base method +func (m *MockFullNode) WalletVerify(arg0 context.Context, arg1 address.Address, arg2 []byte, arg3 *crypto.Signature) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletVerify", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletVerify indicates an expected call of WalletVerify +func (mr *MockFullNodeMockRecorder) WalletVerify(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletVerify", reflect.TypeOf((*MockFullNode)(nil).WalletVerify), arg0, arg1, arg2, arg3) +} From 421338b9f45bc5631e88c6dc944e6cb1f4c72239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Mar 2021 17:33:20 +0100 Subject: [PATCH 05/60] ci: Fix cbor gen check --- .circleci/config.yml | 2 +- Makefile | 1 + api/mocks/mock_full.go | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 83fde80ad18..ecdb169e1b6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -399,7 +399,7 @@ jobs: - run: make deps - run: go install golang.org/x/tools/cmd/goimports - run: go install github.com/hannahhoward/cbor-gen-for - - run: go generate ./... + - run: make type-gen - run: git --no-pager diff - run: git --no-pager diff --quiet diff --git a/Makefile b/Makefile index 02fe23b4a10..4ede5a5a990 100644 --- a/Makefile +++ b/Makefile @@ -321,6 +321,7 @@ dist-clean: type-gen: go run ./gen/main.go go generate ./... + goimports -w api/ method-gen: (cd ./lotuspond/front/src/chain && go run ./methodgen.go) diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 8fd646d9abe..1e0ff151b77 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -6,6 +6,8 @@ package mocks import ( context "context" + reflect "reflect" + address "github.com/filecoin-project/go-address" bitfield "github.com/filecoin-project/go-bitfield" datatransfer "github.com/filecoin-project/go-data-transfer" @@ -32,7 +34,6 @@ import ( network0 "github.com/libp2p/go-libp2p-core/network" peer "github.com/libp2p/go-libp2p-core/peer" protocol "github.com/libp2p/go-libp2p-core/protocol" - reflect "reflect" ) // MockFullNode is a mock of FullNode interface From b3774f8b87518010e0bbd4c46dce7923863c8083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Mar 2021 18:11:52 +0100 Subject: [PATCH 06/60] openrpc: Don't use os.Args in init --- api/docgen-openrpc/cmd/docgen_openrpc.go | 6 +++++- api/docgen-openrpc/openrpc.go | 13 +------------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/api/docgen-openrpc/cmd/docgen_openrpc.go b/api/docgen-openrpc/cmd/docgen_openrpc.go index b1322257c8f..b2eb3105723 100644 --- a/api/docgen-openrpc/cmd/docgen_openrpc.go +++ b/api/docgen-openrpc/cmd/docgen_openrpc.go @@ -7,6 +7,8 @@ import ( "log" "os" + "github.com/filecoin-project/lotus/api/docgen" + "github.com/filecoin-project/lotus/api/apistruct" docgen_openrpc "github.com/filecoin-project/lotus/api/docgen-openrpc" ) @@ -29,7 +31,9 @@ Use: */ func main() { - doc := docgen_openrpc.NewLotusOpenRPCDocument() + Comments, GroupDocs := docgen.ParseApiASTInfo(os.Args[1], os.Args[2], os.Args[3], os.Args[4]) + + doc := docgen_openrpc.NewLotusOpenRPCDocument(Comments, GroupDocs) switch os.Args[2] { case "FullNode": diff --git a/api/docgen-openrpc/openrpc.go b/api/docgen-openrpc/openrpc.go index e2cd9ce53a7..271b43ac607 100644 --- a/api/docgen-openrpc/openrpc.go +++ b/api/docgen-openrpc/openrpc.go @@ -4,7 +4,6 @@ import ( "encoding/json" "go/ast" "net" - "os" "reflect" "github.com/alecthomas/jsonschema" @@ -15,16 +14,6 @@ import ( meta_schema "github.com/open-rpc/meta-schema" ) -// Comments holds API method comments collected by AST parsing. -var Comments map[string]string - -// GroupDocs holds documentation for documentation groups. -var GroupDocs map[string]string - -func init() { - Comments, GroupDocs = docgen.ParseApiASTInfo(os.Args[1], os.Args[2], os.Args[3], os.Args[4]) -} - // schemaDictEntry represents a type association passed to the jsonschema reflector. type schemaDictEntry struct { example interface{} @@ -94,7 +83,7 @@ func OpenRPCSchemaTypeMapper(ty reflect.Type) *jsonschema.Type { } // NewLotusOpenRPCDocument defines application-specific documentation and configuration for its OpenRPC document. -func NewLotusOpenRPCDocument() *go_openrpc_reflect.Document { +func NewLotusOpenRPCDocument(Comments, GroupDocs map[string]string) *go_openrpc_reflect.Document { d := &go_openrpc_reflect.Document{} // Register "Meta" document fields. From 65dcec0ebcf80e250caa625d22a3e57d2fed2309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Mar 2021 19:15:44 +0100 Subject: [PATCH 07/60] api client: Use versioned api packages --- api/client/client.go | 10 ++++++---- api/v0api/storage.go | 9 +++++++++ chain/wallet/remotewallet/remote.go | 2 +- cli/util/api.go | 14 +++++++------- cli/util/apiinfo.go | 6 +++--- cmd/lotus-shed/consensus.go | 2 +- 6 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 api/v0api/storage.go diff --git a/api/client/client.go b/api/client/client.go index 9ffd1707ec5..a08da09299a 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -11,12 +11,14 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/lib/rpcenc" ) // NewCommonRPC creates a new http jsonrpc client. func NewCommonRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Common, jsonrpc.ClientCloser, error) { - var res apistruct.CommonStruct + var res v0api.CommonStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.Internal, @@ -29,7 +31,7 @@ func NewCommonRPC(ctx context.Context, addr string, requestHeader http.Header) ( // NewFullNodeRPC creates a new http jsonrpc client. func NewFullNodeRPC(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) { - var res apistruct.FullNodeStruct + var res v1api.FullNodeStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.CommonStruct.Internal, @@ -40,8 +42,8 @@ func NewFullNodeRPC(ctx context.Context, addr string, requestHeader http.Header) } // NewStorageMinerRPC creates a new http jsonrpc client for miner -func NewStorageMinerRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.StorageMiner, jsonrpc.ClientCloser, error) { - var res apistruct.StorageMinerStruct +func NewStorageMinerRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (v0api.StorageMiner, jsonrpc.ClientCloser, error) { + var res v0api.StorageMinerStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.CommonStruct.Internal, diff --git a/api/v0api/storage.go b/api/v0api/storage.go new file mode 100644 index 00000000000..a05f482858e --- /dev/null +++ b/api/v0api/storage.go @@ -0,0 +1,9 @@ +package v0api + +import ( + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/apistruct" +) + +type StorageMiner = api.StorageMiner +type StorageMinerStruct = apistruct.StorageMinerStruct diff --git a/chain/wallet/remotewallet/remote.go b/chain/wallet/remotewallet/remote.go index 262b5f9c6bd..685d0fc3554 100644 --- a/chain/wallet/remotewallet/remote.go +++ b/chain/wallet/remotewallet/remote.go @@ -20,7 +20,7 @@ func SetupRemoteWallet(info string) func(mctx helpers.MetricsCtx, lc fx.Lifecycl return func(mctx helpers.MetricsCtx, lc fx.Lifecycle) (*RemoteWallet, error) { ai := cliutil.ParseApiInfo(info) - url, err := ai.DialArgs() + url, err := ai.DialArgs("v0") if err != nil { return nil, err } diff --git a/cli/util/api.go b/cli/util/api.go index ce5945f2ebf..c0f0b0ed181 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -133,13 +133,13 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { }, nil } -func GetRawAPI(ctx *cli.Context, t repo.RepoType) (string, http.Header, error) { +func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http.Header, error) { ainfo, err := GetAPIInfo(ctx, t) if err != nil { return "", nil, xerrors.Errorf("could not get API info: %w", err) } - addr, err := ainfo.DialArgs() + addr, err := ainfo.DialArgs(version) if err != nil { return "", nil, xerrors.Errorf("could not get DialArgs: %w", err) } @@ -165,7 +165,7 @@ func GetAPI(ctx *cli.Context) (api.Common, jsonrpc.ClientCloser, error) { return tn.(api.FullNode), func() {}, nil } - addr, headers, err := GetRawAPI(ctx, t) + addr, headers, err := GetRawAPI(ctx, t, "v0") if err != nil { return nil, nil, err } @@ -178,7 +178,7 @@ func GetFullNodeAPI(ctx *cli.Context) (api.FullNode, jsonrpc.ClientCloser, error return tn.(api.FullNode), func() {}, nil } - addr, headers, err := GetRawAPI(ctx, repo.FullNode) + addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v1") if err != nil { return nil, nil, err } @@ -206,7 +206,7 @@ func GetStorageMinerAPI(ctx *cli.Context, opts ...GetStorageMinerOption) (api.St return tn.(api.StorageMiner), func() {}, nil } - addr, headers, err := GetRawAPI(ctx, repo.StorageMiner) + addr, headers, err := GetRawAPI(ctx, repo.StorageMiner, "v0") if err != nil { return nil, nil, err } @@ -231,7 +231,7 @@ func GetStorageMinerAPI(ctx *cli.Context, opts ...GetStorageMinerOption) (api.St } func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { - addr, headers, err := GetRawAPI(ctx, repo.Worker) + addr, headers, err := GetRawAPI(ctx, repo.Worker, "v0") if err != nil { return nil, nil, err } @@ -240,7 +240,7 @@ func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { } func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) { - addr, headers, err := GetRawAPI(ctx, repo.FullNode) + addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v0") if err != nil { return nil, nil, err } diff --git a/cli/util/apiinfo.go b/cli/util/apiinfo.go index 1f9a837697a..41ca18c6104 100644 --- a/cli/util/apiinfo.go +++ b/cli/util/apiinfo.go @@ -36,7 +36,7 @@ func ParseApiInfo(s string) APIInfo { } } -func (a APIInfo) DialArgs() (string, error) { +func (a APIInfo) DialArgs(version string) (string, error) { ma, err := multiaddr.NewMultiaddr(a.Addr) if err == nil { _, addr, err := manet.DialArgs(ma) @@ -44,14 +44,14 @@ func (a APIInfo) DialArgs() (string, error) { return "", err } - return "ws://" + addr + "/rpc/v0", nil + return "ws://" + addr + "/rpc/" + version, nil } _, err = url.Parse(a.Addr) if err != nil { return "", err } - return a.Addr + "/rpc/v0", nil + return a.Addr + "/rpc/" + version, nil } func (a APIInfo) Host() (string, error) { diff --git a/cmd/lotus-shed/consensus.go b/cmd/lotus-shed/consensus.go index c78c9c00f03..8e30f5cee28 100644 --- a/cmd/lotus-shed/consensus.go +++ b/cmd/lotus-shed/consensus.go @@ -113,7 +113,7 @@ var consensusCheckCmd = &cli.Command{ return err } ainfo := cliutil.APIInfo{Addr: apima.String()} - addr, err := ainfo.DialArgs() + addr, err := ainfo.DialArgs("v1") if err != nil { return err } From eed5840de3fc15f3572cdc81ae6bd463d7b1a1f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 23 Mar 2021 19:32:42 +0100 Subject: [PATCH 08/60] fix lotus-shed --- cmd/lotus-shed/rpc.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-shed/rpc.go b/cmd/lotus-shed/rpc.go index fe81e5a62b2..81171916e14 100644 --- a/cmd/lotus-shed/rpc.go +++ b/cmd/lotus-shed/rpc.go @@ -28,6 +28,10 @@ var rpcCmd = &cli.Command{ &cli.BoolFlag{ Name: "miner", }, + &cli.StringFlag{ + Name: "version", + Value: "v0", + }, }, Action: func(cctx *cli.Context) error { rt := repo.FullNode @@ -35,7 +39,7 @@ var rpcCmd = &cli.Command{ rt = repo.StorageMiner } - addr, headers, err := lcli.GetRawAPI(cctx, rt) + addr, headers, err := lcli.GetRawAPI(cctx, rt, cctx.String("version")) if err != nil { return err } From 7a23b411ae988c644f3160afe7ee5703d092a444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 25 Mar 2021 15:09:50 +0100 Subject: [PATCH 09/60] Merge apistruct with the api package --- Makefile | 6 +- api/api_test.go | 6 + api/apistruct/struct_test.go | 9 - api/apistruct/types.go | 12 - api/client/client.go | 7 +- api/docgen-openrpc/cmd/docgen_openrpc.go | 11 +- api/docgen/cmd/docgen.go | 23 +- api/docgen/docgen.go | 37 +++ api/{apistruct => }/permissioned.go | 11 +- api/{apistruct => }/struct.go | 355 +++++++++++------------ api/v0api/common.go | 77 ----- api/v0api/latest.go | 24 ++ api/v0api/permissioned.go | 13 + api/v0api/storage.go | 9 - api/v0api/struct.go | 166 ----------- api/v1api/latest.go | 7 +- build/openrpc/full.json.gz | Bin 22582 -> 22496 bytes build/openrpc/miner.json.gz | Bin 7643 -> 7608 bytes build/openrpc/worker.json.gz | Bin 2578 -> 2561 bytes cli/auth.go | 14 +- cmd/lotus-seal-worker/main.go | 5 +- cmd/lotus-shed/jwt.go | 13 +- cmd/lotus-storage-miner/run.go | 3 +- cmd/lotus/rpc.go | 6 +- gen/api/proxygen.go | 20 +- metrics/proxy.go | 11 +- node/impl/storminer.go | 3 +- node/modules/core.go | 4 +- 28 files changed, 314 insertions(+), 538 deletions(-) delete mode 100644 api/apistruct/struct_test.go delete mode 100644 api/apistruct/types.go rename api/{apistruct => }/permissioned.go (78%) rename api/{apistruct => }/struct.go (87%) delete mode 100644 api/v0api/common.go create mode 100644 api/v0api/latest.go create mode 100644 api/v0api/permissioned.go delete mode 100644 api/v0api/storage.go diff --git a/Makefile b/Makefile index 4ede5a5a990..e3884434783 100644 --- a/Makefile +++ b/Makefile @@ -320,7 +320,7 @@ dist-clean: type-gen: go run ./gen/main.go - go generate ./... + go generate -x ./... goimports -w api/ method-gen: @@ -328,8 +328,8 @@ method-gen: api-gen: go run ./gen/api - goimports -w api/apistruct api/v0api - goimports -w api/apistruct api/v0api + goimports -w api + goimports -w api .PHONY: api-gen docsgen: docsgen-md docsgen-openrpc diff --git a/api/api_test.go b/api/api_test.go index 70d918b5cd3..738e1b06799 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -113,3 +113,9 @@ func TestReturnTypes(t *testing.T) { t.Run("miner", tst(new(StorageMiner))) t.Run("worker", tst(new(Worker))) } + +func TestPermTags(t *testing.T) { + _ = PermissionedFullAPI(&FullNodeStruct{}) + _ = PermissionedStorMinerAPI(&StorageMinerStruct{}) + _ = PermissionedWorkerAPI(&WorkerStruct{}) +} diff --git a/api/apistruct/struct_test.go b/api/apistruct/struct_test.go deleted file mode 100644 index 9f5f5836015..00000000000 --- a/api/apistruct/struct_test.go +++ /dev/null @@ -1,9 +0,0 @@ -package apistruct - -import "testing" - -func TestPermTags(t *testing.T) { - _ = PermissionedFullAPI(&FullNodeStruct{}) - _ = PermissionedStorMinerAPI(&StorageMinerStruct{}) - _ = PermissionedWorkerAPI(&WorkerStruct{}) -} diff --git a/api/apistruct/types.go b/api/apistruct/types.go deleted file mode 100644 index 57c89cdaaf2..00000000000 --- a/api/apistruct/types.go +++ /dev/null @@ -1,12 +0,0 @@ -package apistruct - -import "github.com/filecoin-project/lotus/api" - -type ChainIO = api.ChainIO -type Common = api.Common -type FullNode = api.FullNode -type Gateway = api.Gateway -type Signable = api.Signable -type StorageMiner = api.StorageMiner -type Wallet = api.Wallet -type Worker = api.Worker diff --git a/api/client/client.go b/api/client/client.go index a08da09299a..6c2f00b461a 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -10,7 +10,6 @@ import ( "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/lib/rpcenc" @@ -71,7 +70,7 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) ( u.Path = path.Join(u.Path, "../streams/v0/push") - var res apistruct.WorkerStruct + var res api.WorkerStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.Internal, @@ -87,7 +86,7 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) ( // NewGatewayRPC creates a new http jsonrpc client for a gateway node. func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.Gateway, jsonrpc.ClientCloser, error) { - var res apistruct.GatewayStruct + var res api.GatewayStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.Internal, @@ -100,7 +99,7 @@ func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, } func NewWalletRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Wallet, jsonrpc.ClientCloser, error) { - var res apistruct.WalletStruct + var res api.WalletStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.Internal, diff --git a/api/docgen-openrpc/cmd/docgen_openrpc.go b/api/docgen-openrpc/cmd/docgen_openrpc.go index b2eb3105723..febbef3e412 100644 --- a/api/docgen-openrpc/cmd/docgen_openrpc.go +++ b/api/docgen-openrpc/cmd/docgen_openrpc.go @@ -9,7 +9,6 @@ import ( "github.com/filecoin-project/lotus/api/docgen" - "github.com/filecoin-project/lotus/api/apistruct" docgen_openrpc "github.com/filecoin-project/lotus/api/docgen-openrpc" ) @@ -35,14 +34,8 @@ func main() { doc := docgen_openrpc.NewLotusOpenRPCDocument(Comments, GroupDocs) - switch os.Args[2] { - case "FullNode": - doc.RegisterReceiverName("Filecoin", &apistruct.FullNodeStruct{}) - case "StorageMiner": - doc.RegisterReceiverName("Filecoin", &apistruct.StorageMinerStruct{}) - case "Worker": - doc.RegisterReceiverName("Filecoin", &apistruct.WorkerStruct{}) - } + i, _, _, _ := docgen.GetAPIType(os.Args[2], os.Args[3]) + doc.RegisterReceiverName("Filecoin", i) out, err := doc.Discover() if err != nil { diff --git a/api/docgen/cmd/docgen.go b/api/docgen/cmd/docgen.go index 57182d4004b..912eea841cd 100644 --- a/api/docgen/cmd/docgen.go +++ b/api/docgen/cmd/docgen.go @@ -4,12 +4,9 @@ import ( "encoding/json" "fmt" "os" - "reflect" "sort" "strings" - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/api/docgen" ) @@ -18,25 +15,7 @@ func main() { groups := make(map[string]*docgen.MethodGroup) - var t reflect.Type - var permStruct, commonPermStruct reflect.Type - - switch os.Args[2] { - case "FullNode": - t = reflect.TypeOf(new(struct{ api.FullNode })).Elem() - permStruct = reflect.TypeOf(apistruct.FullNodeStruct{}.Internal) - commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal) - case "StorageMiner": - t = reflect.TypeOf(new(struct{ api.StorageMiner })).Elem() - permStruct = reflect.TypeOf(apistruct.StorageMinerStruct{}.Internal) - commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal) - case "Worker": - t = reflect.TypeOf(new(struct{ api.Worker })).Elem() - permStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal) - commonPermStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal) - default: - panic("unknown type") - } + _, t, permStruct, commonPermStruct := docgen.GetAPIType(os.Args[2], os.Args[3]) for i := 0; i < t.NumMethod(); i++ { m := t.Method(i) diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 49f83895974..9ce10edfef2 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -35,6 +35,7 @@ import ( "github.com/filecoin-project/lotus/api" apitypes "github.com/filecoin-project/lotus/api/types" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/extern/sector-storage/sealtasks" @@ -262,6 +263,42 @@ func init() { ) } +func GetAPIType(name, pkg string) (i interface{}, t, permStruct, commonPermStruct reflect.Type) { + switch pkg { + case "api": // latest + switch name { + case "FullNode": + i = &api.FullNodeStruct{} + t = reflect.TypeOf(new(struct{ api.FullNode })).Elem() + permStruct = reflect.TypeOf(api.FullNodeStruct{}.Internal) + commonPermStruct = reflect.TypeOf(api.CommonStruct{}.Internal) + case "StorageMiner": + i = &api.StorageMinerStruct{} + t = reflect.TypeOf(new(struct{ api.StorageMiner })).Elem() + permStruct = reflect.TypeOf(api.StorageMinerStruct{}.Internal) + commonPermStruct = reflect.TypeOf(api.CommonStruct{}.Internal) + case "Worker": + i = &api.WorkerStruct{} + t = reflect.TypeOf(new(struct{ api.Worker })).Elem() + permStruct = reflect.TypeOf(api.WorkerStruct{}.Internal) + commonPermStruct = reflect.TypeOf(api.WorkerStruct{}.Internal) + default: + panic("unknown type") + } + case "v0api": + switch name { + case "FullNode": + i = v0api.FullNodeStruct{} + t = reflect.TypeOf(new(struct{ v0api.FullNode })).Elem() + permStruct = reflect.TypeOf(v0api.FullNodeStruct{}.Internal) + commonPermStruct = reflect.TypeOf(v0api.CommonStruct{}.Internal) + default: + panic("unknown type") + } + } + return +} + func ExampleValue(method string, t, parent reflect.Type) interface{} { v, ok := ExampleValues[t] if ok { diff --git a/api/apistruct/permissioned.go b/api/permissioned.go similarity index 78% rename from api/apistruct/permissioned.go rename to api/permissioned.go index 23259fa8746..d99e5943b8b 100644 --- a/api/apistruct/permissioned.go +++ b/api/permissioned.go @@ -1,8 +1,7 @@ -package apistruct +package api import ( "github.com/filecoin-project/go-jsonrpc/auth" - "github.com/filecoin-project/lotus/api" ) const ( @@ -17,27 +16,27 @@ const ( var AllPermissions = []auth.Permission{PermRead, PermWrite, PermSign, PermAdmin} var DefaultPerms = []auth.Permission{PermRead} -func PermissionedStorMinerAPI(a api.StorageMiner) api.StorageMiner { +func PermissionedStorMinerAPI(a StorageMiner) StorageMiner { var out StorageMinerStruct auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.CommonStruct.Internal) return &out } -func PermissionedFullAPI(a api.FullNode) api.FullNode { +func PermissionedFullAPI(a FullNode) FullNode { var out FullNodeStruct auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.CommonStruct.Internal) return &out } -func PermissionedWorkerAPI(a api.Worker) api.Worker { +func PermissionedWorkerAPI(a Worker) Worker { var out WorkerStruct auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) return &out } -func PermissionedWalletAPI(a api.Wallet) api.Wallet { +func PermissionedWalletAPI(a Wallet) Wallet { var out WalletStruct auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) return &out diff --git a/api/apistruct/struct.go b/api/struct.go similarity index 87% rename from api/apistruct/struct.go rename to api/struct.go index 63dbb51b00e..9a619e3d0ff 100644 --- a/api/apistruct/struct.go +++ b/api/struct.go @@ -1,6 +1,6 @@ // Code generated by github.com/filecoin-project/lotus/gen/api. DO NOT EDIT. -package apistruct +package api import ( "context" @@ -18,7 +18,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/dline" - "github.com/filecoin-project/lotus/api" apitypes "github.com/filecoin-project/lotus/api/types" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" @@ -66,7 +65,7 @@ type CommonStruct struct { NetAgentVersion func(p0 context.Context, p1 peer.ID) (string, error) `perm:"read"` - NetAutoNatStatus func(p0 context.Context) (api.NatInfo, error) `perm:"read"` + NetAutoNatStatus func(p0 context.Context) (NatInfo, error) `perm:"read"` NetBandwidthStats func(p0 context.Context) (metrics.Stats, error) `perm:"read"` @@ -74,11 +73,11 @@ type CommonStruct struct { NetBandwidthStatsByProtocol func(p0 context.Context) (map[protocol.ID]metrics.Stats, error) `perm:"read"` - NetBlockAdd func(p0 context.Context, p1 api.NetBlockList) error `perm:"admin"` + NetBlockAdd func(p0 context.Context, p1 NetBlockList) error `perm:"admin"` - NetBlockList func(p0 context.Context) (api.NetBlockList, error) `perm:"read"` + NetBlockList func(p0 context.Context) (NetBlockList, error) `perm:"read"` - NetBlockRemove func(p0 context.Context, p1 api.NetBlockList) error `perm:"admin"` + NetBlockRemove func(p0 context.Context, p1 NetBlockList) error `perm:"admin"` NetConnect func(p0 context.Context, p1 peer.AddrInfo) error `perm:"write"` @@ -88,17 +87,17 @@ type CommonStruct struct { NetFindPeer func(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) `perm:"read"` - NetPeerInfo func(p0 context.Context, p1 peer.ID) (*api.ExtendedPeerInfo, error) `perm:"read"` + NetPeerInfo func(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) `perm:"read"` NetPeers func(p0 context.Context) ([]peer.AddrInfo, error) `perm:"read"` - NetPubsubScores func(p0 context.Context) ([]api.PubsubScore, error) `perm:"read"` + NetPubsubScores func(p0 context.Context) ([]PubsubScore, error) `perm:"read"` Session func(p0 context.Context) (uuid.UUID, error) `perm:"read"` Shutdown func(p0 context.Context) error `perm:"admin"` - Version func(p0 context.Context) (api.APIVersion, error) `perm:"read"` + Version func(p0 context.Context) (APIVersion, error) `perm:"read"` } } @@ -114,19 +113,19 @@ type FullNodeStruct struct { ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"` - ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `perm:"read"` + ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `perm:"read"` ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `perm:"read"` ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"` - ChainGetNode func(p0 context.Context, p1 string) (*api.IpldObject, error) `perm:"read"` + ChainGetNode func(p0 context.Context, p1 string) (*IpldObject, error) `perm:"read"` - ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]api.Message, error) `perm:"read"` + ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]Message, error) `perm:"read"` ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` - ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) `perm:"read"` + ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) `perm:"read"` ChainGetRandomnessFromBeacon func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"` @@ -140,47 +139,47 @@ type FullNodeStruct struct { ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"` - ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `perm:"read"` + ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `perm:"read"` ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"` ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` - ChainStatObj func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) `perm:"read"` + ChainStatObj func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) `perm:"read"` ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"` - ClientCalcCommP func(p0 context.Context, p1 string) (*api.CommPRet, error) `perm:"write"` + ClientCalcCommP func(p0 context.Context, p1 string) (*CommPRet, error) `perm:"write"` ClientCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` - ClientDataTransferUpdates func(p0 context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"` + ClientDataTransferUpdates func(p0 context.Context) (<-chan DataTransferChannel, error) `perm:"write"` - ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) `perm:"read"` + ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) `perm:"read"` - ClientDealSize func(p0 context.Context, p1 cid.Cid) (api.DataSize, error) `perm:"read"` + ClientDealSize func(p0 context.Context, p1 cid.Cid) (DataSize, error) `perm:"read"` - ClientFindData func(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) `perm:"read"` + ClientFindData func(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) `perm:"read"` - ClientGenCar func(p0 context.Context, p1 api.FileRef, p2 string) error `perm:"write"` + ClientGenCar func(p0 context.Context, p1 FileRef, p2 string) error `perm:"write"` - ClientGetDealInfo func(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) `perm:"read"` + ClientGetDealInfo func(p0 context.Context, p1 cid.Cid) (*DealInfo, error) `perm:"read"` ClientGetDealStatus func(p0 context.Context, p1 uint64) (string, error) `perm:"read"` - ClientGetDealUpdates func(p0 context.Context) (<-chan api.DealInfo, error) `perm:"write"` + ClientGetDealUpdates func(p0 context.Context) (<-chan DealInfo, error) `perm:"write"` ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"` - ClientImport func(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) `perm:"admin"` + ClientImport func(p0 context.Context, p1 FileRef) (*ImportRes, error) `perm:"admin"` - ClientListDataTransfers func(p0 context.Context) ([]api.DataTransferChannel, error) `perm:"write"` + ClientListDataTransfers func(p0 context.Context) ([]DataTransferChannel, error) `perm:"write"` - ClientListDeals func(p0 context.Context) ([]api.DealInfo, error) `perm:"write"` + ClientListDeals func(p0 context.Context) ([]DealInfo, error) `perm:"write"` - ClientListImports func(p0 context.Context) ([]api.Import, error) `perm:"write"` + ClientListImports func(p0 context.Context) ([]Import, error) `perm:"write"` - ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) `perm:"read"` + ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) `perm:"read"` ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"` @@ -188,13 +187,13 @@ type FullNodeStruct struct { ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` - ClientRetrieve func(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error `perm:"admin"` + ClientRetrieve func(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) error `perm:"admin"` ClientRetrieveTryRestartInsufficientFunds func(p0 context.Context, p1 address.Address) error `perm:"write"` - ClientRetrieveWithEvents func(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"` + ClientRetrieveWithEvents func(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"` - ClientStartDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"admin"` + ClientStartDeal func(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) `perm:"admin"` CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` @@ -204,7 +203,7 @@ type FullNodeStruct struct { GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) `perm:"read"` - GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `perm:"read"` + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `perm:"read"` MarketAddBalance func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` @@ -216,13 +215,13 @@ type FullNodeStruct struct { MarketWithdraw func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` - MinerCreateBlock func(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"` + MinerCreateBlock func(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) `perm:"write"` - MinerGetBaseInfo func(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"` + MinerGetBaseInfo func(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) `perm:"read"` MpoolBatchPush func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` - MpoolBatchPushMessage func(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"` + MpoolBatchPushMessage func(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"` MpoolBatchPushUntrusted func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` @@ -236,7 +235,7 @@ type FullNodeStruct struct { MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` - MpoolPushMessage func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"` + MpoolPushMessage func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"` MpoolPushUntrusted func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` @@ -244,7 +243,7 @@ type FullNodeStruct struct { MpoolSetConfig func(p0 context.Context, p1 *types.MpoolConfig) error `perm:"admin"` - MpoolSub func(p0 context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"` + MpoolSub func(p0 context.Context) (<-chan MpoolUpdate, error) `perm:"read"` MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) `perm:"sign"` @@ -262,11 +261,11 @@ type FullNodeStruct struct { MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` - MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) `perm:"read"` + MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) `perm:"read"` MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` - MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) `perm:"read"` + MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) `perm:"read"` MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) `perm:"sign"` @@ -280,23 +279,23 @@ type FullNodeStruct struct { PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"` - PaychAvailableFunds func(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"` + PaychAvailableFunds func(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) `perm:"sign"` - PaychAvailableFundsByFromTo func(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"` + PaychAvailableFundsByFromTo func(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) `perm:"sign"` PaychCollect func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` - PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) `perm:"sign"` + PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) `perm:"sign"` PaychGetWaitReady func(p0 context.Context, p1 cid.Cid) (address.Address, error) `perm:"sign"` PaychList func(p0 context.Context) ([]address.Address, error) `perm:"read"` - PaychNewPayment func(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"` + PaychNewPayment func(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) `perm:"sign"` PaychSettle func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` - PaychStatus func(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) `perm:"read"` + PaychStatus func(p0 context.Context, p1 address.Address) (*PaychStatus, error) `perm:"read"` PaychVoucherAdd func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) `perm:"write"` @@ -304,7 +303,7 @@ type FullNodeStruct struct { PaychVoucherCheckValid func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error `perm:"read"` - PaychVoucherCreate func(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) `perm:"sign"` + PaychVoucherCreate func(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) `perm:"sign"` PaychVoucherList func(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) `perm:"write"` @@ -312,17 +311,17 @@ type FullNodeStruct struct { StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` - StateAllMinerFaults func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) `perm:"read"` + StateAllMinerFaults func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) `perm:"read"` - StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) `perm:"read"` + StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) `perm:"read"` StateChangedActors func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) `perm:"read"` StateCirculatingSupply func(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) `perm:"read"` - StateCompute func(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"` + StateCompute func(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*ComputeStateOutput, error) `perm:"read"` - StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"` + StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) `perm:"read"` StateDecodeParams func(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) `perm:"read"` @@ -332,25 +331,25 @@ type FullNodeStruct struct { StateListActors func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` - StateListMessages func(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` + StateListMessages func(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` - StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) `perm:"read"` + StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) `perm:"read"` - StateMarketDeals func(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) `perm:"read"` + StateMarketDeals func(p0 context.Context, p1 types.TipSetKey) (map[string]MarketDeal, error) `perm:"read"` - StateMarketParticipants func(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) `perm:"read"` + StateMarketParticipants func(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) `perm:"read"` - StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) `perm:"read"` + StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) `perm:"read"` StateMinerActiveSectors func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` StateMinerAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateMinerDeadlines func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) `perm:"read"` + StateMinerDeadlines func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) `perm:"read"` StateMinerFaults func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` @@ -358,9 +357,9 @@ type FullNodeStruct struct { StateMinerInitialPledgeCollateral func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateMinerPartitions func(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) `perm:"read"` + StateMinerPartitions func(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) `perm:"read"` - StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) `perm:"read"` + StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) `perm:"read"` StateMinerPreCommitDepositForPower func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` @@ -370,7 +369,7 @@ type FullNodeStruct struct { StateMinerSectorAllocated func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) `perm:"read"` - StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) `perm:"read"` + StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) `perm:"read"` StateMinerSectors func(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` @@ -378,13 +377,13 @@ type FullNodeStruct struct { StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `perm:"read"` - StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) `perm:"read"` + StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) `perm:"read"` - StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) `perm:"read"` + StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) `perm:"read"` - StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `perm:"read"` + StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) `perm:"read"` - StateSearchMsgLimited func(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"` + StateSearchMsgLimited func(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*MsgLookup, error) `perm:"read"` StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"` @@ -394,7 +393,7 @@ type FullNodeStruct struct { StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"` - StateVMCirculatingSupplyInternal func(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"` + StateVMCirculatingSupplyInternal func(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) `perm:"read"` StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` @@ -402,9 +401,9 @@ type FullNodeStruct struct { StateVerifierStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` - StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `perm:"read"` + StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) `perm:"read"` - StateWaitMsgLimited func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"` + StateWaitMsgLimited func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*MsgLookup, error) `perm:"read"` SyncCheckBad func(p0 context.Context, p1 cid.Cid) (string, error) `perm:"read"` @@ -414,7 +413,7 @@ type FullNodeStruct struct { SyncMarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` - SyncState func(p0 context.Context) (*api.SyncState, error) `perm:"read"` + SyncState func(p0 context.Context) (*SyncState, error) `perm:"read"` SyncSubmitBlock func(p0 context.Context, p1 *types.BlockMsg) error `perm:"write"` @@ -454,7 +453,7 @@ type FullNodeStruct struct { type GatewayStruct struct { Internal struct { - ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `` + ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `` ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `` @@ -466,23 +465,23 @@ type GatewayStruct struct { ChainHead func(p0 context.Context) (*types.TipSet, error) `` - ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `` + ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `` ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` - GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `` MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `` - MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) `` + MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) `` MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `` StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` - StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) `` + StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) `` StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `` @@ -492,31 +491,31 @@ type GatewayStruct struct { StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` - StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) `` + StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) `` - StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) `` + StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) `` StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) `` - StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) `` + StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) `` StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `` StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `` - StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `` + StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) `` StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `` StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` - StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `` + StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) `` } } type SignableStruct struct { Internal struct { - Sign func(p0 context.Context, p1 api.SignFunc) error `` + Sign func(p0 context.Context, p1 SignFunc) error `` } } @@ -526,7 +525,7 @@ type StorageMinerStruct struct { Internal struct { ActorAddress func(p0 context.Context) (address.Address, error) `perm:"read"` - ActorAddressConfig func(p0 context.Context) (api.AddressConfig, error) `perm:"read"` + ActorAddressConfig func(p0 context.Context) (AddressConfig, error) `perm:"read"` ActorSectorSize func(p0 context.Context, p1 address.Address) (abi.SectorSize, error) `perm:"read"` @@ -548,7 +547,7 @@ type StorageMinerStruct struct { DealsImportData func(p0 context.Context, p1 cid.Cid, p2 string) error `perm:"admin"` - DealsList func(p0 context.Context) ([]api.MarketDeal, error) `perm:"admin"` + DealsList func(p0 context.Context) ([]MarketDeal, error) `perm:"admin"` DealsPieceCidBlocklist func(p0 context.Context) ([]cid.Cid, error) `perm:"admin"` @@ -568,7 +567,7 @@ type StorageMinerStruct struct { MarketCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` - MarketDataTransferUpdates func(p0 context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"` + MarketDataTransferUpdates func(p0 context.Context) (<-chan DataTransferChannel, error) `perm:"write"` MarketGetAsk func(p0 context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"` @@ -578,15 +577,15 @@ type StorageMinerStruct struct { MarketImportDealData func(p0 context.Context, p1 cid.Cid, p2 string) error `perm:"write"` - MarketListDataTransfers func(p0 context.Context) ([]api.DataTransferChannel, error) `perm:"write"` + MarketListDataTransfers func(p0 context.Context) ([]DataTransferChannel, error) `perm:"write"` - MarketListDeals func(p0 context.Context) ([]api.MarketDeal, error) `perm:"read"` + MarketListDeals func(p0 context.Context) ([]MarketDeal, error) `perm:"read"` MarketListIncompleteDeals func(p0 context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"` MarketListRetrievalDeals func(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) `perm:"read"` - MarketPendingDeals func(p0 context.Context) (api.PendingDealInfo, error) `perm:"write"` + MarketPendingDeals func(p0 context.Context) (PendingDealInfo, error) `perm:"write"` MarketPublishPendingDeals func(p0 context.Context) error `perm:"admin"` @@ -656,15 +655,15 @@ type StorageMinerStruct struct { SectorsList func(p0 context.Context) ([]abi.SectorNumber, error) `perm:"read"` - SectorsListInStates func(p0 context.Context, p1 []api.SectorState) ([]abi.SectorNumber, error) `perm:"read"` + SectorsListInStates func(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) `perm:"read"` - SectorsRefs func(p0 context.Context) (map[string][]api.SealedRef, error) `perm:"read"` + SectorsRefs func(p0 context.Context) (map[string][]SealedRef, error) `perm:"read"` - SectorsStatus func(p0 context.Context, p1 abi.SectorNumber, p2 bool) (api.SectorInfo, error) `perm:"read"` + SectorsStatus func(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) `perm:"read"` - SectorsSummary func(p0 context.Context) (map[api.SectorState]int, error) `perm:"read"` + SectorsSummary func(p0 context.Context) (map[SectorState]int, error) `perm:"read"` - SectorsUpdate func(p0 context.Context, p1 abi.SectorNumber, p2 api.SectorState) error `perm:"admin"` + SectorsUpdate func(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error `perm:"admin"` StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"` @@ -714,7 +713,7 @@ type WalletStruct struct { WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `` - WalletSign func(p0 context.Context, p1 address.Address, p2 []byte, p3 api.MsgMeta) (*crypto.Signature, error) `` + WalletSign func(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) `` } } @@ -764,7 +763,7 @@ type WorkerStruct struct { UnsealPiece func(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) `perm:"admin"` - Version func(p0 context.Context) (api.Version, error) `perm:"admin"` + Version func(p0 context.Context) (Version, error) `perm:"admin"` WaitQuiet func(p0 context.Context) error `perm:"admin"` } @@ -814,7 +813,7 @@ func (s *CommonStruct) NetAgentVersion(p0 context.Context, p1 peer.ID) (string, return s.Internal.NetAgentVersion(p0, p1) } -func (s *CommonStruct) NetAutoNatStatus(p0 context.Context) (api.NatInfo, error) { +func (s *CommonStruct) NetAutoNatStatus(p0 context.Context) (NatInfo, error) { return s.Internal.NetAutoNatStatus(p0) } @@ -830,15 +829,15 @@ func (s *CommonStruct) NetBandwidthStatsByProtocol(p0 context.Context) (map[prot return s.Internal.NetBandwidthStatsByProtocol(p0) } -func (s *CommonStruct) NetBlockAdd(p0 context.Context, p1 api.NetBlockList) error { +func (s *CommonStruct) NetBlockAdd(p0 context.Context, p1 NetBlockList) error { return s.Internal.NetBlockAdd(p0, p1) } -func (s *CommonStruct) NetBlockList(p0 context.Context) (api.NetBlockList, error) { +func (s *CommonStruct) NetBlockList(p0 context.Context) (NetBlockList, error) { return s.Internal.NetBlockList(p0) } -func (s *CommonStruct) NetBlockRemove(p0 context.Context, p1 api.NetBlockList) error { +func (s *CommonStruct) NetBlockRemove(p0 context.Context, p1 NetBlockList) error { return s.Internal.NetBlockRemove(p0, p1) } @@ -858,7 +857,7 @@ func (s *CommonStruct) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInf return s.Internal.NetFindPeer(p0, p1) } -func (s *CommonStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*api.ExtendedPeerInfo, error) { +func (s *CommonStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) { return s.Internal.NetPeerInfo(p0, p1) } @@ -866,7 +865,7 @@ func (s *CommonStruct) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) { return s.Internal.NetPeers(p0) } -func (s *CommonStruct) NetPubsubScores(p0 context.Context) ([]api.PubsubScore, error) { +func (s *CommonStruct) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) { return s.Internal.NetPubsubScores(p0) } @@ -878,7 +877,7 @@ func (s *CommonStruct) Shutdown(p0 context.Context) error { return s.Internal.Shutdown(p0) } -func (s *CommonStruct) Version(p0 context.Context) (api.APIVersion, error) { +func (s *CommonStruct) Version(p0 context.Context) (APIVersion, error) { return s.Internal.Version(p0) } @@ -898,7 +897,7 @@ func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.B return s.Internal.ChainGetBlock(p0, p1) } -func (s *FullNodeStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { +func (s *FullNodeStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { return s.Internal.ChainGetBlockMessages(p0, p1) } @@ -910,11 +909,11 @@ func (s *FullNodeStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types return s.Internal.ChainGetMessage(p0, p1) } -func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*api.IpldObject, error) { +func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*IpldObject, error) { return s.Internal.ChainGetNode(p0, p1) } -func (s *FullNodeStruct) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]api.Message, error) { +func (s *FullNodeStruct) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]Message, error) { return s.Internal.ChainGetParentMessages(p0, p1) } @@ -922,7 +921,7 @@ func (s *FullNodeStruct) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) return s.Internal.ChainGetParentReceipts(p0, p1) } -func (s *FullNodeStruct) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) { +func (s *FullNodeStruct) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) { return s.Internal.ChainGetPath(p0, p1, p2) } @@ -950,7 +949,7 @@ func (s *FullNodeStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { return s.Internal.ChainHead(p0) } -func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { +func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { return s.Internal.ChainNotify(p0) } @@ -962,7 +961,7 @@ func (s *FullNodeStruct) ChainSetHead(p0 context.Context, p1 types.TipSetKey) er return s.Internal.ChainSetHead(p0, p1) } -func (s *FullNodeStruct) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) { +func (s *FullNodeStruct) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) { return s.Internal.ChainStatObj(p0, p1, p2) } @@ -970,7 +969,7 @@ func (s *FullNodeStruct) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKe return s.Internal.ChainTipSetWeight(p0, p1) } -func (s *FullNodeStruct) ClientCalcCommP(p0 context.Context, p1 string) (*api.CommPRet, error) { +func (s *FullNodeStruct) ClientCalcCommP(p0 context.Context, p1 string) (*CommPRet, error) { return s.Internal.ClientCalcCommP(p0, p1) } @@ -978,27 +977,27 @@ func (s *FullNodeStruct) ClientCancelDataTransfer(p0 context.Context, p1 datatra return s.Internal.ClientCancelDataTransfer(p0, p1, p2, p3) } -func (s *FullNodeStruct) ClientDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { +func (s *FullNodeStruct) ClientDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { return s.Internal.ClientDataTransferUpdates(p0) } -func (s *FullNodeStruct) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) { +func (s *FullNodeStruct) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) { return s.Internal.ClientDealPieceCID(p0, p1) } -func (s *FullNodeStruct) ClientDealSize(p0 context.Context, p1 cid.Cid) (api.DataSize, error) { +func (s *FullNodeStruct) ClientDealSize(p0 context.Context, p1 cid.Cid) (DataSize, error) { return s.Internal.ClientDealSize(p0, p1) } -func (s *FullNodeStruct) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) { +func (s *FullNodeStruct) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) { return s.Internal.ClientFindData(p0, p1, p2) } -func (s *FullNodeStruct) ClientGenCar(p0 context.Context, p1 api.FileRef, p2 string) error { +func (s *FullNodeStruct) ClientGenCar(p0 context.Context, p1 FileRef, p2 string) error { return s.Internal.ClientGenCar(p0, p1, p2) } -func (s *FullNodeStruct) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) { +func (s *FullNodeStruct) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*DealInfo, error) { return s.Internal.ClientGetDealInfo(p0, p1) } @@ -1006,7 +1005,7 @@ func (s *FullNodeStruct) ClientGetDealStatus(p0 context.Context, p1 uint64) (str return s.Internal.ClientGetDealStatus(p0, p1) } -func (s *FullNodeStruct) ClientGetDealUpdates(p0 context.Context) (<-chan api.DealInfo, error) { +func (s *FullNodeStruct) ClientGetDealUpdates(p0 context.Context) (<-chan DealInfo, error) { return s.Internal.ClientGetDealUpdates(p0) } @@ -1014,23 +1013,23 @@ func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, e return s.Internal.ClientHasLocal(p0, p1) } -func (s *FullNodeStruct) ClientImport(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) { +func (s *FullNodeStruct) ClientImport(p0 context.Context, p1 FileRef) (*ImportRes, error) { return s.Internal.ClientImport(p0, p1) } -func (s *FullNodeStruct) ClientListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { +func (s *FullNodeStruct) ClientListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { return s.Internal.ClientListDataTransfers(p0) } -func (s *FullNodeStruct) ClientListDeals(p0 context.Context) ([]api.DealInfo, error) { +func (s *FullNodeStruct) ClientListDeals(p0 context.Context) ([]DealInfo, error) { return s.Internal.ClientListDeals(p0) } -func (s *FullNodeStruct) ClientListImports(p0 context.Context) ([]api.Import, error) { +func (s *FullNodeStruct) ClientListImports(p0 context.Context) ([]Import, error) { return s.Internal.ClientListImports(p0) } -func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) { +func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) { return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) } @@ -1046,7 +1045,7 @@ func (s *FullNodeStruct) ClientRestartDataTransfer(p0 context.Context, p1 datatr return s.Internal.ClientRestartDataTransfer(p0, p1, p2, p3) } -func (s *FullNodeStruct) ClientRetrieve(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error { +func (s *FullNodeStruct) ClientRetrieve(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) error { return s.Internal.ClientRetrieve(p0, p1, p2) } @@ -1054,11 +1053,11 @@ func (s *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(p0 context.Co return s.Internal.ClientRetrieveTryRestartInsufficientFunds(p0, p1) } -func (s *FullNodeStruct) ClientRetrieveWithEvents(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { +func (s *FullNodeStruct) ClientRetrieveWithEvents(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) (<-chan marketevents.RetrievalEvent, error) { return s.Internal.ClientRetrieveWithEvents(p0, p1, p2) } -func (s *FullNodeStruct) ClientStartDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) { +func (s *FullNodeStruct) ClientStartDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) { return s.Internal.ClientStartDeal(p0, p1) } @@ -1078,7 +1077,7 @@ func (s *FullNodeStruct) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 return s.Internal.GasEstimateGasPremium(p0, p1, p2, p3, p4) } -func (s *FullNodeStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { +func (s *FullNodeStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } @@ -1102,11 +1101,11 @@ func (s *FullNodeStruct) MarketWithdraw(p0 context.Context, p1 address.Address, return s.Internal.MarketWithdraw(p0, p1, p2, p3) } -func (s *FullNodeStruct) MinerCreateBlock(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) { +func (s *FullNodeStruct) MinerCreateBlock(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) { return s.Internal.MinerCreateBlock(p0, p1) } -func (s *FullNodeStruct) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) { +func (s *FullNodeStruct) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) { return s.Internal.MinerGetBaseInfo(p0, p1, p2, p3) } @@ -1114,7 +1113,7 @@ func (s *FullNodeStruct) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMe return s.Internal.MpoolBatchPush(p0, p1) } -func (s *FullNodeStruct) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { +func (s *FullNodeStruct) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) { return s.Internal.MpoolBatchPushMessage(p0, p1, p2) } @@ -1142,7 +1141,7 @@ func (s *FullNodeStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) return s.Internal.MpoolPush(p0, p1) } -func (s *FullNodeStruct) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) { +func (s *FullNodeStruct) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) { return s.Internal.MpoolPushMessage(p0, p1, p2) } @@ -1158,7 +1157,7 @@ func (s *FullNodeStruct) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfi return s.Internal.MpoolSetConfig(p0, p1) } -func (s *FullNodeStruct) MpoolSub(p0 context.Context) (<-chan api.MpoolUpdate, error) { +func (s *FullNodeStruct) MpoolSub(p0 context.Context) (<-chan MpoolUpdate, error) { return s.Internal.MpoolSub(p0) } @@ -1194,7 +1193,7 @@ func (s *FullNodeStruct) MsigGetAvailableBalance(p0 context.Context, p1 address. return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } -func (s *FullNodeStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { +func (s *FullNodeStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { return s.Internal.MsigGetPending(p0, p1, p2) } @@ -1202,7 +1201,7 @@ func (s *FullNodeStruct) MsigGetVested(p0 context.Context, p1 address.Address, p return s.Internal.MsigGetVested(p0, p1, p2, p3) } -func (s *FullNodeStruct) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) { +func (s *FullNodeStruct) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) { return s.Internal.MsigGetVestingSchedule(p0, p1, p2) } @@ -1230,11 +1229,11 @@ func (s *FullNodeStruct) PaychAllocateLane(p0 context.Context, p1 address.Addres return s.Internal.PaychAllocateLane(p0, p1) } -func (s *FullNodeStruct) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) { +func (s *FullNodeStruct) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) { return s.Internal.PaychAvailableFunds(p0, p1) } -func (s *FullNodeStruct) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) { +func (s *FullNodeStruct) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) { return s.Internal.PaychAvailableFundsByFromTo(p0, p1, p2) } @@ -1242,7 +1241,7 @@ func (s *FullNodeStruct) PaychCollect(p0 context.Context, p1 address.Address) (c return s.Internal.PaychCollect(p0, p1) } -func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) { +func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) { return s.Internal.PaychGet(p0, p1, p2, p3) } @@ -1254,7 +1253,7 @@ func (s *FullNodeStruct) PaychList(p0 context.Context) ([]address.Address, error return s.Internal.PaychList(p0) } -func (s *FullNodeStruct) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) { +func (s *FullNodeStruct) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) { return s.Internal.PaychNewPayment(p0, p1, p2, p3) } @@ -1262,7 +1261,7 @@ func (s *FullNodeStruct) PaychSettle(p0 context.Context, p1 address.Address) (ci return s.Internal.PaychSettle(p0, p1) } -func (s *FullNodeStruct) PaychStatus(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) { +func (s *FullNodeStruct) PaychStatus(p0 context.Context, p1 address.Address) (*PaychStatus, error) { return s.Internal.PaychStatus(p0, p1) } @@ -1278,7 +1277,7 @@ func (s *FullNodeStruct) PaychVoucherCheckValid(p0 context.Context, p1 address.A return s.Internal.PaychVoucherCheckValid(p0, p1, p2) } -func (s *FullNodeStruct) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) { +func (s *FullNodeStruct) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) { return s.Internal.PaychVoucherCreate(p0, p1, p2, p3) } @@ -1294,11 +1293,11 @@ func (s *FullNodeStruct) StateAccountKey(p0 context.Context, p1 address.Address, return s.Internal.StateAccountKey(p0, p1, p2) } -func (s *FullNodeStruct) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) { +func (s *FullNodeStruct) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) { return s.Internal.StateAllMinerFaults(p0, p1, p2) } -func (s *FullNodeStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) { +func (s *FullNodeStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) { return s.Internal.StateCall(p0, p1, p2) } @@ -1310,11 +1309,11 @@ func (s *FullNodeStruct) StateCirculatingSupply(p0 context.Context, p1 types.Tip return s.Internal.StateCirculatingSupply(p0, p1) } -func (s *FullNodeStruct) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) { +func (s *FullNodeStruct) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*ComputeStateOutput, error) { return s.Internal.StateCompute(p0, p1, p2, p3) } -func (s *FullNodeStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { +func (s *FullNodeStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } @@ -1334,7 +1333,7 @@ func (s *FullNodeStruct) StateListActors(p0 context.Context, p1 types.TipSetKey) return s.Internal.StateListActors(p0, p1) } -func (s *FullNodeStruct) StateListMessages(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { +func (s *FullNodeStruct) StateListMessages(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { return s.Internal.StateListMessages(p0, p1, p2, p3) } @@ -1346,19 +1345,19 @@ func (s *FullNodeStruct) StateLookupID(p0 context.Context, p1 address.Address, p return s.Internal.StateLookupID(p0, p1, p2) } -func (s *FullNodeStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { +func (s *FullNodeStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { return s.Internal.StateMarketBalance(p0, p1, p2) } -func (s *FullNodeStruct) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) { +func (s *FullNodeStruct) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]MarketDeal, error) { return s.Internal.StateMarketDeals(p0, p1) } -func (s *FullNodeStruct) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) { +func (s *FullNodeStruct) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) { return s.Internal.StateMarketParticipants(p0, p1) } -func (s *FullNodeStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { +func (s *FullNodeStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { return s.Internal.StateMarketStorageDeal(p0, p1, p2) } @@ -1370,7 +1369,7 @@ func (s *FullNodeStruct) StateMinerAvailableBalance(p0 context.Context, p1 addre return s.Internal.StateMinerAvailableBalance(p0, p1, p2) } -func (s *FullNodeStruct) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) { +func (s *FullNodeStruct) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) { return s.Internal.StateMinerDeadlines(p0, p1, p2) } @@ -1386,11 +1385,11 @@ func (s *FullNodeStruct) StateMinerInitialPledgeCollateral(p0 context.Context, p return s.Internal.StateMinerInitialPledgeCollateral(p0, p1, p2, p3) } -func (s *FullNodeStruct) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) { +func (s *FullNodeStruct) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) { return s.Internal.StateMinerPartitions(p0, p1, p2, p3) } -func (s *FullNodeStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { +func (s *FullNodeStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { return s.Internal.StateMinerPower(p0, p1, p2) } @@ -1410,7 +1409,7 @@ func (s *FullNodeStruct) StateMinerSectorAllocated(p0 context.Context, p1 addres return s.Internal.StateMinerSectorAllocated(p0, p1, p2, p3) } -func (s *FullNodeStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) { +func (s *FullNodeStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) { return s.Internal.StateMinerSectorCount(p0, p1, p2) } @@ -1426,19 +1425,19 @@ func (s *FullNodeStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSet return s.Internal.StateNetworkVersion(p0, p1) } -func (s *FullNodeStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) { +func (s *FullNodeStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) { return s.Internal.StateReadState(p0, p1, p2) } -func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) { +func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) { return s.Internal.StateReplay(p0, p1, p2) } -func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { +func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) { return s.Internal.StateSearchMsg(p0, p1) } -func (s *FullNodeStruct) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) { +func (s *FullNodeStruct) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*MsgLookup, error) { return s.Internal.StateSearchMsgLimited(p0, p1, p2) } @@ -1458,7 +1457,7 @@ func (s *FullNodeStruct) StateSectorPreCommitInfo(p0 context.Context, p1 address return s.Internal.StateSectorPreCommitInfo(p0, p1, p2, p3) } -func (s *FullNodeStruct) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) { +func (s *FullNodeStruct) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) { return s.Internal.StateVMCirculatingSupplyInternal(p0, p1) } @@ -1474,11 +1473,11 @@ func (s *FullNodeStruct) StateVerifierStatus(p0 context.Context, p1 address.Addr return s.Internal.StateVerifierStatus(p0, p1, p2) } -func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { +func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) { return s.Internal.StateWaitMsg(p0, p1, p2) } -func (s *FullNodeStruct) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) { +func (s *FullNodeStruct) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*MsgLookup, error) { return s.Internal.StateWaitMsgLimited(p0, p1, p2, p3) } @@ -1498,7 +1497,7 @@ func (s *FullNodeStruct) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { return s.Internal.SyncMarkBad(p0, p1) } -func (s *FullNodeStruct) SyncState(p0 context.Context) (*api.SyncState, error) { +func (s *FullNodeStruct) SyncState(p0 context.Context) (*SyncState, error) { return s.Internal.SyncState(p0) } @@ -1570,7 +1569,7 @@ func (s *FullNodeStruct) WalletVerify(p0 context.Context, p1 address.Address, p2 return s.Internal.WalletVerify(p0, p1, p2, p3) } -func (s *GatewayStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { +func (s *GatewayStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { return s.Internal.ChainGetBlockMessages(p0, p1) } @@ -1594,7 +1593,7 @@ func (s *GatewayStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { return s.Internal.ChainHead(p0) } -func (s *GatewayStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { +func (s *GatewayStruct) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { return s.Internal.ChainNotify(p0) } @@ -1602,7 +1601,7 @@ func (s *GatewayStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, er return s.Internal.ChainReadObj(p0, p1) } -func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { +func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } @@ -1614,7 +1613,7 @@ func (s *GatewayStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.A return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } -func (s *GatewayStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { +func (s *GatewayStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { return s.Internal.MsigGetPending(p0, p1, p2) } @@ -1626,7 +1625,7 @@ func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, return s.Internal.StateAccountKey(p0, p1, p2) } -func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { +func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } @@ -1646,11 +1645,11 @@ func (s *GatewayStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 return s.Internal.StateLookupID(p0, p1, p2) } -func (s *GatewayStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { +func (s *GatewayStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { return s.Internal.StateMarketBalance(p0, p1, p2) } -func (s *GatewayStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { +func (s *GatewayStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { return s.Internal.StateMarketStorageDeal(p0, p1, p2) } @@ -1658,7 +1657,7 @@ func (s *GatewayStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p return s.Internal.StateMinerInfo(p0, p1, p2) } -func (s *GatewayStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { +func (s *GatewayStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { return s.Internal.StateMinerPower(p0, p1, p2) } @@ -1670,7 +1669,7 @@ func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetK return s.Internal.StateNetworkVersion(p0, p1) } -func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { +func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) { return s.Internal.StateSearchMsg(p0, p1) } @@ -1682,11 +1681,11 @@ func (s *GatewayStruct) StateVerifiedClientStatus(p0 context.Context, p1 address return s.Internal.StateVerifiedClientStatus(p0, p1, p2) } -func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { +func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) { return s.Internal.StateWaitMsg(p0, p1, p2) } -func (s *SignableStruct) Sign(p0 context.Context, p1 api.SignFunc) error { +func (s *SignableStruct) Sign(p0 context.Context, p1 SignFunc) error { return s.Internal.Sign(p0, p1) } @@ -1694,7 +1693,7 @@ func (s *StorageMinerStruct) ActorAddress(p0 context.Context) (address.Address, return s.Internal.ActorAddress(p0) } -func (s *StorageMinerStruct) ActorAddressConfig(p0 context.Context) (api.AddressConfig, error) { +func (s *StorageMinerStruct) ActorAddressConfig(p0 context.Context) (AddressConfig, error) { return s.Internal.ActorAddressConfig(p0) } @@ -1738,7 +1737,7 @@ func (s *StorageMinerStruct) DealsImportData(p0 context.Context, p1 cid.Cid, p2 return s.Internal.DealsImportData(p0, p1, p2) } -func (s *StorageMinerStruct) DealsList(p0 context.Context) ([]api.MarketDeal, error) { +func (s *StorageMinerStruct) DealsList(p0 context.Context) ([]MarketDeal, error) { return s.Internal.DealsList(p0) } @@ -1778,7 +1777,7 @@ func (s *StorageMinerStruct) MarketCancelDataTransfer(p0 context.Context, p1 dat return s.Internal.MarketCancelDataTransfer(p0, p1, p2, p3) } -func (s *StorageMinerStruct) MarketDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { +func (s *StorageMinerStruct) MarketDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { return s.Internal.MarketDataTransferUpdates(p0) } @@ -1798,11 +1797,11 @@ func (s *StorageMinerStruct) MarketImportDealData(p0 context.Context, p1 cid.Cid return s.Internal.MarketImportDealData(p0, p1, p2) } -func (s *StorageMinerStruct) MarketListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { +func (s *StorageMinerStruct) MarketListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { return s.Internal.MarketListDataTransfers(p0) } -func (s *StorageMinerStruct) MarketListDeals(p0 context.Context) ([]api.MarketDeal, error) { +func (s *StorageMinerStruct) MarketListDeals(p0 context.Context) ([]MarketDeal, error) { return s.Internal.MarketListDeals(p0) } @@ -1814,7 +1813,7 @@ func (s *StorageMinerStruct) MarketListRetrievalDeals(p0 context.Context) ([]ret return s.Internal.MarketListRetrievalDeals(p0) } -func (s *StorageMinerStruct) MarketPendingDeals(p0 context.Context) (api.PendingDealInfo, error) { +func (s *StorageMinerStruct) MarketPendingDeals(p0 context.Context) (PendingDealInfo, error) { return s.Internal.MarketPendingDeals(p0) } @@ -1954,23 +1953,23 @@ func (s *StorageMinerStruct) SectorsList(p0 context.Context) ([]abi.SectorNumber return s.Internal.SectorsList(p0) } -func (s *StorageMinerStruct) SectorsListInStates(p0 context.Context, p1 []api.SectorState) ([]abi.SectorNumber, error) { +func (s *StorageMinerStruct) SectorsListInStates(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) { return s.Internal.SectorsListInStates(p0, p1) } -func (s *StorageMinerStruct) SectorsRefs(p0 context.Context) (map[string][]api.SealedRef, error) { +func (s *StorageMinerStruct) SectorsRefs(p0 context.Context) (map[string][]SealedRef, error) { return s.Internal.SectorsRefs(p0) } -func (s *StorageMinerStruct) SectorsStatus(p0 context.Context, p1 abi.SectorNumber, p2 bool) (api.SectorInfo, error) { +func (s *StorageMinerStruct) SectorsStatus(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) { return s.Internal.SectorsStatus(p0, p1, p2) } -func (s *StorageMinerStruct) SectorsSummary(p0 context.Context) (map[api.SectorState]int, error) { +func (s *StorageMinerStruct) SectorsSummary(p0 context.Context) (map[SectorState]int, error) { return s.Internal.SectorsSummary(p0) } -func (s *StorageMinerStruct) SectorsUpdate(p0 context.Context, p1 abi.SectorNumber, p2 api.SectorState) error { +func (s *StorageMinerStruct) SectorsUpdate(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error { return s.Internal.SectorsUpdate(p0, p1, p2) } @@ -2062,7 +2061,7 @@ func (s *WalletStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address. return s.Internal.WalletNew(p0, p1) } -func (s *WalletStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte, p3 api.MsgMeta) (*crypto.Signature, error) { +func (s *WalletStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) { return s.Internal.WalletSign(p0, p1, p2, p3) } @@ -2154,7 +2153,7 @@ func (s *WorkerStruct) UnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 return s.Internal.UnsealPiece(p0, p1, p2, p3, p4, p5) } -func (s *WorkerStruct) Version(p0 context.Context) (api.Version, error) { +func (s *WorkerStruct) Version(p0 context.Context) (Version, error) { return s.Internal.Version(p0) } diff --git a/api/v0api/common.go b/api/v0api/common.go deleted file mode 100644 index 6848fa6a880..00000000000 --- a/api/v0api/common.go +++ /dev/null @@ -1,77 +0,0 @@ -package v0api - -import ( - "context" - - "github.com/filecoin-project/lotus/api" - - "github.com/google/uuid" - - "github.com/filecoin-project/go-jsonrpc/auth" - metrics "github.com/libp2p/go-libp2p-core/metrics" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - protocol "github.com/libp2p/go-libp2p-core/protocol" - - apitypes "github.com/filecoin-project/lotus/api/types" -) - -type Common interface { - - // MethodGroup: Auth - - AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) //perm:read - AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error) //perm:admin - - // MethodGroup: Net - - NetConnectedness(context.Context, peer.ID) (network.Connectedness, error) //perm:read - NetPeers(context.Context) ([]peer.AddrInfo, error) //perm:read - NetConnect(context.Context, peer.AddrInfo) error //perm:write - NetAddrsListen(context.Context) (peer.AddrInfo, error) //perm:read - NetDisconnect(context.Context, peer.ID) error //perm:write - NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error) //perm:read - NetPubsubScores(context.Context) ([]api.PubsubScore, error) //perm:read - NetAutoNatStatus(context.Context) (api.NatInfo, error) //perm:read - NetAgentVersion(ctx context.Context, p peer.ID) (string, error) //perm:read - NetPeerInfo(context.Context, peer.ID) (*api.ExtendedPeerInfo, error) //perm:read - - // NetBandwidthStats returns statistics about the nodes total bandwidth - // usage and current rate across all peers and protocols. - NetBandwidthStats(ctx context.Context) (metrics.Stats, error) //perm:read - - // NetBandwidthStatsByPeer returns statistics about the nodes bandwidth - // usage and current rate per peer - NetBandwidthStatsByPeer(ctx context.Context) (map[string]metrics.Stats, error) //perm:read - - // NetBandwidthStatsByProtocol returns statistics about the nodes bandwidth - // usage and current rate per protocol - NetBandwidthStatsByProtocol(ctx context.Context) (map[protocol.ID]metrics.Stats, error) //perm:read - - // ConnectionGater API - NetBlockAdd(ctx context.Context, acl api.NetBlockList) error //perm:admin - NetBlockRemove(ctx context.Context, acl api.NetBlockList) error //perm:admin - NetBlockList(ctx context.Context) (api.NetBlockList, error) //perm:read - - // MethodGroup: Common - - // Discover returns an OpenRPC document describing an RPC API. - Discover(ctx context.Context) (apitypes.OpenRPCDocument, error) //perm:read - - // ID returns peerID of libp2p node backing this API - ID(context.Context) (peer.ID, error) //perm:read - - // Version provides information about API provider - Version(context.Context) (api.APIVersion, error) //perm:read - - LogList(context.Context) ([]string, error) //perm:write - LogSetLevel(context.Context, string, string) error //perm:write - - // trigger graceful shutdown - Shutdown(context.Context) error //perm:admin - - // Session returns a random UUID of api provider session - Session(context.Context) (uuid.UUID, error) //perm:read - - Closing(context.Context) (<-chan struct{}, error) //perm:read -} diff --git a/api/v0api/latest.go b/api/v0api/latest.go new file mode 100644 index 00000000000..9e29f948dc4 --- /dev/null +++ b/api/v0api/latest.go @@ -0,0 +1,24 @@ +package v0api + +import ( + "github.com/filecoin-project/lotus/api" +) + +type Common = api.Common +type CommonStruct = api.CommonStruct + +type Gateway = api.Gateway + +type StorageMiner = api.StorageMiner +type StorageMinerStruct = api.StorageMinerStruct + +type Worker = api.Worker +type WorkerStruct = api.WorkerStruct + +func PermissionedStorMinerAPI(a StorageMiner) StorageMiner { + return api.PermissionedStorMinerAPI(a) +} + +func PermissionedWorkerAPI(a Worker) Worker { + return api.PermissionedWorkerAPI(a) +} diff --git a/api/v0api/permissioned.go b/api/v0api/permissioned.go new file mode 100644 index 00000000000..ad64bc29ede --- /dev/null +++ b/api/v0api/permissioned.go @@ -0,0 +1,13 @@ +package v0api + +import ( + "github.com/filecoin-project/go-jsonrpc/auth" + "github.com/filecoin-project/lotus/api" +) + +func PermissionedFullAPI(a FullNode) FullNode { + var out FullNodeStruct + auth.PermissionedProxy(api.AllPermissions, api.DefaultPerms, a, &out.Internal) + auth.PermissionedProxy(api.AllPermissions, api.DefaultPerms, a, &out.CommonStruct.Internal) + return &out +} diff --git a/api/v0api/storage.go b/api/v0api/storage.go deleted file mode 100644 index a05f482858e..00000000000 --- a/api/v0api/storage.go +++ /dev/null @@ -1,9 +0,0 @@ -package v0api - -import ( - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" -) - -type StorageMiner = api.StorageMiner -type StorageMinerStruct = apistruct.StorageMinerStruct diff --git a/api/v0api/struct.go b/api/v0api/struct.go index e5550814f38..0a7fb97dc7e 100644 --- a/api/v0api/struct.go +++ b/api/v0api/struct.go @@ -9,7 +9,6 @@ import ( "github.com/filecoin-project/go-bitfield" datatransfer "github.com/filecoin-project/go-data-transfer" "github.com/filecoin-project/go-fil-markets/storagemarket" - "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/go-multistore" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" @@ -21,70 +20,10 @@ import ( "github.com/filecoin-project/lotus/chain/types" marketevents "github.com/filecoin-project/lotus/markets/loggers" "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/google/uuid" "github.com/ipfs/go-cid" - metrics "github.com/libp2p/go-libp2p-core/metrics" - "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" - protocol "github.com/libp2p/go-libp2p-core/protocol" ) -type CommonStruct struct { - Internal struct { - AuthNew func(p0 context.Context, p1 []auth.Permission) ([]byte, error) `perm:"admin"` - - AuthVerify func(p0 context.Context, p1 string) ([]auth.Permission, error) `perm:"read"` - - Closing func(p0 context.Context) (<-chan struct{}, error) `perm:"read"` - - Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) `perm:"read"` - - ID func(p0 context.Context) (peer.ID, error) `perm:"read"` - - LogList func(p0 context.Context) ([]string, error) `perm:"write"` - - LogSetLevel func(p0 context.Context, p1 string, p2 string) error `perm:"write"` - - NetAddrsListen func(p0 context.Context) (peer.AddrInfo, error) `perm:"read"` - - NetAgentVersion func(p0 context.Context, p1 peer.ID) (string, error) `perm:"read"` - - NetAutoNatStatus func(p0 context.Context) (api.NatInfo, error) `perm:"read"` - - NetBandwidthStats func(p0 context.Context) (metrics.Stats, error) `perm:"read"` - - NetBandwidthStatsByPeer func(p0 context.Context) (map[string]metrics.Stats, error) `perm:"read"` - - NetBandwidthStatsByProtocol func(p0 context.Context) (map[protocol.ID]metrics.Stats, error) `perm:"read"` - - NetBlockAdd func(p0 context.Context, p1 api.NetBlockList) error `perm:"admin"` - - NetBlockList func(p0 context.Context) (api.NetBlockList, error) `perm:"read"` - - NetBlockRemove func(p0 context.Context, p1 api.NetBlockList) error `perm:"admin"` - - NetConnect func(p0 context.Context, p1 peer.AddrInfo) error `perm:"write"` - - NetConnectedness func(p0 context.Context, p1 peer.ID) (network.Connectedness, error) `perm:"read"` - - NetDisconnect func(p0 context.Context, p1 peer.ID) error `perm:"write"` - - NetFindPeer func(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) `perm:"read"` - - NetPeerInfo func(p0 context.Context, p1 peer.ID) (*api.ExtendedPeerInfo, error) `perm:"read"` - - NetPeers func(p0 context.Context) ([]peer.AddrInfo, error) `perm:"read"` - - NetPubsubScores func(p0 context.Context) ([]api.PubsubScore, error) `perm:"read"` - - Session func(p0 context.Context) (uuid.UUID, error) `perm:"read"` - - Shutdown func(p0 context.Context) error `perm:"admin"` - - Version func(p0 context.Context) (api.APIVersion, error) `perm:"read"` - } -} - type FullNodeStruct struct { CommonStruct @@ -435,110 +374,6 @@ type FullNodeStruct struct { } } -func (s *CommonStruct) AuthNew(p0 context.Context, p1 []auth.Permission) ([]byte, error) { - return s.Internal.AuthNew(p0, p1) -} - -func (s *CommonStruct) AuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { - return s.Internal.AuthVerify(p0, p1) -} - -func (s *CommonStruct) Closing(p0 context.Context) (<-chan struct{}, error) { - return s.Internal.Closing(p0) -} - -func (s *CommonStruct) Discover(p0 context.Context) (apitypes.OpenRPCDocument, error) { - return s.Internal.Discover(p0) -} - -func (s *CommonStruct) ID(p0 context.Context) (peer.ID, error) { - return s.Internal.ID(p0) -} - -func (s *CommonStruct) LogList(p0 context.Context) ([]string, error) { - return s.Internal.LogList(p0) -} - -func (s *CommonStruct) LogSetLevel(p0 context.Context, p1 string, p2 string) error { - return s.Internal.LogSetLevel(p0, p1, p2) -} - -func (s *CommonStruct) NetAddrsListen(p0 context.Context) (peer.AddrInfo, error) { - return s.Internal.NetAddrsListen(p0) -} - -func (s *CommonStruct) NetAgentVersion(p0 context.Context, p1 peer.ID) (string, error) { - return s.Internal.NetAgentVersion(p0, p1) -} - -func (s *CommonStruct) NetAutoNatStatus(p0 context.Context) (api.NatInfo, error) { - return s.Internal.NetAutoNatStatus(p0) -} - -func (s *CommonStruct) NetBandwidthStats(p0 context.Context) (metrics.Stats, error) { - return s.Internal.NetBandwidthStats(p0) -} - -func (s *CommonStruct) NetBandwidthStatsByPeer(p0 context.Context) (map[string]metrics.Stats, error) { - return s.Internal.NetBandwidthStatsByPeer(p0) -} - -func (s *CommonStruct) NetBandwidthStatsByProtocol(p0 context.Context) (map[protocol.ID]metrics.Stats, error) { - return s.Internal.NetBandwidthStatsByProtocol(p0) -} - -func (s *CommonStruct) NetBlockAdd(p0 context.Context, p1 api.NetBlockList) error { - return s.Internal.NetBlockAdd(p0, p1) -} - -func (s *CommonStruct) NetBlockList(p0 context.Context) (api.NetBlockList, error) { - return s.Internal.NetBlockList(p0) -} - -func (s *CommonStruct) NetBlockRemove(p0 context.Context, p1 api.NetBlockList) error { - return s.Internal.NetBlockRemove(p0, p1) -} - -func (s *CommonStruct) NetConnect(p0 context.Context, p1 peer.AddrInfo) error { - return s.Internal.NetConnect(p0, p1) -} - -func (s *CommonStruct) NetConnectedness(p0 context.Context, p1 peer.ID) (network.Connectedness, error) { - return s.Internal.NetConnectedness(p0, p1) -} - -func (s *CommonStruct) NetDisconnect(p0 context.Context, p1 peer.ID) error { - return s.Internal.NetDisconnect(p0, p1) -} - -func (s *CommonStruct) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) { - return s.Internal.NetFindPeer(p0, p1) -} - -func (s *CommonStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*api.ExtendedPeerInfo, error) { - return s.Internal.NetPeerInfo(p0, p1) -} - -func (s *CommonStruct) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) { - return s.Internal.NetPeers(p0) -} - -func (s *CommonStruct) NetPubsubScores(p0 context.Context) ([]api.PubsubScore, error) { - return s.Internal.NetPubsubScores(p0) -} - -func (s *CommonStruct) Session(p0 context.Context) (uuid.UUID, error) { - return s.Internal.Session(p0) -} - -func (s *CommonStruct) Shutdown(p0 context.Context) error { - return s.Internal.Shutdown(p0) -} - -func (s *CommonStruct) Version(p0 context.Context) (api.APIVersion, error) { - return s.Internal.Version(p0) -} - func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { return s.Internal.BeaconGetEntry(p0, p1) } @@ -1227,5 +1062,4 @@ func (s *FullNodeStruct) WalletVerify(p0 context.Context, p1 address.Address, p2 return s.Internal.WalletVerify(p0, p1, p2, p3) } -var _ Common = new(CommonStruct) var _ FullNode = new(FullNodeStruct) diff --git a/api/v1api/latest.go b/api/v1api/latest.go index eb67e1e363a..6f57d88262c 100644 --- a/api/v1api/latest.go +++ b/api/v1api/latest.go @@ -2,8 +2,11 @@ package v1api import ( "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" ) type FullNode = api.FullNode -type FullNodeStruct = apistruct.FullNodeStruct +type FullNodeStruct = api.FullNodeStruct + +func PermissionedFullAPI(a FullNode) FullNode { + return api.PermissionedFullAPI(a) +} diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 42d7e5b954d1b5f955c274b897f12b195c68386a..6225a04aaee0d4f139b65efc61d021589a4e9f48 100644 GIT binary patch literal 22496 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 bMCQV|(2CBVZC)h7&(E={=}o^ts7U_>zxAJ= diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index faab78eb76c65d98e3190189bcda59a2faa51f16..e311dc8cc26a3400418dada4154810e5eac750f1 100644 GIT binary patch literal 7608 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 ac2h+h8qd!+&;K6)0RR8G8tvFgbpZfe663D` literal 7643 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 JfEo*V0RT7s00{s9 diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 7bf6216a75f64bf7adaa10fbee6e214287f259b6..62ec8064c97cfb0a84f7fe2b5284a0161e163955 100644 GIT binary patch literal 2561 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 diff --git a/cli/auth.go b/cli/auth.go index 6426a4ab681..20b9bb39428 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -8,7 +8,7 @@ import ( "github.com/filecoin-project/go-jsonrpc/auth" - "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/api" cliutil "github.com/filecoin-project/lotus/cli/util" "github.com/filecoin-project/lotus/node/repo" ) @@ -47,18 +47,18 @@ var AuthCreateAdminToken = &cli.Command{ perm := cctx.String("perm") idx := 0 - for i, p := range apistruct.AllPermissions { + for i, p := range api.AllPermissions { if auth.Permission(perm) == p { idx = i + 1 } } if idx == 0 { - return fmt.Errorf("--perm flag has to be one of: %s", apistruct.AllPermissions) + return fmt.Errorf("--perm flag has to be one of: %s", api.AllPermissions) } // slice on [:idx] so for example: 'sign' gives you [read, write, sign] - token, err := napi.AuthNew(ctx, apistruct.AllPermissions[:idx]) + token, err := napi.AuthNew(ctx, api.AllPermissions[:idx]) if err != nil { return err } @@ -95,18 +95,18 @@ var AuthApiInfoToken = &cli.Command{ perm := cctx.String("perm") idx := 0 - for i, p := range apistruct.AllPermissions { + for i, p := range api.AllPermissions { if auth.Permission(perm) == p { idx = i + 1 } } if idx == 0 { - return fmt.Errorf("--perm flag has to be one of: %s", apistruct.AllPermissions) + return fmt.Errorf("--perm flag has to be one of: %s", api.AllPermissions) } // slice on [:idx] so for example: 'sign' gives you [read, write, sign] - token, err := napi.AuthNew(ctx, apistruct.AllPermissions[:idx]) + token, err := napi.AuthNew(ctx, api.AllPermissions[:idx]) if err != nil { return err } diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index 24918e52a39..0f0cb88e6f1 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -28,7 +28,6 @@ import ( "github.com/filecoin-project/go-statestore" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" cliutil "github.com/filecoin-project/lotus/cli/util" @@ -366,7 +365,7 @@ var runCmd = &cli.Command{ fh := &stores.FetchHandler{Local: localStore} remoteHandler := func(w http.ResponseWriter, r *http.Request) { - if !auth.HasPerm(r.Context(), nil, apistruct.PermAdmin) { + if !auth.HasPerm(r.Context(), nil, api.PermAdmin) { w.WriteHeader(401) _ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing admin permission"}) return @@ -394,7 +393,7 @@ var runCmd = &cli.Command{ readerHandler, readerServerOpt := rpcenc.ReaderParamDecoder() rpcServer := jsonrpc.NewServer(readerServerOpt) - rpcServer.Register("Filecoin", apistruct.PermissionedWorkerAPI(metrics.MetricedWorkerAPI(workerApi))) + rpcServer.Register("Filecoin", api.PermissionedWorkerAPI(metrics.MetricedWorkerAPI(workerApi))) mux.Handle("/rpc/v0", rpcServer) mux.Handle("/rpc/streams/v0/push/{uuid}", readerHandler) diff --git a/cmd/lotus-shed/jwt.go b/cmd/lotus-shed/jwt.go index 78abcec76ee..e8853b419b6 100644 --- a/cmd/lotus-shed/jwt.go +++ b/cmd/lotus-shed/jwt.go @@ -15,7 +15,8 @@ import ( "github.com/urfave/cli/v2" "github.com/filecoin-project/go-jsonrpc/auth" - "github.com/filecoin-project/lotus/api/apistruct" + + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/modules" ) @@ -98,19 +99,19 @@ var jwtTokenCmd = &cli.Command{ perms := []auth.Permission{} if cctx.Bool("read") { - perms = append(perms, apistruct.PermRead) + perms = append(perms, api.PermRead) } if cctx.Bool("write") { - perms = append(perms, apistruct.PermWrite) + perms = append(perms, api.PermWrite) } if cctx.Bool("sign") { - perms = append(perms, apistruct.PermSign) + perms = append(perms, api.PermSign) } if cctx.Bool("admin") { - perms = append(perms, apistruct.PermAdmin) + perms = append(perms, api.PermAdmin) } p := modules.JwtPayload{ @@ -152,7 +153,7 @@ var jwtNewCmd = &cli.Command{ } p := modules.JwtPayload{ - Allow: apistruct.AllPermissions, + Allow: api.AllPermissions, } token, err := jwt.Sign(&p, jwt.NewHS256(keyInfo.PrivateKey)) diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index cdcc4d88f59..0d2e5a70ef2 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -22,7 +22,6 @@ import ( "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/ulimit" @@ -165,7 +164,7 @@ var runCmd = &cli.Command{ mux := mux.NewRouter() rpcServer := jsonrpc.NewServer() - rpcServer.Register("Filecoin", apistruct.PermissionedStorMinerAPI(metrics.MetricedStorMinerAPI(minerapi))) + rpcServer.Register("Filecoin", api.PermissionedStorMinerAPI(metrics.MetricedStorMinerAPI(minerapi))) mux.Handle("/rpc/v0", rpcServer) mux.PathPrefix("/remote").HandlerFunc(minerapi.(*impl.StorageMinerAPI).ServeRemote) diff --git a/cmd/lotus/rpc.go b/cmd/lotus/rpc.go index 00de0fddb08..95050d63936 100644 --- a/cmd/lotus/rpc.go +++ b/cmd/lotus/rpc.go @@ -21,7 +21,7 @@ import ( "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc/auth" - "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/metrics" @@ -48,7 +48,7 @@ func serveRPC(a v1api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, sh http.Handle(path, ah) } - pma := apistruct.PermissionedFullAPI(metrics.MetricedFullAPI(a)) + pma := api.PermissionedFullAPI(metrics.MetricedFullAPI(a)) serveRpc("/rpc/v1", pma) serveRpc("/rpc/v0", &v0api.WrapperV1Full{FullNode: pma}) @@ -116,7 +116,7 @@ func handleImport(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Reque w.WriteHeader(404) return } - if !auth.HasPerm(r.Context(), nil, apistruct.PermWrite) { + if !auth.HasPerm(r.Context(), nil, api.PermWrite) { w.WriteHeader(401) _ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"}) return diff --git a/gen/api/proxygen.go b/gen/api/proxygen.go index 64859380f84..fb624c80810 100644 --- a/gen/api/proxygen.go +++ b/gen/api/proxygen.go @@ -54,7 +54,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor { } func main() { // latest (v1) - if err := generate("./api", "api", "apistruct", "./api/apistruct/struct.go"); err != nil { + if err := generate("./api", "api", "api", "./api/struct.go"); err != nil { fmt.Println("error: ", err) } @@ -64,34 +64,34 @@ func main() { } } -func typeName(e ast.Expr) (string, error) { +func typeName(e ast.Expr, pkg string) (string, error) { switch t := e.(type) { case *ast.SelectorExpr: return t.X.(*ast.Ident).Name + "." + t.Sel.Name, nil case *ast.Ident: pstr := t.Name - if !unicode.IsLower(rune(pstr[0])) { + if !unicode.IsLower(rune(pstr[0])) && pkg != "api" { pstr = "api." + pstr // todo src pkg name } return pstr, nil case *ast.ArrayType: - subt, err := typeName(t.Elt) + subt, err := typeName(t.Elt, pkg) if err != nil { return "", err } return "[]" + subt, nil case *ast.StarExpr: - subt, err := typeName(t.X) + subt, err := typeName(t.X, pkg) if err != nil { return "", err } return "*" + subt, nil case *ast.MapType: - k, err := typeName(t.Key) + k, err := typeName(t.Key, pkg) if err != nil { return "", err } - v, err := typeName(t.Value) + v, err := typeName(t.Value, pkg) if err != nil { return "", err } @@ -107,7 +107,7 @@ func typeName(e ast.Expr) (string, error) { } return "interface{}", nil case *ast.ChanType: - subt, err := typeName(t.Value) + subt, err := typeName(t.Value, pkg) if err != nil { return "", err } @@ -197,7 +197,7 @@ func generate(path, pkg, outpkg, outfile string) error { if _, ok := info.Methods[mname]; !ok { var params, pnames []string for _, param := range node.ftype.Params.List { - pstr, err := typeName(param.Type) + pstr, err := typeName(param.Type, outpkg) if err != nil { return err } @@ -216,7 +216,7 @@ func generate(path, pkg, outpkg, outfile string) error { var results []string for _, result := range node.ftype.Results.List { - rs, err := typeName(result.Type) + rs, err := typeName(result.Type, outpkg) if err != nil { return err } diff --git a/metrics/proxy.go b/metrics/proxy.go index 309ef80e196..7253a76c2e3 100644 --- a/metrics/proxy.go +++ b/metrics/proxy.go @@ -7,37 +7,36 @@ import ( "go.opencensus.io/tag" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" ) func MetricedStorMinerAPI(a api.StorageMiner) api.StorageMiner { - var out apistruct.StorageMinerStruct + var out api.StorageMinerStruct proxy(a, &out.Internal) proxy(a, &out.CommonStruct.Internal) return &out } func MetricedFullAPI(a api.FullNode) api.FullNode { - var out apistruct.FullNodeStruct + var out api.FullNodeStruct proxy(a, &out.Internal) proxy(a, &out.CommonStruct.Internal) return &out } func MetricedWorkerAPI(a api.Worker) api.Worker { - var out apistruct.WorkerStruct + var out api.WorkerStruct proxy(a, &out.Internal) return &out } func MetricedWalletAPI(a api.Wallet) api.Wallet { - var out apistruct.WalletStruct + var out api.WalletStruct proxy(a, &out.Internal) return &out } func MetricedGatewayAPI(a api.Gateway) api.Gateway { - var out apistruct.GatewayStruct + var out api.GatewayStruct proxy(a, &out.Internal) return &out } diff --git a/node/impl/storminer.go b/node/impl/storminer.go index e81560059c9..fa840d980ca 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -31,7 +31,6 @@ import ( sealing "github.com/filecoin-project/lotus/extern/storage-sealing" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" apitypes "github.com/filecoin-project/lotus/api/types" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/markets/storageadapter" @@ -86,7 +85,7 @@ type StorageMinerAPI struct { } func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { - if !auth.HasPerm(r.Context(), nil, apistruct.PermAdmin) { + if !auth.HasPerm(r.Context(), nil, api.PermAdmin) { w.WriteHeader(401) _ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"}) return diff --git a/node/modules/core.go b/node/modules/core.go index 83a7e8d4297..e089333e71c 100644 --- a/node/modules/core.go +++ b/node/modules/core.go @@ -22,7 +22,7 @@ import ( "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/addrutil" @@ -163,7 +163,7 @@ func APISecret(keystore types.KeyStore, lr repo.LockedRepo) (*dtypes.APIAlg, err // TODO: make this configurable p := JwtPayload{ - Allow: apistruct.AllPermissions, + Allow: api.AllPermissions, } cliToken, err := jwt.Sign(&p, jwt.NewHS256(key.PrivateKey)) From c25190bd8c3f4fbf074a0c7441e13849a8c7b401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 25 Mar 2021 15:11:37 +0100 Subject: [PATCH 10/60] api: struct.go -> proxy_gen.go --- api/{struct.go => proxy_gen.go} | 0 api/v0api/{struct.go => proxy_gen.go} | 0 gen/api/proxygen.go | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename api/{struct.go => proxy_gen.go} (100%) rename api/v0api/{struct.go => proxy_gen.go} (100%) diff --git a/api/struct.go b/api/proxy_gen.go similarity index 100% rename from api/struct.go rename to api/proxy_gen.go diff --git a/api/v0api/struct.go b/api/v0api/proxy_gen.go similarity index 100% rename from api/v0api/struct.go rename to api/v0api/proxy_gen.go diff --git a/gen/api/proxygen.go b/gen/api/proxygen.go index fb624c80810..d17807b44a0 100644 --- a/gen/api/proxygen.go +++ b/gen/api/proxygen.go @@ -54,12 +54,12 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor { } func main() { // latest (v1) - if err := generate("./api", "api", "api", "./api/struct.go"); err != nil { + if err := generate("./api", "api", "api", "./api/proxy_gen.go"); err != nil { fmt.Println("error: ", err) } // v0 - if err := generate("./api/v0api", "v0api", "v0api", "./api/v0api/struct.go"); err != nil { + if err := generate("./api/v0api", "v0api", "v0api", "./api/v0api/proxy_gen.go"); err != nil { fmt.Println("error: ", err) } } From 736c69784a47467af3ef6d96e3ce5a04112a749a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 25 Mar 2021 15:19:22 +0100 Subject: [PATCH 11/60] make: Fix parallel gen --- .circleci/config.yml | 1 + Makefile | 8 ++++---- build/openrpc/full.json.gz | Bin 22496 -> 22508 bytes build/openrpc/miner.json.gz | Bin 7608 -> 7626 bytes build/openrpc/worker.json.gz | Bin 2561 -> 2573 bytes 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ecdb169e1b6..0e4aaa36d6f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -408,6 +408,7 @@ jobs: steps: - install-deps - prepare + - run: go install golang.org/x/tools/cmd/goimports - run: zcat build/openrpc/full.json.gz | jq > ../pre-openrpc-full - run: zcat build/openrpc/miner.json.gz | jq > ../pre-openrpc-miner - run: zcat build/openrpc/worker.json.gz | jq > ../pre-openrpc-worker diff --git a/Makefile b/Makefile index e3884434783..016e1e8741b 100644 --- a/Makefile +++ b/Makefile @@ -318,12 +318,12 @@ dist-clean: git submodule deinit --all -f .PHONY: dist-clean -type-gen: +type-gen: api-gen go run ./gen/main.go go generate -x ./... goimports -w api/ -method-gen: +method-gen: api-gen (cd ./lotuspond/front/src/chain && go run ./methodgen.go) api-gen: @@ -334,9 +334,9 @@ api-gen: docsgen: docsgen-md docsgen-openrpc -docsgen-md-bin: +docsgen-md-bin: api-gen go build $(GOFLAGS) -o docgen-md ./api/docgen/cmd -docsgen-openrpc-bin: +docsgen-openrpc-bin: api-gen go build $(GOFLAGS) -o docgen-openrpc ./api/docgen-openrpc/cmd docsgen-md: docsgen-md-full docsgen-md-storage docsgen-md-worker diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 6225a04aaee0d4f139b65efc61d021589a4e9f48..e50096a5bf3702bf791833d0f75fcac62db3f6ec 100644 GIT binary patch literal 22508 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 literal 22496 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 literal 7608 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 ac2h+h8qd!+&;K6)0RR8G8tvFgbpZfe663D` diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 62ec8064c97cfb0a84f7fe2b5284a0161e163955..95b70fcf106d7e53cd28357bedf18ca9a6a3fc05 100644 GIT binary patch delta 2435 zcmV-}34Hc}6pa*3ABzY8000000RQYgZFAZ>)_+B#=Sy?P0Rl8_`PPT*?PjJgY;wE( z&}25kK7blq@|ENyG{b-2k!6gH?O?mmCB)O2wg{c0Bk8>BNRdpXf4=F*xXy?oN9dLQ zNGHUG){waF`I&`42riD$;}yG70#qOvlC5*5KrrIA5~OOac)kk;>D|J@Bfw~+J!66Ee_mUdDu|dOGlTS4W~~sF zh@iDeeqX{|>%CpJ5h2LD`Yd~ykt@!z&O8$9a?|HK`r z;Vv%8E$1sXPT>o53X9ltcOKIg+@-A7mldQ^T!$qPm$E5N5G9oeTejoFWyH7~T^_%K z+C(*Oe_Z3n9hw{W=Cr_yQ$}3+6QaGSXwFl>Rr5c~_6x$MwXE~{=u0!*nCHC^p?xsV zYg|?@S5skWzf2|)RJpYc6Du_rre@}+v22ZHJ2cDowv%t!&e?=lv}YP5KQ*y_4xoE( zvQH7Vo#ZL<=y^hLQ=Q5P??1Uz@le`zMt8&wf3*I*0LcSkM=T58Xf~JBCN3WIyOwUa zyeEGA;Q}OxJIyecY<|c&6_d-oH3$hiN0^N0!9pHG zd`Q?OL>`ynz2#}#!V16CB;|i=1UKW?edIQAL)!Dc{RVV8D;4-}F`VC5ad=m7WH=Js z1}QH=O2b^0Fo0S~3&I@kA&ndH3AztSL(;%oXbKF3 z-iD~7J4g33U{Sv-=9}@5R79w11!Q@07tb@ZhRJVAoRgF?d^;&z+HA@WL>3AX?-xL7 zRa?ezMX?Cwt#5)V5OEB$9+@Q1&6lNK|36o7&K!6M572Xqz-ojoNn(HNA$q(Bf4{Bv zYomAG#8UeiOFeZMo{^3n7DDzry|=rmg?v6GolR`m#D)hJ8=iCu&L=Lw1tQ@qlR&B$ zQm#S&?z8vo@J&u~ucT-na+1yAdt=-h<967_t>Con0>TQ+sy0mn6`3;a#hR@>KRYt! zsn|M2h%{inL5gybsExj;8HlZ2f9Xq7SyEODB($2)?UsKla%-NZ`y9C0n-x)GBKC-* z2G@P=qET=ra0$d6a?hhG%RNuaM*^~%zh{_|xEEn=l7W=*HQP{Th^^=yWP0?YOS)mq zXewU(*K0!zsUvInkLjtbr-t-6jUTxe25TSu$SnIF;GNq-L44M8%_gJPe^koOgMx6R zVRWV!ElQ{{nL_6dFhwUc$;qoDz5hXokXX6b8|eA4SrXfK$b1_AWDcYWhxZxdfdRk<3x z+I}XNp$gW~A1u|u zXGxmOL1W_^8~=iAe7B%-CS?)p#G5PNdLie^9M_LJQ#3Sz=UxfYe?FM=TwZ&A7QL}c zja@o8yHrs0Qtw{Vb}lq+y2rffKxY^uUdNFsF zPP&DqE2`eJuPeYJhilBayP>Kph2)9KuDBcWh`5zV&0xvTL?STXwU>O|LZ7)pYDV;5 zR3ZsVQ8v9|9+@LWe{KO0G=Y00!RE}7NO7clblGiooEZKeV7*_oGMCnBtr7{w&KQ^W? z4m`QgFNnQNfAwOW7b6mob>FYcdnMwjpXtgy41bMm>a>Q`sgW^H&!M?5(4@{wy@mH2 z-)}hBpX55Q0)=dWex%+u?@VqLK^oVPI!Nf@B`~F@BEg*;n?7S5ZQBtJ;y41N1P9R= zTML~ly#Ny~JaEu>jtKg<`8`Mr5j5lu*yz>$jM_6qf0;w|6!jQh;3{hCZ;yRq-+~j5 zqC)4JFb5IzN%xu&IcudEXFHbxnjh_G4w{;SCgTgfF33zqvRu&*jG*%4npizN?T4*! z?BqSkqKU2AcVqKTU%z?Rt!?!7m3s=3iQfoS{|YFmiu@D9<#N!IiJ2s5KI6na(Aeen ztwaG+E!0J71_BTffS5UIkw^rLg$Fdh$ZIbyQ*zqDi^cWgzX1RM|Nr(akxfl{008F* Bzjput delta 2423 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 Date: Thu, 25 Mar 2021 15:26:30 +0100 Subject: [PATCH 12/60] Fix lotus-soup build --- testplans/lotus-soup/testkit/role_client.go | 7 +++---- testplans/lotus-soup/testkit/role_miner.go | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/testplans/lotus-soup/testkit/role_client.go b/testplans/lotus-soup/testkit/role_client.go index 8db68bddf1f..9fcd429020f 100644 --- a/testplans/lotus-soup/testkit/role_client.go +++ b/testplans/lotus-soup/testkit/role_client.go @@ -10,7 +10,6 @@ import ( "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/node" @@ -157,11 +156,11 @@ func (c *LotusClient) RunDefault() error { return nil } -func startFullNodeAPIServer(t *TestEnvironment, repo repo.Repo, api api.FullNode) (*http.Server, error) { +func startFullNodeAPIServer(t *TestEnvironment, repo repo.Repo, napi api.FullNode) (*http.Server, error) { mux := mux.NewRouter() rpcServer := jsonrpc.NewServer() - rpcServer.Register("Filecoin", api) + rpcServer.Register("Filecoin", napi) mux.Handle("/rpc/v0", rpcServer) @@ -176,7 +175,7 @@ func startFullNodeAPIServer(t *TestEnvironment, repo repo.Repo, api api.FullNode ah := &auth.Handler{ Verify: func(ctx context.Context, token string) ([]auth.Permission, error) { - return apistruct.AllPermissions, nil + return api.AllPermissions, nil }, Next: mux.ServeHTTP, } diff --git a/testplans/lotus-soup/testkit/role_miner.go b/testplans/lotus-soup/testkit/role_miner.go index 7bd68878051..a0248cfddb4 100644 --- a/testplans/lotus-soup/testkit/role_miner.go +++ b/testplans/lotus-soup/testkit/role_miner.go @@ -17,7 +17,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-storedcounter" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" genesis_chain "github.com/filecoin-project/lotus/chain/gen/genesis" @@ -321,7 +320,7 @@ func PrepareMiner(t *TestEnvironment) (*LotusMiner, error) { } // print out the admin auth token - token, err := n.MinerApi.AuthNew(ctx, apistruct.AllPermissions) + token, err := n.MinerApi.AuthNew(ctx, api.AllPermissions) if err != nil { return nil, err } @@ -615,7 +614,7 @@ func startStorageMinerAPIServer(t *TestEnvironment, repo repo.Repo, minerApi api ah := &auth.Handler{ Verify: func(ctx context.Context, token string) ([]auth.Permission, error) { - return apistruct.AllPermissions, nil + return api.AllPermissions, nil }, Next: mux.ServeHTTP, } From e003977559dae78f6cfe92d5a84ea752ebdf10fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 25 Mar 2021 15:39:48 +0100 Subject: [PATCH 13/60] apiclient: Version client funcs --- api/client/client.go | 32 ++++++++++++++++++++--------- chain/wallet/remotewallet/remote.go | 2 +- cli/util/api.go | 10 ++++----- cmd/lotus-chainwatch/util/api.go | 2 +- cmd/lotus-gateway/endtoend_test.go | 2 +- cmd/lotus-shed/consensus.go | 2 +- node/impl/remoteworker.go | 2 +- node/test/builder.go | 4 ++-- tools/stats/rpc.go | 2 +- 9 files changed, 35 insertions(+), 23 deletions(-) diff --git a/api/client/client.go b/api/client/client.go index 6c2f00b461a..7dea837e856 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -15,8 +15,8 @@ import ( "github.com/filecoin-project/lotus/lib/rpcenc" ) -// NewCommonRPC creates a new http jsonrpc client. -func NewCommonRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Common, jsonrpc.ClientCloser, error) { +// NewCommonRPCV0 creates a new http jsonrpc client. +func NewCommonRPCV0(ctx context.Context, addr string, requestHeader http.Header) (api.Common, jsonrpc.ClientCloser, error) { var res v0api.CommonStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ @@ -28,8 +28,20 @@ func NewCommonRPC(ctx context.Context, addr string, requestHeader http.Header) ( return &res, closer, err } -// NewFullNodeRPC creates a new http jsonrpc client. -func NewFullNodeRPC(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) { +// NewFullNodeRPCV0 creates a new http jsonrpc client. +func NewFullNodeRPCV0(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) { + var res v0api.FullNodeStruct + closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", + []interface{}{ + &res.CommonStruct.Internal, + &res.Internal, + }, requestHeader) + + return &res, closer, err +} + +// NewFullNodeRPCV1 creates a new http jsonrpc client. +func NewFullNodeRPCV1(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) { var res v1api.FullNodeStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ @@ -40,8 +52,8 @@ func NewFullNodeRPC(ctx context.Context, addr string, requestHeader http.Header) return &res, closer, err } -// NewStorageMinerRPC creates a new http jsonrpc client for miner -func NewStorageMinerRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (v0api.StorageMiner, jsonrpc.ClientCloser, error) { +// NewStorageMinerRPCV0 creates a new http jsonrpc client for miner +func NewStorageMinerRPCV0(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (v0api.StorageMiner, jsonrpc.ClientCloser, error) { var res v0api.StorageMinerStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ @@ -55,7 +67,7 @@ func NewStorageMinerRPC(ctx context.Context, addr string, requestHeader http.Hea return &res, closer, err } -func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Worker, jsonrpc.ClientCloser, error) { +func NewWorkerRPCV0(ctx context.Context, addr string, requestHeader http.Header) (api.Worker, jsonrpc.ClientCloser, error) { u, err := url.Parse(addr) if err != nil { return nil, nil, err @@ -84,8 +96,8 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) ( return &res, closer, err } -// NewGatewayRPC creates a new http jsonrpc client for a gateway node. -func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.Gateway, jsonrpc.ClientCloser, error) { +// NewGatewayRPCV0 creates a new http jsonrpc client for a gateway node. +func NewGatewayRPCV0(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.Gateway, jsonrpc.ClientCloser, error) { var res api.GatewayStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ @@ -98,7 +110,7 @@ func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, return &res, closer, err } -func NewWalletRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Wallet, jsonrpc.ClientCloser, error) { +func NewWalletRPCV0(ctx context.Context, addr string, requestHeader http.Header) (api.Wallet, jsonrpc.ClientCloser, error) { var res api.WalletStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ diff --git a/chain/wallet/remotewallet/remote.go b/chain/wallet/remotewallet/remote.go index 685d0fc3554..d1734518e1b 100644 --- a/chain/wallet/remotewallet/remote.go +++ b/chain/wallet/remotewallet/remote.go @@ -25,7 +25,7 @@ func SetupRemoteWallet(info string) func(mctx helpers.MetricsCtx, lc fx.Lifecycl return nil, err } - wapi, closer, err := client.NewWalletRPC(mctx, url, ai.AuthHeader()) + wapi, closer, err := client.NewWalletRPCV0(mctx, url, ai.AuthHeader()) if err != nil { return nil, xerrors.Errorf("creating jsonrpc client: %w", err) } diff --git a/cli/util/api.go b/cli/util/api.go index c0f0b0ed181..c296c84ffb3 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -170,7 +170,7 @@ func GetAPI(ctx *cli.Context) (api.Common, jsonrpc.ClientCloser, error) { return nil, nil, err } - return client.NewCommonRPC(ctx.Context, addr, headers) + return client.NewCommonRPCV0(ctx.Context, addr, headers) } func GetFullNodeAPI(ctx *cli.Context) (api.FullNode, jsonrpc.ClientCloser, error) { @@ -183,7 +183,7 @@ func GetFullNodeAPI(ctx *cli.Context) (api.FullNode, jsonrpc.ClientCloser, error return nil, nil, err } - return client.NewFullNodeRPC(ctx.Context, addr, headers) + return client.NewFullNodeRPCV1(ctx.Context, addr, headers) } type GetStorageMinerOptions struct { @@ -227,7 +227,7 @@ func GetStorageMinerAPI(ctx *cli.Context, opts ...GetStorageMinerOption) (api.St addr = u.String() } - return client.NewStorageMinerRPC(ctx.Context, addr, headers) + return client.NewStorageMinerRPCV0(ctx.Context, addr, headers) } func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { @@ -236,7 +236,7 @@ func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { return nil, nil, err } - return client.NewWorkerRPC(ctx.Context, addr, headers) + return client.NewWorkerRPCV0(ctx.Context, addr, headers) } func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) { @@ -245,7 +245,7 @@ func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) return nil, nil, err } - return client.NewGatewayRPC(ctx.Context, addr, headers) + return client.NewGatewayRPCV0(ctx.Context, addr, headers) } func DaemonContext(cctx *cli.Context) context.Context { diff --git a/cmd/lotus-chainwatch/util/api.go b/cmd/lotus-chainwatch/util/api.go index cfda833e023..57e75fe58e4 100644 --- a/cmd/lotus-chainwatch/util/api.go +++ b/cmd/lotus-chainwatch/util/api.go @@ -22,7 +22,7 @@ func GetFullNodeAPIUsingCredentials(ctx context.Context, listenAddr, token strin return nil, nil, err } - return client.NewFullNodeRPC(ctx, apiURI(addr), apiHeaders(token)) + return client.NewFullNodeRPCV1(ctx, apiURI(addr), apiHeaders(token)) } func apiURI(addr string) string { return "ws://" + addr + "/rpc/v0" diff --git a/cmd/lotus-gateway/endtoend_test.go b/cmd/lotus-gateway/endtoend_test.go index 8c1901d65b5..f575c577626 100644 --- a/cmd/lotus-gateway/endtoend_test.go +++ b/cmd/lotus-gateway/endtoend_test.go @@ -250,7 +250,7 @@ func startNodes( // Create a gateway client API that connects to the gateway server var gapi api.Gateway - gapi, closer, err = client.NewGatewayRPC(ctx, addr, nil) + gapi, closer, err = client.NewGatewayRPCV0(ctx, addr, nil) require.NoError(t, err) // Provide the gateway API to dependency injection diff --git a/cmd/lotus-shed/consensus.go b/cmd/lotus-shed/consensus.go index 8e30f5cee28..2c5df4ea59f 100644 --- a/cmd/lotus-shed/consensus.go +++ b/cmd/lotus-shed/consensus.go @@ -118,7 +118,7 @@ var consensusCheckCmd = &cli.Command{ return err } - api, closer, err := client.NewFullNodeRPC(cctx.Context, addr, nil) + api, closer, err := client.NewFullNodeRPCV1(cctx.Context, addr, nil) if err != nil { return err } diff --git a/node/impl/remoteworker.go b/node/impl/remoteworker.go index 1369dc24873..8dc7510b48e 100644 --- a/node/impl/remoteworker.go +++ b/node/impl/remoteworker.go @@ -33,7 +33,7 @@ func connectRemoteWorker(ctx context.Context, fa api.Common, url string) (*remot headers := http.Header{} headers.Add("Authorization", "Bearer "+string(token)) - wapi, closer, err := client.NewWorkerRPC(context.TODO(), url, headers) + wapi, closer, err := client.NewWorkerRPCV0(context.TODO(), url, headers) if err != nil { return nil, xerrors.Errorf("creating jsonrpc client: %w", err) } diff --git a/node/test/builder.go b/node/test/builder.go index 72a55ab499a..9c4515a9b99 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -505,7 +505,7 @@ func fullRpc(t *testing.T, nd test.TestNode) test.TestNode { var stop func() var full test.TestNode - full.FullNode, stop, err = client.NewFullNodeRPC(context.Background(), listenAddr, nil) + full.FullNode, stop, err = client.NewFullNodeRPCV1(context.Background(), listenAddr, nil) require.NoError(t, err) t.Cleanup(stop) @@ -519,7 +519,7 @@ func storerRpc(t *testing.T, nd test.TestStorageNode) test.TestStorageNode { var stop func() var storer test.TestStorageNode - storer.StorageMiner, stop, err = client.NewStorageMinerRPC(context.Background(), listenAddr, nil) + storer.StorageMiner, stop, err = client.NewStorageMinerRPCV0(context.Background(), listenAddr, nil) require.NoError(t, err) t.Cleanup(stop) diff --git a/tools/stats/rpc.go b/tools/stats/rpc.go index b01c07a3579..cd3987ff1f1 100644 --- a/tools/stats/rpc.go +++ b/tools/stats/rpc.go @@ -220,5 +220,5 @@ func GetFullNodeAPI(ctx context.Context, repo string) (api.FullNode, jsonrpc.Cli return nil, nil, err } - return client.NewFullNodeRPC(ctx, addr, headers) + return client.NewFullNodeRPCV1(ctx, addr, headers) } From 1e10429326016428523e8f2a466817681948883f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 25 Mar 2021 18:00:29 +0100 Subject: [PATCH 14/60] api: Add basic package readme --- api/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 api/README.md diff --git a/api/README.md b/api/README.md new file mode 100644 index 00000000000..07089d7ae9f --- /dev/null +++ b/api/README.md @@ -0,0 +1,14 @@ +## Lotus API + +This package contains all lotus API definitions. Interfaces defined here are +exposed as JsonRPC 2.0 endpoints by lotus programs. + +### Versions + +| File | Alias File | Interface | Exposed by | Version | HTTP Endpoint | Status | Docs +|------------------|-------------------|----------------|--------------------|---------|---------------|------------------------------|------ +| `api_common.go` | `v0api/latest.go` | `Common` | lotus; lotus-miner | v0 | `/rpc/v0` | Latest, Stable | [Methods](../documentation/en/api-v0-methods.md) +| `api_full.go` | `v1api/latest.go` | `FullNode` | lotus | v1 | `/rpc/v1` | Latest, **Work in progress** | [Methods](../documentation/en/api-v1-unstable-methods.md) +| `api_storage.go` | `v0api/latest.go` | `StorageMiner` | lotus-miner | v0 | `/rpc/v0` | Latest, Stable | [Methods](../documentation/en/api-v0-methods-miner.md) +| `api_worker.go` | `v0api/latest.go` | `Worker` | lotus-worker | v0 | `/rpc/v0` | Latest, Stable | [Methods](../documentation/en/api-v0-methods-worker.md) +| `v0api/full.go` | | `FullNode` | lotus | v0 | `/rpc/v0` | Stable | [Methods](../documentation/en/api-v0-methods.md) From ba49c6206eee6d3a790c857e2bc0f285721ff55c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 1 Apr 2021 14:17:22 +0200 Subject: [PATCH 15/60] cli: Default to v0 api for now --- api/client/client.go | 2 +- cli/util/api.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/api/client/client.go b/api/client/client.go index 7dea837e856..1b49aae78df 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -29,7 +29,7 @@ func NewCommonRPCV0(ctx context.Context, addr string, requestHeader http.Header) } // NewFullNodeRPCV0 creates a new http jsonrpc client. -func NewFullNodeRPCV0(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) { +func NewFullNodeRPCV0(ctx context.Context, addr string, requestHeader http.Header) (v0api.FullNode, jsonrpc.ClientCloser, error) { var res v0api.FullNodeStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ diff --git a/cli/util/api.go b/cli/util/api.go index c296c84ffb3..811b0925774 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -18,6 +18,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/node/repo" ) @@ -173,7 +174,7 @@ func GetAPI(ctx *cli.Context) (api.Common, jsonrpc.ClientCloser, error) { return client.NewCommonRPCV0(ctx.Context, addr, headers) } -func GetFullNodeAPI(ctx *cli.Context) (api.FullNode, jsonrpc.ClientCloser, error) { +func GetFullNodeAPI(ctx *cli.Context) (v0api.FullNode, jsonrpc.ClientCloser, error) { if tn, ok := ctx.App.Metadata["testnode-full"]; ok { return tn.(api.FullNode), func() {}, nil } @@ -183,7 +184,7 @@ func GetFullNodeAPI(ctx *cli.Context) (api.FullNode, jsonrpc.ClientCloser, error return nil, nil, err } - return client.NewFullNodeRPCV1(ctx.Context, addr, headers) + return client.NewFullNodeRPCV0(ctx.Context, addr, headers) } type GetStorageMinerOptions struct { From 3cac23b4a77adf42267e9ab90a1ac899f326ac38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 2 Apr 2021 13:07:56 +0200 Subject: [PATCH 16/60] cli: get raw full api correctly --- cli/util/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/util/api.go b/cli/util/api.go index 811b0925774..ea7e6751f0f 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -179,7 +179,7 @@ func GetFullNodeAPI(ctx *cli.Context) (v0api.FullNode, jsonrpc.ClientCloser, err return tn.(api.FullNode), func() {}, nil } - addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v1") + addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v0") if err != nil { return nil, nil, err } From 64bf5b382b15b7e6208d2cdde1aa33b637ca6911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 2 Apr 2021 13:20:31 +0200 Subject: [PATCH 17/60] cliutil: cast full api to the v0 interface --- cli/util/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/util/api.go b/cli/util/api.go index ea7e6751f0f..6c85dc5330d 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -176,7 +176,7 @@ func GetAPI(ctx *cli.Context) (api.Common, jsonrpc.ClientCloser, error) { func GetFullNodeAPI(ctx *cli.Context) (v0api.FullNode, jsonrpc.ClientCloser, error) { if tn, ok := ctx.App.Metadata["testnode-full"]; ok { - return tn.(api.FullNode), func() {}, nil + return tn.(v0api.FullNode), func() {}, nil } addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v0") From 0103d2f6216d10c9d0e247a196d8fa968cf0cbbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 2 Apr 2021 13:52:24 +0200 Subject: [PATCH 18/60] v1 api: Cleanup message wait/search apis --- api/api_full.go | 61 +++++++---------------------------------- api/proxy_gen.go | 30 ++++---------------- api/v0api/v1_wrapper.go | 38 ++++++++++++++++++------- chain/stmgr/stmgr.go | 38 ++++++++----------------- node/impl/full/state.go | 37 ++++++++----------------- 5 files changed, 66 insertions(+), 138 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 6a56f04737e..8739fba3890 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -430,7 +430,7 @@ type FullNode interface { StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) //perm:read // StateSectorPartition finds deadline/partition with the specified sector StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error) //perm:read - // StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed + // StateSearchMsg looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed // // NOTE: If a replacing message is found on chain, this method will return // a MsgLookup for the replacing message - the MsgLookup.Message will be a different @@ -438,48 +438,16 @@ type FullNode interface { // result of the execution of the replacing message. // // If the caller wants to ensure that exactly the requested message was executed, - // they MUST check that MsgLookup.Message is equal to the provided 'cid'. - // Without this check both the requested and original message may appear as - // successfully executed on-chain, which may look like a double-spend. - // - // A replacing message is a message with a different CID, any of Gas values, and - // different signature, but with all other parameters matching (source/destination, - // nonce, params, etc.) - StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error) //perm:read - // StateSearchMsgLimited looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed - // - // NOTE: If a replacing message is found on chain, this method will return - // a MsgLookup for the replacing message - the MsgLookup.Message will be a different - // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the - // result of the execution of the replacing message. - // - // If the caller wants to ensure that exactly the requested message was executed, - // they MUST check that MsgLookup.Message is equal to the provided 'cid'. - // Without this check both the requested and original message may appear as - // successfully executed on-chain, which may look like a double-spend. - // - // A replacing message is a message with a different CID, any of Gas values, and - // different signature, but with all other parameters matching (source/destination, - // nonce, params, etc.) - StateSearchMsgLimited(ctx context.Context, msg cid.Cid, limit abi.ChainEpoch) (*MsgLookup, error) //perm:read - // StateWaitMsg looks back in the chain for a message. If not found, it blocks until the - // message arrives on chain, and gets to the indicated confidence depth. - // - // NOTE: If a replacing message is found on chain, this method will return - // a MsgLookup for the replacing message - the MsgLookup.Message will be a different - // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the - // result of the execution of the replacing message. - // - // If the caller wants to ensure that exactly the requested message was executed, - // they MUST check that MsgLookup.Message is equal to the provided 'cid'. - // Without this check both the requested and original message may appear as + // they must check that MsgLookup.Message is equal to the provided 'cid', or set the + // `allowReplaced` parameter to false. Without this check, and with `allowReplaced` + // set to true, both the requested and original message may appear as // successfully executed on-chain, which may look like a double-spend. // // A replacing message is a message with a different CID, any of Gas values, and // different signature, but with all other parameters matching (source/destination, // nonce, params, etc.) - StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error) //perm:read - // StateWaitMsgLimited looks back up to limit epochs in the chain for a message. + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) //perm:read + // StateWaitMsg looks back up to limit epochs in the chain for a message. // If not found, it blocks until the message arrives on chain, and gets to the // indicated confidence depth. // @@ -489,14 +457,15 @@ type FullNode interface { // result of the execution of the replacing message. // // If the caller wants to ensure that exactly the requested message was executed, - // they MUST check that MsgLookup.Message is equal to the provided 'cid'. - // Without this check both the requested and original message may appear as + // they must check that MsgLookup.Message is equal to the provided 'cid', or set the + // `allowReplaced` parameter to false. Without this check, and with `allowReplaced` + // set to true, both the requested and original message may appear as // successfully executed on-chain, which may look like a double-spend. // // A replacing message is a message with a different CID, any of Gas values, and // different signature, but with all other parameters matching (source/destination, // nonce, params, etc.) - StateWaitMsgLimited(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch) (*MsgLookup, error) //perm:read + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) //perm:read // StateListMiners returns the addresses of every miner that has claimed power in the Power Actor StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error) //perm:read // StateListActors returns the addresses of every actor in the state @@ -516,16 +485,6 @@ type FullNode interface { // StateChangedActors returns all the actors whose states change between the two given state CIDs // TODO: Should this take tipset keys instead? StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) //perm:read - // StateGetReceipt returns the message receipt for the given message or for a - // matching gas-repriced replacing message - // - // NOTE: If the requested message was replaced, this method will return the receipt - // for the replacing message - if the caller needs the receipt for exactly the - // requested message, use StateSearchMsg().Receipt, and check that MsgLookup.Message - // is matching the requested CID - // - // DEPRECATED: Use StateSearchMsg, this method won't be supported in v1 API - StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) //perm:read // StateMinerSectorCount returns the number of sectors in a miner's sector set and proving set StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error) //perm:read // StateCompute is a flexible command that applies the given messages on the given tipset. diff --git a/api/proxy_gen.go b/api/proxy_gen.go index d11ed0244e5..2808c8a1ffa 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -330,8 +330,6 @@ type FullNodeStruct struct { StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"` - StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"` - StateListActors func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` StateListMessages func(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` @@ -384,9 +382,7 @@ type FullNodeStruct struct { StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) `perm:"read"` - StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) `perm:"read"` - - StateSearchMsgLimited func(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*MsgLookup, error) `perm:"read"` + StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `perm:"read"` StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"` @@ -404,9 +400,7 @@ type FullNodeStruct struct { StateVerifierStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` - StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) `perm:"read"` - - StateWaitMsgLimited func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*MsgLookup, error) `perm:"read"` + StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `perm:"read"` SyncCheckBad func(p0 context.Context, p1 cid.Cid) (string, error) `perm:"read"` @@ -1334,10 +1328,6 @@ func (s *FullNodeStruct) StateGetActor(p0 context.Context, p1 address.Address, p return s.Internal.StateGetActor(p0, p1, p2) } -func (s *FullNodeStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { - return s.Internal.StateGetReceipt(p0, p1, p2) -} - func (s *FullNodeStruct) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { return s.Internal.StateListActors(p0, p1) } @@ -1442,12 +1432,8 @@ func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 return s.Internal.StateReplay(p0, p1, p2) } -func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) { - return s.Internal.StateSearchMsg(p0, p1) -} - -func (s *FullNodeStruct) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*MsgLookup, error) { - return s.Internal.StateSearchMsgLimited(p0, p1, p2) +func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return s.Internal.StateSearchMsg(p0, p1, p2, p3, p4) } func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { @@ -1482,12 +1468,8 @@ func (s *FullNodeStruct) StateVerifierStatus(p0 context.Context, p1 address.Addr return s.Internal.StateVerifierStatus(p0, p1, p2) } -func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) { - return s.Internal.StateWaitMsg(p0, p1, p2) -} - -func (s *FullNodeStruct) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*MsgLookup, error) { - return s.Internal.StateWaitMsgLimited(p0, p1, p2, p3) +func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return s.Internal.StateWaitMsg(p0, p1, p2, p3, p4) } func (s *FullNodeStruct) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { diff --git a/api/v0api/v1_wrapper.go b/api/v0api/v1_wrapper.go index 92b223390b1..091ec2fdf07 100644 --- a/api/v0api/v1_wrapper.go +++ b/api/v0api/v1_wrapper.go @@ -1,32 +1,50 @@ package v0api import ( + "context" + + "github.com/filecoin-project/lotus/chain/types" + + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/v1api" + "github.com/filecoin-project/lotus/chain/stmgr" ) type WrapperV1Full struct { v1api.FullNode } -/* example: -- dropped StateGetReceipt -- tsk param for StateSearchMsg +func (w *WrapperV1Full) StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) { + return w.FullNode.StateSearchMsg(ctx, types.EmptyTSK, msg, stmgr.LookbackNoLimit, true) +} + +func (w *WrapperV1Full) StateSearchMsgLimited(ctx context.Context, msg cid.Cid, limit abi.ChainEpoch) (*api.MsgLookup, error) { + return w.FullNode.StateSearchMsg(ctx, types.EmptyTSK, msg, limit, true) +} -func (w *WrapperV1Full) StateSearchMsg(ctx context.Context, c cid.Cid) (*api.MsgLookup, error) { - return w.FullNode.StateSearchMsg(ctx, c, types.EmptyTSK) +func (w *WrapperV1Full) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) { + return w.FullNode.StateWaitMsg(ctx, msg, confidence, stmgr.LookbackNoLimit, true) } -func (w *WrapperV1Full) StateGetReceipt(ctx context.Context, cid cid.Cid, key types.TipSetKey) (*types.MessageReceipt, error) { - m, err := w.FullNode.StateSearchMsg(ctx, cid, key) +func (w *WrapperV1Full) StateWaitMsgLimited(ctx context.Context, msg cid.Cid, confidence uint64, limit abi.ChainEpoch) (*api.MsgLookup, error) { + return w.FullNode.StateWaitMsg(ctx, msg, confidence, limit, true) +} + +func (w *WrapperV1Full) StateGetReceipt(ctx context.Context, msg cid.Cid, from types.TipSetKey) (*types.MessageReceipt, error) { + ml, err := w.FullNode.StateSearchMsg(ctx, from, msg, stmgr.LookbackNoLimit, true) if err != nil { return nil, err } - if m == nil { + if ml == nil { return nil, nil } - return &m.Receipt, nil -}*/ + return &ml.Receipt, nil +} var _ FullNode = &WrapperV1Full{} diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index ffbe08474ff..60e2ae2cb17 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -564,24 +564,10 @@ func (sm *StateManager) LookupID(ctx context.Context, addr address.Address, ts * return state.LookupID(addr) } -func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.TipSet) (*types.MessageReceipt, error) { - m, err := sm.cs.GetCMessage(msg) - if err != nil { - return nil, fmt.Errorf("failed to load message: %w", err) - } - - _, r, _, err := sm.searchBackForMsg(ctx, ts, m, LookbackNoLimit) - if err != nil { - return nil, fmt.Errorf("failed to look back through chain for message: %w", err) - } - - return r, nil -} - // WaitForMessage blocks until a message appears on chain. It looks backwards in the chain to see if this has already // happened, with an optional limit to how many epochs it will search. It guarantees that the message has been on // chain for at least confidence epochs without being reverted before returning. -func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { +func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch, allowReplaced bool) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -605,7 +591,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid return nil, nil, cid.Undef, fmt.Errorf("expected current head on SHC stream (got %s)", head[0].Type) } - r, foundMsg, err := sm.tipsetExecutedMessage(head[0].Val, mcid, msg.VMMessage()) + r, foundMsg, err := sm.tipsetExecutedMessage(head[0].Val, mcid, msg.VMMessage(), allowReplaced) if err != nil { return nil, nil, cid.Undef, err } @@ -619,7 +605,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid var backFm cid.Cid backSearchWait := make(chan struct{}) go func() { - fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head[0].Val, msg, lookbackLimit) + fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head[0].Val, msg, lookbackLimit, allowReplaced) if err != nil { log.Warnf("failed to look back through chain for message: %v", err) return @@ -658,7 +644,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid if candidateTs != nil && val.Val.Height() >= candidateTs.Height()+abi.ChainEpoch(confidence) { return candidateTs, candidateRcp, candidateFm, nil } - r, foundMsg, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage()) + r, foundMsg, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage(), allowReplaced) if err != nil { return nil, nil, cid.Undef, err } @@ -694,15 +680,13 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid } } -func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid, lookbackLimit abi.ChainEpoch) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { +func (sm *StateManager) SearchForMessage(ctx context.Context, head *types.TipSet, mcid cid.Cid, lookbackLimit abi.ChainEpoch, allowReplaced bool) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { msg, err := sm.cs.GetCMessage(mcid) if err != nil { return nil, nil, cid.Undef, fmt.Errorf("failed to load message: %w", err) } - head := sm.cs.GetHeaviestTipSet() - - r, foundMsg, err := sm.tipsetExecutedMessage(head, mcid, msg.VMMessage()) + r, foundMsg, err := sm.tipsetExecutedMessage(head, mcid, msg.VMMessage(), allowReplaced) if err != nil { return nil, nil, cid.Undef, err } @@ -711,7 +695,7 @@ func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid, look return head, r, foundMsg, nil } - fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head, msg, lookbackLimit) + fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head, msg, lookbackLimit, allowReplaced) if err != nil { log.Warnf("failed to look back through chain for message %s", mcid) @@ -731,7 +715,7 @@ func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid, look // - 0 then no tipsets are searched // - 5 then five tipset are searched // - LookbackNoLimit then there is no limit -func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet, m types.ChainMsg, limit abi.ChainEpoch) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { +func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet, m types.ChainMsg, limit abi.ChainEpoch, allowReplaced bool) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { limitHeight := from.Height() - limit noLimit := limit == LookbackNoLimit @@ -781,7 +765,7 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet // check that between cur and parent tipset the nonce fell into range of our message if actorNoExist || (curActor.Nonce > mNonce && act.Nonce <= mNonce) { - r, foundMsg, err := sm.tipsetExecutedMessage(cur, m.Cid(), m.VMMessage()) + r, foundMsg, err := sm.tipsetExecutedMessage(cur, m.Cid(), m.VMMessage(), allowReplaced) if err != nil { return nil, nil, cid.Undef, xerrors.Errorf("checking for message execution during lookback: %w", err) } @@ -796,7 +780,7 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet } } -func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm *types.Message) (*types.MessageReceipt, cid.Cid, error) { +func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm *types.Message, allowReplaced bool) (*types.MessageReceipt, cid.Cid, error) { // The genesis block did not execute any messages if ts.Height() == 0 { return nil, cid.Undef, nil @@ -819,7 +803,7 @@ func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm if m.VMMessage().From == vmm.From { // cheaper to just check origin first if m.VMMessage().Nonce == vmm.Nonce { - if m.VMMessage().EqualCall(vmm) { + if allowReplaced && m.VMMessage().EqualCall(vmm) { if m.Cid() != msg { log.Warnw("found message with equal nonce and call params but different CID", "wanted", msg, "found", m.Cid(), "nonce", vmm.Nonce, "from", vmm.From) diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 7fcd9dc13c1..aa806bfe0b5 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -520,28 +520,22 @@ func (a *StateAPI) MinerCreateBlock(ctx context.Context, bt *api.BlockTemplate) return &out, nil } -func (m *StateModule) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) { - return stateWaitMsgLimited(ctx, m.StateManager, m.Chain, msg, confidence, stmgr.LookbackNoLimit) -} -func (a *StateAPI) StateWaitMsgLimited(ctx context.Context, msg cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) { - return stateWaitMsgLimited(ctx, a.StateManager, a.Chain, msg, confidence, lookbackLimit) -} -func stateWaitMsgLimited(ctx context.Context, smgr *stmgr.StateManager, cstore *store.ChainStore, msg cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) { - ts, recpt, found, err := smgr.WaitForMessage(ctx, msg, confidence, lookbackLimit) +func (m *StateModule) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) { + ts, recpt, found, err := m.StateManager.WaitForMessage(ctx, msg, confidence, lookbackLimit) if err != nil { return nil, err } var returndec interface{} if recpt.ExitCode == 0 && len(recpt.Return) > 0 { - cmsg, err := cstore.GetCMessage(msg) + cmsg, err := m.Chain.GetCMessage(msg) if err != nil { return nil, xerrors.Errorf("failed to load message after successful receipt search: %w", err) } vmsg := cmsg.VMMessage() - t, err := stmgr.GetReturnType(ctx, smgr, vmsg.To, vmsg.Method, ts) + t, err := stmgr.GetReturnType(ctx, m.StateManager, vmsg.To, vmsg.Method, ts) if err != nil { return nil, xerrors.Errorf("failed to get return type: %w", err) } @@ -562,14 +556,13 @@ func stateWaitMsgLimited(ctx context.Context, smgr *stmgr.StateManager, cstore * }, nil } -func (m *StateModule) StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) { - return stateSearchMsgLimited(ctx, m.StateManager, msg, stmgr.LookbackNoLimit) -} -func (a *StateAPI) StateSearchMsgLimited(ctx context.Context, msg cid.Cid, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) { - return stateSearchMsgLimited(ctx, a.StateManager, msg, lookbackLimit) -} -func stateSearchMsgLimited(ctx context.Context, smgr *stmgr.StateManager, msg cid.Cid, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) { - ts, recpt, found, err := smgr.SearchForMessage(ctx, msg, lookbackLimit) +func (m *StateModule) StateSearchMsg(ctx context.Context, tsk types.TipSetKey, msg cid.Cid, lookbackLimit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + fromTs, err := m.Chain.GetTipSetFromKey(tsk) + if err != nil { + return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) + } + + ts, recpt, found, err := m.StateManager.SearchForMessage(ctx, fromTs, msg, lookbackLimit, allowReplaced) if err != nil { return nil, err } @@ -585,14 +578,6 @@ func stateSearchMsgLimited(ctx context.Context, smgr *stmgr.StateManager, msg ci return nil, nil } -func (m *StateModule) StateGetReceipt(ctx context.Context, msg cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) { - ts, err := m.Chain.GetTipSetFromKey(tsk) - if err != nil { - return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) - } - return m.StateManager.GetReceipt(ctx, msg, ts) -} - func (m *StateModule) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { From 1b32d7f52f07ed8e58d3d9cf79512e7c4c424d30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 3 Apr 2021 12:55:29 +0200 Subject: [PATCH 19/60] cli: fix build with v1 api changes --- cli/chain.go | 9 +++++---- cli/client.go | 9 +++++---- cli/disputer.go | 7 ++++--- cli/services.go | 4 ++-- cli/servicesmock_test.go | 3 ++- cli/state.go | 12 +++++++----- cli/sync.go | 3 ++- cli/util.go | 4 ++-- node/impl/full/state.go | 4 ++-- 9 files changed, 31 insertions(+), 24 deletions(-) diff --git a/cli/chain.go b/cli/chain.go index 1574f3f6494..9954813dea9 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -32,6 +32,7 @@ import ( "golang.org/x/xerrors" lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/stmgr" @@ -806,7 +807,7 @@ var ChainGetCmd = &cli.Command{ type apiIpldStore struct { ctx context.Context - api lapi.FullNode + api v0api.FullNode } func (ht *apiIpldStore) Context() context.Context { @@ -834,7 +835,7 @@ func (ht *apiIpldStore) Put(ctx context.Context, v interface{}) (cid.Cid, error) panic("No mutations allowed") } -func handleAmt(ctx context.Context, api lapi.FullNode, r cid.Cid) error { +func handleAmt(ctx context.Context, api v0api.FullNode, r cid.Cid) error { s := &apiIpldStore{ctx, api} mp, err := adt.AsArray(s, r) if err != nil { @@ -847,7 +848,7 @@ func handleAmt(ctx context.Context, api lapi.FullNode, r cid.Cid) error { }) } -func handleHamtEpoch(ctx context.Context, api lapi.FullNode, r cid.Cid) error { +func handleHamtEpoch(ctx context.Context, api v0api.FullNode, r cid.Cid) error { s := &apiIpldStore{ctx, api} mp, err := adt.AsMap(s, r) if err != nil { @@ -865,7 +866,7 @@ func handleHamtEpoch(ctx context.Context, api lapi.FullNode, r cid.Cid) error { }) } -func handleHamtAddress(ctx context.Context, api lapi.FullNode, r cid.Cid) error { +func handleHamtAddress(ctx context.Context, api v0api.FullNode, r cid.Cid) error { s := &apiIpldStore{ctx, api} mp, err := adt.AsMap(s, r) if err != nil { diff --git a/cli/client.go b/cli/client.go index 347a09b5a43..33c32f8730a 100644 --- a/cli/client.go +++ b/cli/client.go @@ -40,6 +40,7 @@ import ( "github.com/filecoin-project/lotus/api" lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/market" @@ -1340,7 +1341,7 @@ type QueriedAsk struct { Ping time.Duration } -func GetAsks(ctx context.Context, api lapi.FullNode) ([]QueriedAsk, error) { +func GetAsks(ctx context.Context, api v0api.FullNode) ([]QueriedAsk, error) { isTTY := true if fileInfo, _ := os.Stdout.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 { isTTY = false @@ -1647,7 +1648,7 @@ var clientListDeals = &cli.Command{ }, } -func dealFromDealInfo(ctx context.Context, full api.FullNode, head *types.TipSet, v api.DealInfo) deal { +func dealFromDealInfo(ctx context.Context, full v0api.FullNode, head *types.TipSet, v api.DealInfo) deal { if v.DealID == 0 { return deal{ LocalDeal: v, @@ -1666,7 +1667,7 @@ func dealFromDealInfo(ctx context.Context, full api.FullNode, head *types.TipSet } } -func outputStorageDeals(ctx context.Context, out io.Writer, full lapi.FullNode, localDeals []lapi.DealInfo, verbose bool, color bool, showFailed bool) error { +func outputStorageDeals(ctx context.Context, out io.Writer, full v0api.FullNode, localDeals []lapi.DealInfo, verbose bool, color bool, showFailed bool) error { sort.Slice(localDeals, func(i, j int) bool { return localDeals[i].CreationTime.Before(localDeals[j].CreationTime) }) @@ -2285,7 +2286,7 @@ func ellipsis(s string, length int) string { return s } -func inspectDealCmd(ctx context.Context, api lapi.FullNode, proposalCid string, dealId int) error { +func inspectDealCmd(ctx context.Context, api v0api.FullNode, proposalCid string, dealId int) error { ctx, cancel := context.WithCancel(ctx) defer cancel() diff --git a/cli/disputer.go b/cli/disputer.go index ded240a80b7..235c4cf03f4 100644 --- a/cli/disputer.go +++ b/cli/disputer.go @@ -22,6 +22,7 @@ import ( logging "github.com/ipfs/go-log/v2" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/store" "github.com/urfave/cli/v2" ) @@ -356,7 +357,7 @@ var disputerStartCmd = &cli.Command{ // for a given miner, index, and maxPostIndex, tries to dispute posts from 0...postsSnapshotted-1 // returns a list of DisputeWindowedPoSt msgs that are expected to succeed if sent -func makeDisputeWindowedPosts(ctx context.Context, api lapi.FullNode, dl minerDeadline, postsSnapshotted uint64, sender address.Address) ([]*types.Message, error) { +func makeDisputeWindowedPosts(ctx context.Context, api v0api.FullNode, dl minerDeadline, postsSnapshotted uint64, sender address.Address) ([]*types.Message, error) { disputes := make([]*types.Message, 0) for i := uint64(0); i < postsSnapshotted; i++ { @@ -388,7 +389,7 @@ func makeDisputeWindowedPosts(ctx context.Context, api lapi.FullNode, dl minerDe return disputes, nil } -func makeMinerDeadline(ctx context.Context, api lapi.FullNode, mAddr address.Address) (abi.ChainEpoch, *minerDeadline, error) { +func makeMinerDeadline(ctx context.Context, api v0api.FullNode, mAddr address.Address) (abi.ChainEpoch, *minerDeadline, error) { dl, err := api.StateMinerProvingDeadline(ctx, mAddr, types.EmptyTSK) if err != nil { return -1, nil, xerrors.Errorf("getting proving index list: %w", err) @@ -400,7 +401,7 @@ func makeMinerDeadline(ctx context.Context, api lapi.FullNode, mAddr address.Add }, nil } -func getSender(ctx context.Context, api lapi.FullNode, fromStr string) (address.Address, error) { +func getSender(ctx context.Context, api v0api.FullNode, fromStr string) (address.Address, error) { if fromStr == "" { return api.WalletDefaultAddress(ctx) } diff --git a/cli/services.go b/cli/services.go index 069bed81159..3de0b567bf6 100644 --- a/cli/services.go +++ b/cli/services.go @@ -11,7 +11,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/stmgr" types "github.com/filecoin-project/lotus/chain/types" cid "github.com/ipfs/go-cid" @@ -35,7 +35,7 @@ type ServicesAPI interface { } type ServicesImpl struct { - api api.FullNode + api v0api.FullNode closer jsonrpc.ClientCloser } diff --git a/cli/servicesmock_test.go b/cli/servicesmock_test.go index 48f1a95ec19..fcedea7185d 100644 --- a/cli/servicesmock_test.go +++ b/cli/servicesmock_test.go @@ -6,11 +6,12 @@ package cli import ( context "context" + reflect "reflect" + go_address "github.com/filecoin-project/go-address" abi "github.com/filecoin-project/go-state-types/abi" gomock "github.com/golang/mock/gomock" go_cid "github.com/ipfs/go-cid" - reflect "reflect" ) // MockServicesAPI is a mock of ServicesAPI interface diff --git a/cli/state.go b/cli/state.go index 12689c7e316..d9669df6a89 100644 --- a/cli/state.go +++ b/cli/state.go @@ -15,6 +15,8 @@ import ( "strings" "time" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/fatih/color" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -178,7 +180,7 @@ func ParseTipSetString(ts string) ([]cid.Cid, error) { return cids, nil } -func LoadTipSet(ctx context.Context, cctx *cli.Context, api api.FullNode) (*types.TipSet, error) { +func LoadTipSet(ctx context.Context, cctx *cli.Context, api v0api.FullNode) (*types.TipSet, error) { tss := cctx.String("tipset") if tss == "" { return nil, nil @@ -187,7 +189,7 @@ func LoadTipSet(ctx context.Context, cctx *cli.Context, api api.FullNode) (*type return ParseTipSetRef(ctx, api, tss) } -func ParseTipSetRef(ctx context.Context, api api.FullNode, tss string) (*types.TipSet, error) { +func ParseTipSetRef(ctx context.Context, api v0api.FullNode, tss string) (*types.TipSet, error) { if tss[0] == '@' { if tss == "@head" { return api.ChainHead(ctx) @@ -574,7 +576,7 @@ var StateListMinersCmd = &cli.Command{ }, } -func getDealsCounts(ctx context.Context, lapi api.FullNode) (map[address.Address]int, error) { +func getDealsCounts(ctx context.Context, lapi v0api.FullNode) (map[address.Address]int, error) { allDeals, err := lapi.StateMarketDeals(ctx, types.EmptyTSK) if err != nil { return nil, err @@ -1443,7 +1445,7 @@ var StateSearchMsgCmd = &cli.Command{ }, } -func printReceiptReturn(ctx context.Context, api api.FullNode, m *types.Message, r types.MessageReceipt) error { +func printReceiptReturn(ctx context.Context, api v0api.FullNode, m *types.Message, r types.MessageReceipt) error { if len(r.Return) == 0 { return nil } @@ -1463,7 +1465,7 @@ func printReceiptReturn(ctx context.Context, api api.FullNode, m *types.Message, return nil } -func printMsg(ctx context.Context, api api.FullNode, msg cid.Cid, mw *lapi.MsgLookup, m *types.Message) error { +func printMsg(ctx context.Context, api v0api.FullNode, msg cid.Cid, mw *lapi.MsgLookup, m *types.Message) error { if mw != nil { if mw.Message != msg { fmt.Printf("Message was replaced: %s\n", mw.Message) diff --git a/cli/sync.go b/cli/sync.go index 223d50337ac..c7b010111c3 100644 --- a/cli/sync.go +++ b/cli/sync.go @@ -12,6 +12,7 @@ import ( "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" ) @@ -240,7 +241,7 @@ var SyncCheckpointCmd = &cli.Command{ }, } -func SyncWait(ctx context.Context, napi api.FullNode, watch bool) error { +func SyncWait(ctx context.Context, napi v0api.FullNode, watch bool) error { tick := time.Second / 4 lastLines := 0 diff --git a/cli/util.go b/cli/util.go index fb555e320f0..3183e21cff8 100644 --- a/cli/util.go +++ b/cli/util.go @@ -10,12 +10,12 @@ import ( "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" ) -func parseTipSet(ctx context.Context, api api.FullNode, vals []string) (*types.TipSet, error) { +func parseTipSet(ctx context.Context, api v0api.FullNode, vals []string) (*types.TipSet, error) { var headers []*types.BlockHeader for _, c := range vals { blkc, err := cid.Decode(c) diff --git a/node/impl/full/state.go b/node/impl/full/state.go index aa806bfe0b5..f6cf2759e0d 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -520,8 +520,8 @@ func (a *StateAPI) MinerCreateBlock(ctx context.Context, bt *api.BlockTemplate) return &out, nil } -func (m *StateModule) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) { - ts, recpt, found, err := m.StateManager.WaitForMessage(ctx, msg, confidence, lookbackLimit) +func (m *StateModule) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + ts, recpt, found, err := m.StateManager.WaitForMessage(ctx, msg, confidence, lookbackLimit, allowReplaced) if err != nil { return nil, err } From 09c374cdde32cdc47b2ae494aaded2adbb47ee89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 3 Apr 2021 13:12:50 +0200 Subject: [PATCH 20/60] api stub codegen --- api/proxy_gen.go | 1415 ++++++++++++++++++++++++++++++++++++++++ api/v0api/latest.go | 1 + api/v0api/proxy_gen.go | 697 ++++++++++++++++++++ gen/api/proxygen.go | 40 +- 4 files changed, 2148 insertions(+), 5 deletions(-) diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 2808c8a1ffa..32d1992d03d 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -36,6 +36,7 @@ import ( "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" protocol "github.com/libp2p/go-libp2p-core/protocol" + xerrors "golang.org/x/xerrors" ) type ChainIOStruct struct { @@ -46,6 +47,9 @@ type ChainIOStruct struct { } } +type ChainIOStub struct { +} + type CommonStruct struct { Internal struct { AuthNew func(p0 context.Context, p1 []auth.Permission) ([]byte, error) `perm:"admin"` @@ -102,6 +106,9 @@ type CommonStruct struct { } } +type CommonStub struct { +} + type FullNodeStruct struct { CommonStruct @@ -448,6 +455,10 @@ type FullNodeStruct struct { } } +type FullNodeStub struct { + CommonStub +} + type GatewayStruct struct { Internal struct { ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `` @@ -510,12 +521,18 @@ type GatewayStruct struct { } } +type GatewayStub struct { +} + type SignableStruct struct { Internal struct { Sign func(p0 context.Context, p1 SignFunc) error `` } } +type SignableStub struct { +} + type StorageMinerStruct struct { CommonStruct @@ -698,6 +715,10 @@ type StorageMinerStruct struct { } } +type StorageMinerStub struct { + CommonStub +} + type WalletStruct struct { Internal struct { WalletDelete func(p0 context.Context, p1 address.Address) error `` @@ -716,6 +737,9 @@ type WalletStruct struct { } } +type WalletStub struct { +} + type WorkerStruct struct { Internal struct { AddPiece func(p0 context.Context, p1 storage.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storage.Data) (storiface.CallID, error) `perm:"admin"` @@ -768,1394 +792,2785 @@ type WorkerStruct struct { } } +type WorkerStub struct { +} + func (s *ChainIOStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { return s.Internal.ChainHasObj(p0, p1) } +func (s *ChainIOStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *ChainIOStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { return s.Internal.ChainReadObj(p0, p1) } +func (s *ChainIOStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") +} + func (s *CommonStruct) AuthNew(p0 context.Context, p1 []auth.Permission) ([]byte, error) { return s.Internal.AuthNew(p0, p1) } +func (s *CommonStub) AuthNew(p0 context.Context, p1 []auth.Permission) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") +} + func (s *CommonStruct) AuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { return s.Internal.AuthVerify(p0, p1) } +func (s *CommonStub) AuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { + return *new([]auth.Permission), xerrors.New("method not supported") +} + func (s *CommonStruct) Closing(p0 context.Context) (<-chan struct{}, error) { return s.Internal.Closing(p0) } +func (s *CommonStub) Closing(p0 context.Context) (<-chan struct{}, error) { + return nil, xerrors.New("method not supported") +} + func (s *CommonStruct) Discover(p0 context.Context) (apitypes.OpenRPCDocument, error) { return s.Internal.Discover(p0) } +func (s *CommonStub) Discover(p0 context.Context) (apitypes.OpenRPCDocument, error) { + return *new(apitypes.OpenRPCDocument), xerrors.New("method not supported") +} + func (s *CommonStruct) ID(p0 context.Context) (peer.ID, error) { return s.Internal.ID(p0) } +func (s *CommonStub) ID(p0 context.Context) (peer.ID, error) { + return *new(peer.ID), xerrors.New("method not supported") +} + func (s *CommonStruct) LogList(p0 context.Context) ([]string, error) { return s.Internal.LogList(p0) } +func (s *CommonStub) LogList(p0 context.Context) ([]string, error) { + return *new([]string), xerrors.New("method not supported") +} + func (s *CommonStruct) LogSetLevel(p0 context.Context, p1 string, p2 string) error { return s.Internal.LogSetLevel(p0, p1, p2) } +func (s *CommonStub) LogSetLevel(p0 context.Context, p1 string, p2 string) error { + return xerrors.New("method not supported") +} + func (s *CommonStruct) NetAddrsListen(p0 context.Context) (peer.AddrInfo, error) { return s.Internal.NetAddrsListen(p0) } +func (s *CommonStub) NetAddrsListen(p0 context.Context) (peer.AddrInfo, error) { + return *new(peer.AddrInfo), xerrors.New("method not supported") +} + func (s *CommonStruct) NetAgentVersion(p0 context.Context, p1 peer.ID) (string, error) { return s.Internal.NetAgentVersion(p0, p1) } +func (s *CommonStub) NetAgentVersion(p0 context.Context, p1 peer.ID) (string, error) { + return "", xerrors.New("method not supported") +} + func (s *CommonStruct) NetAutoNatStatus(p0 context.Context) (NatInfo, error) { return s.Internal.NetAutoNatStatus(p0) } +func (s *CommonStub) NetAutoNatStatus(p0 context.Context) (NatInfo, error) { + return *new(NatInfo), xerrors.New("method not supported") +} + func (s *CommonStruct) NetBandwidthStats(p0 context.Context) (metrics.Stats, error) { return s.Internal.NetBandwidthStats(p0) } +func (s *CommonStub) NetBandwidthStats(p0 context.Context) (metrics.Stats, error) { + return *new(metrics.Stats), xerrors.New("method not supported") +} + func (s *CommonStruct) NetBandwidthStatsByPeer(p0 context.Context) (map[string]metrics.Stats, error) { return s.Internal.NetBandwidthStatsByPeer(p0) } +func (s *CommonStub) NetBandwidthStatsByPeer(p0 context.Context) (map[string]metrics.Stats, error) { + return *new(map[string]metrics.Stats), xerrors.New("method not supported") +} + func (s *CommonStruct) NetBandwidthStatsByProtocol(p0 context.Context) (map[protocol.ID]metrics.Stats, error) { return s.Internal.NetBandwidthStatsByProtocol(p0) } +func (s *CommonStub) NetBandwidthStatsByProtocol(p0 context.Context) (map[protocol.ID]metrics.Stats, error) { + return *new(map[protocol.ID]metrics.Stats), xerrors.New("method not supported") +} + func (s *CommonStruct) NetBlockAdd(p0 context.Context, p1 NetBlockList) error { return s.Internal.NetBlockAdd(p0, p1) } +func (s *CommonStub) NetBlockAdd(p0 context.Context, p1 NetBlockList) error { + return xerrors.New("method not supported") +} + func (s *CommonStruct) NetBlockList(p0 context.Context) (NetBlockList, error) { return s.Internal.NetBlockList(p0) } +func (s *CommonStub) NetBlockList(p0 context.Context) (NetBlockList, error) { + return *new(NetBlockList), xerrors.New("method not supported") +} + func (s *CommonStruct) NetBlockRemove(p0 context.Context, p1 NetBlockList) error { return s.Internal.NetBlockRemove(p0, p1) } +func (s *CommonStub) NetBlockRemove(p0 context.Context, p1 NetBlockList) error { + return xerrors.New("method not supported") +} + func (s *CommonStruct) NetConnect(p0 context.Context, p1 peer.AddrInfo) error { return s.Internal.NetConnect(p0, p1) } +func (s *CommonStub) NetConnect(p0 context.Context, p1 peer.AddrInfo) error { + return xerrors.New("method not supported") +} + func (s *CommonStruct) NetConnectedness(p0 context.Context, p1 peer.ID) (network.Connectedness, error) { return s.Internal.NetConnectedness(p0, p1) } +func (s *CommonStub) NetConnectedness(p0 context.Context, p1 peer.ID) (network.Connectedness, error) { + return *new(network.Connectedness), xerrors.New("method not supported") +} + func (s *CommonStruct) NetDisconnect(p0 context.Context, p1 peer.ID) error { return s.Internal.NetDisconnect(p0, p1) } +func (s *CommonStub) NetDisconnect(p0 context.Context, p1 peer.ID) error { + return xerrors.New("method not supported") +} + func (s *CommonStruct) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) { return s.Internal.NetFindPeer(p0, p1) } +func (s *CommonStub) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) { + return *new(peer.AddrInfo), xerrors.New("method not supported") +} + func (s *CommonStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) { return s.Internal.NetPeerInfo(p0, p1) } +func (s *CommonStub) NetPeerInfo(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *CommonStruct) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) { return s.Internal.NetPeers(p0) } +func (s *CommonStub) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) { + return *new([]peer.AddrInfo), xerrors.New("method not supported") +} + func (s *CommonStruct) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) { return s.Internal.NetPubsubScores(p0) } +func (s *CommonStub) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) { + return *new([]PubsubScore), xerrors.New("method not supported") +} + func (s *CommonStruct) Session(p0 context.Context) (uuid.UUID, error) { return s.Internal.Session(p0) } +func (s *CommonStub) Session(p0 context.Context) (uuid.UUID, error) { + return *new(uuid.UUID), xerrors.New("method not supported") +} + func (s *CommonStruct) Shutdown(p0 context.Context) error { return s.Internal.Shutdown(p0) } +func (s *CommonStub) Shutdown(p0 context.Context) error { + return xerrors.New("method not supported") +} + func (s *CommonStruct) Version(p0 context.Context) (APIVersion, error) { return s.Internal.Version(p0) } +func (s *CommonStub) Version(p0 context.Context) (APIVersion, error) { + return *new(APIVersion), xerrors.New("method not supported") +} + func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { return s.Internal.BeaconGetEntry(p0, p1) } +func (s *FullNodeStub) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { return s.Internal.ChainDeleteObj(p0, p1) } +func (s *FullNodeStub) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { return s.Internal.ChainExport(p0, p1, p2, p3) } +func (s *FullNodeStub) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { return s.Internal.ChainGetBlock(p0, p1) } +func (s *FullNodeStub) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { return s.Internal.ChainGetBlockMessages(p0, p1) } +func (s *FullNodeStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { return s.Internal.ChainGetGenesis(p0) } +func (s *FullNodeStub) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { return s.Internal.ChainGetMessage(p0, p1) } +func (s *FullNodeStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*IpldObject, error) { return s.Internal.ChainGetNode(p0, p1) } +func (s *FullNodeStub) ChainGetNode(p0 context.Context, p1 string) (*IpldObject, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]Message, error) { return s.Internal.ChainGetParentMessages(p0, p1) } +func (s *FullNodeStub) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]Message, error) { + return *new([]Message), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { return s.Internal.ChainGetParentReceipts(p0, p1) } +func (s *FullNodeStub) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { + return *new([]*types.MessageReceipt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) { return s.Internal.ChainGetPath(p0, p1, p2) } +func (s *FullNodeStub) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) { + return *new([]*HeadChange), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { return s.Internal.ChainGetRandomnessFromBeacon(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return *new(abi.Randomness), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { return s.Internal.ChainGetRandomnessFromTickets(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return *new(abi.Randomness), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { return s.Internal.ChainGetTipSet(p0, p1) } +func (s *FullNodeStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) } +func (s *FullNodeStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { return s.Internal.ChainHasObj(p0, p1) } +func (s *FullNodeStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { return s.Internal.ChainHead(p0) } +func (s *FullNodeStub) ChainHead(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { return s.Internal.ChainNotify(p0) } +func (s *FullNodeStub) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { return s.Internal.ChainReadObj(p0, p1) } +func (s *FullNodeStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { return s.Internal.ChainSetHead(p0, p1) } +func (s *FullNodeStub) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) { return s.Internal.ChainStatObj(p0, p1, p2) } +func (s *FullNodeStub) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) { + return *new(ObjStat), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { return s.Internal.ChainTipSetWeight(p0, p1) } +func (s *FullNodeStub) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientCalcCommP(p0 context.Context, p1 string) (*CommPRet, error) { return s.Internal.ClientCalcCommP(p0, p1) } +func (s *FullNodeStub) ClientCalcCommP(p0 context.Context, p1 string) (*CommPRet, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { return s.Internal.ClientCancelDataTransfer(p0, p1, p2, p3) } +func (s *FullNodeStub) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { return s.Internal.ClientCancelRetrievalDeal(p0, p1) } +func (s *FullNodeStub) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { return s.Internal.ClientDataTransferUpdates(p0) } +func (s *FullNodeStub) ClientDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) { return s.Internal.ClientDealPieceCID(p0, p1) } +func (s *FullNodeStub) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) { + return *new(DataCIDSize), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientDealSize(p0 context.Context, p1 cid.Cid) (DataSize, error) { return s.Internal.ClientDealSize(p0, p1) } +func (s *FullNodeStub) ClientDealSize(p0 context.Context, p1 cid.Cid) (DataSize, error) { + return *new(DataSize), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) { return s.Internal.ClientFindData(p0, p1, p2) } +func (s *FullNodeStub) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) { + return *new([]QueryOffer), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientGenCar(p0 context.Context, p1 FileRef, p2 string) error { return s.Internal.ClientGenCar(p0, p1, p2) } +func (s *FullNodeStub) ClientGenCar(p0 context.Context, p1 FileRef, p2 string) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*DealInfo, error) { return s.Internal.ClientGetDealInfo(p0, p1) } +func (s *FullNodeStub) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*DealInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { return s.Internal.ClientGetDealStatus(p0, p1) } +func (s *FullNodeStub) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { + return "", xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientGetDealUpdates(p0 context.Context) (<-chan DealInfo, error) { return s.Internal.ClientGetDealUpdates(p0) } +func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan DealInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { return s.Internal.ClientHasLocal(p0, p1) } +func (s *FullNodeStub) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientImport(p0 context.Context, p1 FileRef) (*ImportRes, error) { return s.Internal.ClientImport(p0, p1) } +func (s *FullNodeStub) ClientImport(p0 context.Context, p1 FileRef) (*ImportRes, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { return s.Internal.ClientListDataTransfers(p0) } +func (s *FullNodeStub) ClientListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { + return *new([]DataTransferChannel), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientListDeals(p0 context.Context) ([]DealInfo, error) { return s.Internal.ClientListDeals(p0) } +func (s *FullNodeStub) ClientListDeals(p0 context.Context) ([]DealInfo, error) { + return *new([]DealInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientListImports(p0 context.Context) ([]Import, error) { return s.Internal.ClientListImports(p0) } +func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]Import, error) { + return *new([]Import), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) { return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) } +func (s *FullNodeStub) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) { + return *new(QueryOffer), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { return s.Internal.ClientQueryAsk(p0, p1, p2) } +func (s *FullNodeStub) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { return s.Internal.ClientRemoveImport(p0, p1) } +func (s *FullNodeStub) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { return s.Internal.ClientRestartDataTransfer(p0, p1, p2, p3) } +func (s *FullNodeStub) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientRetrieve(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) error { return s.Internal.ClientRetrieve(p0, p1, p2) } +func (s *FullNodeStub) ClientRetrieve(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { return s.Internal.ClientRetrieveTryRestartInsufficientFunds(p0, p1) } +func (s *FullNodeStub) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientRetrieveWithEvents(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) (<-chan marketevents.RetrievalEvent, error) { return s.Internal.ClientRetrieveWithEvents(p0, p1, p2) } +func (s *FullNodeStub) ClientRetrieveWithEvents(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) (<-chan marketevents.RetrievalEvent, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientStartDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) { return s.Internal.ClientStartDeal(p0, p1) } +func (s *FullNodeStub) ClientStartDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) CreateBackup(p0 context.Context, p1 string) error { return s.Internal.CreateBackup(p0, p1) } +func (s *FullNodeStub) CreateBackup(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.GasEstimateFeeCap(p0, p1, p2, p3) } +func (s *FullNodeStub) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { return s.Internal.GasEstimateGasLimit(p0, p1, p2) } +func (s *FullNodeStub) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { + return 0, xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { return s.Internal.GasEstimateGasPremium(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } +func (s *FullNodeStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { return s.Internal.MarketAddBalance(p0, p1, p2, p3) } +func (s *FullNodeStub) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { return s.Internal.MarketGetReserved(p0, p1) } +func (s *FullNodeStub) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { return s.Internal.MarketReleaseFunds(p0, p1, p2) } +func (s *FullNodeStub) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { return s.Internal.MarketReserveFunds(p0, p1, p2, p3) } +func (s *FullNodeStub) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { return s.Internal.MarketWithdraw(p0, p1, p2, p3) } +func (s *FullNodeStub) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MinerCreateBlock(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) { return s.Internal.MinerCreateBlock(p0, p1) } +func (s *FullNodeStub) MinerCreateBlock(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) { return s.Internal.MinerGetBaseInfo(p0, p1, p2, p3) } +func (s *FullNodeStub) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { return s.Internal.MpoolBatchPush(p0, p1) } +func (s *FullNodeStub) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) { return s.Internal.MpoolBatchPushMessage(p0, p1, p2) } +func (s *FullNodeStub) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { return s.Internal.MpoolBatchPushUntrusted(p0, p1) } +func (s *FullNodeStub) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolClear(p0 context.Context, p1 bool) error { return s.Internal.MpoolClear(p0, p1) } +func (s *FullNodeStub) MpoolClear(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { return s.Internal.MpoolGetConfig(p0) } +func (s *FullNodeStub) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { return s.Internal.MpoolGetNonce(p0, p1) } +func (s *FullNodeStub) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { + return 0, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { return s.Internal.MpoolPending(p0, p1) } +func (s *FullNodeStub) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { return s.Internal.MpoolPush(p0, p1) } +func (s *FullNodeStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) { return s.Internal.MpoolPushMessage(p0, p1, p2) } +func (s *FullNodeStub) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { return s.Internal.MpoolPushUntrusted(p0, p1) } +func (s *FullNodeStub) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { return s.Internal.MpoolSelect(p0, p1, p2) } +func (s *FullNodeStub) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { return s.Internal.MpoolSetConfig(p0, p1) } +func (s *FullNodeStub) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolSub(p0 context.Context) (<-chan MpoolUpdate, error) { return s.Internal.MpoolSub(p0) } +func (s *FullNodeStub) MpoolSub(p0 context.Context) (<-chan MpoolUpdate, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) { return s.Internal.MsigAddApprove(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) { return s.Internal.MsigAddCancel(p0, p1, p2, p3, p4, p5) } +func (s *FullNodeStub) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { return s.Internal.MsigAddPropose(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) { return s.Internal.MsigApprove(p0, p1, p2, p3) } +func (s *FullNodeStub) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) { return s.Internal.MsigApproveTxnHash(p0, p1, p2, p3, p4, p5, p6, p7, p8) } +func (s *FullNodeStub) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) { return s.Internal.MsigCancel(p0, p1, p2, p3, p4, p5, p6, p7) } +func (s *FullNodeStub) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) { return s.Internal.MsigCreate(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } +func (s *FullNodeStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { return s.Internal.MsigGetPending(p0, p1, p2) } +func (s *FullNodeStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { + return *new([]*MsigTransaction), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.MsigGetVested(p0, p1, p2, p3) } +func (s *FullNodeStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) { return s.Internal.MsigGetVestingSchedule(p0, p1, p2) } +func (s *FullNodeStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) { + return *new(MsigVesting), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) { return s.Internal.MsigPropose(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { return s.Internal.MsigRemoveSigner(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) { return s.Internal.MsigSwapApprove(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) { return s.Internal.MsigSwapCancel(p0, p1, p2, p3, p4, p5) } +func (s *FullNodeStub) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) { return s.Internal.MsigSwapPropose(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { return s.Internal.PaychAllocateLane(p0, p1) } +func (s *FullNodeStub) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { + return 0, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) { return s.Internal.PaychAvailableFunds(p0, p1) } +func (s *FullNodeStub) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) { return s.Internal.PaychAvailableFundsByFromTo(p0, p1, p2) } +func (s *FullNodeStub) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { return s.Internal.PaychCollect(p0, p1) } +func (s *FullNodeStub) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) { return s.Internal.PaychGet(p0, p1, p2, p3) } +func (s *FullNodeStub) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { return s.Internal.PaychGetWaitReady(p0, p1) } +func (s *FullNodeStub) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychList(p0 context.Context) ([]address.Address, error) { return s.Internal.PaychList(p0) } +func (s *FullNodeStub) PaychList(p0 context.Context) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) { return s.Internal.PaychNewPayment(p0, p1, p2, p3) } +func (s *FullNodeStub) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { return s.Internal.PaychSettle(p0, p1) } +func (s *FullNodeStub) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychStatus(p0 context.Context, p1 address.Address) (*PaychStatus, error) { return s.Internal.PaychStatus(p0, p1) } +func (s *FullNodeStub) PaychStatus(p0 context.Context, p1 address.Address) (*PaychStatus, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { return s.Internal.PaychVoucherAdd(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { return s.Internal.PaychVoucherCheckSpendable(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { return s.Internal.PaychVoucherCheckValid(p0, p1, p2) } +func (s *FullNodeStub) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) { return s.Internal.PaychVoucherCreate(p0, p1, p2, p3) } +func (s *FullNodeStub) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { return s.Internal.PaychVoucherList(p0, p1) } +func (s *FullNodeStub) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { + return *new([]*paych.SignedVoucher), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { return s.Internal.PaychVoucherSubmit(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { return s.Internal.StateAccountKey(p0, p1, p2) } +func (s *FullNodeStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) { return s.Internal.StateAllMinerFaults(p0, p1, p2) } +func (s *FullNodeStub) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) { + return *new([]*Fault), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) { return s.Internal.StateCall(p0, p1, p2) } +func (s *FullNodeStub) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { return s.Internal.StateChangedActors(p0, p1, p2) } +func (s *FullNodeStub) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { + return *new(map[string]types.Actor), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { return s.Internal.StateCirculatingSupply(p0, p1) } +func (s *FullNodeStub) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { + return *new(abi.TokenAmount), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*ComputeStateOutput, error) { return s.Internal.StateCompute(p0, p1, p2, p3) } +func (s *FullNodeStub) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*ComputeStateOutput, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } +func (s *FullNodeStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { + return *new(DealCollateralBounds), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { return s.Internal.StateDecodeParams(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { return s.Internal.StateGetActor(p0, p1, p2) } +func (s *FullNodeStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { return s.Internal.StateListActors(p0, p1) } +func (s *FullNodeStub) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateListMessages(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { return s.Internal.StateListMessages(p0, p1, p2, p3) } +func (s *FullNodeStub) StateListMessages(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { return s.Internal.StateListMiners(p0, p1) } +func (s *FullNodeStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { return s.Internal.StateLookupID(p0, p1, p2) } +func (s *FullNodeStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { return s.Internal.StateMarketBalance(p0, p1, p2) } +func (s *FullNodeStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { + return *new(MarketBalance), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]MarketDeal, error) { return s.Internal.StateMarketDeals(p0, p1) } +func (s *FullNodeStub) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]MarketDeal, error) { + return *new(map[string]MarketDeal), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) { return s.Internal.StateMarketParticipants(p0, p1) } +func (s *FullNodeStub) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) { + return *new(map[string]MarketBalance), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { return s.Internal.StateMarketStorageDeal(p0, p1, p2) } +func (s *FullNodeStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { return s.Internal.StateMinerActiveSectors(p0, p1, p2) } +func (s *FullNodeStub) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { return s.Internal.StateMinerAvailableBalance(p0, p1, p2) } +func (s *FullNodeStub) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) { return s.Internal.StateMinerDeadlines(p0, p1, p2) } +func (s *FullNodeStub) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) { + return *new([]Deadline), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { return s.Internal.StateMinerFaults(p0, p1, p2) } +func (s *FullNodeStub) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return *new(bitfield.BitField), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { return s.Internal.StateMinerInfo(p0, p1, p2) } +func (s *FullNodeStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return *new(miner.MinerInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.StateMinerInitialPledgeCollateral(p0, p1, p2, p3) } +func (s *FullNodeStub) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) { return s.Internal.StateMinerPartitions(p0, p1, p2, p3) } +func (s *FullNodeStub) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) { + return *new([]Partition), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { return s.Internal.StateMinerPower(p0, p1, p2) } +func (s *FullNodeStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.StateMinerPreCommitDepositForPower(p0, p1, p2, p3) } +func (s *FullNodeStub) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { return s.Internal.StateMinerProvingDeadline(p0, p1, p2) } +func (s *FullNodeStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { return s.Internal.StateMinerRecoveries(p0, p1, p2) } +func (s *FullNodeStub) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return *new(bitfield.BitField), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { return s.Internal.StateMinerSectorAllocated(p0, p1, p2, p3) } +func (s *FullNodeStub) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) { return s.Internal.StateMinerSectorCount(p0, p1, p2) } +func (s *FullNodeStub) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) { + return *new(MinerSectors), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { return s.Internal.StateMinerSectors(p0, p1, p2, p3) } +func (s *FullNodeStub) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { return s.Internal.StateNetworkName(p0) } +func (s *FullNodeStub) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { + return *new(dtypes.NetworkName), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { return s.Internal.StateNetworkVersion(p0, p1) } +func (s *FullNodeStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + return *new(apitypes.NetworkVersion), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) { return s.Internal.StateReadState(p0, p1, p2) } +func (s *FullNodeStub) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) { return s.Internal.StateReplay(p0, p1, p2) } +func (s *FullNodeStub) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { return s.Internal.StateSearchMsg(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { return s.Internal.StateSectorExpiration(p0, p1, p2, p3) } +func (s *FullNodeStub) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } +func (s *FullNodeStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { return s.Internal.StateSectorPartition(p0, p1, p2, p3) } +func (s *FullNodeStub) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { return s.Internal.StateSectorPreCommitInfo(p0, p1, p2, p3) } +func (s *FullNodeStub) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + return *new(miner.SectorPreCommitOnChainInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) { return s.Internal.StateVMCirculatingSupplyInternal(p0, p1) } +func (s *FullNodeStub) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) { + return *new(CirculatingSupply), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { return s.Internal.StateVerifiedClientStatus(p0, p1, p2) } +func (s *FullNodeStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { return s.Internal.StateVerifiedRegistryRootKey(p0, p1) } +func (s *FullNodeStub) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { return s.Internal.StateVerifierStatus(p0, p1, p2) } +func (s *FullNodeStub) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { return s.Internal.StateWaitMsg(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { return s.Internal.SyncCheckBad(p0, p1) } +func (s *FullNodeStub) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { + return "", xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { return s.Internal.SyncCheckpoint(p0, p1) } +func (s *FullNodeStub) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { return s.Internal.SyncIncomingBlocks(p0) } +func (s *FullNodeStub) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { return s.Internal.SyncMarkBad(p0, p1) } +func (s *FullNodeStub) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncState(p0 context.Context) (*SyncState, error) { return s.Internal.SyncState(p0) } +func (s *FullNodeStub) SyncState(p0 context.Context) (*SyncState, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { return s.Internal.SyncSubmitBlock(p0, p1) } +func (s *FullNodeStub) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncUnmarkAllBad(p0 context.Context) error { return s.Internal.SyncUnmarkAllBad(p0) } +func (s *FullNodeStub) SyncUnmarkAllBad(p0 context.Context) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { return s.Internal.SyncUnmarkBad(p0, p1) } +func (s *FullNodeStub) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { return s.Internal.SyncValidateTipset(p0, p1) } +func (s *FullNodeStub) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { return s.Internal.WalletBalance(p0, p1) } +func (s *FullNodeStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletDefaultAddress(p0 context.Context) (address.Address, error) { return s.Internal.WalletDefaultAddress(p0) } +func (s *FullNodeStub) WalletDefaultAddress(p0 context.Context) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletDelete(p0 context.Context, p1 address.Address) error { return s.Internal.WalletDelete(p0, p1) } +func (s *FullNodeStub) WalletDelete(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { return s.Internal.WalletExport(p0, p1) } +func (s *FullNodeStub) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { return s.Internal.WalletHas(p0, p1) } +func (s *FullNodeStub) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { return s.Internal.WalletImport(p0, p1) } +func (s *FullNodeStub) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletList(p0 context.Context) ([]address.Address, error) { return s.Internal.WalletList(p0) } +func (s *FullNodeStub) WalletList(p0 context.Context) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { return s.Internal.WalletNew(p0, p1) } +func (s *FullNodeStub) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletSetDefault(p0 context.Context, p1 address.Address) error { return s.Internal.WalletSetDefault(p0, p1) } +func (s *FullNodeStub) WalletSetDefault(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { return s.Internal.WalletSign(p0, p1, p2) } +func (s *FullNodeStub) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { return s.Internal.WalletSignMessage(p0, p1, p2) } +func (s *FullNodeStub) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { return s.Internal.WalletValidateAddress(p0, p1) } +func (s *FullNodeStub) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { return s.Internal.WalletVerify(p0, p1, p2, p3) } +func (s *FullNodeStub) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *GatewayStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { return s.Internal.ChainGetBlockMessages(p0, p1) } +func (s *GatewayStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { return s.Internal.ChainGetMessage(p0, p1) } +func (s *GatewayStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { return s.Internal.ChainGetTipSet(p0, p1) } +func (s *GatewayStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) } +func (s *GatewayStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { return s.Internal.ChainHasObj(p0, p1) } +func (s *GatewayStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *GatewayStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { return s.Internal.ChainHead(p0) } +func (s *GatewayStub) ChainHead(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { return s.Internal.ChainNotify(p0) } +func (s *GatewayStub) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { return s.Internal.ChainReadObj(p0, p1) } +func (s *GatewayStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") +} + func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } +func (s *GatewayStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { return s.Internal.MpoolPush(p0, p1) } +func (s *GatewayStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *GatewayStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } +func (s *GatewayStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *GatewayStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { return s.Internal.MsigGetPending(p0, p1, p2) } +func (s *GatewayStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { + return *new([]*MsigTransaction), xerrors.New("method not supported") +} + func (s *GatewayStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.MsigGetVested(p0, p1, p2, p3) } +func (s *GatewayStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { return s.Internal.StateAccountKey(p0, p1, p2) } +func (s *GatewayStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } +func (s *GatewayStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { + return *new(DealCollateralBounds), xerrors.New("method not supported") +} + func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { return s.Internal.StateGetActor(p0, p1, p2) } +func (s *GatewayStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { return s.Internal.StateGetReceipt(p0, p1, p2) } +func (s *GatewayStub) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { return s.Internal.StateListMiners(p0, p1) } +func (s *GatewayStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + func (s *GatewayStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { return s.Internal.StateLookupID(p0, p1, p2) } +func (s *GatewayStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *GatewayStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { return s.Internal.StateMarketBalance(p0, p1, p2) } +func (s *GatewayStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { + return *new(MarketBalance), xerrors.New("method not supported") +} + func (s *GatewayStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { return s.Internal.StateMarketStorageDeal(p0, p1, p2) } +func (s *GatewayStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { return s.Internal.StateMinerInfo(p0, p1, p2) } +func (s *GatewayStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return *new(miner.MinerInfo), xerrors.New("method not supported") +} + func (s *GatewayStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { return s.Internal.StateMinerPower(p0, p1, p2) } +func (s *GatewayStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { return s.Internal.StateMinerProvingDeadline(p0, p1, p2) } +func (s *GatewayStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { return s.Internal.StateNetworkVersion(p0, p1) } +func (s *GatewayStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + return *new(apitypes.NetworkVersion), xerrors.New("method not supported") +} + func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) { return s.Internal.StateSearchMsg(p0, p1) } +func (s *GatewayStub) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } +func (s *GatewayStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { return s.Internal.StateVerifiedClientStatus(p0, p1, p2) } +func (s *GatewayStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") +} + func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) { return s.Internal.StateWaitMsg(p0, p1, p2) } +func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + func (s *SignableStruct) Sign(p0 context.Context, p1 SignFunc) error { return s.Internal.Sign(p0, p1) } +func (s *SignableStub) Sign(p0 context.Context, p1 SignFunc) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ActorAddress(p0 context.Context) (address.Address, error) { return s.Internal.ActorAddress(p0) } +func (s *StorageMinerStub) ActorAddress(p0 context.Context) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ActorAddressConfig(p0 context.Context) (AddressConfig, error) { return s.Internal.ActorAddressConfig(p0) } +func (s *StorageMinerStub) ActorAddressConfig(p0 context.Context) (AddressConfig, error) { + return *new(AddressConfig), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ActorSectorSize(p0 context.Context, p1 address.Address) (abi.SectorSize, error) { return s.Internal.ActorSectorSize(p0, p1) } +func (s *StorageMinerStub) ActorSectorSize(p0 context.Context, p1 address.Address) (abi.SectorSize, error) { + return *new(abi.SectorSize), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) { return s.Internal.CheckProvable(p0, p1, p2, p3) } +func (s *StorageMinerStub) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) { + return *new(map[abi.SectorNumber]string), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ComputeProof(p0 context.Context, p1 []builtin.SectorInfo, p2 abi.PoStRandomness) ([]builtin.PoStProof, error) { return s.Internal.ComputeProof(p0, p1, p2) } +func (s *StorageMinerStub) ComputeProof(p0 context.Context, p1 []builtin.SectorInfo, p2 abi.PoStRandomness) ([]builtin.PoStProof, error) { + return *new([]builtin.PoStProof), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) CreateBackup(p0 context.Context, p1 string) error { return s.Internal.CreateBackup(p0, p1) } +func (s *StorageMinerStub) CreateBackup(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsConsiderOfflineRetrievalDeals(p0 context.Context) (bool, error) { return s.Internal.DealsConsiderOfflineRetrievalDeals(p0) } +func (s *StorageMinerStub) DealsConsiderOfflineRetrievalDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsConsiderOfflineStorageDeals(p0 context.Context) (bool, error) { return s.Internal.DealsConsiderOfflineStorageDeals(p0) } +func (s *StorageMinerStub) DealsConsiderOfflineStorageDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsConsiderOnlineRetrievalDeals(p0 context.Context) (bool, error) { return s.Internal.DealsConsiderOnlineRetrievalDeals(p0) } +func (s *StorageMinerStub) DealsConsiderOnlineRetrievalDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsConsiderOnlineStorageDeals(p0 context.Context) (bool, error) { return s.Internal.DealsConsiderOnlineStorageDeals(p0) } +func (s *StorageMinerStub) DealsConsiderOnlineStorageDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsConsiderUnverifiedStorageDeals(p0 context.Context) (bool, error) { return s.Internal.DealsConsiderUnverifiedStorageDeals(p0) } +func (s *StorageMinerStub) DealsConsiderUnverifiedStorageDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsConsiderVerifiedStorageDeals(p0 context.Context) (bool, error) { return s.Internal.DealsConsiderVerifiedStorageDeals(p0) } +func (s *StorageMinerStub) DealsConsiderVerifiedStorageDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsImportData(p0 context.Context, p1 cid.Cid, p2 string) error { return s.Internal.DealsImportData(p0, p1, p2) } +func (s *StorageMinerStub) DealsImportData(p0 context.Context, p1 cid.Cid, p2 string) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsList(p0 context.Context) ([]MarketDeal, error) { return s.Internal.DealsList(p0) } +func (s *StorageMinerStub) DealsList(p0 context.Context) ([]MarketDeal, error) { + return *new([]MarketDeal), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsPieceCidBlocklist(p0 context.Context) ([]cid.Cid, error) { return s.Internal.DealsPieceCidBlocklist(p0) } +func (s *StorageMinerStub) DealsPieceCidBlocklist(p0 context.Context) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsSetConsiderOfflineRetrievalDeals(p0 context.Context, p1 bool) error { return s.Internal.DealsSetConsiderOfflineRetrievalDeals(p0, p1) } +func (s *StorageMinerStub) DealsSetConsiderOfflineRetrievalDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsSetConsiderOfflineStorageDeals(p0 context.Context, p1 bool) error { return s.Internal.DealsSetConsiderOfflineStorageDeals(p0, p1) } +func (s *StorageMinerStub) DealsSetConsiderOfflineStorageDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsSetConsiderOnlineRetrievalDeals(p0 context.Context, p1 bool) error { return s.Internal.DealsSetConsiderOnlineRetrievalDeals(p0, p1) } +func (s *StorageMinerStub) DealsSetConsiderOnlineRetrievalDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsSetConsiderOnlineStorageDeals(p0 context.Context, p1 bool) error { return s.Internal.DealsSetConsiderOnlineStorageDeals(p0, p1) } +func (s *StorageMinerStub) DealsSetConsiderOnlineStorageDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsSetConsiderUnverifiedStorageDeals(p0 context.Context, p1 bool) error { return s.Internal.DealsSetConsiderUnverifiedStorageDeals(p0, p1) } +func (s *StorageMinerStub) DealsSetConsiderUnverifiedStorageDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsSetConsiderVerifiedStorageDeals(p0 context.Context, p1 bool) error { return s.Internal.DealsSetConsiderVerifiedStorageDeals(p0, p1) } +func (s *StorageMinerStub) DealsSetConsiderVerifiedStorageDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) DealsSetPieceCidBlocklist(p0 context.Context, p1 []cid.Cid) error { return s.Internal.DealsSetPieceCidBlocklist(p0, p1) } +func (s *StorageMinerStub) DealsSetPieceCidBlocklist(p0 context.Context, p1 []cid.Cid) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { return s.Internal.MarketCancelDataTransfer(p0, p1, p2, p3) } +func (s *StorageMinerStub) MarketCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { return s.Internal.MarketDataTransferUpdates(p0) } +func (s *StorageMinerStub) MarketDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { + return nil, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketGetAsk(p0 context.Context) (*storagemarket.SignedStorageAsk, error) { return s.Internal.MarketGetAsk(p0) } +func (s *StorageMinerStub) MarketGetAsk(p0 context.Context) (*storagemarket.SignedStorageAsk, error) { + return nil, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketGetDealUpdates(p0 context.Context) (<-chan storagemarket.MinerDeal, error) { return s.Internal.MarketGetDealUpdates(p0) } +func (s *StorageMinerStub) MarketGetDealUpdates(p0 context.Context) (<-chan storagemarket.MinerDeal, error) { + return nil, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketGetRetrievalAsk(p0 context.Context) (*retrievalmarket.Ask, error) { return s.Internal.MarketGetRetrievalAsk(p0) } +func (s *StorageMinerStub) MarketGetRetrievalAsk(p0 context.Context) (*retrievalmarket.Ask, error) { + return nil, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketImportDealData(p0 context.Context, p1 cid.Cid, p2 string) error { return s.Internal.MarketImportDealData(p0, p1, p2) } +func (s *StorageMinerStub) MarketImportDealData(p0 context.Context, p1 cid.Cid, p2 string) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { return s.Internal.MarketListDataTransfers(p0) } +func (s *StorageMinerStub) MarketListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { + return *new([]DataTransferChannel), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketListDeals(p0 context.Context) ([]MarketDeal, error) { return s.Internal.MarketListDeals(p0) } +func (s *StorageMinerStub) MarketListDeals(p0 context.Context) ([]MarketDeal, error) { + return *new([]MarketDeal), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketListIncompleteDeals(p0 context.Context) ([]storagemarket.MinerDeal, error) { return s.Internal.MarketListIncompleteDeals(p0) } +func (s *StorageMinerStub) MarketListIncompleteDeals(p0 context.Context) ([]storagemarket.MinerDeal, error) { + return *new([]storagemarket.MinerDeal), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketListRetrievalDeals(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) { return s.Internal.MarketListRetrievalDeals(p0) } +func (s *StorageMinerStub) MarketListRetrievalDeals(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) { + return *new([]retrievalmarket.ProviderDealState), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketPendingDeals(p0 context.Context) (PendingDealInfo, error) { return s.Internal.MarketPendingDeals(p0) } +func (s *StorageMinerStub) MarketPendingDeals(p0 context.Context) (PendingDealInfo, error) { + return *new(PendingDealInfo), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketPublishPendingDeals(p0 context.Context) error { return s.Internal.MarketPublishPendingDeals(p0) } +func (s *StorageMinerStub) MarketPublishPendingDeals(p0 context.Context) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { return s.Internal.MarketRestartDataTransfer(p0, p1, p2, p3) } +func (s *StorageMinerStub) MarketRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketSetAsk(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error { return s.Internal.MarketSetAsk(p0, p1, p2, p3, p4, p5) } +func (s *StorageMinerStub) MarketSetAsk(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MarketSetRetrievalAsk(p0 context.Context, p1 *retrievalmarket.Ask) error { return s.Internal.MarketSetRetrievalAsk(p0, p1) } +func (s *StorageMinerStub) MarketSetRetrievalAsk(p0 context.Context, p1 *retrievalmarket.Ask) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) MiningBase(p0 context.Context) (*types.TipSet, error) { return s.Internal.MiningBase(p0) } +func (s *StorageMinerStub) MiningBase(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) PiecesGetCIDInfo(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) { return s.Internal.PiecesGetCIDInfo(p0, p1) } +func (s *StorageMinerStub) PiecesGetCIDInfo(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) PiecesGetPieceInfo(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) { return s.Internal.PiecesGetPieceInfo(p0, p1) } +func (s *StorageMinerStub) PiecesGetPieceInfo(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) PiecesListCidInfos(p0 context.Context) ([]cid.Cid, error) { return s.Internal.PiecesListCidInfos(p0) } +func (s *StorageMinerStub) PiecesListCidInfos(p0 context.Context) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) PiecesListPieces(p0 context.Context) ([]cid.Cid, error) { return s.Internal.PiecesListPieces(p0) } +func (s *StorageMinerStub) PiecesListPieces(p0 context.Context) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) PledgeSector(p0 context.Context) (abi.SectorID, error) { return s.Internal.PledgeSector(p0) } +func (s *StorageMinerStub) PledgeSector(p0 context.Context) (abi.SectorID, error) { + return *new(abi.SectorID), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnAddPiece(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error { return s.Internal.ReturnAddPiece(p0, p1, p2, p3) } +func (s *StorageMinerStub) ReturnAddPiece(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnFetch(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { return s.Internal.ReturnFetch(p0, p1, p2) } +func (s *StorageMinerStub) ReturnFetch(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnFinalizeSector(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { return s.Internal.ReturnFinalizeSector(p0, p1, p2) } +func (s *StorageMinerStub) ReturnFinalizeSector(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnMoveStorage(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { return s.Internal.ReturnMoveStorage(p0, p1, p2) } +func (s *StorageMinerStub) ReturnMoveStorage(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnReadPiece(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error { return s.Internal.ReturnReadPiece(p0, p1, p2, p3) } +func (s *StorageMinerStub) ReturnReadPiece(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnReleaseUnsealed(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { return s.Internal.ReturnReleaseUnsealed(p0, p1, p2) } +func (s *StorageMinerStub) ReturnReleaseUnsealed(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnSealCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error { return s.Internal.ReturnSealCommit1(p0, p1, p2, p3) } +func (s *StorageMinerStub) ReturnSealCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnSealCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.Proof, p3 *storiface.CallError) error { return s.Internal.ReturnSealCommit2(p0, p1, p2, p3) } +func (s *StorageMinerStub) ReturnSealCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.Proof, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnSealPreCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.PreCommit1Out, p3 *storiface.CallError) error { return s.Internal.ReturnSealPreCommit1(p0, p1, p2, p3) } +func (s *StorageMinerStub) ReturnSealPreCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.PreCommit1Out, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnSealPreCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.SectorCids, p3 *storiface.CallError) error { return s.Internal.ReturnSealPreCommit2(p0, p1, p2, p3) } +func (s *StorageMinerStub) ReturnSealPreCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.SectorCids, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) ReturnUnsealPiece(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { return s.Internal.ReturnUnsealPiece(p0, p1, p2) } +func (s *StorageMinerStub) ReturnUnsealPiece(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SealingAbort(p0 context.Context, p1 storiface.CallID) error { return s.Internal.SealingAbort(p0, p1) } +func (s *StorageMinerStub) SealingAbort(p0 context.Context, p1 storiface.CallID) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SealingSchedDiag(p0 context.Context, p1 bool) (interface{}, error) { return s.Internal.SealingSchedDiag(p0, p1) } +func (s *StorageMinerStub) SealingSchedDiag(p0 context.Context, p1 bool) (interface{}, error) { + return nil, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorGetExpectedSealDuration(p0 context.Context) (time.Duration, error) { return s.Internal.SectorGetExpectedSealDuration(p0) } +func (s *StorageMinerStub) SectorGetExpectedSealDuration(p0 context.Context) (time.Duration, error) { + return *new(time.Duration), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorGetSealDelay(p0 context.Context) (time.Duration, error) { return s.Internal.SectorGetSealDelay(p0) } +func (s *StorageMinerStub) SectorGetSealDelay(p0 context.Context) (time.Duration, error) { + return *new(time.Duration), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorMarkForUpgrade(p0 context.Context, p1 abi.SectorNumber) error { return s.Internal.SectorMarkForUpgrade(p0, p1) } +func (s *StorageMinerStub) SectorMarkForUpgrade(p0 context.Context, p1 abi.SectorNumber) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorRemove(p0 context.Context, p1 abi.SectorNumber) error { return s.Internal.SectorRemove(p0, p1) } +func (s *StorageMinerStub) SectorRemove(p0 context.Context, p1 abi.SectorNumber) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorSetExpectedSealDuration(p0 context.Context, p1 time.Duration) error { return s.Internal.SectorSetExpectedSealDuration(p0, p1) } +func (s *StorageMinerStub) SectorSetExpectedSealDuration(p0 context.Context, p1 time.Duration) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorSetSealDelay(p0 context.Context, p1 time.Duration) error { return s.Internal.SectorSetSealDelay(p0, p1) } +func (s *StorageMinerStub) SectorSetSealDelay(p0 context.Context, p1 time.Duration) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorStartSealing(p0 context.Context, p1 abi.SectorNumber) error { return s.Internal.SectorStartSealing(p0, p1) } +func (s *StorageMinerStub) SectorStartSealing(p0 context.Context, p1 abi.SectorNumber) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorTerminate(p0 context.Context, p1 abi.SectorNumber) error { return s.Internal.SectorTerminate(p0, p1) } +func (s *StorageMinerStub) SectorTerminate(p0 context.Context, p1 abi.SectorNumber) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorTerminateFlush(p0 context.Context) (*cid.Cid, error) { return s.Internal.SectorTerminateFlush(p0) } +func (s *StorageMinerStub) SectorTerminateFlush(p0 context.Context) (*cid.Cid, error) { + return nil, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorTerminatePending(p0 context.Context) ([]abi.SectorID, error) { return s.Internal.SectorTerminatePending(p0) } +func (s *StorageMinerStub) SectorTerminatePending(p0 context.Context) ([]abi.SectorID, error) { + return *new([]abi.SectorID), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorsList(p0 context.Context) ([]abi.SectorNumber, error) { return s.Internal.SectorsList(p0) } +func (s *StorageMinerStub) SectorsList(p0 context.Context) ([]abi.SectorNumber, error) { + return *new([]abi.SectorNumber), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorsListInStates(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) { return s.Internal.SectorsListInStates(p0, p1) } +func (s *StorageMinerStub) SectorsListInStates(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) { + return *new([]abi.SectorNumber), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorsRefs(p0 context.Context) (map[string][]SealedRef, error) { return s.Internal.SectorsRefs(p0) } +func (s *StorageMinerStub) SectorsRefs(p0 context.Context) (map[string][]SealedRef, error) { + return *new(map[string][]SealedRef), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorsStatus(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) { return s.Internal.SectorsStatus(p0, p1, p2) } +func (s *StorageMinerStub) SectorsStatus(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) { + return *new(SectorInfo), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorsSummary(p0 context.Context) (map[SectorState]int, error) { return s.Internal.SectorsSummary(p0) } +func (s *StorageMinerStub) SectorsSummary(p0 context.Context) (map[SectorState]int, error) { + return *new(map[SectorState]int), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) SectorsUpdate(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error { return s.Internal.SectorsUpdate(p0, p1, p2) } +func (s *StorageMinerStub) SectorsUpdate(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageAddLocal(p0 context.Context, p1 string) error { return s.Internal.StorageAddLocal(p0, p1) } +func (s *StorageMinerStub) StorageAddLocal(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageAttach(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error { return s.Internal.StorageAttach(p0, p1, p2) } +func (s *StorageMinerStub) StorageAttach(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) { return s.Internal.StorageBestAlloc(p0, p1, p2, p3) } +func (s *StorageMinerStub) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) { + return *new([]stores.StorageInfo), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageDeclareSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error { return s.Internal.StorageDeclareSector(p0, p1, p2, p3, p4) } +func (s *StorageMinerStub) StorageDeclareSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageDropSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error { return s.Internal.StorageDropSector(p0, p1, p2, p3) } +func (s *StorageMinerStub) StorageDropSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) { return s.Internal.StorageFindSector(p0, p1, p2, p3, p4) } +func (s *StorageMinerStub) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) { + return *new([]stores.SectorStorageInfo), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) { return s.Internal.StorageInfo(p0, p1) } +func (s *StorageMinerStub) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) { + return *new(stores.StorageInfo), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageList(p0 context.Context) (map[stores.ID][]stores.Decl, error) { return s.Internal.StorageList(p0) } +func (s *StorageMinerStub) StorageList(p0 context.Context) (map[stores.ID][]stores.Decl, error) { + return *new(map[stores.ID][]stores.Decl), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageLocal(p0 context.Context) (map[stores.ID]string, error) { return s.Internal.StorageLocal(p0) } +func (s *StorageMinerStub) StorageLocal(p0 context.Context) (map[stores.ID]string, error) { + return *new(map[stores.ID]string), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error { return s.Internal.StorageLock(p0, p1, p2, p3) } +func (s *StorageMinerStub) StorageLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageReportHealth(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error { return s.Internal.StorageReportHealth(p0, p1, p2) } +func (s *StorageMinerStub) StorageReportHealth(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageStat(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) { return s.Internal.StorageStat(p0, p1) } +func (s *StorageMinerStub) StorageStat(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) { + return *new(fsutil.FsStat), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) StorageTryLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) { return s.Internal.StorageTryLock(p0, p1, p2, p3) } +func (s *StorageMinerStub) StorageTryLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *StorageMinerStruct) WorkerConnect(p0 context.Context, p1 string) error { return s.Internal.WorkerConnect(p0, p1) } +func (s *StorageMinerStub) WorkerConnect(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + func (s *StorageMinerStruct) WorkerJobs(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) { return s.Internal.WorkerJobs(p0) } +func (s *StorageMinerStub) WorkerJobs(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) { + return *new(map[uuid.UUID][]storiface.WorkerJob), xerrors.New("method not supported") +} + func (s *StorageMinerStruct) WorkerStats(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) { return s.Internal.WorkerStats(p0) } +func (s *StorageMinerStub) WorkerStats(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) { + return *new(map[uuid.UUID]storiface.WorkerStats), xerrors.New("method not supported") +} + func (s *WalletStruct) WalletDelete(p0 context.Context, p1 address.Address) error { return s.Internal.WalletDelete(p0, p1) } +func (s *WalletStub) WalletDelete(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + func (s *WalletStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { return s.Internal.WalletExport(p0, p1) } +func (s *WalletStub) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *WalletStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { return s.Internal.WalletHas(p0, p1) } +func (s *WalletStub) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *WalletStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { return s.Internal.WalletImport(p0, p1) } +func (s *WalletStub) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *WalletStruct) WalletList(p0 context.Context) ([]address.Address, error) { return s.Internal.WalletList(p0) } +func (s *WalletStub) WalletList(p0 context.Context) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + func (s *WalletStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { return s.Internal.WalletNew(p0, p1) } +func (s *WalletStub) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *WalletStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) { return s.Internal.WalletSign(p0, p1, p2, p3) } +func (s *WalletStub) WalletSign(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) { + return nil, xerrors.New("method not supported") +} + func (s *WorkerStruct) AddPiece(p0 context.Context, p1 storage.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storage.Data) (storiface.CallID, error) { return s.Internal.AddPiece(p0, p1, p2, p3, p4) } +func (s *WorkerStub) AddPiece(p0 context.Context, p1 storage.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storage.Data) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) Enabled(p0 context.Context) (bool, error) { return s.Internal.Enabled(p0) } +func (s *WorkerStub) Enabled(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *WorkerStruct) Fetch(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) { return s.Internal.Fetch(p0, p1, p2, p3, p4) } +func (s *WorkerStub) Fetch(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) FinalizeSector(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { return s.Internal.FinalizeSector(p0, p1, p2) } +func (s *WorkerStub) FinalizeSector(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) Info(p0 context.Context) (storiface.WorkerInfo, error) { return s.Internal.Info(p0) } +func (s *WorkerStub) Info(p0 context.Context) (storiface.WorkerInfo, error) { + return *new(storiface.WorkerInfo), xerrors.New("method not supported") +} + func (s *WorkerStruct) MoveStorage(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) { return s.Internal.MoveStorage(p0, p1, p2) } +func (s *WorkerStub) MoveStorage(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) Paths(p0 context.Context) ([]stores.StoragePath, error) { return s.Internal.Paths(p0) } +func (s *WorkerStub) Paths(p0 context.Context) ([]stores.StoragePath, error) { + return *new([]stores.StoragePath), xerrors.New("method not supported") +} + func (s *WorkerStruct) ProcessSession(p0 context.Context) (uuid.UUID, error) { return s.Internal.ProcessSession(p0) } +func (s *WorkerStub) ProcessSession(p0 context.Context) (uuid.UUID, error) { + return *new(uuid.UUID), xerrors.New("method not supported") +} + func (s *WorkerStruct) ReadPiece(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) { return s.Internal.ReadPiece(p0, p1, p2, p3, p4) } +func (s *WorkerStub) ReadPiece(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) ReleaseUnsealed(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { return s.Internal.ReleaseUnsealed(p0, p1, p2) } +func (s *WorkerStub) ReleaseUnsealed(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) Remove(p0 context.Context, p1 abi.SectorID) error { return s.Internal.Remove(p0, p1) } +func (s *WorkerStub) Remove(p0 context.Context, p1 abi.SectorID) error { + return xerrors.New("method not supported") +} + func (s *WorkerStruct) SealCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) { return s.Internal.SealCommit1(p0, p1, p2, p3, p4, p5) } +func (s *WorkerStub) SealCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) SealCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.Commit1Out) (storiface.CallID, error) { return s.Internal.SealCommit2(p0, p1, p2) } +func (s *WorkerStub) SealCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.Commit1Out) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) SealPreCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) { return s.Internal.SealPreCommit1(p0, p1, p2, p3) } +func (s *WorkerStub) SealPreCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) SealPreCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.PreCommit1Out) (storiface.CallID, error) { return s.Internal.SealPreCommit2(p0, p1, p2) } +func (s *WorkerStub) SealPreCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.PreCommit1Out) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) Session(p0 context.Context) (uuid.UUID, error) { return s.Internal.Session(p0) } +func (s *WorkerStub) Session(p0 context.Context) (uuid.UUID, error) { + return *new(uuid.UUID), xerrors.New("method not supported") +} + func (s *WorkerStruct) SetEnabled(p0 context.Context, p1 bool) error { return s.Internal.SetEnabled(p0, p1) } +func (s *WorkerStub) SetEnabled(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + func (s *WorkerStruct) StorageAddLocal(p0 context.Context, p1 string) error { return s.Internal.StorageAddLocal(p0, p1) } +func (s *WorkerStub) StorageAddLocal(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + func (s *WorkerStruct) TaskDisable(p0 context.Context, p1 sealtasks.TaskType) error { return s.Internal.TaskDisable(p0, p1) } +func (s *WorkerStub) TaskDisable(p0 context.Context, p1 sealtasks.TaskType) error { + return xerrors.New("method not supported") +} + func (s *WorkerStruct) TaskEnable(p0 context.Context, p1 sealtasks.TaskType) error { return s.Internal.TaskEnable(p0, p1) } +func (s *WorkerStub) TaskEnable(p0 context.Context, p1 sealtasks.TaskType) error { + return xerrors.New("method not supported") +} + func (s *WorkerStruct) TaskTypes(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) { return s.Internal.TaskTypes(p0) } +func (s *WorkerStub) TaskTypes(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) { + return *new(map[sealtasks.TaskType]struct{}), xerrors.New("method not supported") +} + func (s *WorkerStruct) UnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) { return s.Internal.UnsealPiece(p0, p1, p2, p3, p4, p5) } +func (s *WorkerStub) UnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + func (s *WorkerStruct) Version(p0 context.Context) (Version, error) { return s.Internal.Version(p0) } +func (s *WorkerStub) Version(p0 context.Context) (Version, error) { + return *new(Version), xerrors.New("method not supported") +} + func (s *WorkerStruct) WaitQuiet(p0 context.Context) error { return s.Internal.WaitQuiet(p0) } +func (s *WorkerStub) WaitQuiet(p0 context.Context) error { + return xerrors.New("method not supported") +} + var _ ChainIO = new(ChainIOStruct) var _ Common = new(CommonStruct) var _ FullNode = new(FullNodeStruct) diff --git a/api/v0api/latest.go b/api/v0api/latest.go index 9e29f948dc4..2fdb7962f54 100644 --- a/api/v0api/latest.go +++ b/api/v0api/latest.go @@ -6,6 +6,7 @@ import ( type Common = api.Common type CommonStruct = api.CommonStruct +type CommonStub = api.CommonStub type Gateway = api.Gateway diff --git a/api/v0api/proxy_gen.go b/api/v0api/proxy_gen.go index 21fb08c7832..a32371f4f97 100644 --- a/api/v0api/proxy_gen.go +++ b/api/v0api/proxy_gen.go @@ -23,6 +23,7 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" + "golang.org/x/xerrors" ) type FullNodeStruct struct { @@ -377,696 +378,1392 @@ type FullNodeStruct struct { } } +type FullNodeStub struct { + CommonStub +} + func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { return s.Internal.BeaconGetEntry(p0, p1) } +func (s *FullNodeStub) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { return s.Internal.ChainDeleteObj(p0, p1) } +func (s *FullNodeStub) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { return s.Internal.ChainExport(p0, p1, p2, p3) } +func (s *FullNodeStub) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { return s.Internal.ChainGetBlock(p0, p1) } +func (s *FullNodeStub) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { return s.Internal.ChainGetBlockMessages(p0, p1) } +func (s *FullNodeStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { return s.Internal.ChainGetGenesis(p0) } +func (s *FullNodeStub) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { return s.Internal.ChainGetMessage(p0, p1) } +func (s *FullNodeStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*api.IpldObject, error) { return s.Internal.ChainGetNode(p0, p1) } +func (s *FullNodeStub) ChainGetNode(p0 context.Context, p1 string) (*api.IpldObject, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]api.Message, error) { return s.Internal.ChainGetParentMessages(p0, p1) } +func (s *FullNodeStub) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]api.Message, error) { + return *new([]api.Message), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { return s.Internal.ChainGetParentReceipts(p0, p1) } +func (s *FullNodeStub) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { + return *new([]*types.MessageReceipt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) { return s.Internal.ChainGetPath(p0, p1, p2) } +func (s *FullNodeStub) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) { + return *new([]*api.HeadChange), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { return s.Internal.ChainGetRandomnessFromBeacon(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return *new(abi.Randomness), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { return s.Internal.ChainGetRandomnessFromTickets(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return *new(abi.Randomness), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { return s.Internal.ChainGetTipSet(p0, p1) } +func (s *FullNodeStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) } +func (s *FullNodeStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { return s.Internal.ChainHasObj(p0, p1) } +func (s *FullNodeStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { return s.Internal.ChainHead(p0) } +func (s *FullNodeStub) ChainHead(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { return s.Internal.ChainNotify(p0) } +func (s *FullNodeStub) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { return s.Internal.ChainReadObj(p0, p1) } +func (s *FullNodeStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { return s.Internal.ChainSetHead(p0, p1) } +func (s *FullNodeStub) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) { return s.Internal.ChainStatObj(p0, p1, p2) } +func (s *FullNodeStub) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) { + return *new(api.ObjStat), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { return s.Internal.ChainTipSetWeight(p0, p1) } +func (s *FullNodeStub) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientCalcCommP(p0 context.Context, p1 string) (*api.CommPRet, error) { return s.Internal.ClientCalcCommP(p0, p1) } +func (s *FullNodeStub) ClientCalcCommP(p0 context.Context, p1 string) (*api.CommPRet, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { return s.Internal.ClientCancelDataTransfer(p0, p1, p2, p3) } +func (s *FullNodeStub) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { return s.Internal.ClientCancelRetrievalDeal(p0, p1) } +func (s *FullNodeStub) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { return s.Internal.ClientDataTransferUpdates(p0) } +func (s *FullNodeStub) ClientDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) { return s.Internal.ClientDealPieceCID(p0, p1) } +func (s *FullNodeStub) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) { + return *new(api.DataCIDSize), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientDealSize(p0 context.Context, p1 cid.Cid) (api.DataSize, error) { return s.Internal.ClientDealSize(p0, p1) } +func (s *FullNodeStub) ClientDealSize(p0 context.Context, p1 cid.Cid) (api.DataSize, error) { + return *new(api.DataSize), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) { return s.Internal.ClientFindData(p0, p1, p2) } +func (s *FullNodeStub) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) { + return *new([]api.QueryOffer), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientGenCar(p0 context.Context, p1 api.FileRef, p2 string) error { return s.Internal.ClientGenCar(p0, p1, p2) } +func (s *FullNodeStub) ClientGenCar(p0 context.Context, p1 api.FileRef, p2 string) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) { return s.Internal.ClientGetDealInfo(p0, p1) } +func (s *FullNodeStub) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { return s.Internal.ClientGetDealStatus(p0, p1) } +func (s *FullNodeStub) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { + return "", xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientGetDealUpdates(p0 context.Context) (<-chan api.DealInfo, error) { return s.Internal.ClientGetDealUpdates(p0) } +func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan api.DealInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { return s.Internal.ClientHasLocal(p0, p1) } +func (s *FullNodeStub) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientImport(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) { return s.Internal.ClientImport(p0, p1) } +func (s *FullNodeStub) ClientImport(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { return s.Internal.ClientListDataTransfers(p0) } +func (s *FullNodeStub) ClientListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { + return *new([]api.DataTransferChannel), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientListDeals(p0 context.Context) ([]api.DealInfo, error) { return s.Internal.ClientListDeals(p0) } +func (s *FullNodeStub) ClientListDeals(p0 context.Context) ([]api.DealInfo, error) { + return *new([]api.DealInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientListImports(p0 context.Context) ([]api.Import, error) { return s.Internal.ClientListImports(p0) } +func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]api.Import, error) { + return *new([]api.Import), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) { return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) } +func (s *FullNodeStub) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) { + return *new(api.QueryOffer), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { return s.Internal.ClientQueryAsk(p0, p1, p2) } +func (s *FullNodeStub) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { return s.Internal.ClientRemoveImport(p0, p1) } +func (s *FullNodeStub) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { return s.Internal.ClientRestartDataTransfer(p0, p1, p2, p3) } +func (s *FullNodeStub) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientRetrieve(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error { return s.Internal.ClientRetrieve(p0, p1, p2) } +func (s *FullNodeStub) ClientRetrieve(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { return s.Internal.ClientRetrieveTryRestartInsufficientFunds(p0, p1) } +func (s *FullNodeStub) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientRetrieveWithEvents(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { return s.Internal.ClientRetrieveWithEvents(p0, p1, p2) } +func (s *FullNodeStub) ClientRetrieveWithEvents(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) ClientStartDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) { return s.Internal.ClientStartDeal(p0, p1) } +func (s *FullNodeStub) ClientStartDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) CreateBackup(p0 context.Context, p1 string) error { return s.Internal.CreateBackup(p0, p1) } +func (s *FullNodeStub) CreateBackup(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.GasEstimateFeeCap(p0, p1, p2, p3) } +func (s *FullNodeStub) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { return s.Internal.GasEstimateGasLimit(p0, p1, p2) } +func (s *FullNodeStub) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { + return 0, xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { return s.Internal.GasEstimateGasPremium(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } +func (s *FullNodeStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { return s.Internal.MarketAddBalance(p0, p1, p2, p3) } +func (s *FullNodeStub) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { return s.Internal.MarketGetReserved(p0, p1) } +func (s *FullNodeStub) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { return s.Internal.MarketReleaseFunds(p0, p1, p2) } +func (s *FullNodeStub) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { return s.Internal.MarketReserveFunds(p0, p1, p2, p3) } +func (s *FullNodeStub) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { return s.Internal.MarketWithdraw(p0, p1, p2, p3) } +func (s *FullNodeStub) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MinerCreateBlock(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) { return s.Internal.MinerCreateBlock(p0, p1) } +func (s *FullNodeStub) MinerCreateBlock(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) { return s.Internal.MinerGetBaseInfo(p0, p1, p2, p3) } +func (s *FullNodeStub) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { return s.Internal.MpoolBatchPush(p0, p1) } +func (s *FullNodeStub) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { return s.Internal.MpoolBatchPushMessage(p0, p1, p2) } +func (s *FullNodeStub) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { return s.Internal.MpoolBatchPushUntrusted(p0, p1) } +func (s *FullNodeStub) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolClear(p0 context.Context, p1 bool) error { return s.Internal.MpoolClear(p0, p1) } +func (s *FullNodeStub) MpoolClear(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { return s.Internal.MpoolGetConfig(p0) } +func (s *FullNodeStub) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { return s.Internal.MpoolGetNonce(p0, p1) } +func (s *FullNodeStub) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { + return 0, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { return s.Internal.MpoolPending(p0, p1) } +func (s *FullNodeStub) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { return s.Internal.MpoolPush(p0, p1) } +func (s *FullNodeStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) { return s.Internal.MpoolPushMessage(p0, p1, p2) } +func (s *FullNodeStub) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { return s.Internal.MpoolPushUntrusted(p0, p1) } +func (s *FullNodeStub) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { return s.Internal.MpoolSelect(p0, p1, p2) } +func (s *FullNodeStub) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { return s.Internal.MpoolSetConfig(p0, p1) } +func (s *FullNodeStub) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolSub(p0 context.Context) (<-chan api.MpoolUpdate, error) { return s.Internal.MpoolSub(p0) } +func (s *FullNodeStub) MpoolSub(p0 context.Context) (<-chan api.MpoolUpdate, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) { return s.Internal.MsigAddApprove(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) { return s.Internal.MsigAddCancel(p0, p1, p2, p3, p4, p5) } +func (s *FullNodeStub) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { return s.Internal.MsigAddPropose(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) { return s.Internal.MsigApprove(p0, p1, p2, p3) } +func (s *FullNodeStub) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) { return s.Internal.MsigApproveTxnHash(p0, p1, p2, p3, p4, p5, p6, p7, p8) } +func (s *FullNodeStub) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) { return s.Internal.MsigCancel(p0, p1, p2, p3, p4, p5, p6, p7) } +func (s *FullNodeStub) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) { return s.Internal.MsigCreate(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } +func (s *FullNodeStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { return s.Internal.MsigGetPending(p0, p1, p2) } +func (s *FullNodeStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { + return *new([]*api.MsigTransaction), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.MsigGetVested(p0, p1, p2, p3) } +func (s *FullNodeStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) { return s.Internal.MsigGetVestingSchedule(p0, p1, p2) } +func (s *FullNodeStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) { + return *new(api.MsigVesting), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) { return s.Internal.MsigPropose(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { return s.Internal.MsigRemoveSigner(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) { return s.Internal.MsigSwapApprove(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) { return s.Internal.MsigSwapCancel(p0, p1, p2, p3, p4, p5) } +func (s *FullNodeStub) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) { return s.Internal.MsigSwapPropose(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { return s.Internal.PaychAllocateLane(p0, p1) } +func (s *FullNodeStub) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { + return 0, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) { return s.Internal.PaychAvailableFunds(p0, p1) } +func (s *FullNodeStub) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) { return s.Internal.PaychAvailableFundsByFromTo(p0, p1, p2) } +func (s *FullNodeStub) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { return s.Internal.PaychCollect(p0, p1) } +func (s *FullNodeStub) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) { return s.Internal.PaychGet(p0, p1, p2, p3) } +func (s *FullNodeStub) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { return s.Internal.PaychGetWaitReady(p0, p1) } +func (s *FullNodeStub) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychList(p0 context.Context) ([]address.Address, error) { return s.Internal.PaychList(p0) } +func (s *FullNodeStub) PaychList(p0 context.Context) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) { return s.Internal.PaychNewPayment(p0, p1, p2, p3) } +func (s *FullNodeStub) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { return s.Internal.PaychSettle(p0, p1) } +func (s *FullNodeStub) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychStatus(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) { return s.Internal.PaychStatus(p0, p1) } +func (s *FullNodeStub) PaychStatus(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { return s.Internal.PaychVoucherAdd(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { return s.Internal.PaychVoucherCheckSpendable(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { return s.Internal.PaychVoucherCheckValid(p0, p1, p2) } +func (s *FullNodeStub) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) { return s.Internal.PaychVoucherCreate(p0, p1, p2, p3) } +func (s *FullNodeStub) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { return s.Internal.PaychVoucherList(p0, p1) } +func (s *FullNodeStub) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { + return *new([]*paych.SignedVoucher), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { return s.Internal.PaychVoucherSubmit(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { return s.Internal.StateAccountKey(p0, p1, p2) } +func (s *FullNodeStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) { return s.Internal.StateAllMinerFaults(p0, p1, p2) } +func (s *FullNodeStub) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) { + return *new([]*api.Fault), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) { return s.Internal.StateCall(p0, p1, p2) } +func (s *FullNodeStub) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { return s.Internal.StateChangedActors(p0, p1, p2) } +func (s *FullNodeStub) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { + return *new(map[string]types.Actor), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { return s.Internal.StateCirculatingSupply(p0, p1) } +func (s *FullNodeStub) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { + return *new(abi.TokenAmount), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) { return s.Internal.StateCompute(p0, p1, p2, p3) } +func (s *FullNodeStub) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } +func (s *FullNodeStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { + return *new(api.DealCollateralBounds), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { return s.Internal.StateDecodeParams(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { return s.Internal.StateGetActor(p0, p1, p2) } +func (s *FullNodeStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { return s.Internal.StateGetReceipt(p0, p1, p2) } +func (s *FullNodeStub) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { return s.Internal.StateListActors(p0, p1) } +func (s *FullNodeStub) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateListMessages(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { return s.Internal.StateListMessages(p0, p1, p2, p3) } +func (s *FullNodeStub) StateListMessages(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { return s.Internal.StateListMiners(p0, p1) } +func (s *FullNodeStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { return s.Internal.StateLookupID(p0, p1, p2) } +func (s *FullNodeStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { return s.Internal.StateMarketBalance(p0, p1, p2) } +func (s *FullNodeStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { + return *new(api.MarketBalance), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) { return s.Internal.StateMarketDeals(p0, p1) } +func (s *FullNodeStub) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) { + return *new(map[string]api.MarketDeal), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) { return s.Internal.StateMarketParticipants(p0, p1) } +func (s *FullNodeStub) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) { + return *new(map[string]api.MarketBalance), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { return s.Internal.StateMarketStorageDeal(p0, p1, p2) } +func (s *FullNodeStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { return s.Internal.StateMinerActiveSectors(p0, p1, p2) } +func (s *FullNodeStub) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { return s.Internal.StateMinerAvailableBalance(p0, p1, p2) } +func (s *FullNodeStub) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) { return s.Internal.StateMinerDeadlines(p0, p1, p2) } +func (s *FullNodeStub) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) { + return *new([]api.Deadline), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { return s.Internal.StateMinerFaults(p0, p1, p2) } +func (s *FullNodeStub) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return *new(bitfield.BitField), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { return s.Internal.StateMinerInfo(p0, p1, p2) } +func (s *FullNodeStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return *new(miner.MinerInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.StateMinerInitialPledgeCollateral(p0, p1, p2, p3) } +func (s *FullNodeStub) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) { return s.Internal.StateMinerPartitions(p0, p1, p2, p3) } +func (s *FullNodeStub) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) { + return *new([]api.Partition), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { return s.Internal.StateMinerPower(p0, p1, p2) } +func (s *FullNodeStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.StateMinerPreCommitDepositForPower(p0, p1, p2, p3) } +func (s *FullNodeStub) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { return s.Internal.StateMinerProvingDeadline(p0, p1, p2) } +func (s *FullNodeStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { return s.Internal.StateMinerRecoveries(p0, p1, p2) } +func (s *FullNodeStub) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return *new(bitfield.BitField), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { return s.Internal.StateMinerSectorAllocated(p0, p1, p2, p3) } +func (s *FullNodeStub) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) { return s.Internal.StateMinerSectorCount(p0, p1, p2) } +func (s *FullNodeStub) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) { + return *new(api.MinerSectors), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { return s.Internal.StateMinerSectors(p0, p1, p2, p3) } +func (s *FullNodeStub) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { return s.Internal.StateNetworkName(p0) } +func (s *FullNodeStub) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { + return *new(dtypes.NetworkName), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { return s.Internal.StateNetworkVersion(p0, p1) } +func (s *FullNodeStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + return *new(apitypes.NetworkVersion), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) { return s.Internal.StateReadState(p0, p1, p2) } +func (s *FullNodeStub) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) { return s.Internal.StateReplay(p0, p1, p2) } +func (s *FullNodeStub) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { return s.Internal.StateSearchMsg(p0, p1) } +func (s *FullNodeStub) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) { return s.Internal.StateSearchMsgLimited(p0, p1, p2) } +func (s *FullNodeStub) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { return s.Internal.StateSectorExpiration(p0, p1, p2, p3) } +func (s *FullNodeStub) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } +func (s *FullNodeStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { return s.Internal.StateSectorPartition(p0, p1, p2, p3) } +func (s *FullNodeStub) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { return s.Internal.StateSectorPreCommitInfo(p0, p1, p2, p3) } +func (s *FullNodeStub) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + return *new(miner.SectorPreCommitOnChainInfo), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) { return s.Internal.StateVMCirculatingSupplyInternal(p0, p1) } +func (s *FullNodeStub) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) { + return *new(api.CirculatingSupply), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { return s.Internal.StateVerifiedClientStatus(p0, p1, p2) } +func (s *FullNodeStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { return s.Internal.StateVerifiedRegistryRootKey(p0, p1) } +func (s *FullNodeStub) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { return s.Internal.StateVerifierStatus(p0, p1, p2) } +func (s *FullNodeStub) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { return s.Internal.StateWaitMsg(p0, p1, p2) } +func (s *FullNodeStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) { return s.Internal.StateWaitMsgLimited(p0, p1, p2, p3) } +func (s *FullNodeStub) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { return s.Internal.SyncCheckBad(p0, p1) } +func (s *FullNodeStub) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { + return "", xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { return s.Internal.SyncCheckpoint(p0, p1) } +func (s *FullNodeStub) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { return s.Internal.SyncIncomingBlocks(p0) } +func (s *FullNodeStub) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { return s.Internal.SyncMarkBad(p0, p1) } +func (s *FullNodeStub) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncState(p0 context.Context) (*api.SyncState, error) { return s.Internal.SyncState(p0) } +func (s *FullNodeStub) SyncState(p0 context.Context) (*api.SyncState, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { return s.Internal.SyncSubmitBlock(p0, p1) } +func (s *FullNodeStub) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncUnmarkAllBad(p0 context.Context) error { return s.Internal.SyncUnmarkAllBad(p0) } +func (s *FullNodeStub) SyncUnmarkAllBad(p0 context.Context) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { return s.Internal.SyncUnmarkBad(p0, p1) } +func (s *FullNodeStub) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { return s.Internal.SyncValidateTipset(p0, p1) } +func (s *FullNodeStub) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { return s.Internal.WalletBalance(p0, p1) } +func (s *FullNodeStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletDefaultAddress(p0 context.Context) (address.Address, error) { return s.Internal.WalletDefaultAddress(p0) } +func (s *FullNodeStub) WalletDefaultAddress(p0 context.Context) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletDelete(p0 context.Context, p1 address.Address) error { return s.Internal.WalletDelete(p0, p1) } +func (s *FullNodeStub) WalletDelete(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { return s.Internal.WalletExport(p0, p1) } +func (s *FullNodeStub) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { return s.Internal.WalletHas(p0, p1) } +func (s *FullNodeStub) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + return false, xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { return s.Internal.WalletImport(p0, p1) } +func (s *FullNodeStub) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletList(p0 context.Context) ([]address.Address, error) { return s.Internal.WalletList(p0) } +func (s *FullNodeStub) WalletList(p0 context.Context) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { return s.Internal.WalletNew(p0, p1) } +func (s *FullNodeStub) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletSetDefault(p0 context.Context, p1 address.Address) error { return s.Internal.WalletSetDefault(p0, p1) } +func (s *FullNodeStub) WalletSetDefault(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { return s.Internal.WalletSign(p0, p1, p2) } +func (s *FullNodeStub) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { return s.Internal.WalletSignMessage(p0, p1, p2) } +func (s *FullNodeStub) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { return s.Internal.WalletValidateAddress(p0, p1) } +func (s *FullNodeStub) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + func (s *FullNodeStruct) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { return s.Internal.WalletVerify(p0, p1, p2, p3) } +func (s *FullNodeStub) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { + return false, xerrors.New("method not supported") +} + var _ FullNode = new(FullNodeStruct) diff --git a/gen/api/proxygen.go b/gen/api/proxygen.go index d17807b44a0..71c2f414dd8 100644 --- a/gen/api/proxygen.go +++ b/gen/api/proxygen.go @@ -52,6 +52,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor { return v } + func main() { // latest (v1) if err := generate("./api", "api", "api", "./api/proxy_gen.go"); err != nil { @@ -143,10 +144,10 @@ func generate(path, pkg, outpkg, outfile string) error { ast.Walk(v, ap) type methodInfo struct { - Name string - node ast.Node - Tags map[string][]string - NamedParams, ParamNames, Results string + Name string + node ast.Node + Tags map[string][]string + NamedParams, ParamNames, Results, DefRes string } type strinfo struct { @@ -214,7 +215,7 @@ func generate(path, pkg, outpkg, outfile string) error { } } - var results []string + results := []string{} for _, result := range node.ftype.Results.List { rs, err := typeName(result.Type, outpkg) if err != nil { @@ -223,6 +224,24 @@ func generate(path, pkg, outpkg, outfile string) error { results = append(results, rs) } + defRes := "" + if len(results) > 1 { + defRes = results[0] + switch { + case defRes[0] == '*' || defRes[0] == '<', defRes == "interface{}": + defRes = "nil" + case defRes == "bool": + defRes = "false" + case defRes == "string": + defRes = `""` + case defRes == "int", defRes == "int64", defRes == "uint64", defRes == "uint": + defRes = "0" + default: + defRes = "*new(" + defRes + ")" + } + defRes += ", " + } + info.Methods[mname] = &methodInfo{ Name: mname, node: node.node, @@ -230,6 +249,7 @@ func generate(path, pkg, outpkg, outfile string) error { NamedParams: strings.Join(params, ", "), ParamNames: strings.Join(pnames, ", "), Results: strings.Join(results, ", "), + DefRes: defRes, } } @@ -289,6 +309,12 @@ type {{.Name}}Struct struct { {{end}} } } + +type {{.Name}}Stub struct { +{{range .Include}} + {{.}}Stub +{{end}} +} {{end}} {{range .Infos}} @@ -297,6 +323,10 @@ type {{.Name}}Struct struct { func (s *{{$name}}Struct) {{.Name}}({{.NamedParams}}) ({{.Results}}) { return s.Internal.{{.Name}}({{.ParamNames}}) } + +func (s *{{$name}}Stub) {{.Name}}({{.NamedParams}}) ({{.Results}}) { + return {{.DefRes}}xerrors.New("method not supported") +} {{end}} {{end}} From f4e46c9003ba636e96c6aa030ba02fed31451172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 3 Apr 2021 13:20:50 +0200 Subject: [PATCH 21/60] implement v1 api with api modules --- node/impl/full/chain.go | 2 ++ node/impl/full/gas.go | 2 ++ node/impl/full/mpool.go | 2 ++ node/impl/full/state.go | 9 +++++---- paychmgr/settler/settler.go | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 25d366a87b0..de62d80a683 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -51,6 +51,8 @@ type ChainModuleAPI interface { ChainReadObj(context.Context, cid.Cid) ([]byte, error) } +var _ ChainModuleAPI = *new(api.FullNode) + // ChainModule provides a default implementation of ChainModuleAPI. // It can be swapped out with another implementation through Dependency // Injection (for example with a thin RPC client). diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index 3d9889c10e8..a3bbc8d78ed 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -31,6 +31,8 @@ type GasModuleAPI interface { GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) } +var _ GasModuleAPI = *new(api.FullNode) + // GasModule provides a default implementation of GasModuleAPI. // It can be swapped out with another implementation through Dependency // Injection (for example with a thin RPC client). diff --git a/node/impl/full/mpool.go b/node/impl/full/mpool.go index b1e9f94f994..1cc2d24d78f 100644 --- a/node/impl/full/mpool.go +++ b/node/impl/full/mpool.go @@ -20,6 +20,8 @@ type MpoolModuleAPI interface { MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) } +var _ MpoolModuleAPI = *new(api.FullNode) + // MpoolModule provides a default implementation of MpoolModuleAPI. // It can be swapped out with another implementation through Dependency // Injection (for example with a thin RPC client). diff --git a/node/impl/full/state.go b/node/impl/full/state.go index f6cf2759e0d..de1b77b4fc4 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -44,7 +44,6 @@ type StateModuleAPI interface { StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) - StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) @@ -53,12 +52,14 @@ type StateModuleAPI interface { StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) StateNetworkVersion(ctx context.Context, key types.TipSetKey) (network.Version, error) - StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) - StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) } +var _ StateModuleAPI = *new(api.FullNode) + // StateModule provides a default implementation of StateModuleAPI. // It can be swapped out with another implementation through Dependency // Injection (for example with a thin RPC client). @@ -378,7 +379,7 @@ func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid. var ts *types.TipSet var err error if tsk == types.EmptyTSK { - mlkp, err := a.StateSearchMsg(ctx, mc) + mlkp, err := a.StateSearchMsg(ctx, types.EmptyTSK, mc, stmgr.LookbackNoLimit, true) if err != nil { return nil, xerrors.Errorf("searching for msg %s: %w", mc, err) } diff --git a/paychmgr/settler/settler.go b/paychmgr/settler/settler.go index 3abd136fc6a..d5ecc5631c0 100644 --- a/paychmgr/settler/settler.go +++ b/paychmgr/settler/settler.go @@ -41,7 +41,7 @@ type settlerAPI interface { PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) - StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) } type paymentChannelSettler struct { From deb2b90b6a2457afafb2d1615967bec414ebd580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 5 Apr 2021 13:23:46 +0200 Subject: [PATCH 22/60] Fix lotus/miner build --- api/api_full.go | 2 ++ api/v0api/latest.go | 2 ++ api/wrap.go | 21 +++++++++++++++++++++ chain/events/events.go | 8 ++++---- chain/events/events_called.go | 12 ++++++------ chain/events/events_test.go | 2 +- chain/market/fundmanager.go | 4 ++-- chain/stmgr/stmgr.go | 2 +- cmd/lotus-shed/ledger.go | 4 ++-- cmd/lotus-storage-miner/init.go | 11 ++++++----- cmd/lotus-storage-miner/run.go | 3 ++- cmd/lotus-storage-miner/storage.go | 3 ++- cmd/lotus-wallet/interactive.go | 5 +++-- cmd/lotus-wallet/main.go | 5 +++-- markets/retrievaladapter/provider.go | 6 +++--- markets/storageadapter/client.go | 11 +++++++---- markets/storageadapter/provider.go | 7 ++++--- miner/miner.go | 5 +++-- miner/testminer.go | 6 +++--- node/modules/storageminer.go | 16 ++++++++-------- paychmgr/settler/settler.go | 10 ++++++---- storage/miner.go | 3 ++- 22 files changed, 93 insertions(+), 55 deletions(-) create mode 100644 api/wrap.go diff --git a/api/api_full.go b/api/api_full.go index 8739fba3890..0a2463505a3 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -39,6 +39,8 @@ type ChainIO interface { ChainHasObj(context.Context, cid.Cid) (bool, error) } +const LookbackNoLimit = abi.ChainEpoch(-1) + // FullNode API is a low-level interface to the Filecoin network full node type FullNode interface { Common diff --git a/api/v0api/latest.go b/api/v0api/latest.go index 2fdb7962f54..9d64b645021 100644 --- a/api/v0api/latest.go +++ b/api/v0api/latest.go @@ -16,6 +16,8 @@ type StorageMinerStruct = api.StorageMinerStruct type Worker = api.Worker type WorkerStruct = api.WorkerStruct +type Wallet = api.Wallet + func PermissionedStorMinerAPI(a StorageMiner) StorageMiner { return api.PermissionedStorMinerAPI(a) } diff --git a/api/wrap.go b/api/wrap.go new file mode 100644 index 00000000000..92f40776d1a --- /dev/null +++ b/api/wrap.go @@ -0,0 +1,21 @@ +package api + +import "reflect" + +// Wrap adapts partial api impl to another version +// proxyT is the proxy type used as input in wrapperT +// Usage: Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), eventsApi).(EventAPI) +func Wrap(proxyT, wrapperT, impl interface{}) interface{} { + proxy := reflect.New(reflect.TypeOf(proxyT).Elem()) + proxyMethods := proxy.FieldByName("Internal") + ri := reflect.ValueOf(impl) + + for i := 0; i < ri.NumMethod(); i++ { + mt := ri.Type().Method(i) + proxyMethods.FieldByName(mt.Name).Set(ri.Method(i)) + } + + wp := reflect.New(reflect.TypeOf(wrapperT).Elem()) + wp.Field(0).Set(proxy) + return wp.Interface() +} \ No newline at end of file diff --git a/chain/events/events.go b/chain/events/events.go index 8ad40f95f0c..e295d81e4c5 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -33,7 +33,7 @@ type heightHandler struct { revert RevertHandler } -type eventAPI interface { +type EventAPI interface { ChainNotify(context.Context) (<-chan []*api.HeadChange, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) @@ -45,7 +45,7 @@ type eventAPI interface { } type Events struct { - api eventAPI + api EventAPI tsc *tipSetCache lk sync.Mutex @@ -59,7 +59,7 @@ type Events struct { observers []TipSetObserver } -func NewEventsWithConfidence(ctx context.Context, api eventAPI, gcConfidence abi.ChainEpoch) *Events { +func NewEventsWithConfidence(ctx context.Context, api EventAPI, gcConfidence abi.ChainEpoch) *Events { tsc := newTSCache(gcConfidence, api) e := &Events{ @@ -93,7 +93,7 @@ func NewEventsWithConfidence(ctx context.Context, api eventAPI, gcConfidence abi return e } -func NewEvents(ctx context.Context, api eventAPI) *Events { +func NewEvents(ctx context.Context, api EventAPI) *Events { gcConfidence := 2 * build.ForkLengthThreshold return NewEventsWithConfidence(ctx, api, gcConfidence) } diff --git a/chain/events/events_called.go b/chain/events/events_called.go index 7f39e9038a6..bb8660abd7a 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -66,7 +66,7 @@ type queuedEvent struct { // Manages chain head change events, which may be forward (new tipset added to // chain) or backward (chain branch discarded in favour of heavier branch) type hcEvents struct { - cs eventAPI + cs EventAPI tsc *tipSetCache ctx context.Context gcConfidence uint64 @@ -93,7 +93,7 @@ type hcEvents struct { watcherEvents } -func newHCEvents(ctx context.Context, cs eventAPI, tsc *tipSetCache, gcConfidence uint64) *hcEvents { +func newHCEvents(ctx context.Context, cs EventAPI, tsc *tipSetCache, gcConfidence uint64) *hcEvents { e := hcEvents{ ctx: ctx, cs: cs, @@ -353,14 +353,14 @@ type headChangeAPI interface { // watcherEvents watches for a state change type watcherEvents struct { ctx context.Context - cs eventAPI + cs EventAPI hcAPI headChangeAPI lk sync.RWMutex matchers map[triggerID]StateMatchFunc } -func newWatcherEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) watcherEvents { +func newWatcherEvents(ctx context.Context, hcAPI headChangeAPI, cs EventAPI) watcherEvents { return watcherEvents{ ctx: ctx, cs: cs, @@ -455,14 +455,14 @@ func (we *watcherEvents) StateChanged(check CheckFunc, scHnd StateChangeHandler, // messageEvents watches for message calls to actors type messageEvents struct { ctx context.Context - cs eventAPI + cs EventAPI hcAPI headChangeAPI lk sync.RWMutex matchers map[triggerID]MsgMatchFunc } -func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) messageEvents { +func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs EventAPI) messageEvents { return messageEvents{ ctx: ctx, cs: cs, diff --git a/chain/events/events_test.go b/chain/events/events_test.go index 3957f425ca2..5369d849ed3 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -229,7 +229,7 @@ func (fcs *fakeCS) notifDone() { fcs.sync.Unlock() } -var _ eventAPI = &fakeCS{} +var _ EventAPI = &fakeCS{} func TestAt(t *testing.T) { fcs := &fakeCS{ diff --git a/chain/market/fundmanager.go b/chain/market/fundmanager.go index e3f10fdecd5..63acc5f00b8 100644 --- a/chain/market/fundmanager.go +++ b/chain/market/fundmanager.go @@ -36,7 +36,7 @@ type FundManagerAPI struct { type fundManagerAPI interface { MpoolPushMessage(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error) StateMarketBalance(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error) - StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) } // FundManager keeps track of funds in a set of addresses @@ -721,6 +721,6 @@ func (env *fundManagerEnvironment) WithdrawFunds( } func (env *fundManagerEnvironment) WaitMsg(ctx context.Context, c cid.Cid) error { - _, err := env.api.StateWaitMsg(ctx, c, build.MessageConfidence) + _, err := env.api.StateWaitMsg(ctx, c, build.MessageConfidence, api.LookbackNoLimit, true) return err } diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 60e2ae2cb17..38e2a32c6b9 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -45,7 +45,7 @@ import ( "github.com/filecoin-project/lotus/chain/vm" ) -const LookbackNoLimit = abi.ChainEpoch(-1) +const LookbackNoLimit = api.LookbackNoLimit const ReceiptAmtBitwidth = 3 var log = logging.Logger("statemgr") diff --git a/cmd/lotus-shed/ledger.go b/cmd/lotus-shed/ledger.go index 8d42b0e55c8..a77b74bb3ba 100644 --- a/cmd/lotus-shed/ledger.go +++ b/cmd/lotus-shed/ledger.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + "github.com/filecoin-project/lotus/api/v0api" "strconv" "strings" @@ -12,7 +13,6 @@ import ( "github.com/urfave/cli/v2" ledgerfil "github.com/whyrusleeping/ledger-filecoin-go" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" ledgerwallet "github.com/filecoin-project/lotus/chain/wallet/ledger" lcli "github.com/filecoin-project/lotus/cli" @@ -42,7 +42,7 @@ var ledgerListAddressesCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - var api api.FullNode + var api v0api.FullNode if cctx.Bool("print-balances") { a, closer, err := lcli.GetFullNodeAPI(cctx) if err != nil { diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 2e38dcc06ca..714aff0621a 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -37,6 +37,7 @@ import ( power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -269,7 +270,7 @@ var initCmd = &cli.Command{ }, } -func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string, maddr address.Address, mds dtypes.MetadataDS) error { +func migratePreSealMeta(ctx context.Context, api v0api.FullNode, metadata string, maddr address.Address, mds dtypes.MetadataDS) error { metadata, err := homedir.Expand(metadata) if err != nil { return xerrors.Errorf("expanding preseal dir: %w", err) @@ -379,7 +380,7 @@ func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string, return mds.Put(datastore.NewKey(modules.StorageCounterDSPrefix), buf[:size]) } -func findMarketDealID(ctx context.Context, api lapi.FullNode, deal market2.DealProposal) (abi.DealID, error) { +func findMarketDealID(ctx context.Context, api v0api.FullNode, deal market2.DealProposal) (abi.DealID, error) { // TODO: find a better way // (this is only used by genesis miners) @@ -398,7 +399,7 @@ func findMarketDealID(ctx context.Context, api lapi.FullNode, deal market2.DealP return 0, xerrors.New("deal not found") } -func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode, r repo.Repo, ssize abi.SectorSize, gasPrice types.BigInt) error { +func storageMinerInit(ctx context.Context, cctx *cli.Context, api v0api.FullNode, r repo.Repo, ssize abi.SectorSize, gasPrice types.BigInt) error { lr, err := r.Lock(repo.StorageMiner) if err != nil { return err @@ -562,7 +563,7 @@ func makeHostKey(lr repo.LockedRepo) (crypto.PrivKey, error) { return pk, nil } -func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.Address, peerid peer.ID, gasPrice types.BigInt) error { +func configureStorageMiner(ctx context.Context, api v0api.FullNode, addr address.Address, peerid peer.ID, gasPrice types.BigInt) error { mi, err := api.StateMinerInfo(ctx, addr, types.EmptyTSK) if err != nil { return xerrors.Errorf("getWorkerAddr returned bad address: %w", err) @@ -600,7 +601,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address. return nil } -func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, gasPrice types.BigInt, cctx *cli.Context) (address.Address, error) { +func createStorageMiner(ctx context.Context, api v0api.FullNode, peerid peer.ID, gasPrice types.BigInt, cctx *cli.Context) (address.Address, error) { var err error var owner address.Address if cctx.String("owner") != "" { diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index 0d2e5a70ef2..0fb28d1fe03 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -2,6 +2,7 @@ package main import ( "context" + "github.com/filecoin-project/lotus/api/v0api" "net" "net/http" _ "net/http/pprof" @@ -133,7 +134,7 @@ var runCmd = &cli.Command{ node.Override(new(dtypes.APIEndpoint), func() (dtypes.APIEndpoint, error) { return multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/" + cctx.String("miner-api")) })), - node.Override(new(api.FullNode), nodeApi), + node.Override(new(v0api.FullNode), nodeApi), ) if err != nil { return xerrors.Errorf("creating node: %w", err) diff --git a/cmd/lotus-storage-miner/storage.go b/cmd/lotus-storage-miner/storage.go index 2f42fd530e4..9a4971d5514 100644 --- a/cmd/lotus-storage-miner/storage.go +++ b/cmd/lotus-storage-miner/storage.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/filecoin-project/lotus/api/v0api" "io/ioutil" "os" "path/filepath" @@ -668,7 +669,7 @@ var storageCleanupCmd = &cli.Command{ }, } -func cleanupRemovedSectorData(ctx context.Context, api api.StorageMiner, napi api.FullNode) error { +func cleanupRemovedSectorData(ctx context.Context, api api.StorageMiner, napi v0api.FullNode) error { sectors, err := api.SectorsList(ctx) if err != nil { return err diff --git a/cmd/lotus-wallet/interactive.go b/cmd/lotus-wallet/interactive.go index 91c181e6530..e1ad2cbb292 100644 --- a/cmd/lotus-wallet/interactive.go +++ b/cmd/lotus-wallet/interactive.go @@ -20,6 +20,7 @@ import ( "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/stmgr" @@ -30,8 +31,8 @@ import ( type InteractiveWallet struct { lk sync.Mutex - apiGetter func() (api.FullNode, jsonrpc.ClientCloser, error) - under api.Wallet + apiGetter func() (v0api.FullNode, jsonrpc.ClientCloser, error) + under v0api.Wallet } func (c *InteractiveWallet) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) { diff --git a/cmd/lotus-wallet/main.go b/cmd/lotus-wallet/main.go index 271ed198ec3..bd137d29f81 100644 --- a/cmd/lotus-wallet/main.go +++ b/cmd/lotus-wallet/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "github.com/filecoin-project/lotus/api/v0api" "net" "net/http" "os" @@ -149,10 +150,10 @@ var runCmd = &cli.Command{ log.Info("Setting up API endpoint at " + address) if cctx.Bool("interactive") { - var ag func() (api.FullNode, jsonrpc.ClientCloser, error) + var ag func() (v0api.FullNode, jsonrpc.ClientCloser, error) if !cctx.Bool("offline") { - ag = func() (api.FullNode, jsonrpc.ClientCloser, error) { + ag = func() (v0api.FullNode, jsonrpc.ClientCloser, error) { return lcli.GetFullNodeAPI(cctx) } } diff --git a/markets/retrievaladapter/provider.go b/markets/retrievaladapter/provider.go index 3c8505c51d9..c6d398d20bd 100644 --- a/markets/retrievaladapter/provider.go +++ b/markets/retrievaladapter/provider.go @@ -7,7 +7,7 @@ import ( "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/types" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" @@ -26,12 +26,12 @@ var log = logging.Logger("retrievaladapter") type retrievalProviderNode struct { miner *storage.Miner sealer sectorstorage.SectorManager - full api.FullNode + full v0api.FullNode } // NewRetrievalProviderNode returns a new node adapter for a retrieval provider that talks to the // Lotus Node -func NewRetrievalProviderNode(miner *storage.Miner, sealer sectorstorage.SectorManager, full api.FullNode) retrievalmarket.RetrievalProviderNode { +func NewRetrievalProviderNode(miner *storage.Miner, sealer sectorstorage.SectorManager, full v0api.FullNode) retrievalmarket.RetrievalProviderNode { return &retrievalProviderNode{miner, sealer, full} } diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index c0d78a506d6..2164880c286 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -5,6 +5,9 @@ package storageadapter import ( "bytes" "context" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" + sealing "github.com/filecoin-project/lotus/extern/storage-sealing" "github.com/ipfs/go-cid" "go.uber.org/fx" @@ -54,7 +57,7 @@ func NewClientNodeAdapter(mctx helpers.MetricsCtx, lc fx.Lifecycle, stateapi ful capi := &clientApi{chain, stateapi, mpool} ctx := helpers.LifecycleCtx(mctx, lc) - ev := events.NewEvents(ctx, capi) + ev := events.NewEvents(ctx, api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), capi).(events.EventAPI)) a := &ClientNodeAdapter{ clientApi: capi, @@ -62,7 +65,7 @@ func NewClientNodeAdapter(mctx helpers.MetricsCtx, lc fx.Lifecycle, stateapi ful ev: ev, dsMatcher: newDealStateMatcher(state.NewStatePredicates(state.WrapFastAPI(capi))), } - a.scMgr = NewSectorCommittedManager(ev, a, &apiWrapper{api: capi}) + a.scMgr = NewSectorCommittedManager(ev, api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), a).(sealing.CurrentDealInfoTskAPI), &apiWrapper{api: capi}) return a } @@ -196,7 +199,7 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor } // TODO: timeout - ret, err := c.StateWaitMsg(ctx, *deal.PublishMessage, build.MessageConfidence) + ret, err := c.StateWaitMsg(ctx, *deal.PublishMessage, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return 0, xerrors.Errorf("waiting for deal publish message: %w", err) } @@ -363,7 +366,7 @@ func (c *ClientNodeAdapter) GetChainHead(ctx context.Context) (shared.TipSetToke } func (c *ClientNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, cb func(code exitcode.ExitCode, bytes []byte, finalCid cid.Cid, err error) error) error { - receipt, err := c.StateWaitMsg(ctx, mcid, build.MessageConfidence) + receipt, err := c.StateWaitMsg(ctx, mcid, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return cb(0, nil, cid.Undef, err) } diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index dcfcdcbcf07..dc1057aad6a 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -21,6 +21,7 @@ import ( market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -42,7 +43,7 @@ var defaultMaxProviderCollateralMultiplier = uint64(2) var log = logging.Logger("storageadapter") type ProviderNodeAdapter struct { - api.FullNode + v0api.FullNode // this goes away with the data transfer module dag dtypes.StagingDAG @@ -58,8 +59,8 @@ type ProviderNodeAdapter struct { scMgr *SectorCommittedManager } -func NewProviderNodeAdapter(fc *config.MinerFeeConfig, dc *config.DealmakingConfig) func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { - return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { +func NewProviderNodeAdapter(fc *config.MinerFeeConfig, dc *config.DealmakingConfig) func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full v0api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full v0api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { ctx := helpers.LifecycleCtx(mctx, lc) ev := events.NewEvents(ctx, full) diff --git a/miner/miner.go b/miner/miner.go index eb7dd95f54d..6304d7431da 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -6,6 +6,7 @@ import ( "crypto/rand" "encoding/binary" "fmt" + "github.com/filecoin-project/lotus/api/v0api" "sync" "time" @@ -56,7 +57,7 @@ func randTimeOffset(width time.Duration) time.Duration { // NewMiner instantiates a miner with a concrete WinningPoStProver and a miner // address (which can be different from the worker's address). -func NewMiner(api api.FullNode, epp gen.WinningPoStProver, addr address.Address, sf *slashfilter.SlashFilter, j journal.Journal) *Miner { +func NewMiner(api v0api.FullNode, epp gen.WinningPoStProver, addr address.Address, sf *slashfilter.SlashFilter, j journal.Journal) *Miner { arc, err := lru.NewARC(10000) if err != nil { panic(err) @@ -100,7 +101,7 @@ func NewMiner(api api.FullNode, epp gen.WinningPoStProver, addr address.Address, // // Refer to the godocs on mineOne and mine methods for more detail. type Miner struct { - api api.FullNode + api v0api.FullNode epp gen.WinningPoStProver diff --git a/miner/testminer.go b/miner/testminer.go index 5f461d88482..a0adc71736a 100644 --- a/miner/testminer.go +++ b/miner/testminer.go @@ -2,13 +2,13 @@ package miner import ( "context" + "github.com/filecoin-project/lotus/api/v0api" lru "github.com/hashicorp/golang-lru" ds "github.com/ipfs/go-datastore" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen/slashfilter" "github.com/filecoin-project/lotus/journal" @@ -19,8 +19,8 @@ type MineReq struct { Done func(bool, abi.ChainEpoch, error) } -func NewTestMiner(nextCh <-chan MineReq, addr address.Address) func(api.FullNode, gen.WinningPoStProver) *Miner { - return func(api api.FullNode, epp gen.WinningPoStProver) *Miner { +func NewTestMiner(nextCh <-chan MineReq, addr address.Address) func(v0api.FullNode, gen.WinningPoStProver) *Miner { + return func(api v0api.FullNode, epp gen.WinningPoStProver) *Miner { arc, err := lru.NewARC(10000) if err != nil { panic(err) diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 1781d049309..c5010b5e04d 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -55,7 +55,7 @@ import ( sealing "github.com/filecoin-project/lotus/extern/storage-sealing" "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" - lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -116,14 +116,14 @@ func MinerID(ma dtypes.MinerAddress) (dtypes.MinerID, error) { return dtypes.MinerID(id), err } -func StorageNetworkName(ctx helpers.MetricsCtx, a lapi.FullNode) (dtypes.NetworkName, error) { +func StorageNetworkName(ctx helpers.MetricsCtx, a v0api.FullNode) (dtypes.NetworkName, error) { if !build.Devnet { return "testnetnet", nil } return a.StateNetworkName(ctx) } -func SealProofType(maddr dtypes.MinerAddress, fnapi lapi.FullNode) (abi.RegisteredSealProof, error) { +func SealProofType(maddr dtypes.MinerAddress, fnapi v0api.FullNode) (abi.RegisteredSealProof, error) { mi, err := fnapi.StateMinerInfo(context.TODO(), address.Address(maddr), types.EmptyTSK) if err != nil { return 0, err @@ -196,7 +196,7 @@ type StorageMinerParams struct { Lifecycle fx.Lifecycle MetricsCtx helpers.MetricsCtx - API lapi.FullNode + API v0api.FullNode Host host.Host MetadataDS dtypes.MetadataDS Sealer sectorstorage.SectorManager @@ -437,7 +437,7 @@ func StagingGraphsync(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.Stagi return gs } -func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode, epp gen.WinningPoStProver, sf *slashfilter.SlashFilter, j journal.Journal) (*lotusminer.Miner, error) { +func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api v0api.FullNode, epp gen.WinningPoStProver, sf *slashfilter.SlashFilter, j journal.Journal) (*lotusminer.Miner, error) { minerAddr, err := minerAddrFromDS(ds) if err != nil { return nil, err @@ -460,7 +460,7 @@ func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode return m, nil } -func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.MetadataDS, minerAddress dtypes.MinerAddress, spn storagemarket.StorageProviderNode) (*storedask.StoredAsk, error) { +func NewStorageAsk(ctx helpers.MetricsCtx, fapi v0api.FullNode, ds dtypes.MetadataDS, minerAddress dtypes.MinerAddress, spn storagemarket.StorageProviderNode) (*storedask.StoredAsk, error) { mi, err := fapi.StateMinerInfo(ctx, address.Address(minerAddress), types.EmptyTSK) if err != nil { @@ -635,7 +635,7 @@ func RetrievalDealFilter(userFilter dtypes.RetrievalDealFilter) func(onlineOk dt func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.SectorManager, - full lapi.FullNode, + full v0api.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, mds dtypes.StagingMultiDstore, @@ -678,7 +678,7 @@ func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, ls stores.LocalStor return sst, nil } -func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageAuth, error) { +func StorageAuth(ctx helpers.MetricsCtx, ca v0api.Common) (sectorstorage.StorageAuth, error) { token, err := ca.AuthNew(ctx, []auth.Permission{"admin"}) if err != nil { return nil, xerrors.Errorf("creating storage auth header: %w", err) diff --git a/paychmgr/settler/settler.go b/paychmgr/settler/settler.go index d5ecc5631c0..c107d26a627 100644 --- a/paychmgr/settler/settler.go +++ b/paychmgr/settler/settler.go @@ -2,6 +2,8 @@ package settler import ( "context" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "sync" "github.com/filecoin-project/lotus/paychmgr" @@ -51,12 +53,12 @@ type paymentChannelSettler struct { // SettlePaymentChannels checks the chain for events related to payment channels settling and // submits any vouchers for inbound channels tracked for this node -func SettlePaymentChannels(mctx helpers.MetricsCtx, lc fx.Lifecycle, api API) error { +func SettlePaymentChannels(mctx helpers.MetricsCtx, lc fx.Lifecycle, papi API) error { ctx := helpers.LifecycleCtx(mctx, lc) lc.Append(fx.Hook{ OnStart: func(context.Context) error { - pcs := newPaymentChannelSettler(ctx, &api) - ev := events.NewEvents(ctx, &api) + pcs := newPaymentChannelSettler(ctx, &papi) + ev := events.NewEvents(ctx, api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), &papi).(events.EventAPI)) return ev.Called(pcs.check, pcs.messageHandler, pcs.revertHandler, int(build.MessageConfidence+1), events.NoTimeout, pcs.matcher) }, }) @@ -93,7 +95,7 @@ func (pcs *paymentChannelSettler) messageHandler(msg *types.Message, rec *types. } go func(voucher *paych.SignedVoucher, submitMessageCID cid.Cid) { defer wg.Done() - msgLookup, err := pcs.api.StateWaitMsg(pcs.ctx, submitMessageCID, build.MessageConfidence) + msgLookup, err := pcs.api.StateWaitMsg(pcs.ctx, submitMessageCID, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { log.Errorf("submitting voucher: %s", err.Error()) } diff --git a/storage/miner.go b/storage/miner.go index 52be4d7b895..38552ddc9c7 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -3,6 +3,7 @@ package storage import ( "context" "errors" + "github.com/filecoin-project/lotus/api/v0api" "time" "github.com/filecoin-project/go-state-types/network" @@ -215,7 +216,7 @@ type StorageWpp struct { winnRpt abi.RegisteredPoStProof } -func NewWinningPoStProver(api api.FullNode, prover storage.Prover, verifier ffiwrapper.Verifier, miner dtypes.MinerID) (*StorageWpp, error) { +func NewWinningPoStProver(api v0api.FullNode, prover storage.Prover, verifier ffiwrapper.Verifier, miner dtypes.MinerID) (*StorageWpp, error) { ma, err := address.NewIDAddress(uint64(miner)) if err != nil { return nil, err From d8bff4d19f06f2260fa356db732f0aa53b9cb4ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 5 Apr 2021 13:47:10 +0200 Subject: [PATCH 23/60] Make gateway work with v1 api --- api/api_gateway.go | 5 +- api/mocks/mock_full.go | 61 +------- api/proxy_gen.go | 26 +-- api/wrap.go | 2 +- build/openrpc/full.json.gz | Bin 22733 -> 22458 bytes build/openrpc/miner.json.gz | Bin 7810 -> 7847 bytes build/openrpc/worker.json.gz | Bin 2568 -> 2577 bytes cli/cmd.go | 1 + cli/servicesmock_test.go | 3 +- cli/util/api.go | 14 ++ cmd/lotus-gateway/api.go | 40 +++-- cmd/lotus-gateway/main.go | 24 ++- documentation/en/api-v1-unstable-methods.md | 165 ++------------------ 13 files changed, 90 insertions(+), 251 deletions(-) diff --git a/api/api_gateway.go b/api/api_gateway.go index b550bcbbc33..187fad86fc0 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -31,7 +31,6 @@ type Gateway interface { StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (DealCollateralBounds, error) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) - StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (MarketBalance, error) @@ -40,8 +39,8 @@ type Gateway interface { 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) (apitypes.NetworkVersion, error) - StateSearchMsg(ctx context.Context, msg cid.Cid) (*MsgLookup, error) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) - StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*MsgLookup, error) + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) } diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index b5670bdf5e1..4336a56f9cc 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -2095,21 +2095,6 @@ func (mr *MockFullNodeMockRecorder) StateGetActor(arg0, arg1, arg2 interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetActor", reflect.TypeOf((*MockFullNode)(nil).StateGetActor), arg0, arg1, arg2) } -// StateGetReceipt mocks base method -func (m *MockFullNode) StateGetReceipt(arg0 context.Context, arg1 cid.Cid, arg2 types.TipSetKey) (*types.MessageReceipt, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateGetReceipt", arg0, arg1, arg2) - ret0, _ := ret[0].(*types.MessageReceipt) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// StateGetReceipt indicates an expected call of StateGetReceipt -func (mr *MockFullNodeMockRecorder) StateGetReceipt(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetReceipt", reflect.TypeOf((*MockFullNode)(nil).StateGetReceipt), arg0, arg1, arg2) -} - // StateListActors mocks base method func (m *MockFullNode) StateListActors(arg0 context.Context, arg1 types.TipSetKey) ([]address.Address, error) { m.ctrl.T.Helper() @@ -2501,33 +2486,18 @@ func (mr *MockFullNodeMockRecorder) StateReplay(arg0, arg1, arg2 interface{}) *g } // StateSearchMsg mocks base method -func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 cid.Cid) (*api.MsgLookup, error) { +func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 types.TipSetKey, arg2 cid.Cid, arg3 abi.ChainEpoch, arg4 bool) (*api.MsgLookup, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateSearchMsg", arg0, arg1) + ret := m.ctrl.Call(m, "StateSearchMsg", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(*api.MsgLookup) ret1, _ := ret[1].(error) return ret0, ret1 } // StateSearchMsg indicates an expected call of StateSearchMsg -func (mr *MockFullNodeMockRecorder) StateSearchMsg(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsg", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsg), arg0, arg1) -} - -// StateSearchMsgLimited mocks base method -func (m *MockFullNode) StateSearchMsgLimited(arg0 context.Context, arg1 cid.Cid, arg2 abi.ChainEpoch) (*api.MsgLookup, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateSearchMsgLimited", arg0, arg1, arg2) - ret0, _ := ret[0].(*api.MsgLookup) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// StateSearchMsgLimited indicates an expected call of StateSearchMsgLimited -func (mr *MockFullNodeMockRecorder) StateSearchMsgLimited(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockFullNodeMockRecorder) StateSearchMsg(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsgLimited", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsgLimited), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsg", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsg), arg0, arg1, arg2, arg3, arg4) } // StateSectorExpiration mocks base method @@ -2651,33 +2621,18 @@ func (mr *MockFullNodeMockRecorder) StateVerifierStatus(arg0, arg1, arg2 interfa } // StateWaitMsg mocks base method -func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uint64) (*api.MsgLookup, error) { +func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uint64, arg3 abi.ChainEpoch, arg4 bool) (*api.MsgLookup, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateWaitMsg", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "StateWaitMsg", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(*api.MsgLookup) ret1, _ := ret[1].(error) return ret0, ret1 } // StateWaitMsg indicates an expected call of StateWaitMsg -func (mr *MockFullNodeMockRecorder) StateWaitMsg(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsg", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsg), arg0, arg1, arg2) -} - -// StateWaitMsgLimited mocks base method -func (m *MockFullNode) StateWaitMsgLimited(arg0 context.Context, arg1 cid.Cid, arg2 uint64, arg3 abi.ChainEpoch) (*api.MsgLookup, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateWaitMsgLimited", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*api.MsgLookup) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// StateWaitMsgLimited indicates an expected call of StateWaitMsgLimited -func (mr *MockFullNodeMockRecorder) StateWaitMsgLimited(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockFullNodeMockRecorder) StateWaitMsg(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsgLimited", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsgLimited), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsg", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsg), arg0, arg1, arg2, arg3, arg4) } // SyncCheckBad mocks base method diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 32d1992d03d..402da34c0ea 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -493,8 +493,6 @@ type GatewayStruct struct { StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `` - StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) `` - StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `` StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` @@ -511,13 +509,13 @@ type GatewayStruct struct { StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `` - StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) `` + StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `` StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `` StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` - StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) `` + StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `` } } @@ -2507,14 +2505,6 @@ func (s *GatewayStub) StateGetActor(p0 context.Context, p1 address.Address, p2 t return nil, xerrors.New("method not supported") } -func (s *GatewayStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { - return s.Internal.StateGetReceipt(p0, p1, p2) -} - -func (s *GatewayStub) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { - return nil, xerrors.New("method not supported") -} - func (s *GatewayStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { return s.Internal.StateListMiners(p0, p1) } @@ -2579,11 +2569,11 @@ func (s *GatewayStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey return *new(apitypes.NetworkVersion), xerrors.New("method not supported") } -func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) { - return s.Internal.StateSearchMsg(p0, p1) +func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return s.Internal.StateSearchMsg(p0, p1, p2, p3, p4) } -func (s *GatewayStub) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*MsgLookup, error) { +func (s *GatewayStub) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { return nil, xerrors.New("method not supported") } @@ -2603,11 +2593,11 @@ func (s *GatewayStub) StateVerifiedClientStatus(p0 context.Context, p1 address.A return nil, xerrors.New("method not supported") } -func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) { - return s.Internal.StateWaitMsg(p0, p1, p2) +func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return s.Internal.StateWaitMsg(p0, p1, p2, p3, p4) } -func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*MsgLookup, error) { +func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { return nil, xerrors.New("method not supported") } diff --git a/api/wrap.go b/api/wrap.go index 92f40776d1a..bb9f6194342 100644 --- a/api/wrap.go +++ b/api/wrap.go @@ -18,4 +18,4 @@ func Wrap(proxyT, wrapperT, impl interface{}) interface{} { wp := reflect.New(reflect.TypeOf(wrapperT).Elem()) wp.Field(0).Set(proxy) return wp.Interface() -} \ No newline at end of file +} diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index c2252beecd62aeae9891dbd13c301d919cf0c369..dac544a8dcc371df62d9babd97e3aacc9ec402c5 100644 GIT binary patch literal 22458 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 Xf4?66L4<+%^C#^(s7XN|0p@=Iguu-^ literal 22733 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 U-#-8U00030|8lEQD&c(r09L(PL;wH) diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 463744849960dcd59058c50498228573801317b4..d80a33cbebab0528e1cbf3b1bf05ebfd5a59a1be 100644 GIT binary patch delta 2518 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 SEdCn+0RR7=+5kUIdH?{=S a.stateWaitLookbackLimit { + limit = a.stateWaitLookbackLimit + } + if err := a.checkTipsetKey(ctx, from); err != nil { + return nil, err + } + + return a.api.StateSearchMsg(ctx, from, msg, limit, allowReplaced) } -func (a *GatewayAPI) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) { - return a.api.StateWaitMsgLimited(ctx, msg, confidence, a.stateWaitLookbackLimit) +func (a *GatewayAPI) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + if limit == api.LookbackNoLimit { + limit = a.stateWaitLookbackLimit + } + if a.stateWaitLookbackLimit != api.LookbackNoLimit && limit > a.stateWaitLookbackLimit { + limit = a.stateWaitLookbackLimit + } + + return a.api.StateWaitMsg(ctx, msg, confidence, limit, allowReplaced) } func (a *GatewayAPI) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) { diff --git a/cmd/lotus-gateway/main.go b/cmd/lotus-gateway/main.go index 05fa62c7501..0546896902d 100644 --- a/cmd/lotus-gateway/main.go +++ b/cmd/lotus-gateway/main.go @@ -11,6 +11,9 @@ import ( promclient "github.com/prometheus/client_golang/prometheus" "go.opencensus.io/tag" + lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/lotuslog" @@ -82,7 +85,7 @@ var runCmd = &cli.Command{ log.Fatalf("Cannot register the view: %v", err) } - api, closer, err := lcli.GetFullNodeAPI(cctx) + api, closer, err := lcli.GetFullNodeAPIV1(cctx) if err != nil { return err } @@ -93,14 +96,21 @@ var runCmd = &cli.Command{ log.Info("Setting up API endpoint at " + address) - serverOptions := make([]jsonrpc.ServerOption, 0) - if maxRequestSize := cctx.Int("api-max-req-size"); maxRequestSize != 0 { - serverOptions = append(serverOptions, jsonrpc.WithMaxRequestSize(int64(maxRequestSize))) + serveRpc := func(path string, hnd interface{}) { + serverOptions := make([]jsonrpc.ServerOption, 0) + if maxRequestSize := cctx.Int("api-max-req-size"); maxRequestSize != 0 { + serverOptions = append(serverOptions, jsonrpc.WithMaxRequestSize(int64(maxRequestSize))) + } + rpcServer := jsonrpc.NewServer(serverOptions...) + rpcServer.Register("Filecoin", hnd) + + mux.Handle("/rpc/v1", rpcServer) } - rpcServer := jsonrpc.NewServer(serverOptions...) - rpcServer.Register("Filecoin", metrics.MetricedGatewayAPI(NewGatewayAPI(api))) - mux.Handle("/rpc/v0", rpcServer) // todo: v1 support + ma := metrics.MetricedGatewayAPI(NewGatewayAPI(api)) + + serveRpc("/rpc/v1", ma) + serveRpc("/rpc/v0", lapi.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), ma)) registry := promclient.DefaultRegisterer.(*promclient.Registry) exporter, err := prometheus.NewExporter(prometheus.Options{ diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 2830be0bdb0..d94ef4ef3f2 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -153,7 +153,6 @@ * [StateDealProviderCollateralBounds](#StateDealProviderCollateralBounds) * [StateDecodeParams](#StateDecodeParams) * [StateGetActor](#StateGetActor) - * [StateGetReceipt](#StateGetReceipt) * [StateListActors](#StateListActors) * [StateListMessages](#StateListMessages) * [StateListMiners](#StateListMiners) @@ -181,7 +180,6 @@ * [StateReadState](#StateReadState) * [StateReplay](#StateReplay) * [StateSearchMsg](#StateSearchMsg) - * [StateSearchMsgLimited](#StateSearchMsgLimited) * [StateSectorExpiration](#StateSectorExpiration) * [StateSectorGetInfo](#StateSectorGetInfo) * [StateSectorPartition](#StateSectorPartition) @@ -191,7 +189,6 @@ * [StateVerifiedRegistryRootKey](#StateVerifiedRegistryRootKey) * [StateVerifierStatus](#StateVerifierStatus) * [StateWaitMsg](#StateWaitMsg) - * [StateWaitMsgLimited](#StateWaitMsgLimited) * [Sync](#Sync) * [SyncCheckBad](#SyncCheckBad) * [SyncCheckpoint](#SyncCheckpoint) @@ -3780,46 +3777,6 @@ Response: } ``` -### StateGetReceipt -StateGetReceipt returns the message receipt for the given message or for a -matching gas-repriced replacing message - -NOTE: If the requested message was replaced, this method will return the receipt -for the replacing message - if the caller needs the receipt for exactly the -requested message, use StateSearchMsg().Receipt, and check that MsgLookup.Message -is matching the requested CID - -DEPRECATED: Use StateSearchMsg, this method won't be supported in v1 API - - -Perms: read - -Inputs: -```json -[ - { - "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" - }, - [ - { - "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" - }, - { - "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" - } - ] -] -``` - -Response: -```json -{ - "ExitCode": 0, - "Return": "Ynl0ZSBhcnJheQ==", - "GasUsed": 9 -} -``` - ### StateListActors StateListActors returns the addresses of every actor in the state @@ -4660,7 +4617,7 @@ Response: ``` ### StateSearchMsg -StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed +StateSearchMsg looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed NOTE: If a replacing message is found on chain, this method will return a MsgLookup for the replacing message - the MsgLookup.Message will be a different @@ -4668,8 +4625,9 @@ CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the result of the execution of the replacing message. If the caller wants to ensure that exactly the requested message was executed, -they MUST check that MsgLookup.Message is equal to the provided 'cid'. -Without this check both the requested and original message may appear as +they must check that MsgLookup.Message is equal to the provided 'cid', or set the +`allowReplaced` parameter to false. Without this check, and with `allowReplaced` +set to true, both the requested and original message may appear as successfully executed on-chain, which may look like a double-spend. A replacing message is a message with a different CID, any of Gas values, and @@ -4682,25 +4640,7 @@ Perms: read Inputs: ```json [ - { - "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" - } -] -``` - -Response: -```json -{ - "Message": { - "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" - }, - "Receipt": { - "ExitCode": 0, - "Return": "Ynl0ZSBhcnJheQ==", - "GasUsed": 9 - }, - "ReturnDec": {}, - "TipSet": [ + [ { "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" }, @@ -4708,37 +4648,11 @@ Response: "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" } ], - "Height": 10101 -} -``` - -### StateSearchMsgLimited -StateSearchMsgLimited looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed - -NOTE: If a replacing message is found on chain, this method will return -a MsgLookup for the replacing message - the MsgLookup.Message will be a different -CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the -result of the execution of the replacing message. - -If the caller wants to ensure that exactly the requested message was executed, -they MUST check that MsgLookup.Message is equal to the provided 'cid'. -Without this check both the requested and original message may appear as -successfully executed on-chain, which may look like a double-spend. - -A replacing message is a message with a different CID, any of Gas values, and -different signature, but with all other parameters matching (source/destination, -nonce, params, etc.) - - -Perms: read - -Inputs: -```json -[ { "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" }, - 10101 + 10101, + true ] ``` @@ -5020,62 +4934,7 @@ Inputs: Response: `"0"` ### StateWaitMsg -StateWaitMsg looks back in the chain for a message. If not found, it blocks until the -message arrives on chain, and gets to the indicated confidence depth. - -NOTE: If a replacing message is found on chain, this method will return -a MsgLookup for the replacing message - the MsgLookup.Message will be a different -CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the -result of the execution of the replacing message. - -If the caller wants to ensure that exactly the requested message was executed, -they MUST check that MsgLookup.Message is equal to the provided 'cid'. -Without this check both the requested and original message may appear as -successfully executed on-chain, which may look like a double-spend. - -A replacing message is a message with a different CID, any of Gas values, and -different signature, but with all other parameters matching (source/destination, -nonce, params, etc.) - - -Perms: read - -Inputs: -```json -[ - { - "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" - }, - 42 -] -``` - -Response: -```json -{ - "Message": { - "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" - }, - "Receipt": { - "ExitCode": 0, - "Return": "Ynl0ZSBhcnJheQ==", - "GasUsed": 9 - }, - "ReturnDec": {}, - "TipSet": [ - { - "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" - }, - { - "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" - } - ], - "Height": 10101 -} -``` - -### StateWaitMsgLimited -StateWaitMsgLimited looks back up to limit epochs in the chain for a message. +StateWaitMsg looks back up to limit epochs in the chain for a message. If not found, it blocks until the message arrives on chain, and gets to the indicated confidence depth. @@ -5085,8 +4944,9 @@ CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the result of the execution of the replacing message. If the caller wants to ensure that exactly the requested message was executed, -they MUST check that MsgLookup.Message is equal to the provided 'cid'. -Without this check both the requested and original message may appear as +they must check that MsgLookup.Message is equal to the provided 'cid', or set the +`allowReplaced` parameter to false. Without this check, and with `allowReplaced` +set to true, both the requested and original message may appear as successfully executed on-chain, which may look like a double-spend. A replacing message is a message with a different CID, any of Gas values, and @@ -5103,7 +4963,8 @@ Inputs: "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" }, 42, - 10101 + 10101, + true ] ``` From 81bd27911f0ab06d64c6a38e3e1ba3ab1cf6e528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 5 Apr 2021 19:56:53 +0200 Subject: [PATCH 24/60] Propagate StateMsg api changes --- api/test/test.go | 3 ++- api/wrap.go | 19 +++++++++++++++---- chain/events/events.go | 2 +- chain/events/events_called.go | 10 ++++++++-- chain/events/events_test.go | 2 +- chain/events/utils.go | 10 ++++++++-- cmd/lotus-shed/ledger.go | 3 ++- cmd/lotus-storage-miner/init.go | 21 +++++++++++---------- cmd/lotus-storage-miner/init_restore.go | 6 ++++-- cmd/lotus-storage-miner/run.go | 10 ++++++---- cmd/lotus-storage-miner/storage.go | 3 ++- cmd/lotus-wallet/main.go | 3 ++- extern/storage-sealing/currentdealinfo.go | 4 ++-- markets/retrievaladapter/provider.go | 7 ++++--- markets/storageadapter/client.go | 7 ++----- markets/storageadapter/provider.go | 12 ++++++------ miner/miner.go | 7 ++++--- miner/testminer.go | 7 ++++--- node/modules/paych.go | 2 ++ node/modules/storageminer.go | 13 +++++++------ node/test/builder.go | 3 ++- paychmgr/manager.go | 3 ++- paychmgr/settler/settler.go | 4 +--- paychmgr/simple.go | 4 ++-- storage/adapter_storage_miner.go | 4 ++-- storage/miner.go | 9 ++++----- storage/wdpost_run.go | 6 +++--- 27 files changed, 109 insertions(+), 75 deletions(-) diff --git a/api/test/test.go b/api/test/test.go index eed760bc24c..aaaf55b8b44 100644 --- a/api/test/test.go +++ b/api/test/test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" @@ -36,7 +37,7 @@ func init() { } type TestNode struct { - api.FullNode + v1api.FullNode // ListenAddr is the address on which an API server is listening, if an // API server is created for this Node ListenAddr multiaddr.Multiaddr diff --git a/api/wrap.go b/api/wrap.go index bb9f6194342..09f103e0c16 100644 --- a/api/wrap.go +++ b/api/wrap.go @@ -1,21 +1,32 @@ package api -import "reflect" +import ( + "reflect" +) // Wrap adapts partial api impl to another version // proxyT is the proxy type used as input in wrapperT // Usage: Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), eventsApi).(EventAPI) func Wrap(proxyT, wrapperT, impl interface{}) interface{} { proxy := reflect.New(reflect.TypeOf(proxyT).Elem()) - proxyMethods := proxy.FieldByName("Internal") + proxyMethods := proxy.Elem().FieldByName("Internal") ri := reflect.ValueOf(impl) for i := 0; i < ri.NumMethod(); i++ { mt := ri.Type().Method(i) - proxyMethods.FieldByName(mt.Name).Set(ri.Method(i)) + if proxyMethods.FieldByName(mt.Name).IsZero() { + continue + } + + fn := ri.Method(i) + of := proxyMethods.FieldByName(mt.Name) + + proxyMethods.FieldByName(mt.Name).Set(reflect.MakeFunc(of.Type(), func(args []reflect.Value) (results []reflect.Value) { + return fn.Call(args) + })) } wp := reflect.New(reflect.TypeOf(wrapperT).Elem()) - wp.Field(0).Set(proxy) + wp.Elem().Field(0).Set(proxy) return wp.Interface() } diff --git a/chain/events/events.go b/chain/events/events.go index e295d81e4c5..8511de9217b 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -38,7 +38,7 @@ type EventAPI interface { ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) ChainHead(context.Context) (*types.TipSet, error) - StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) // optional / for CalledMsg diff --git a/chain/events/events_called.go b/chain/events/events_called.go index bb8660abd7a..1a619c195de 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -5,6 +5,8 @@ import ( "math" "sync" + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -583,12 +585,16 @@ func (me *messageEvents) Called(check CheckFunc, msgHnd MsgHandler, rev RevertHa panic("expected msg") } - rec, err := me.cs.StateGetReceipt(me.ctx, msg.Cid(), ts.Key()) + ml, err := me.cs.StateSearchMsg(me.ctx, ts.Key(), msg.Cid(), stmgr.LookbackNoLimit, true) if err != nil { return false, err } - return msgHnd(msg, rec, ts, height) + if ml == nil { + return msgHnd(msg, nil, ts, height) + } + + return msgHnd(msg, &ml.Receipt, ts, height) } id, err := me.hcAPI.onHeadChanged(check, hnd, rev, confidence, timeout) diff --git a/chain/events/events_test.go b/chain/events/events_test.go index 5369d849ed3..0aab626dd20 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -54,7 +54,7 @@ func (fcs *fakeCS) ChainGetTipSet(ctx context.Context, key types.TipSetKey) (*ty return fcs.tipsets[key], nil } -func (fcs *fakeCS) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) { +func (fcs *fakeCS) StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { return nil, nil } diff --git a/chain/events/utils.go b/chain/events/utils.go index c26ca5b836a..91ea0cd7a07 100644 --- a/chain/events/utils.go +++ b/chain/events/utils.go @@ -3,6 +3,8 @@ package events import ( "context" + "github.com/filecoin-project/lotus/chain/stmgr" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/types" @@ -22,12 +24,16 @@ func (me *messageEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd return false, true, nil } - rec, err := me.cs.StateGetReceipt(ctx, smsg.VMMessage().Cid(), ts.Key()) + ml, err := me.cs.StateSearchMsg(me.ctx, ts.Key(), msg.Cid(), stmgr.LookbackNoLimit, true) if err != nil { return false, true, xerrors.Errorf("getting receipt in CheckMsg: %w", err) } - more, err = hnd(msg, rec, ts, ts.Height()) + if ml == nil { + more, err = hnd(msg, nil, ts, ts.Height()) + } else { + more, err = hnd(msg, &ml.Receipt, ts, ts.Height()) + } return true, more, err } diff --git a/cmd/lotus-shed/ledger.go b/cmd/lotus-shed/ledger.go index a77b74bb3ba..0e9c11742cc 100644 --- a/cmd/lotus-shed/ledger.go +++ b/cmd/lotus-shed/ledger.go @@ -3,10 +3,11 @@ package main import ( "encoding/json" "fmt" - "github.com/filecoin-project/lotus/api/v0api" "strconv" "strings" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 714aff0621a..abb8d3abe48 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -38,6 +38,7 @@ import ( lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -150,7 +151,7 @@ var initCmd = &cli.Command{ log.Info("Trying to connect to full node RPC") - api, closer, err := lcli.GetFullNodeAPI(cctx) // TODO: consider storing full node address in config + api, closer, err := lcli.GetFullNodeAPIV1(cctx) // TODO: consider storing full node address in config if err != nil { return err } @@ -159,7 +160,7 @@ var initCmd = &cli.Command{ log.Info("Checking full node sync status") if !cctx.Bool("genesis-miner") && !cctx.Bool("nosync") { - if err := lcli.SyncWait(ctx, api, false); err != nil { + if err := lcli.SyncWait(ctx, &v0api.WrapperV1Full{FullNode: api}, false); err != nil { return xerrors.Errorf("sync wait: %w", err) } } @@ -270,7 +271,7 @@ var initCmd = &cli.Command{ }, } -func migratePreSealMeta(ctx context.Context, api v0api.FullNode, metadata string, maddr address.Address, mds dtypes.MetadataDS) error { +func migratePreSealMeta(ctx context.Context, api v1api.FullNode, metadata string, maddr address.Address, mds dtypes.MetadataDS) error { metadata, err := homedir.Expand(metadata) if err != nil { return xerrors.Errorf("expanding preseal dir: %w", err) @@ -380,7 +381,7 @@ func migratePreSealMeta(ctx context.Context, api v0api.FullNode, metadata string return mds.Put(datastore.NewKey(modules.StorageCounterDSPrefix), buf[:size]) } -func findMarketDealID(ctx context.Context, api v0api.FullNode, deal market2.DealProposal) (abi.DealID, error) { +func findMarketDealID(ctx context.Context, api v1api.FullNode, deal market2.DealProposal) (abi.DealID, error) { // TODO: find a better way // (this is only used by genesis miners) @@ -399,7 +400,7 @@ func findMarketDealID(ctx context.Context, api v0api.FullNode, deal market2.Deal return 0, xerrors.New("deal not found") } -func storageMinerInit(ctx context.Context, cctx *cli.Context, api v0api.FullNode, r repo.Repo, ssize abi.SectorSize, gasPrice types.BigInt) error { +func storageMinerInit(ctx context.Context, cctx *cli.Context, api v1api.FullNode, r repo.Repo, ssize abi.SectorSize, gasPrice types.BigInt) error { lr, err := r.Lock(repo.StorageMiner) if err != nil { return err @@ -563,7 +564,7 @@ func makeHostKey(lr repo.LockedRepo) (crypto.PrivKey, error) { return pk, nil } -func configureStorageMiner(ctx context.Context, api v0api.FullNode, addr address.Address, peerid peer.ID, gasPrice types.BigInt) error { +func configureStorageMiner(ctx context.Context, api v1api.FullNode, addr address.Address, peerid peer.ID, gasPrice types.BigInt) error { mi, err := api.StateMinerInfo(ctx, addr, types.EmptyTSK) if err != nil { return xerrors.Errorf("getWorkerAddr returned bad address: %w", err) @@ -589,7 +590,7 @@ func configureStorageMiner(ctx context.Context, api v0api.FullNode, addr address } log.Info("Waiting for message: ", smsg.Cid()) - ret, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) + ret, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence, lapi.LookbackNoLimit, true) if err != nil { return err } @@ -601,7 +602,7 @@ func configureStorageMiner(ctx context.Context, api v0api.FullNode, addr address return nil } -func createStorageMiner(ctx context.Context, api v0api.FullNode, peerid peer.ID, gasPrice types.BigInt, cctx *cli.Context) (address.Address, error) { +func createStorageMiner(ctx context.Context, api v1api.FullNode, peerid peer.ID, gasPrice types.BigInt, cctx *cli.Context) (address.Address, error) { var err error var owner address.Address if cctx.String("owner") != "" { @@ -643,7 +644,7 @@ func createStorageMiner(ctx context.Context, api v0api.FullNode, peerid peer.ID, log.Infof("Initializing worker account %s, message: %s", worker, signed.Cid()) log.Infof("Waiting for confirmation") - mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence) + mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence, lapi.LookbackNoLimit, true) if err != nil { return address.Undef, xerrors.Errorf("waiting for worker init: %w", err) } @@ -701,7 +702,7 @@ func createStorageMiner(ctx context.Context, api v0api.FullNode, peerid peer.ID, log.Infof("Pushed CreateMiner message: %s", signed.Cid()) log.Infof("Waiting for confirmation") - mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence) + mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence, lapi.LookbackNoLimit, true) if err != nil { return address.Undef, xerrors.Errorf("waiting for createMiner message: %w", err) } diff --git a/cmd/lotus-storage-miner/init_restore.go b/cmd/lotus-storage-miner/init_restore.go index 12358e63a75..082c456148d 100644 --- a/cmd/lotus-storage-miner/init_restore.go +++ b/cmd/lotus-storage-miner/init_restore.go @@ -6,6 +6,8 @@ import ( "io/ioutil" "os" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/docker/go-units" "github.com/ipfs/go-datastore" "github.com/libp2p/go-libp2p-core/peer" @@ -54,7 +56,7 @@ var initRestoreCmd = &cli.Command{ log.Info("Trying to connect to full node RPC") - api, closer, err := lcli.GetFullNodeAPI(cctx) // TODO: consider storing full node address in config + api, closer, err := lcli.GetFullNodeAPIV1(cctx) // TODO: consider storing full node address in config if err != nil { return err } @@ -74,7 +76,7 @@ var initRestoreCmd = &cli.Command{ } if !cctx.Bool("nosync") { - if err := lcli.SyncWait(ctx, api, false); err != nil { + if err := lcli.SyncWait(ctx, &v0api.WrapperV1Full{FullNode: api}, false); err != nil { return xerrors.Errorf("sync wait: %w", err) } } diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index 0fb28d1fe03..a66c0b61d2c 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -2,7 +2,7 @@ package main import ( "context" - "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "net" "net/http" _ "net/http/pprof" @@ -10,6 +10,8 @@ import ( "os/signal" "syscall" + "github.com/filecoin-project/lotus/api/v0api" + mux "github.com/gorilla/mux" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" @@ -64,7 +66,7 @@ var runCmd = &cli.Command{ } } - nodeApi, ncloser, err := lcli.GetFullNodeAPI(cctx) + nodeApi, ncloser, err := lcli.GetFullNodeAPIV1(cctx) if err != nil { return xerrors.Errorf("getting full node api: %w", err) } @@ -102,7 +104,7 @@ var runCmd = &cli.Command{ log.Info("Checking full node sync status") if !cctx.Bool("nosync") { - if err := lcli.SyncWait(ctx, nodeApi, false); err != nil { + if err := lcli.SyncWait(ctx, &v0api.WrapperV1Full{FullNode: nodeApi}, false); err != nil { return xerrors.Errorf("sync wait: %w", err) } } @@ -134,7 +136,7 @@ var runCmd = &cli.Command{ node.Override(new(dtypes.APIEndpoint), func() (dtypes.APIEndpoint, error) { return multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/" + cctx.String("miner-api")) })), - node.Override(new(v0api.FullNode), nodeApi), + node.Override(new(v1api.FullNode), nodeApi), ) if err != nil { return xerrors.Errorf("creating node: %w", err) diff --git a/cmd/lotus-storage-miner/storage.go b/cmd/lotus-storage-miner/storage.go index 9a4971d5514..b4ab26ad3e2 100644 --- a/cmd/lotus-storage-miner/storage.go +++ b/cmd/lotus-storage-miner/storage.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/filecoin-project/lotus/api/v0api" "io/ioutil" "os" "path/filepath" @@ -13,6 +12,8 @@ import ( "strings" "time" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/docker/go-units" "github.com/fatih/color" "github.com/google/uuid" diff --git a/cmd/lotus-wallet/main.go b/cmd/lotus-wallet/main.go index bd137d29f81..2c86c6180fa 100644 --- a/cmd/lotus-wallet/main.go +++ b/cmd/lotus-wallet/main.go @@ -2,11 +2,12 @@ package main import ( "context" - "github.com/filecoin-project/lotus/api/v0api" "net" "net/http" "os" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/gorilla/mux" logging "github.com/ipfs/go-log/v2" "github.com/urfave/cli/v2" diff --git a/extern/storage-sealing/currentdealinfo.go b/extern/storage-sealing/currentdealinfo.go index 105a42d1ef4..44fa68b5468 100644 --- a/extern/storage-sealing/currentdealinfo.go +++ b/extern/storage-sealing/currentdealinfo.go @@ -160,7 +160,7 @@ type CurrentDealInfoTskAPI interface { ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error) StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) - StateSearchMsg(context.Context, cid.Cid) (*api.MsgLookup, error) + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) } type CurrentDealInfoAPIAdapter struct { @@ -186,7 +186,7 @@ func (c *CurrentDealInfoAPIAdapter) StateMarketStorageDeal(ctx context.Context, } func (c *CurrentDealInfoAPIAdapter) StateSearchMsg(ctx context.Context, k cid.Cid) (*MsgLookup, error) { - wmsg, err := c.CurrentDealInfoTskAPI.StateSearchMsg(ctx, k) + wmsg, err := c.CurrentDealInfoTskAPI.StateSearchMsg(ctx, types.EmptyTSK, k, api.LookbackNoLimit, true) if err != nil { return nil, err } diff --git a/markets/retrievaladapter/provider.go b/markets/retrievaladapter/provider.go index c6d398d20bd..557dd3b6d64 100644 --- a/markets/retrievaladapter/provider.go +++ b/markets/retrievaladapter/provider.go @@ -4,10 +4,11 @@ import ( "context" "io" + "github.com/filecoin-project/lotus/api/v1api" + "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" - "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/types" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" @@ -26,12 +27,12 @@ var log = logging.Logger("retrievaladapter") type retrievalProviderNode struct { miner *storage.Miner sealer sectorstorage.SectorManager - full v0api.FullNode + full v1api.FullNode } // NewRetrievalProviderNode returns a new node adapter for a retrieval provider that talks to the // Lotus Node -func NewRetrievalProviderNode(miner *storage.Miner, sealer sectorstorage.SectorManager, full v0api.FullNode) retrievalmarket.RetrievalProviderNode { +func NewRetrievalProviderNode(miner *storage.Miner, sealer sectorstorage.SectorManager, full v1api.FullNode) retrievalmarket.RetrievalProviderNode { return &retrievalProviderNode{miner, sealer, full} } diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 2164880c286..8e7c26558e3 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -5,9 +5,6 @@ package storageadapter import ( "bytes" "context" - "github.com/filecoin-project/lotus/api/v0api" - "github.com/filecoin-project/lotus/api/v1api" - sealing "github.com/filecoin-project/lotus/extern/storage-sealing" "github.com/ipfs/go-cid" "go.uber.org/fx" @@ -57,7 +54,7 @@ func NewClientNodeAdapter(mctx helpers.MetricsCtx, lc fx.Lifecycle, stateapi ful capi := &clientApi{chain, stateapi, mpool} ctx := helpers.LifecycleCtx(mctx, lc) - ev := events.NewEvents(ctx, api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), capi).(events.EventAPI)) + ev := events.NewEvents(ctx, capi) a := &ClientNodeAdapter{ clientApi: capi, @@ -65,7 +62,7 @@ func NewClientNodeAdapter(mctx helpers.MetricsCtx, lc fx.Lifecycle, stateapi ful ev: ev, dsMatcher: newDealStateMatcher(state.NewStatePredicates(state.WrapFastAPI(capi))), } - a.scMgr = NewSectorCommittedManager(ev, api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), a).(sealing.CurrentDealInfoTskAPI), &apiWrapper{api: capi}) + a.scMgr = NewSectorCommittedManager(ev, a, &apiWrapper{api: capi}) return a } diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index dc1057aad6a..fbeaf3b3dca 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -21,7 +21,7 @@ import ( market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -43,7 +43,7 @@ var defaultMaxProviderCollateralMultiplier = uint64(2) var log = logging.Logger("storageadapter") type ProviderNodeAdapter struct { - v0api.FullNode + v1api.FullNode // this goes away with the data transfer module dag dtypes.StagingDAG @@ -59,8 +59,8 @@ type ProviderNodeAdapter struct { scMgr *SectorCommittedManager } -func NewProviderNodeAdapter(fc *config.MinerFeeConfig, dc *config.DealmakingConfig) func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full v0api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { - return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full v0api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { +func NewProviderNodeAdapter(fc *config.MinerFeeConfig, dc *config.DealmakingConfig) func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full v1api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full v1api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { ctx := helpers.LifecycleCtx(mctx, lc) ev := events.NewEvents(ctx, full) @@ -291,7 +291,7 @@ func (n *ProviderNodeAdapter) GetChainHead(ctx context.Context) (shared.TipSetTo } func (n *ProviderNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, cb func(code exitcode.ExitCode, bytes []byte, finalCid cid.Cid, err error) error) error { - receipt, err := n.StateWaitMsg(ctx, mcid, 2*build.MessageConfidence) + receipt, err := n.StateWaitMsg(ctx, mcid, 2*build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return cb(0, nil, cid.Undef, err) } @@ -300,7 +300,7 @@ func (n *ProviderNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, func (n *ProviderNodeAdapter) WaitForPublishDeals(ctx context.Context, publishCid cid.Cid, proposal market2.DealProposal) (*storagemarket.PublishDealsWaitResult, error) { // Wait for deal to be published (plus additional time for confidence) - receipt, err := n.StateWaitMsg(ctx, publishCid, 2*build.MessageConfidence) + receipt, err := n.StateWaitMsg(ctx, publishCid, 2*build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return nil, xerrors.Errorf("WaitForPublishDeals errored: %w", err) } diff --git a/miner/miner.go b/miner/miner.go index 6304d7431da..e7e012d7c9c 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -6,10 +6,11 @@ import ( "crypto/rand" "encoding/binary" "fmt" - "github.com/filecoin-project/lotus/api/v0api" "sync" "time" + "github.com/filecoin-project/lotus/api/v1api" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" "github.com/filecoin-project/lotus/chain/gen/slashfilter" @@ -57,7 +58,7 @@ func randTimeOffset(width time.Duration) time.Duration { // NewMiner instantiates a miner with a concrete WinningPoStProver and a miner // address (which can be different from the worker's address). -func NewMiner(api v0api.FullNode, epp gen.WinningPoStProver, addr address.Address, sf *slashfilter.SlashFilter, j journal.Journal) *Miner { +func NewMiner(api v1api.FullNode, epp gen.WinningPoStProver, addr address.Address, sf *slashfilter.SlashFilter, j journal.Journal) *Miner { arc, err := lru.NewARC(10000) if err != nil { panic(err) @@ -101,7 +102,7 @@ func NewMiner(api v0api.FullNode, epp gen.WinningPoStProver, addr address.Addres // // Refer to the godocs on mineOne and mine methods for more detail. type Miner struct { - api v0api.FullNode + api v1api.FullNode epp gen.WinningPoStProver diff --git a/miner/testminer.go b/miner/testminer.go index a0adc71736a..7f29a7ae028 100644 --- a/miner/testminer.go +++ b/miner/testminer.go @@ -2,13 +2,14 @@ package miner import ( "context" - "github.com/filecoin-project/lotus/api/v0api" lru "github.com/hashicorp/golang-lru" ds "github.com/ipfs/go-datastore" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen/slashfilter" "github.com/filecoin-project/lotus/journal" @@ -19,8 +20,8 @@ type MineReq struct { Done func(bool, abi.ChainEpoch, error) } -func NewTestMiner(nextCh <-chan MineReq, addr address.Address) func(v0api.FullNode, gen.WinningPoStProver) *Miner { - return func(api v0api.FullNode, epp gen.WinningPoStProver) *Miner { +func NewTestMiner(nextCh <-chan MineReq, addr address.Address) func(v1api.FullNode, gen.WinningPoStProver) *Miner { + return func(api v1api.FullNode, epp gen.WinningPoStProver) *Miner { arc, err := lru.NewARC(10000) if err != nil { panic(err) diff --git a/node/modules/paych.go b/node/modules/paych.go index a9fd25a3ec9..905590057f9 100644 --- a/node/modules/paych.go +++ b/node/modules/paych.go @@ -32,6 +32,8 @@ type PaychAPI struct { full.StateAPI } +var _ paychmgr.PaychAPI = &PaychAPI{} + // HandlePaychManager is called by dependency injection to set up hooks func HandlePaychManager(lc fx.Lifecycle, pm *paychmgr.Manager) { lc.Append(fx.Hook{ diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index c5010b5e04d..be949255f7e 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -56,6 +56,7 @@ import ( "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -116,14 +117,14 @@ func MinerID(ma dtypes.MinerAddress) (dtypes.MinerID, error) { return dtypes.MinerID(id), err } -func StorageNetworkName(ctx helpers.MetricsCtx, a v0api.FullNode) (dtypes.NetworkName, error) { +func StorageNetworkName(ctx helpers.MetricsCtx, a v1api.FullNode) (dtypes.NetworkName, error) { if !build.Devnet { return "testnetnet", nil } return a.StateNetworkName(ctx) } -func SealProofType(maddr dtypes.MinerAddress, fnapi v0api.FullNode) (abi.RegisteredSealProof, error) { +func SealProofType(maddr dtypes.MinerAddress, fnapi v1api.FullNode) (abi.RegisteredSealProof, error) { mi, err := fnapi.StateMinerInfo(context.TODO(), address.Address(maddr), types.EmptyTSK) if err != nil { return 0, err @@ -196,7 +197,7 @@ type StorageMinerParams struct { Lifecycle fx.Lifecycle MetricsCtx helpers.MetricsCtx - API v0api.FullNode + API v1api.FullNode Host host.Host MetadataDS dtypes.MetadataDS Sealer sectorstorage.SectorManager @@ -437,7 +438,7 @@ func StagingGraphsync(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.Stagi return gs } -func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api v0api.FullNode, epp gen.WinningPoStProver, sf *slashfilter.SlashFilter, j journal.Journal) (*lotusminer.Miner, error) { +func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api v1api.FullNode, epp gen.WinningPoStProver, sf *slashfilter.SlashFilter, j journal.Journal) (*lotusminer.Miner, error) { minerAddr, err := minerAddrFromDS(ds) if err != nil { return nil, err @@ -460,7 +461,7 @@ func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api v0api.FullNod return m, nil } -func NewStorageAsk(ctx helpers.MetricsCtx, fapi v0api.FullNode, ds dtypes.MetadataDS, minerAddress dtypes.MinerAddress, spn storagemarket.StorageProviderNode) (*storedask.StoredAsk, error) { +func NewStorageAsk(ctx helpers.MetricsCtx, fapi v1api.FullNode, ds dtypes.MetadataDS, minerAddress dtypes.MinerAddress, spn storagemarket.StorageProviderNode) (*storedask.StoredAsk, error) { mi, err := fapi.StateMinerInfo(ctx, address.Address(minerAddress), types.EmptyTSK) if err != nil { @@ -635,7 +636,7 @@ func RetrievalDealFilter(userFilter dtypes.RetrievalDealFilter) func(onlineOk dt func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.SectorManager, - full v0api.FullNode, + full v1api.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, mds dtypes.StagingMultiDstore, diff --git a/node/test/builder.go b/node/test/builder.go index 9c4515a9b99..8a887f55d27 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -22,6 +22,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/api/test" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain/actors" @@ -122,7 +123,7 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr node.MockHost(mn), - node.Override(new(api.FullNode), tnd), + node.Override(new(v1api.FullNode), tnd), node.Override(new(*lotusminer.Miner), lotusminer.NewTestMiner(mineBlock, act)), opts, diff --git a/paychmgr/manager.go b/paychmgr/manager.go index e9700bc9d14..6f6efa7ea91 100644 --- a/paychmgr/manager.go +++ b/paychmgr/manager.go @@ -11,6 +11,7 @@ import ( xerrors "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/network" @@ -34,7 +35,7 @@ type stateManagerAPI interface { // paychAPI defines the API methods needed by the payment channel manager type PaychAPI interface { StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error) - StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) MpoolPushMessage(ctx context.Context, msg *types.Message, maxFee *api.MessageSendSpec) (*types.SignedMessage, error) WalletHas(ctx context.Context, addr address.Address) (bool, error) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) diff --git a/paychmgr/settler/settler.go b/paychmgr/settler/settler.go index c107d26a627..676b15c271f 100644 --- a/paychmgr/settler/settler.go +++ b/paychmgr/settler/settler.go @@ -2,8 +2,6 @@ package settler import ( "context" - "github.com/filecoin-project/lotus/api/v0api" - "github.com/filecoin-project/lotus/api/v1api" "sync" "github.com/filecoin-project/lotus/paychmgr" @@ -58,7 +56,7 @@ func SettlePaymentChannels(mctx helpers.MetricsCtx, lc fx.Lifecycle, papi API) e lc.Append(fx.Hook{ OnStart: func(context.Context) error { pcs := newPaymentChannelSettler(ctx, &papi) - ev := events.NewEvents(ctx, api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), &papi).(events.EventAPI)) + ev := events.NewEvents(ctx, papi) return ev.Called(pcs.check, pcs.messageHandler, pcs.revertHandler, int(build.MessageConfidence+1), events.NoTimeout, pcs.matcher) }, }) diff --git a/paychmgr/simple.go b/paychmgr/simple.go index 939a5a5be25..f93c6d5bd20 100644 --- a/paychmgr/simple.go +++ b/paychmgr/simple.go @@ -413,7 +413,7 @@ func (ca *channelAccessor) waitForPaychCreateMsg(channelID string, mcid cid.Cid) } func (ca *channelAccessor) waitPaychCreateMsg(channelID string, mcid cid.Cid) error { - mwait, err := ca.api.StateWaitMsg(ca.chctx, mcid, build.MessageConfidence) + mwait, err := ca.api.StateWaitMsg(ca.chctx, mcid, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { log.Errorf("wait msg: %v", err) return err @@ -499,7 +499,7 @@ func (ca *channelAccessor) waitForAddFundsMsg(channelID string, mcid cid.Cid) { } func (ca *channelAccessor) waitAddFundsMsg(channelID string, mcid cid.Cid) error { - mwait, err := ca.api.StateWaitMsg(ca.chctx, mcid, build.MessageConfidence) + mwait, err := ca.api.StateWaitMsg(ca.chctx, mcid, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { log.Error(err) return err diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 41d7461a811..fea02651aa3 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -103,7 +103,7 @@ func (s SealingAPIAdapter) StateMinerSectorAllocated(ctx context.Context, maddr } func (s SealingAPIAdapter) StateWaitMsg(ctx context.Context, mcid cid.Cid) (sealing.MsgLookup, error) { - wmsg, err := s.delegate.StateWaitMsg(ctx, mcid, build.MessageConfidence) + wmsg, err := s.delegate.StateWaitMsg(ctx, mcid, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return sealing.MsgLookup{}, err } @@ -120,7 +120,7 @@ func (s SealingAPIAdapter) StateWaitMsg(ctx context.Context, mcid cid.Cid) (seal } func (s SealingAPIAdapter) StateSearchMsg(ctx context.Context, c cid.Cid) (*sealing.MsgLookup, error) { - wmsg, err := s.delegate.StateSearchMsg(ctx, c) + wmsg, err := s.delegate.StateSearchMsg(ctx, types.EmptyTSK, c, api.LookbackNoLimit, true) if err != nil { return nil, err } diff --git a/storage/miner.go b/storage/miner.go index 38552ddc9c7..ae0ac0bef1c 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -3,7 +3,7 @@ package storage import ( "context" "errors" - "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "time" "github.com/filecoin-project/go-state-types/network" @@ -84,10 +84,9 @@ type storageMinerApi interface { StateMinerPreCommitDepositForPower(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) StateMinerSectorAllocated(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error) - StateSearchMsg(context.Context, cid.Cid) (*api.MsgLookup, error) - StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) // TODO: removeme eventually + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) - StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) @@ -216,7 +215,7 @@ type StorageWpp struct { winnRpt abi.RegisteredPoStProof } -func NewWinningPoStProver(api v0api.FullNode, prover storage.Prover, verifier ffiwrapper.Verifier, miner dtypes.MinerID) (*StorageWpp, error) { +func NewWinningPoStProver(api v1api.FullNode, prover storage.Prover, verifier ffiwrapper.Verifier, miner dtypes.MinerID) (*StorageWpp, error) { ma, err := address.NewIDAddress(uint64(miner)) if err != nil { return nil, err diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index fd7c4f184be..4218daea1bd 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -313,7 +313,7 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uin log.Warnw("declare faults recovered Message CID", "cid", sm.Cid()) - rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence) + rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return recoveries, sm, xerrors.Errorf("declare faults recovered wait error: %w", err) } @@ -398,7 +398,7 @@ func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64, log.Warnw("declare faults Message CID", "cid", sm.Cid()) - rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence) + rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return faults, sm, xerrors.Errorf("declare faults wait error: %w", err) } @@ -787,7 +787,7 @@ func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.Submi log.Infof("Submitted window post: %s", sm.Cid()) go func() { - rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence) + rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { log.Error(err) return From eee50caaf1a5b877a32f8d06ab27750aef5d4f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 5 Apr 2021 20:12:47 +0200 Subject: [PATCH 25/60] Fix buildall --- Makefile | 7 +++++++ cmd/lotus-chainwatch/processor/miner.go | 4 ++-- cmd/lotus-chainwatch/processor/processor.go | 6 +++--- cmd/lotus-chainwatch/run.go | 4 ++-- cmd/lotus-chainwatch/syncer/sync.go | 6 +++--- cmd/lotus-chainwatch/util/api.go | 6 +++--- cmd/lotus-chainwatch/util/contextStore.go | 6 +++--- cmd/lotus-fountain/main.go | 4 ++-- cmd/lotus-health/main.go | 10 +++++----- cmd/tvx/extract_message.go | 5 +++-- cmd/tvx/main.go | 4 ++-- cmd/tvx/state.go | 8 ++++---- cmd/tvx/stores.go | 6 +++--- conformance/rand_record.go | 6 +++--- tools/stats/collect.go | 4 ++-- tools/stats/metrics.go | 8 ++++---- tools/stats/rpc.go | 11 ++++++----- 17 files changed, 57 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index 016e1e8741b..e2d4e37642b 100644 --- a/Makefile +++ b/Makefile @@ -233,6 +233,13 @@ testground: .PHONY: testground BINS+=testground + +tvx: + rm -f tvx + go build -o tvx ./cmd/tvx +.PHONY: tvx +BINS+=tvx + install-chainwatch: lotus-chainwatch install -C ./lotus-chainwatch /usr/local/bin/lotus-chainwatch diff --git a/cmd/lotus-chainwatch/processor/miner.go b/cmd/lotus-chainwatch/processor/miner.go index 5f2ef55dd19..f3514df88ce 100644 --- a/cmd/lotus-chainwatch/processor/miner.go +++ b/cmd/lotus-chainwatch/processor/miner.go @@ -14,7 +14,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/power" @@ -1026,7 +1026,7 @@ func (p *Processor) storeMinersPower(miners []minerActorInfo) error { } // load the power actor state clam as an adt.Map at the tipset `ts`. -func getPowerActorState(ctx context.Context, api api.FullNode, ts types.TipSetKey) (power.State, error) { +func getPowerActorState(ctx context.Context, api v0api.FullNode, ts types.TipSetKey) (power.State, error) { powerActor, err := api.StateGetActor(ctx, power.Address, ts) if err != nil { return nil, err diff --git a/cmd/lotus-chainwatch/processor/processor.go b/cmd/lotus-chainwatch/processor/processor.go index 8da6b08cc2b..af5935d4795 100644 --- a/cmd/lotus-chainwatch/processor/processor.go +++ b/cmd/lotus-chainwatch/processor/processor.go @@ -17,7 +17,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/types" cw_util "github.com/filecoin-project/lotus/cmd/lotus-chainwatch/util" "github.com/filecoin-project/lotus/lib/parmap" @@ -28,7 +28,7 @@ var log = logging.Logger("processor") type Processor struct { db *sql.DB - node api.FullNode + node v0api.FullNode ctxStore *cw_util.APIIpldStore genesisTs *types.TipSet @@ -52,7 +52,7 @@ type actorInfo struct { state string } -func NewProcessor(ctx context.Context, db *sql.DB, node api.FullNode, batch int) *Processor { +func NewProcessor(ctx context.Context, db *sql.DB, node v0api.FullNode, batch int) *Processor { ctxStore := cw_util.NewAPIIpldStore(ctx, node) return &Processor{ db: db, diff --git a/cmd/lotus-chainwatch/run.go b/cmd/lotus-chainwatch/run.go index 64f242755ab..aa417a8633e 100644 --- a/cmd/lotus-chainwatch/run.go +++ b/cmd/lotus-chainwatch/run.go @@ -3,6 +3,7 @@ package main import ( "database/sql" "fmt" + "github.com/filecoin-project/lotus/api/v0api" "net/http" _ "net/http/pprof" "os" @@ -15,7 +16,6 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/api" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/cmd/lotus-chainwatch/processor" "github.com/filecoin-project/lotus/cmd/lotus-chainwatch/scheduler" @@ -44,7 +44,7 @@ var runCmd = &cli.Command{ return err } - var api api.FullNode + var api v0api.FullNode var closer jsonrpc.ClientCloser var err error if tokenMaddr := cctx.String("api"); tokenMaddr != "" { diff --git a/cmd/lotus-chainwatch/syncer/sync.go b/cmd/lotus-chainwatch/syncer/sync.go index 37af9cce08c..b5e9c73d6f4 100644 --- a/cmd/lotus-chainwatch/syncer/sync.go +++ b/cmd/lotus-chainwatch/syncer/sync.go @@ -13,7 +13,7 @@ import ( "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" ) @@ -26,10 +26,10 @@ type Syncer struct { lookbackLimit uint64 headerLk sync.Mutex - node api.FullNode + node v0api.FullNode } -func NewSyncer(db *sql.DB, node api.FullNode, lookbackLimit uint64) *Syncer { +func NewSyncer(db *sql.DB, node v0api.FullNode, lookbackLimit uint64) *Syncer { return &Syncer{ db: db, node: node, diff --git a/cmd/lotus-chainwatch/util/api.go b/cmd/lotus-chainwatch/util/api.go index 57e75fe58e4..5b6b7529d0c 100644 --- a/cmd/lotus-chainwatch/util/api.go +++ b/cmd/lotus-chainwatch/util/api.go @@ -2,16 +2,16 @@ package util import ( "context" + "github.com/filecoin-project/lotus/api/v0api" "net/http" "github.com/filecoin-project/go-jsonrpc" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) -func GetFullNodeAPIUsingCredentials(ctx context.Context, listenAddr, token string) (api.FullNode, jsonrpc.ClientCloser, error) { +func GetFullNodeAPIUsingCredentials(ctx context.Context, listenAddr, token string) (v0api.FullNode, jsonrpc.ClientCloser, error) { parsedAddr, err := ma.NewMultiaddr(listenAddr) if err != nil { return nil, nil, err @@ -22,7 +22,7 @@ func GetFullNodeAPIUsingCredentials(ctx context.Context, listenAddr, token strin return nil, nil, err } - return client.NewFullNodeRPCV1(ctx, apiURI(addr), apiHeaders(token)) + return client.NewFullNodeRPCV0(ctx, apiURI(addr), apiHeaders(token)) } func apiURI(addr string) string { return "ws://" + addr + "/rpc/v0" diff --git a/cmd/lotus-chainwatch/util/contextStore.go b/cmd/lotus-chainwatch/util/contextStore.go index bd812581b13..c93f87f9b66 100644 --- a/cmd/lotus-chainwatch/util/contextStore.go +++ b/cmd/lotus-chainwatch/util/contextStore.go @@ -8,7 +8,7 @@ import ( "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" ) // TODO extract this to a common location in lotus and reuse the code @@ -16,10 +16,10 @@ import ( // APIIpldStore is required for AMT and HAMT access. type APIIpldStore struct { ctx context.Context - api api.FullNode + api v0api.FullNode } -func NewAPIIpldStore(ctx context.Context, api api.FullNode) *APIIpldStore { +func NewAPIIpldStore(ctx context.Context, api v0api.FullNode) *APIIpldStore { return &APIIpldStore{ ctx: ctx, api: api, diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index 79f08aa8392..7ac598d8e9a 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -15,7 +15,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" @@ -143,7 +143,7 @@ func prepFundsHtml(box *rice.Box) http.HandlerFunc { type handler struct { ctx context.Context - api api.FullNode + api v0api.FullNode from address.Address sendPerRequest types.FIL diff --git a/cmd/lotus-health/main.go b/cmd/lotus-health/main.go index e8a32a71946..b4146f71a77 100644 --- a/cmd/lotus-health/main.go +++ b/cmd/lotus-health/main.go @@ -3,6 +3,7 @@ package main import ( "context" "errors" + "github.com/filecoin-project/lotus/api/v0api" "os" "os/signal" "syscall" @@ -14,7 +15,6 @@ import ( "github.com/filecoin-project/go-jsonrpc" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" @@ -180,7 +180,7 @@ func checkWindow(window CidWindow, t int) bool { * returns a slice of slices of Cids * len of slice <= `t` - threshold */ -func updateWindow(ctx context.Context, a api.FullNode, w CidWindow, t int, r int, to time.Duration) (CidWindow, error) { +func updateWindow(ctx context.Context, a v0api.FullNode, w CidWindow, t int, r int, to time.Duration) (CidWindow, error) { head, err := getHead(ctx, a, r, to) if err != nil { return nil, err @@ -194,7 +194,7 @@ func updateWindow(ctx context.Context, a api.FullNode, w CidWindow, t int, r int * retries if API no available * returns tipset */ -func getHead(ctx context.Context, a api.FullNode, r int, t time.Duration) (*types.TipSet, error) { +func getHead(ctx context.Context, a v0api.FullNode, r int, t time.Duration) (*types.TipSet, error) { for i := 0; i < r; i++ { head, err := a.ChainHead(ctx) if err != nil && i == (r-1) { @@ -226,7 +226,7 @@ func appendCIDsToWindow(w CidWindow, c []cid.Cid, t int) CidWindow { /* * wait for node to sync */ -func waitForSyncComplete(ctx context.Context, a api.FullNode, r int, t time.Duration) error { +func waitForSyncComplete(ctx context.Context, a v0api.FullNode, r int, t time.Duration) error { for { select { case <-ctx.Done(): @@ -248,7 +248,7 @@ func waitForSyncComplete(ctx context.Context, a api.FullNode, r int, t time.Dura * A thin wrapper around lotus cli GetFullNodeAPI * Adds retry logic */ -func getFullNodeAPI(ctx *cli.Context, r int, t time.Duration) (api.FullNode, jsonrpc.ClientCloser, error) { +func getFullNodeAPI(ctx *cli.Context, r int, t time.Duration) (v0api.FullNode, jsonrpc.ClientCloser, error) { for i := 0; i < r; i++ { api, closer, err := lcli.GetFullNodeAPI(ctx) if err != nil && i == (r-1) { diff --git a/cmd/tvx/extract_message.go b/cmd/tvx/extract_message.go index 0c2fcff4a88..f29b39bb190 100644 --- a/cmd/tvx/extract_message.go +++ b/cmd/tvx/extract_message.go @@ -5,6 +5,7 @@ import ( "compress/gzip" "context" "fmt" + "github.com/filecoin-project/lotus/api/v0api" "io" "log" @@ -318,7 +319,7 @@ func doExtractMessage(opts extractOpts) error { // resolveFromChain queries the chain for the provided message, using the block CID to // speed up the query, if provided -func resolveFromChain(ctx context.Context, api api.FullNode, mcid cid.Cid, block string) (msg *types.Message, execTs *types.TipSet, incTs *types.TipSet, err error) { +func resolveFromChain(ctx context.Context, api v0api.FullNode, mcid cid.Cid, block string) (msg *types.Message, execTs *types.TipSet, incTs *types.TipSet, err error) { // Extract the full message. msg, err = api.ChainGetMessage(ctx, mcid) if err != nil { @@ -373,7 +374,7 @@ func resolveFromChain(ctx context.Context, api api.FullNode, mcid cid.Cid, block // as the previous tipset. In the context of vector generation, the target // tipset is the one where a message was executed, and the previous tipset is // the one where the message was included. -func fetchThisAndPrevTipset(ctx context.Context, api api.FullNode, target types.TipSetKey) (targetTs *types.TipSet, prevTs *types.TipSet, err error) { +func fetchThisAndPrevTipset(ctx context.Context, api v0api.FullNode, target types.TipSetKey) (targetTs *types.TipSet, prevTs *types.TipSet, err error) { // get the tipset on which this message was "executed" on. // https://github.com/filecoin-project/lotus/issues/2847 targetTs, err = api.ChainGetTipSet(ctx, target) diff --git a/cmd/tvx/main.go b/cmd/tvx/main.go index 94a656c3e87..0fed8fad4b1 100644 --- a/cmd/tvx/main.go +++ b/cmd/tvx/main.go @@ -9,13 +9,13 @@ import ( "github.com/filecoin-project/go-jsonrpc" "github.com/urfave/cli/v2" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" lcli "github.com/filecoin-project/lotus/cli" ) // FullAPI is a JSON-RPC client targeting a full node. It's initialized in a // cli.BeforeFunc. -var FullAPI api.FullNode +var FullAPI v0api.FullNode // Closer is the closer for the JSON-RPC client, which must be called on // cli.AfterFunc. diff --git a/cmd/tvx/state.go b/cmd/tvx/state.go index bff5cbd6ecb..a60ebac41b9 100644 --- a/cmd/tvx/state.go +++ b/cmd/tvx/state.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "github.com/filecoin-project/lotus/api/v0api" "io" "log" @@ -13,7 +14,6 @@ import ( "github.com/ipld/go-car" cbg "github.com/whyrusleeping/cbor-gen" - "github.com/filecoin-project/lotus/api" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" @@ -23,13 +23,13 @@ import ( // StateSurgeon is an object used to fetch and manipulate state. type StateSurgeon struct { ctx context.Context - api api.FullNode + api v0api.FullNode stores *Stores } // NewSurgeon returns a state surgeon, an object used to fetch and manipulate // state. -func NewSurgeon(ctx context.Context, api api.FullNode, stores *Stores) *StateSurgeon { +func NewSurgeon(ctx context.Context, api v0api.FullNode, stores *Stores) *StateSurgeon { return &StateSurgeon{ ctx: ctx, api: api, @@ -85,7 +85,7 @@ func (sg *StateSurgeon) GetMaskedStateTree(previousRoot cid.Cid, retain []addres // GetAccessedActors identifies the actors that were accessed during the // execution of a message. -func (sg *StateSurgeon) GetAccessedActors(ctx context.Context, a api.FullNode, mid cid.Cid) ([]address.Address, error) { +func (sg *StateSurgeon) GetAccessedActors(ctx context.Context, a v0api.FullNode, mid cid.Cid) ([]address.Address, error) { log.Printf("calculating accessed actors during execution of message: %s", mid) msgInfo, err := a.StateSearchMsg(ctx, mid) if err != nil { diff --git a/cmd/tvx/stores.go b/cmd/tvx/stores.go index 66445be70b2..0f90033ac6b 100644 --- a/cmd/tvx/stores.go +++ b/cmd/tvx/stores.go @@ -2,13 +2,13 @@ package main import ( "context" + "github.com/filecoin-project/lotus/api/v0api" "log" "sync" "github.com/fatih/color" dssync "github.com/ipfs/go-datastore/sync" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -40,7 +40,7 @@ type Stores struct { // NewProxyingStores is a set of Stores backed by a proxying Blockstore that // proxies Get requests for unknown CIDs to a Filecoin node, via the // ChainReadObj RPC. -func NewProxyingStores(ctx context.Context, api api.FullNode) *Stores { +func NewProxyingStores(ctx context.Context, api v0api.FullNode) *Stores { ds := dssync.MutexWrap(ds.NewMapDatastore()) bs := &proxyingBlockstore{ ctx: ctx, @@ -85,7 +85,7 @@ type TracingBlockstore interface { // a Filecoin node via JSON-RPC. type proxyingBlockstore struct { ctx context.Context - api api.FullNode + api v0api.FullNode lk sync.Mutex tracing bool diff --git a/conformance/rand_record.go b/conformance/rand_record.go index 6f6d064dc74..92a0b1a53a1 100644 --- a/conformance/rand_record.go +++ b/conformance/rand_record.go @@ -3,6 +3,7 @@ package conformance import ( "context" "fmt" + "github.com/filecoin-project/lotus/api/v0api" "sync" "github.com/filecoin-project/go-state-types/abi" @@ -10,14 +11,13 @@ import ( "github.com/filecoin-project/test-vectors/schema" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" ) type RecordingRand struct { reporter Reporter - api api.FullNode + api v0api.FullNode // once guards the loading of the head tipset. // can be removed when https://github.com/filecoin-project/lotus/issues/4223 @@ -33,7 +33,7 @@ var _ vm.Rand = (*RecordingRand)(nil) // NewRecordingRand returns a vm.Rand implementation that proxies calls to a // full Lotus node via JSON-RPC, and records matching rules and responses so // they can later be embedded in test vectors. -func NewRecordingRand(reporter Reporter, api api.FullNode) *RecordingRand { +func NewRecordingRand(reporter Reporter, api v0api.FullNode) *RecordingRand { return &RecordingRand{reporter: reporter, api: api} } diff --git a/tools/stats/collect.go b/tools/stats/collect.go index 221dc37e2c9..e33ec994b66 100644 --- a/tools/stats/collect.go +++ b/tools/stats/collect.go @@ -5,11 +5,11 @@ import ( "time" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" client "github.com/influxdata/influxdb1-client/v2" ) -func Collect(ctx context.Context, api api.FullNode, influx client.Client, database string, height int64, headlag int) { +func Collect(ctx context.Context, api v0api.FullNode, influx client.Client, database string, height int64, headlag int) { tipsetsCh, err := GetTips(ctx, api, abi.ChainEpoch(height), headlag) if err != nil { log.Fatal(err) diff --git a/tools/stats/metrics.go b/tools/stats/metrics.go index 795203c40a2..20377d496c7 100644 --- a/tools/stats/metrics.go +++ b/tools/stats/metrics.go @@ -5,13 +5,13 @@ import ( "context" "encoding/json" "fmt" + "github.com/filecoin-project/lotus/api/v0api" "math" "math/big" "strings" "time" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/actors/builtin/reward" @@ -115,7 +115,7 @@ func NewPointFrom(p models.Point) *client.Point { return client.NewPointFrom(p) } -func RecordTipsetPoints(ctx context.Context, api api.FullNode, pl *PointList, tipset *types.TipSet) error { +func RecordTipsetPoints(ctx context.Context, api v0api.FullNode, pl *PointList, tipset *types.TipSet) error { cids := []string{} for _, cid := range tipset.Cids() { cids = append(cids, cid.String()) @@ -238,7 +238,7 @@ func (ht *ApiIpldStore) Put(ctx context.Context, v interface{}) (cid.Cid, error) return cid.Undef, fmt.Errorf("Put is not implemented on ApiIpldStore") } -func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointList, tipset *types.TipSet) error { +func RecordTipsetStatePoints(ctx context.Context, api v0api.FullNode, pl *PointList, tipset *types.TipSet) error { attoFil := types.NewInt(build.FilecoinPrecision).Int //TODO: StatePledgeCollateral API is not implemented and is commented out - re-enable this block once the API is implemented again. @@ -299,7 +299,7 @@ type msgTag struct { exitcode uint8 } -func RecordTipsetMessagesPoints(ctx context.Context, api api.FullNode, pl *PointList, tipset *types.TipSet) error { +func RecordTipsetMessagesPoints(ctx context.Context, api v0api.FullNode, pl *PointList, tipset *types.TipSet) error { cids := tipset.Cids() if len(cids) == 0 { return fmt.Errorf("no cids in tipset") diff --git a/tools/stats/rpc.go b/tools/stats/rpc.go index cd3987ff1f1..fdd22ca9928 100644 --- a/tools/stats/rpc.go +++ b/tools/stats/rpc.go @@ -2,6 +2,7 @@ package stats import ( "context" + "github.com/filecoin-project/lotus/api/v0api" "net/http" "time" @@ -45,7 +46,7 @@ func getAPI(path string) (string, http.Header, error) { return "ws://" + addr + "/rpc/v0", headers, nil } -func WaitForSyncComplete(ctx context.Context, napi api.FullNode) error { +func WaitForSyncComplete(ctx context.Context, napi v0api.FullNode) error { sync_complete: for { select { @@ -120,7 +121,7 @@ sync_complete: } } -func GetTips(ctx context.Context, api api.FullNode, lastHeight abi.ChainEpoch, headlag int) (<-chan *types.TipSet, error) { +func GetTips(ctx context.Context, api v0api.FullNode, lastHeight abi.ChainEpoch, headlag int) (<-chan *types.TipSet, error) { chmain := make(chan *types.TipSet) hb := newHeadBuffer(headlag) @@ -184,7 +185,7 @@ func GetTips(ctx context.Context, api api.FullNode, lastHeight abi.ChainEpoch, h return chmain, nil } -func loadTipsets(ctx context.Context, api api.FullNode, curr *types.TipSet, lowestHeight abi.ChainEpoch) ([]*types.TipSet, error) { +func loadTipsets(ctx context.Context, api v0api.FullNode, curr *types.TipSet, lowestHeight abi.ChainEpoch) ([]*types.TipSet, error) { tipsets := []*types.TipSet{} for { if curr.Height() == 0 { @@ -214,11 +215,11 @@ func loadTipsets(ctx context.Context, api api.FullNode, curr *types.TipSet, lowe return tipsets, nil } -func GetFullNodeAPI(ctx context.Context, repo string) (api.FullNode, jsonrpc.ClientCloser, error) { +func GetFullNodeAPI(ctx context.Context, repo string) (v0api.FullNode, jsonrpc.ClientCloser, error) { addr, headers, err := getAPI(repo) if err != nil { return nil, nil, err } - return client.NewFullNodeRPCV1(ctx, addr, headers) + return client.NewFullNodeRPCV0(ctx, addr, headers) } From e8f28d7b9ffe26e39523adaa3933c169aff1c02b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 5 Apr 2021 21:34:03 +0200 Subject: [PATCH 26/60] Fix tests --- api/client/client.go | 4 ++-- api/test/paych.go | 6 +++--- api/test/test.go | 10 +++++----- api/test/util.go | 3 ++- api/test/window_post.go | 6 +++--- api/v0api/v1_wrapper.go | 7 +++---- api/wrap.go | 2 +- chain/market/fundmanager_test.go | 2 +- chain/sync_test.go | 8 ++++---- cli/services_send_test.go | 2 +- cli/util/api.go | 4 ++-- cmd/chain-noise/main.go | 4 ++-- cmd/lotus-gateway/endtoend_test.go | 17 +++++++++++------ node/test/builder.go | 27 +++++++++++++++++++-------- paychmgr/mock_test.go | 3 ++- storage/wdpost_run_test.go | 4 ++-- 16 files changed, 63 insertions(+), 46 deletions(-) diff --git a/api/client/client.go b/api/client/client.go index 1b49aae78df..0165bcbd8b3 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -96,8 +96,8 @@ func NewWorkerRPCV0(ctx context.Context, addr string, requestHeader http.Header) return &res, closer, err } -// NewGatewayRPCV0 creates a new http jsonrpc client for a gateway node. -func NewGatewayRPCV0(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.Gateway, jsonrpc.ClientCloser, error) { +// NewGatewayRPCV1 creates a new http jsonrpc client for a gateway node. +func NewGatewayRPCV1(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.Gateway, jsonrpc.ClientCloser, error) { var res api.GatewayStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ diff --git a/api/test/paych.go b/api/test/paych.go index b38ba6189f3..93a083c4a8c 100644 --- a/api/test/paych.go +++ b/api/test/paych.go @@ -235,7 +235,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { if err != nil { t.Fatal(err) } - res, err = paymentReceiver.StateWaitMsg(ctx, collectMsg, 3) + res, err = paymentReceiver.StateWaitMsg(ctx, collectMsg, 3, api.LookbackNoLimit, true) if err != nil { t.Fatal(err) } @@ -287,7 +287,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentRec t.Fatal(err) } - _, err = paymentReceiver.StateWaitMsg(ctx, m.Cid(), 1) + _, err = paymentReceiver.StateWaitMsg(ctx, m.Cid(), 1, api.LookbackNoLimit, true) if err != nil { t.Fatal(err) } @@ -299,7 +299,7 @@ func waitForMessage(ctx context.Context, t *testing.T, paymentCreator TestNode, defer cancel() fmt.Println("Waiting for", desc) - res, err := paymentCreator.StateWaitMsg(ctx, msgCid, 1) + res, err := paymentCreator.StateWaitMsg(ctx, msgCid, 1, api.LookbackNoLimit, true) if err != nil { fmt.Println("Error waiting for", desc, err) t.Fatal(err) diff --git a/api/test/test.go b/api/test/test.go index aaaf55b8b44..e5edcbe3b0b 100644 --- a/api/test/test.go +++ b/api/test/test.go @@ -21,7 +21,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/api" + lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node" @@ -44,7 +44,7 @@ type TestNode struct { } type TestStorageNode struct { - api.StorageMiner + lapi.StorageMiner // ListenAddr is the address on which an API server is listening, if an // API server is created for this Node ListenAddr multiaddr.Multiaddr @@ -156,7 +156,7 @@ var MineNext = miner.MineReq{ } func (ts *testSuite) testVersion(t *testing.T) { - api.RunningNodeType = api.NodeFull + lapi.RunningNodeType = lapi.NodeFull ctx := context.Background() apis, _ := ts.makeNodes(t, OneFull, OneMiner) @@ -197,7 +197,7 @@ func (ts *testSuite) testSearchMsg(t *testing.T) { if err != nil { t.Fatal(err) } - res, err := api.StateWaitMsg(ctx, sm.Cid(), 1) + res, err := api.StateWaitMsg(ctx, sm.Cid(), 1, lapi.LookbackNoLimit, true) if err != nil { t.Fatal(err) } @@ -205,7 +205,7 @@ func (ts *testSuite) testSearchMsg(t *testing.T) { t.Fatal("did not successfully send message") } - searchRes, err := api.StateSearchMsg(ctx, sm.Cid()) + searchRes, err := api.StateSearchMsg(ctx, types.EmptyTSK, sm.Cid(), lapi.LookbackNoLimit, true) if err != nil { t.Fatal(err) } diff --git a/api/test/util.go b/api/test/util.go index 8695e2e2efb..f571b48da5d 100644 --- a/api/test/util.go +++ b/api/test/util.go @@ -8,6 +8,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-address" + lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/miner" ) @@ -28,7 +29,7 @@ func SendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address. if err != nil { t.Fatal(err) } - res, err := sender.StateWaitMsg(ctx, sm.Cid(), 1) + res, err := sender.StateWaitMsg(ctx, sm.Cid(), 1, lapi.LookbackNoLimit, true) if err != nil { t.Fatal(err) } diff --git a/api/test/window_post.go b/api/test/window_post.go index ce42318b2b2..fec7e0d731c 100644 --- a/api/test/window_post.go +++ b/api/test/window_post.go @@ -766,7 +766,7 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration) require.NoError(t, err) fmt.Println("waiting dispute") - rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence) + rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) require.NoError(t, err) require.Zero(t, rec.Receipt.ExitCode, "dispute not accepted: %s", rec.Receipt.ExitCode.Error()) } @@ -807,7 +807,7 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration) sm, err := client.MpoolPushMessage(ctx, msg, nil) require.NoError(t, err) - rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence) + rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) require.NoError(t, err) require.Zero(t, rec.Receipt.ExitCode, "recovery not accepted: %s", rec.Receipt.ExitCode.Error()) } @@ -886,7 +886,7 @@ func submitBadProof( return err } - rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence) + rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return err } diff --git a/api/v0api/v1_wrapper.go b/api/v0api/v1_wrapper.go index 091ec2fdf07..bb33fa12aa4 100644 --- a/api/v0api/v1_wrapper.go +++ b/api/v0api/v1_wrapper.go @@ -11,7 +11,6 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/v1api" - "github.com/filecoin-project/lotus/chain/stmgr" ) type WrapperV1Full struct { @@ -19,7 +18,7 @@ type WrapperV1Full struct { } func (w *WrapperV1Full) StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) { - return w.FullNode.StateSearchMsg(ctx, types.EmptyTSK, msg, stmgr.LookbackNoLimit, true) + return w.FullNode.StateSearchMsg(ctx, types.EmptyTSK, msg, api.LookbackNoLimit, true) } func (w *WrapperV1Full) StateSearchMsgLimited(ctx context.Context, msg cid.Cid, limit abi.ChainEpoch) (*api.MsgLookup, error) { @@ -27,7 +26,7 @@ func (w *WrapperV1Full) StateSearchMsgLimited(ctx context.Context, msg cid.Cid, } func (w *WrapperV1Full) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) { - return w.FullNode.StateWaitMsg(ctx, msg, confidence, stmgr.LookbackNoLimit, true) + return w.FullNode.StateWaitMsg(ctx, msg, confidence, api.LookbackNoLimit, true) } func (w *WrapperV1Full) StateWaitMsgLimited(ctx context.Context, msg cid.Cid, confidence uint64, limit abi.ChainEpoch) (*api.MsgLookup, error) { @@ -35,7 +34,7 @@ func (w *WrapperV1Full) StateWaitMsgLimited(ctx context.Context, msg cid.Cid, co } func (w *WrapperV1Full) StateGetReceipt(ctx context.Context, msg cid.Cid, from types.TipSetKey) (*types.MessageReceipt, error) { - ml, err := w.FullNode.StateSearchMsg(ctx, from, msg, stmgr.LookbackNoLimit, true) + ml, err := w.FullNode.StateSearchMsg(ctx, from, msg, api.LookbackNoLimit, true) if err != nil { return nil, err } diff --git a/api/wrap.go b/api/wrap.go index 09f103e0c16..1ded6713296 100644 --- a/api/wrap.go +++ b/api/wrap.go @@ -14,7 +14,7 @@ func Wrap(proxyT, wrapperT, impl interface{}) interface{} { for i := 0; i < ri.NumMethod(); i++ { mt := ri.Type().Method(i) - if proxyMethods.FieldByName(mt.Name).IsZero() { + if proxyMethods.FieldByName(mt.Name).Kind() == reflect.Invalid { continue } diff --git a/chain/market/fundmanager_test.go b/chain/market/fundmanager_test.go index ac6b2a405c0..12530434311 100644 --- a/chain/market/fundmanager_test.go +++ b/chain/market/fundmanager_test.go @@ -793,7 +793,7 @@ func (mapi *mockFundManagerAPI) publish(addr address.Address, amt abi.TokenAmoun mapi.escrow[addr] = escrow } -func (mapi *mockFundManagerAPI) StateWaitMsg(ctx context.Context, c cid.Cid, confidence uint64) (*api.MsgLookup, error) { +func (mapi *mockFundManagerAPI) StateWaitMsg(ctx context.Context, c cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { res := &api.MsgLookup{ Message: c, Receipt: types.MessageReceipt{ diff --git a/chain/sync_test.go b/chain/sync_test.go index 9570eda328f..c7cd66a8e67 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -622,17 +622,17 @@ func TestDuplicateNonce(t *testing.T) { var includedMsg cid.Cid var skippedMsg cid.Cid - r0, err0 := tu.nds[0].StateGetReceipt(context.TODO(), msgs[0][0].Cid(), ts2.TipSet().Key()) - r1, err1 := tu.nds[0].StateGetReceipt(context.TODO(), msgs[1][0].Cid(), ts2.TipSet().Key()) + r0, err0 := tu.nds[0].StateSearchMsg(context.TODO(), ts2.TipSet().Key(), msgs[0][0].Cid(), api.LookbackNoLimit, true) + r1, err1 := tu.nds[0].StateSearchMsg(context.TODO(), ts2.TipSet().Key(), msgs[1][0].Cid(), api.LookbackNoLimit, true) if err0 == nil { require.Error(t, err1, "at least one of the StateGetReceipt calls should fail") - require.True(t, r0.ExitCode.IsSuccess()) + require.True(t, r0.Receipt.ExitCode.IsSuccess()) includedMsg = msgs[0][0].Message.Cid() skippedMsg = msgs[1][0].Message.Cid() } else { require.NoError(t, err1, "both the StateGetReceipt calls should not fail") - require.True(t, r1.ExitCode.IsSuccess()) + require.True(t, r1.Receipt.ExitCode.IsSuccess()) includedMsg = msgs[1][0].Message.Cid() skippedMsg = msgs[0][0].Message.Cid() } diff --git a/cli/services_send_test.go b/cli/services_send_test.go index 9dfc3b38a5f..713e81b2a24 100644 --- a/cli/services_send_test.go +++ b/cli/services_send_test.go @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/mocks" + mocks "github.com/filecoin-project/lotus/api/v0api/v0mocks" types "github.com/filecoin-project/lotus/chain/types" gomock "github.com/golang/mock/gomock" cid "github.com/ipfs/go-cid" diff --git a/cli/util/api.go b/cli/util/api.go index 998d1e7603e..38ff5efeda6 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -177,7 +177,7 @@ func GetAPI(ctx *cli.Context) (api.Common, jsonrpc.ClientCloser, error) { func GetFullNodeAPI(ctx *cli.Context) (v0api.FullNode, jsonrpc.ClientCloser, error) { if tn, ok := ctx.App.Metadata["testnode-full"]; ok { - return tn.(v0api.FullNode), func() {}, nil + return &v0api.WrapperV1Full{FullNode: tn.(v1api.FullNode)}, func() {}, nil } addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v0") @@ -260,7 +260,7 @@ func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) return nil, nil, err } - return client.NewGatewayRPCV0(ctx.Context, addr, headers) + return client.NewGatewayRPCV1(ctx.Context, addr, headers) } func DaemonContext(cctx *cli.Context) context.Context { diff --git a/cmd/chain-noise/main.go b/cmd/chain-noise/main.go index 37d623ce2af..8106ce592b2 100644 --- a/cmd/chain-noise/main.go +++ b/cmd/chain-noise/main.go @@ -8,7 +8,7 @@ import ( "time" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" @@ -72,7 +72,7 @@ var runCmd = &cli.Command{ }, } -func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Address, rate, limit int) error { +func sendSmallFundsTxs(ctx context.Context, api v0api.FullNode, from address.Address, rate, limit int) error { var sendSet []address.Address for i := 0; i < 20; i++ { naddr, err := api.WalletNew(ctx, types.KTSecp256k1) diff --git a/cmd/lotus-gateway/endtoend_test.go b/cmd/lotus-gateway/endtoend_test.go index f575c577626..084218b249c 100644 --- a/cmd/lotus-gateway/endtoend_test.go +++ b/cmd/lotus-gateway/endtoend_test.go @@ -24,6 +24,8 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/api/test" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" @@ -103,7 +105,7 @@ func TestWalletMsig(t *testing.T) { addProposal, err := lite.MsigCreate(ctx, 2, msigAddrs, abi.ChainEpoch(50), amt, liteWalletAddr, types.NewInt(0)) require.NoError(t, err) - res, err := lite.StateWaitMsg(ctx, addProposal, 1) + res, err := lite.StateWaitMsg(ctx, addProposal, 1, api.LookbackNoLimit, true) require.NoError(t, err) require.EqualValues(t, 0, res.Receipt.ExitCode) @@ -123,7 +125,7 @@ func TestWalletMsig(t *testing.T) { addProposal, err = lite.MsigAddPropose(ctx, msig, walletAddrs[0], walletAddrs[3], false) require.NoError(t, err) - res, err = lite.StateWaitMsg(ctx, addProposal, 1) + res, err = lite.StateWaitMsg(ctx, addProposal, 1, api.LookbackNoLimit, true) require.NoError(t, err) require.EqualValues(t, 0, res.Receipt.ExitCode) @@ -137,7 +139,7 @@ func TestWalletMsig(t *testing.T) { approval1, err := lite.MsigAddApprove(ctx, msig, walletAddrs[1], txnID, walletAddrs[0], walletAddrs[3], false) require.NoError(t, err) - res, err = lite.StateWaitMsg(ctx, approval1, 1) + res, err = lite.StateWaitMsg(ctx, approval1, 1, api.LookbackNoLimit, true) require.NoError(t, err) require.EqualValues(t, 0, res.Receipt.ExitCode) @@ -245,12 +247,15 @@ func startNodes( // Create a gateway server in front of the full node gapiImpl := newGatewayAPI(fullNode, lookbackCap, stateWaitLookbackLimit) - _, addr, err := builder.CreateRPCServer(t, gapiImpl) + _, addr, err := builder.CreateRPCServer(t, map[string]interface{}{ + "/rpc/v1": gapiImpl, + "/rpc/v0": api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), gapiImpl), + }) require.NoError(t, err) // Create a gateway client API that connects to the gateway server var gapi api.Gateway - gapi, closer, err = client.NewGatewayRPCV0(ctx, addr, nil) + gapi, closer, err = client.NewGatewayRPCV1(ctx, addr+"/rpc/v1", nil) require.NoError(t, err) // Provide the gateway API to dependency injection @@ -299,7 +304,7 @@ func sendFunds(ctx context.Context, fromNode test.TestNode, fromAddr address.Add return err } - res, err := fromNode.StateWaitMsg(ctx, sm.Cid(), 1) + res, err := fromNode.StateWaitMsg(ctx, sm.Cid(), 1, api.LookbackNoLimit, true) if err != nil { return err } diff --git a/node/test/builder.go b/node/test/builder.go index 8a887f55d27..497591cdec5 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/gorilla/mux" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -22,6 +23,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/api/test" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain" @@ -501,12 +503,15 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes } func fullRpc(t *testing.T, nd test.TestNode) test.TestNode { - ma, listenAddr, err := CreateRPCServer(t, nd) + ma, listenAddr, err := CreateRPCServer(t, map[string]interface{}{ + "/rpc/v1": nd, + "/rpc/v0": &v0api.WrapperV1Full{FullNode: nd}, + }) require.NoError(t, err) var stop func() var full test.TestNode - full.FullNode, stop, err = client.NewFullNodeRPCV1(context.Background(), listenAddr, nil) + full.FullNode, stop, err = client.NewFullNodeRPCV1(context.Background(), listenAddr+"/rpc/v1", nil) require.NoError(t, err) t.Cleanup(stop) @@ -515,12 +520,14 @@ func fullRpc(t *testing.T, nd test.TestNode) test.TestNode { } func storerRpc(t *testing.T, nd test.TestStorageNode) test.TestStorageNode { - ma, listenAddr, err := CreateRPCServer(t, nd) + ma, listenAddr, err := CreateRPCServer(t, map[string]interface{}{ + "/rpc/v0": nd, + }) require.NoError(t, err) var stop func() var storer test.TestStorageNode - storer.StorageMiner, stop, err = client.NewStorageMinerRPCV0(context.Background(), listenAddr, nil) + storer.StorageMiner, stop, err = client.NewStorageMinerRPCV0(context.Background(), listenAddr+"/rpc/v0", nil) require.NoError(t, err) t.Cleanup(stop) @@ -529,10 +536,14 @@ func storerRpc(t *testing.T, nd test.TestStorageNode) test.TestStorageNode { return storer } -func CreateRPCServer(t *testing.T, handler interface{}) (multiaddr.Multiaddr, string, error) { - rpcServer := jsonrpc.NewServer() - rpcServer.Register("Filecoin", handler) - testServ := httptest.NewServer(rpcServer) // todo: close +func CreateRPCServer(t *testing.T, handlers map[string]interface{}) (multiaddr.Multiaddr, string, error) { + m := mux.NewRouter() + for path, handler := range handlers { + rpcServer := jsonrpc.NewServer() + rpcServer.Register("Filecoin", handler) + m.Handle(path, rpcServer) + } + testServ := httptest.NewServer(m) // todo: close t.Cleanup(testServ.Close) t.Cleanup(testServ.CloseClientConnections) diff --git a/paychmgr/mock_test.go b/paychmgr/mock_test.go index 3393a3072e8..2c891803bcd 100644 --- a/paychmgr/mock_test.go +++ b/paychmgr/mock_test.go @@ -8,6 +8,7 @@ import ( "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/network" @@ -132,7 +133,7 @@ func newMockPaychAPI() *mockPaychAPI { } } -func (pchapi *mockPaychAPI) StateWaitMsg(ctx context.Context, mcid cid.Cid, confidence uint64) (*api.MsgLookup, error) { +func (pchapi *mockPaychAPI) StateWaitMsg(ctx context.Context, mcid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { pchapi.lk.Lock() response := make(chan types.MessageReceipt) diff --git a/storage/wdpost_run_test.go b/storage/wdpost_run_test.go index 4bf30e3e990..6a55bad1fc5 100644 --- a/storage/wdpost_run_test.go +++ b/storage/wdpost_run_test.go @@ -92,7 +92,7 @@ func (m *mockStorageMinerAPI) MpoolPushMessage(ctx context.Context, message *typ }, nil } -func (m *mockStorageMinerAPI) StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) { +func (m *mockStorageMinerAPI) StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { return &api.MsgLookup{ Receipt: types.MessageReceipt{ ExitCode: 0, @@ -311,7 +311,7 @@ func (m *mockStorageMinerAPI) StateMinerInitialPledgeCollateral(ctx context.Cont panic("implement me") } -func (m *mockStorageMinerAPI) StateSearchMsg(ctx context.Context, cid cid.Cid) (*api.MsgLookup, error) { +func (m *mockStorageMinerAPI) StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { panic("implement me") } From c3736f40fe571b7121cbcf0ee93358d50035b3cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 6 Apr 2021 12:29:11 +0200 Subject: [PATCH 27/60] gateway: use correct path in serveRpc --- cmd/lotus-gateway/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-gateway/main.go b/cmd/lotus-gateway/main.go index 0546896902d..698eefb9af2 100644 --- a/cmd/lotus-gateway/main.go +++ b/cmd/lotus-gateway/main.go @@ -104,7 +104,7 @@ var runCmd = &cli.Command{ rpcServer := jsonrpc.NewServer(serverOptions...) rpcServer.Register("Filecoin", hnd) - mux.Handle("/rpc/v1", rpcServer) + mux.Handle(path, rpcServer) } ma := metrics.MetricedGatewayAPI(NewGatewayAPI(api)) From a5921a9bf947e3dd0e6fce8c6d0244e3cfe66f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 6 Apr 2021 12:36:32 +0200 Subject: [PATCH 28/60] fix lotus-soup build --- testplans/lotus-soup/deals_e2e.go | 2 +- testplans/lotus-soup/go.mod | 2 +- testplans/lotus-soup/go.sum | 73 ++++++++++++++----- testplans/lotus-soup/paych/stress.go | 5 +- testplans/lotus-soup/rfwp/chain_state.go | 3 +- testplans/lotus-soup/rfwp/html_chain_state.go | 3 +- testplans/lotus-soup/testkit/deals.go | 3 +- testplans/lotus-soup/testkit/node.go | 3 +- 8 files changed, 67 insertions(+), 27 deletions(-) diff --git a/testplans/lotus-soup/deals_e2e.go b/testplans/lotus-soup/deals_e2e.go index ee7b2c9e86e..234754ae9a7 100644 --- a/testplans/lotus-soup/deals_e2e.go +++ b/testplans/lotus-soup/deals_e2e.go @@ -158,7 +158,7 @@ func initPaymentChannel(t *testkit.TestEnvironment, ctx context.Context, cl *tes t.RecordMessage("waiting for payment channel message to appear on chain") // wait for the channel creation message to appear on chain. - _, err = cl.FullApi.StateWaitMsg(ctx, channel.WaitSentinel, 2) + _, err = cl.FullApi.StateWaitMsg(ctx, channel.WaitSentinel, 2, api.LookbackNoLimit, true) if err != nil { return fmt.Errorf("failed while waiting for payment channel creation msg to appear on chain: %w", err) } diff --git a/testplans/lotus-soup/go.mod b/testplans/lotus-soup/go.mod index 918b1f508d2..f4b8687dce0 100644 --- a/testplans/lotus-soup/go.mod +++ b/testplans/lotus-soup/go.mod @@ -8,7 +8,7 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/drand/drand v1.2.1 github.com/filecoin-project/go-address v0.0.5 - github.com/filecoin-project/go-fil-markets v1.1.9 + github.com/filecoin-project/go-fil-markets v1.2.4 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-state-types v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b diff --git a/testplans/lotus-soup/go.sum b/testplans/lotus-soup/go.sum index 67eb30cba59..458cac48631 100644 --- a/testplans/lotus-soup/go.sum +++ b/testplans/lotus-soup/go.sum @@ -46,8 +46,13 @@ github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee h1:8doiS7ib3zi6/K1 github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee/go.mod h1:W0GbEAA4uFNYOGG2cJpmFJ04E6SD1NLELPYZB57/7AY= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= @@ -63,6 +68,7 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +github.com/alecthomas/jsonschema v0.0.0-20200530073317-71f438968921/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -146,6 +152,7 @@ github.com/cockroachdb/pebble v0.0.0-20201001221639-879f3bfeef07/go.mod h1:hU7vh github.com/cockroachdb/redact v0.0.0-20200622112456-cd282804bbd3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/codeskyblue/go-sh v0.0.0-20200712050446-30169cf553fe h1:69JI97HlzP+PH5Mi1thcGlDoBr6PS2Oe+l3mNmAkbs4= @@ -165,6 +172,7 @@ github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7 github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -236,6 +244,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etclabscore/go-jsonschema-walk v0.0.6/go.mod h1:VdfDY72AFAiUhy0ZXEaWSpveGjMT5JcDIm903NGqFwQ= +github.com/etclabscore/go-openrpc-reflect v0.0.36/go.mod h1:0404Ky3igAasAOpyj1eESjstTyneBAIk5PgJFbK4s5E= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -252,24 +262,27 @@ github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349/ github.com/filecoin-project/go-amt-ipld/v3 v3.0.0 h1:Ou/q82QeHGOhpkedvaxxzpBYuqTxLCcj5OChkDNx4qc= github.com/filecoin-project/go-amt-ipld/v3 v3.0.0/go.mod h1:Qa95YNAbtoVCTSVtX38aAC1ptBnJfPma1R/zZsKmx4o= github.com/filecoin-project/go-bitfield v0.2.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= -github.com/filecoin-project/go-bitfield v0.2.3 h1:pedK/7maYF06Z+BYJf2OeFFqIDEh6SP6mIOlLFpYXGs= github.com/filecoin-project/go-bitfield v0.2.3/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-bitfield v0.2.4 h1:uZ7MeE+XfM5lqrHJZ93OnhQKc/rveW8p9au0C68JPgk= github.com/filecoin-project/go-bitfield v0.2.4/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg= -github.com/filecoin-project/go-commp-utils v0.0.0-20201119054358-b88f7a96a434 h1:0kHszkYP3hgApcjl5x4rpwONhN9+j7XDobf6at5XfHs= github.com/filecoin-project/go-commp-utils v0.0.0-20201119054358-b88f7a96a434/go.mod h1:6s95K91mCyHY51RPWECZieD3SGWTqIFLf1mPOes9l5U= +github.com/filecoin-project/go-commp-utils v0.1.0 h1:PaDxoXYh1TXnnz5kA/xSObpAQwcJSUs4Szb72nuaNdk= +github.com/filecoin-project/go-commp-utils v0.1.0/go.mod h1:6s95K91mCyHY51RPWECZieD3SGWTqIFLf1mPOes9l5U= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= +github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= +github.com/filecoin-project/go-data-transfer v1.4.1 h1:4GoMGEdMeDLqbKR74Q5ceZTN35nv+66JZERqQ+SjxWU= +github.com/filecoin-project/go-data-transfer v1.4.1/go.mod h1:n8kbDQXWrY1c4UgfMa9KERxNCWbOTDwdNhf2MpN9dpo= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.1.9 h1:sA0NIEOpy7brZaeXeNgdXg5pvHaBtD5OTRlraOUbI0w= -github.com/filecoin-project/go-fil-markets v1.1.9/go.mod h1:0yQu5gvrjFoAIyzPSSJ+xUdCG83vjInAFbTswIB5/hk= +github.com/filecoin-project/go-fil-markets v1.2.4 h1:AcNMy/XGvSdv4GjuVoeqe67Q7OvppkSx1zWEGqVHixg= +github.com/filecoin-project/go-fil-markets v1.2.4/go.mod h1:8WEpiMkwdvtHb5dXmRIWX4vz4XjkVlhxRdHJdouV1b0= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= @@ -292,12 +305,11 @@ github.com/filecoin-project/go-state-types v0.1.0 h1:9r2HCSMMCmyMfGyMKxQtv0GKp6V github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= -github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ= github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= +github.com/filecoin-project/go-statestore v0.1.1 h1:ufMFq00VqnT2CAuDpcGnwLnCX1I/c3OROw/kXVNSTZk= +github.com/filecoin-project/go-statestore v0.1.1/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= -github.com/filecoin-project/lotus v1.5.2 h1:JXMTx9HYJ1G/sRPceNs4ZmGtYra5qpD22f3qDr2i0Zc= -github.com/filecoin-project/lotus v1.5.2/go.mod h1:ogeUSGizrAVxRbETP7Xe2muIXvxSyf+OfIb0kS4q3DQ= github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.12/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= github.com/filecoin-project/specs-actors v0.9.13 h1:rUEOQouefi9fuVY/2HOroROJlZbOzWYXXeIh41KF2M4= @@ -345,6 +357,17 @@ github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/spec v0.19.7/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.11/go.mod h1:vqK/dIdLGCosfvYsQV3WfC7N3TiZSnGY2RZKoFK7X28= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.8/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY= github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4= github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -384,6 +407,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -504,7 +528,10 @@ github.com/huin/goupnp v0.0.0-20180415215157-1395d1447324/go.mod h1:MZ2ZmwcBpvOo github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= +github.com/iancoleman/orderedmap v0.1.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8= @@ -529,7 +556,6 @@ github.com/ipfs/go-bitswap v0.1.8/go.mod h1:TOWoxllhccevbWFUR2N7B1MTSVVge1s6XSMi github.com/ipfs/go-bitswap v0.3.2 h1:TdKx7lpidYe2dMAKfdeNS26y6Pc/AZX/i8doI1GV210= github.com/ipfs/go-bitswap v0.3.2/go.mod h1:AyWWfN3moBzQX0banEtfKOfbXb3ZeoOeXnZGNPV9S6w= github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= -github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= @@ -588,9 +614,8 @@ github.com/ipfs/go-filestore v1.0.0/go.mod h1:/XOCuNtIe2f1YPbiXdYvD0BKLA0JR1MgPi github.com/ipfs/go-fs-lock v0.0.6 h1:sn3TWwNVQqSeNjlWy6zQ1uUGAZrV3hPOyEA6y1/N2a0= github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28L7zESmM= github.com/ipfs/go-graphsync v0.1.0/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE= +github.com/ipfs/go-graphsync v0.4.2/go.mod h1:/VmbZTUdUMTbNkgzAiCEucIIAU3BkLE2cZrDCVUhyi0= github.com/ipfs/go-graphsync v0.4.3/go.mod h1:mPOwDYv128gf8gxPFgXnz4fNrSYPsWyqisJ7ych+XDY= -github.com/ipfs/go-graphsync v0.5.2 h1:USD+daaSC+7pLHCxROThSaF6SF7WYXF03sjrta0rCfA= -github.com/ipfs/go-graphsync v0.5.2/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-graphsync v0.6.0 h1:x6UvDUGA7wjaKNqx5Vbo7FGT8aJ5ryYA0dMQ5jN3dF0= github.com/ipfs/go-graphsync v0.6.0/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-hamt-ipld v0.1.1/go.mod h1:1EZCr2v0jlCnhpa+aZ0JZYp8Tt2w16+JJOAVz17YcDk= @@ -739,6 +764,7 @@ github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1 h1:qBCV/RLV02TSfQa7tFmxTihnG+u+7JXByOkhlkR5rmQ= github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -786,7 +812,6 @@ github.com/kpacha/opencensus-influxdb v0.0.0-20181102202715-663e2683a27c/go.mod github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -1120,6 +1145,10 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI= github.com/marten-seemann/qpack v0.2.0/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= @@ -1258,14 +1287,13 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy8ALwOebjekYExl9HTT9urdawqC95tA= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= -github.com/nonsense/go-data-transfer v0.0.2 h1:WmkpzXYsGFeNTCpuEtJXJauT0qehWJsKITWWqTOFDzE= -github.com/nonsense/go-data-transfer v0.0.2/go.mod h1:n8kbDQXWrY1c4UgfMa9KERxNCWbOTDwdNhf2MpN9dpo= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -1289,6 +1317,7 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333/go.mod h1:Ag6rSXkHIckQmjFBCweJEEt1mrTPBv8b9W4aU/NQWfI= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= @@ -1468,11 +1497,13 @@ github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3 github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -1485,6 +1516,9 @@ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cb github.com/testground/sdk-go v0.2.6 h1:sMwv0/caNNODKfdPigNqmSSIZLcse7pZX6fgrjCGBIs= github.com/testground/sdk-go v0.2.6/go.mod h1:Q4dnWsUBH+dZ1u7aEGDBHWGUaLfhitjUq3UJQqxeTmk= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= +github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tj/go-spin v1.1.0 h1:lhdWZsvImxvZ3q1C5OIB7d72DuOwP4O2NdBg9PyzNds= github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= @@ -1532,7 +1566,6 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200806213330-63aa96ca5488/go.mod h1:f github.com/whyrusleeping/cbor-gen v0.0.0-20200810223238-211df3b9e24c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200812213548-958ddffe352c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= -github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2 h1:7HzUKl5d/dELS9lLeT4W6YvliZx+s9k/eOOIdHKrA/w= github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 h1:bsUlNhdmbtlfdLVXAVfuvKQ01RnWAM09TVrJkI7NZs4= github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= @@ -1738,13 +1771,15 @@ golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201022231255-08b38378de70 h1:Z6x4N9mAi4oF0TbHweCsH618MO6OI6UFgV0FP5n0wBY= +golang.org/x/net v0.0.0-20201022231255-08b38378de70/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1832,7 +1867,6 @@ golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200812155832-6a926be9bd1d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1877,6 +1911,7 @@ golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1980,7 +2015,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2016,8 +2050,9 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= modernc.org/cc v1.0.0 h1:nPibNuDEx6tvYrUAtvDTTw98rx5juGsa5zuDnKwEEQQ= diff --git a/testplans/lotus-soup/paych/stress.go b/testplans/lotus-soup/paych/stress.go index e3f2fb6b72e..85246603f0f 100644 --- a/testplans/lotus-soup/paych/stress.go +++ b/testplans/lotus-soup/paych/stress.go @@ -8,6 +8,7 @@ import ( "github.com/ipfs/go-cid" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/specs-actors/actors/builtin/paych" @@ -136,7 +137,7 @@ func runSender(ctx context.Context, t *testkit.TestEnvironment, clients []*testk t.RecordMessage("waiting for payment channel message to appear on chain") // wait for the channel creation message to appear on chain. - _, err = cl.FullApi.StateWaitMsg(ctx, channel.WaitSentinel, 2) + _, err = cl.FullApi.StateWaitMsg(ctx, channel.WaitSentinel, 2, api.LookbackNoLimit, true) if err != nil { return fmt.Errorf("failed while waiting for payment channel creation msg to appear on chain: %w", err) } @@ -285,7 +286,7 @@ func runReceiver(t *testkit.TestEnvironment, ctx context.Context, cl *testkit.Lo time.Sleep(5 * time.Second) t.RecordMessage("waiting for confirmation of settle message on chain: %s", settleMsgCid) - _, err = cl.FullApi.StateWaitMsg(ctx, settleMsgCid, 10) + _, err = cl.FullApi.StateWaitMsg(ctx, settleMsgCid, 10, api.LookbackNoLimit, true) if err != nil { return fmt.Errorf("failed to wait for settle message: %w", err) } diff --git a/testplans/lotus-soup/rfwp/chain_state.go b/testplans/lotus-soup/rfwp/chain_state.go index 676dca03db6..90159e92410 100644 --- a/testplans/lotus-soup/rfwp/chain_state.go +++ b/testplans/lotus-soup/rfwp/chain_state.go @@ -18,6 +18,7 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -36,7 +37,7 @@ func UpdateChainState(t *testkit.TestEnvironment, m *testkit.LotusMiner) error { ctx := context.Background() - tipsetsCh, err := tstats.GetTips(ctx, m.FullApi, abi.ChainEpoch(height), headlag) + tipsetsCh, err := tstats.GetTips(ctx, &v0api.WrapperV1Full{FullNode: m.FullApi}, abi.ChainEpoch(height), headlag) if err != nil { return err } diff --git a/testplans/lotus-soup/rfwp/html_chain_state.go b/testplans/lotus-soup/rfwp/html_chain_state.go index 4b288b8c5b0..7a3d56be4b7 100644 --- a/testplans/lotus-soup/rfwp/html_chain_state.go +++ b/testplans/lotus-soup/rfwp/html_chain_state.go @@ -9,6 +9,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/cli" tstats "github.com/filecoin-project/lotus/tools/stats" "github.com/ipfs/go-cid" @@ -21,7 +22,7 @@ func FetchChainState(t *testkit.TestEnvironment, m *testkit.LotusMiner) error { ctx := context.Background() api := m.FullApi - tipsetsCh, err := tstats.GetTips(ctx, m.FullApi, abi.ChainEpoch(height), headlag) + tipsetsCh, err := tstats.GetTips(ctx, &v0api.WrapperV1Full{FullNode: m.FullApi}, abi.ChainEpoch(height), headlag) if err != nil { return err } diff --git a/testplans/lotus-soup/testkit/deals.go b/testplans/lotus-soup/testkit/deals.go index 0696af8a224..f0910537da1 100644 --- a/testplans/lotus-soup/testkit/deals.go +++ b/testplans/lotus-soup/testkit/deals.go @@ -8,6 +8,7 @@ import ( "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/v0api" "github.com/filecoin-project/lotus/chain/types" "github.com/ipfs/go-cid" @@ -45,7 +46,7 @@ func WaitDealSealed(t *TestEnvironment, ctx context.Context, client api.FullNode cctx, cancel := context.WithCancel(ctx) defer cancel() - tipsetsCh, err := tstats.GetTips(cctx, client, abi.ChainEpoch(height), headlag) + tipsetsCh, err := tstats.GetTips(cctx, &v0api.WrapperV1Full{FullNode: client}, abi.ChainEpoch(height), headlag) if err != nil { panic(err) } diff --git a/testplans/lotus-soup/testkit/node.go b/testplans/lotus-soup/testkit/node.go index 08439bfcb9b..915f2a1ac4e 100644 --- a/testplans/lotus-soup/testkit/node.go +++ b/testplans/lotus-soup/testkit/node.go @@ -9,6 +9,7 @@ import ( "time" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/metrics" @@ -245,7 +246,7 @@ func collectStats(t *TestEnvironment, ctx context.Context, api api.FullNode) err go func() { time.Sleep(15 * time.Second) t.RecordMessage("calling tstats.Collect") - tstats.Collect(context.Background(), api, influx, influxDb, height, headlag) + tstats.Collect(context.Background(), &v0api.WrapperV1Full{FullNode: api}, influx, influxDb, height, headlag) }() return nil From cf96ad4fdb0d2fe7e6e0250d5adb48eae0faacc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 6 Apr 2021 13:36:16 +0200 Subject: [PATCH 29/60] fix lint --- cli/util/api.go | 2 +- cmd/lotus-chainwatch/run.go | 3 ++- cmd/lotus-chainwatch/util/api.go | 2 +- cmd/lotus-health/main.go | 3 ++- cmd/lotus-storage-miner/run.go | 3 ++- cmd/tvx/extract_message.go | 3 ++- cmd/tvx/state.go | 3 ++- cmd/tvx/stores.go | 3 ++- conformance/rand_record.go | 2 +- storage/miner.go | 2 +- tools/stats/metrics.go | 2 +- tools/stats/rpc.go | 2 +- 12 files changed, 18 insertions(+), 12 deletions(-) diff --git a/cli/util/api.go b/cli/util/api.go index 38ff5efeda6..16913751d1f 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -3,7 +3,6 @@ package cliutil import ( "context" "fmt" - "github.com/filecoin-project/lotus/api/v1api" "net/http" "net/url" "os" @@ -20,6 +19,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/node/repo" ) diff --git a/cmd/lotus-chainwatch/run.go b/cmd/lotus-chainwatch/run.go index aa417a8633e..6e47a100d79 100644 --- a/cmd/lotus-chainwatch/run.go +++ b/cmd/lotus-chainwatch/run.go @@ -3,12 +3,13 @@ package main import ( "database/sql" "fmt" - "github.com/filecoin-project/lotus/api/v0api" "net/http" _ "net/http/pprof" "os" "strings" + "github.com/filecoin-project/lotus/api/v0api" + _ "github.com/lib/pq" "github.com/filecoin-project/go-jsonrpc" diff --git a/cmd/lotus-chainwatch/util/api.go b/cmd/lotus-chainwatch/util/api.go index 5b6b7529d0c..f8f22cbbf67 100644 --- a/cmd/lotus-chainwatch/util/api.go +++ b/cmd/lotus-chainwatch/util/api.go @@ -2,11 +2,11 @@ package util import ( "context" - "github.com/filecoin-project/lotus/api/v0api" "net/http" "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/lotus/api/client" + "github.com/filecoin-project/lotus/api/v0api" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/cmd/lotus-health/main.go b/cmd/lotus-health/main.go index b4146f71a77..a226e743d90 100644 --- a/cmd/lotus-health/main.go +++ b/cmd/lotus-health/main.go @@ -3,12 +3,13 @@ package main import ( "context" "errors" - "github.com/filecoin-project/lotus/api/v0api" "os" "os/signal" "syscall" "time" + "github.com/filecoin-project/lotus/api/v0api" + cid "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log" "github.com/urfave/cli/v2" diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index a66c0b61d2c..f7a4efd1af0 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -2,7 +2,6 @@ package main import ( "context" - "github.com/filecoin-project/lotus/api/v1api" "net" "net/http" _ "net/http/pprof" @@ -10,6 +9,8 @@ import ( "os/signal" "syscall" + "github.com/filecoin-project/lotus/api/v1api" + "github.com/filecoin-project/lotus/api/v0api" mux "github.com/gorilla/mux" diff --git a/cmd/tvx/extract_message.go b/cmd/tvx/extract_message.go index f29b39bb190..8e993cbd369 100644 --- a/cmd/tvx/extract_message.go +++ b/cmd/tvx/extract_message.go @@ -5,10 +5,11 @@ import ( "compress/gzip" "context" "fmt" - "github.com/filecoin-project/lotus/api/v0api" "io" "log" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/fatih/color" "github.com/filecoin-project/go-address" diff --git a/cmd/tvx/state.go b/cmd/tvx/state.go index a60ebac41b9..f2d25300adb 100644 --- a/cmd/tvx/state.go +++ b/cmd/tvx/state.go @@ -3,10 +3,11 @@ package main import ( "context" "fmt" - "github.com/filecoin-project/lotus/api/v0api" "io" "log" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" diff --git a/cmd/tvx/stores.go b/cmd/tvx/stores.go index 0f90033ac6b..04000564178 100644 --- a/cmd/tvx/stores.go +++ b/cmd/tvx/stores.go @@ -2,10 +2,11 @@ package main import ( "context" - "github.com/filecoin-project/lotus/api/v0api" "log" "sync" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/fatih/color" dssync "github.com/ipfs/go-datastore/sync" diff --git a/conformance/rand_record.go b/conformance/rand_record.go index 92a0b1a53a1..165e86e850e 100644 --- a/conformance/rand_record.go +++ b/conformance/rand_record.go @@ -3,7 +3,6 @@ package conformance import ( "context" "fmt" - "github.com/filecoin-project/lotus/api/v0api" "sync" "github.com/filecoin-project/go-state-types/abi" @@ -11,6 +10,7 @@ import ( "github.com/filecoin-project/test-vectors/schema" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" ) diff --git a/storage/miner.go b/storage/miner.go index ae0ac0bef1c..9a24cbe9dfd 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -3,7 +3,6 @@ package storage import ( "context" "errors" - "github.com/filecoin-project/lotus/api/v1api" "time" "github.com/filecoin-project/go-state-types/network" @@ -26,6 +25,7 @@ import ( "github.com/filecoin-project/specs-storage/storage" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" diff --git a/tools/stats/metrics.go b/tools/stats/metrics.go index 20377d496c7..7764c4bcabd 100644 --- a/tools/stats/metrics.go +++ b/tools/stats/metrics.go @@ -5,13 +5,13 @@ import ( "context" "encoding/json" "fmt" - "github.com/filecoin-project/lotus/api/v0api" "math" "math/big" "strings" "time" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/actors/builtin/reward" diff --git a/tools/stats/rpc.go b/tools/stats/rpc.go index fdd22ca9928..0aa3d141ee4 100644 --- a/tools/stats/rpc.go +++ b/tools/stats/rpc.go @@ -2,7 +2,6 @@ package stats import ( "context" - "github.com/filecoin-project/lotus/api/v0api" "net/http" "time" @@ -14,6 +13,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" From a9e8695e86cd843e967ef79bf54d018d115bb54e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serhat=20=C5=9Eevki=20Din=C3=A7er?= Date: Mon, 12 Apr 2021 15:28:29 +0300 Subject: [PATCH 30/60] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000000..69deb3f2420 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,67 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + schedule: + - cron: '37 14 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'go', 'javascript', 'python' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 8ce9412b2be3929b6f2ee13fe5f49c953c867dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serhat=20=C5=9Eevki=20Din=C3=A7er?= Date: Mon, 12 Apr 2021 22:14:14 +0300 Subject: [PATCH 31/60] rm schedule, python, js from codeql --- .github/workflows/codeql-analysis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 69deb3f2420..2bf602a851d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -17,8 +17,6 @@ on: pull_request: # The branches below must be a subset of the branches above branches: [ master ] - schedule: - - cron: '37 14 * * 5' jobs: analyze: @@ -28,7 +26,7 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'go', 'javascript', 'python' ] + language: [ 'go' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed From 578505427b0ed7ab80b70aeaf71d4dc9045c36ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 13 Apr 2021 12:23:22 +0200 Subject: [PATCH 32/60] Bump version to 1.7.1-dev --- build/openrpc/full.json.gz | Bin 22803 -> 22803 bytes build/openrpc/miner.json.gz | Bin 7828 -> 7828 bytes build/openrpc/worker.json.gz | Bin 2574 -> 2574 bytes build/version.go | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 3af032baba190eb94427b32e9ca001de22222994..b8c37428d4f5cfe353a08f0e26ae19e712b27ac5 100644 GIT binary patch delta 24 gcmbQdiE;8K#tCgqZ})8MXpZ3E*16lJRKvmm0Eb}-rT_o{ delta 24 gcmbQdiE;8K#tCgqx%)SEG)Hh~PFH@fRKvmm0D+kaVE_OC diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 07ec95fd47ef22b9fbe2614ac6dbb01c244cde80..71462deb3bb50dcfe92336956784ae004f70d94c 100644 GIT binary patch delta 21 dcmbPYJH>WFE93W#ZESKJYJHEUtZrar003ei2x$NS delta 21 dcmbPYJH>WFE93KxZESKJ^)t^|t!`js003ed2u}b2 diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index cfe344989ae17abed055d93710ffbc919a380d23..9254b3b0ad779679d12bc30361764d3da693e69b 100644 GIT binary patch delta 2474 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 delta 2474 zcmV;b303xv6pj>-et+s5J8*{=7WP2RxFhl4`y*z=)0BTw7i>;h>%HTQDA<54?0~cd z^_6Mi=H_O~uh=ADHhLw|AK$pR1#ziFV5=jvBzxs|kj=fE55Pwy5M9tqATf6aZsgSU%o3lql)*&^;pa36%Cx}6DeC0N)` z6fIk>KoBvpl0#+~v9JmmSbkotSlnE95ts1s53m(Z52``~-8I%&U*Gm+86U80(B9F)t^bZvQ%GWEF?eFH|jUD9UM7v8HGSN^x|pE6KoBy6uR! zbrY4#=~{&{Ho(}7C+&b%X54vW{vGH1SpLJctVATtkEKL+qjm7e!?|hj2p13VOetRu+U;pr zrDb!kJ&9oc*cV*$)poVV&>p*d-1dl6Alk&I`o9cOt!;j_ru-ityPdaPJ+!RP@GnNj zE;tokhKMT1V>m*u#+EPrH%6cuh(PW_4#MorTJVFw}yr}=X5 zCn$SXQ3^tuYF^{YSekO(zjg{jw{i7wMAR%Q?k9@h+u`hg;ttes9+&Kv^Bfx&@ddhw zMdGqN0YcID1?Qc;xCY)|ji%s9~&(0)B{U#wI4i!@5aG%~6>yQqxwFz)X5$ z6;@W^ZN63b#P8tJcm@@XLxOTU`K%hAZ<>e3?cFPU-3Pb#`6Qp~-Rz-!K3hSXfUyY}4>VvrDOkd|02hdauS^1|z5#QM`ggC=XS;9mm3yU3 z`;f0}mgyUeYcTFbU|hk1+y#U?H>*OMCMrTS?bDh!e13LhP^uWDqJ}hKJ}yOhO4LSQ z)C|Pd4hAN;C&9n%0qJK#VEhbaw+ySQO zgeE005q_v9^j z{ty1}w;#;8=l>Xc6PQnW{R!;_^V1-Je)q0#9PVwlSJ70iIWJ$xU2;~HIXXCR5Ewc0M=e8***Z)!RJhxJVFEY4b;Cts4v)D zlLE#%(dUY|UI4m6<@zybiiai)-79_C2UO3MwdV)y4LmjQbbqMuRIo3m-g&6)9E93* z0_r2Zg|(ws78(Z%#Ydx9wCyHw-bo9tLuGiUXLHu+#hrEP7w&FR_3oEl5f-^$W6s?T z`@d3+Jh2BXu7*4!ZY5GPSc)}~2+XtgQoLK}GgnB>i2gw(lAsi2(<|nYIa1^n5J3~T zM-pt#9ElW1+JB^yDN&$5C?ao>mRBcmx47f%_grqsZvWZEj$f~`dmVWOklZKKJ{hqigU=S!8y*9D31zlgj&Gv=$JG$tquB@u|L zZJG?bF?ZiQDV6CqcQ26{{>tBl+rI0x?J%@zcN+=ahJS<>wmemO$h zz<6esHrFqcyjhC87NDin4<5q}gFaDuQbwuVMeC1^$&QzihBz$<&&(dkI+sx-DC^#r zmv;fhQ-9wamb-}l8rjro4XINj#hxBRbLybUwU@ek?>Sx#aj@SKc3>MDvfKP4^S1fT z6{=61sZ{OzELWa3{y6&R9p{cGL!O905{-gJ|4Z3!N)H0TV7faL{;;2>P%2 zib@L+G~^E0=+*s<+A~C%L-i1KA70=pYU`)RK7X-q!HIiOp({?9g9!ShYt4w9wbFvK zog)R!H-|JUQ_ad$+9fPVUPdZi(H)Ga@}nH$(^hOLo_5Jr?d;?Z%LFG`BuPEn4Gf;X ze)Fzd8wdAWpxzYZ9={Q){u5A86-6qh%N4386F5oId^w71ps~yCTZsausEgDL1Rx>+ oF(b21BasLg3s-l3QS@GFM&(U-qHpoP00030|0ji}jsbfB0MDw%=>Px# diff --git a/build/version.go b/build/version.go index 5baa4743a3f..5af3cce3991 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.7.0-dev" +const BuildVersion = "1.7.1-dev" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit From cc55aba1934930831ef43a061dfed9bf262b6809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 13 Apr 2021 14:25:03 +0200 Subject: [PATCH 33/60] Docsgen --- build/openrpc/full.json.gz | Bin 22803 -> 22465 bytes build/openrpc/miner.json.gz | Bin 7828 -> 7847 bytes build/openrpc/worker.json.gz | Bin 2574 -> 2577 bytes documentation/en/api-v1-unstable-methods.md | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index b8c37428d4f5cfe353a08f0e26ae19e712b27ac5..1e995899520c08f65d32debb37b873695c1119d5 100644 GIT binary patch literal 22465 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 LK#s5Y5fSiTw*JII literal 22803 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 Xb$=HE&yW8v009603oPA+B76h@Jm(g( diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 71462deb3bb50dcfe92336956784ae004f70d94c..00fbcf79740028d2708912cce352ba2d93336cf1 100644 GIT binary patch literal 7847 zcmV;Y9$4WYiwFP!00000|LlEhbK5r7|5w5A|KdqHvZ7mTSu^{>v6IxT)9SID=Gi8m z79t@DYZBm+kYhLF@BSYEBt?pZ2wtSf3U@oLMFIx^anA2tZ~%NWsEdf_n#RcJwtMYk zqh(++qsHi)!7#ItF*2?wTl(O7d=AdWmqyFDN1l%<5j9TQ-6IR#8&566L2N-S-xz)V zW)SG`n(wfUOo~bS%w*I%vn&t!zR@x)aRM*g4lpTU=z+D*<$qs-7f`-z2ZdSyc^>s%f^T2Q7v>?h^a$|VmxLjY zK)bz0@Z}fs^o9KW_uod#@RyDQy+>nY7%jtv9&}_cmL4C|^zq20J{ElsUh^^EwhRyX zOPld87Yu)`OR0gU-zS>(%>{BGr-vS({X4QP)&>LQO}USbAq zAGHkj=ptU6PXB{UX52pU{{44}J!Bap<}DHLjO!s2GX6x=ddhg#GSGwkWEa%*d1sPi zc#qj)IRzeaC_});o1@3INOaq`nKMsZw6+_5pOiaBb1J(=mGRR_{e`}_x@X0Zc3?*Ac>V+ zA4^uz^mnbTzv)@1iS*NfVM(vE0ZS%G{2Tv+$^*%YMh1$sfZGLYxX+c>6t`FPw4f!? z3@2L|TcU5`cK2UZW$N3+S4@v#{k38Uq1{84&J=kmGQWw(0Q&%fs7P$s{Xzfr=}CXs zKOWw$1{aik=CU))mYwqjGVjJ7z2`t!N^%kulyWo0?Q1m0yno0V(+L}Ul+Ief?Sap? zz9bt=@ipSl`+%eGOYp*h?&sC~%PG9|nTJWPB46(s?+R~{li#k)We<02j9Z>vSEJ~q zTFsakE%e|<#BD3oVV`r9SkfrCyvWsh$qIrOGe2RV41?cKt>7!_lzqz3tzrgm#M1%< zV%Qj)BdMSZPf`JA-%7g^Wx6IKdq4pJLWr(BQ$DMg3z1v{T1jG87_D31p8EPyzer+vyV943l7T zFUgDwROj=}f$tg;i#kLaORLf`6_A7B$xeh2zE$|n8r0U2Z-PW2I@1F)UL0BH5--Ez zVrB>fmlh%n&v3kI$o{r#|WsfSbpc15>SpHoynp z1~&`zg~-S<2qx4AYyp|5B0lGl!-vQv(OVLN$sByeY{B1uAy>cOe4PCC=Is2}kK@1I zoK4>TH9ouf86a|xJxUyoa`(`~+_DEgVt`TLQwISTvPBC(Vu`lC5Z)Mn7VG5K1tP$N zw#{2i3={jJ2bhRHaz++)zmS>~O97iFC=2ePy+lS#OadC^;pn%eZD)X@co_3YB0#k5 zXD*bl6*1@w1a1GE5+7U0`+YXEF+taec^KV8Tf8hKs`+HIW7OOx&$EWKXm2G{9e5hw z!~NJ-zB*RKBeNzcV3c~fDo(Uso?4^aaMX@CN)e??P7&D(P-Rf9i>I~?Rr@%n{G{Pr6k_4)^1qqRL4;NV=Ii6 zMYSfjQjl(#Y9~x}(%EFCUpg-J*ac*;JPWO8r~)%4w%X^|5^-^@AWfR?PU7A{Kl7I< zGvmxjTIbjT9%l$25#|F3d}Pm#WSJ=@bNQhN3sWkP1#m>I4K5kLKA2I@K^B-k0to() zxr;3T!8x^%30{0%U~>U5v9KwEQxG^yn_-i`J#wLWhpea-&eJbNSO|g-ywn2vi*|Aq z^_%fZgfC~0z3D&DM6mzWw-(2beb_%{)4qR)9QQx;;lJ+kkvi^wrp^pK&iaEH?k^vY zmrFG0-4BeXvZ0!dq46eg^j)B1lRI{WeO4Ycc?*NEm-?_{WOQ{{5u zIV2{sFCc?A9wh!OgKKmoQ$HIC`s>;9= zk2wGGu7a?y(ViGE$M=Y=o?l)FMy70mJTZdWwy7vS)%MO^*vj_xU{dvxCc3?g{;!mN zdjHSEKfnI@?|by~|1tOd@tN;^{N;`L>EY)$?i*aNW3$r96??j+ z`^Up6MJz&!=zGM@{JRR+Bnf0M`TZ0et>B1~?FpWf$XY$~@A4J`*BaQ$@?TCDQy(V3 zyv|O4UQ(ocV3T*EW2_eG zWxRcGG4E9HbAtZ+8#P9Q-c!rqV}SC@eKX|Q551Nl(gjDxzlq)XbMj_kl3y0+fB*F_ zfKv}IiRmHeBZ1Dvur@_rDO{=$A{4zw|E&W*9Q+ zWu<-d0uw}nWcc*k56Ji79A)O~|IQZ38>2+k*x6eQ&Qbo!zH3K=MV0i<1zy_%Ax^ll zxJy*r4!MZWa>jVB=)82tuIN0IW{@afro&mj*!p?Pzd6s*exPD7jsIab{WXmc;VUu~i&7 z&+Z|%;nYU&s24?Fv)zD|f=N-4ub$a5Kuh`xn3A&20_u(8nC+^^wWw&MAqe_i=0kPXl^^-- zWJT=aT<5!VEn=ts-amkyt2*^~Wii&UKTt(XW#z6fB8QO7D+&J8w|94Qo~TBbGYnsy zI@>jYLt!j>ozC|V#+Gru^t{5W^MQG2B3#Nm)E(&+nnUw(>`_Kds<2cynVMtxXj543 zrjGBBwNTBBy9_R%E#m74@F}^3P{iZ7LS)V~b>;7~nU7eJNR3`Ebk--zPC>R2SS1N1 z5H7_^7P7^_3(nXz{94kpt-69z%&4IZ+LO?`&n;eay3T=_BC3P(r7|BQ!l%Bf5fUep zZGOZ`$ZM)}OpP_NTQM@$I+pqf>GwKmcLA`0MI@JfV3=)q@Zhk{0toVX3VJPKqhyNp(BPJ zw81<%khE0QT^)hi2)|Q3x-CsDQ^jdyqGprYidy^O@(WcrZOAWwjeIUIHEn#&ptiG} zui0(uZhg(D4IpF4ahVSo1)hB0?1OFg!8ZF~cY<50D_x|#PO9#Mov8M~3UuP%(Qm)O z^Gm`6B&|K@i>rjs7Z4L+Jhgy3khcp%%R*LUJhp)QI_tR>qD5VdgBWj#Q{CzwjreHw zM6_e%d12-3tW6lQkG)JoMv_ss2Ge4ra1BsB$i4wN$-Y}0MZZ_WAYMP)K{U{R)f=j= zT#8_^rk%2r+?}#Q8D#A;)dlc1`ddFlso4>G=sRK?gt+RRs_xJFfC(n^H+=R>!9rAB zv1?wM95>jVAeI}dj}zO@9{G58(onGWRtE#lu@yzt}@L3ucV+!|jI@P&-xK zwj`_w|2<;omlv7KBRcH1P9$f4H)lXsRAJOZ?VwT~8)h`JbuHBF@&1l`yfcv^%{OVh z$Sk9U8ghZ9jzI?tF9Lh6s44Qk0}Lu?N|ayqS#P}DQenZI&hjf&*T~k-3@NZD^gs|? zb*)l_i>n-=N*ErIDTd-vHEkS^H`E~ckBsDM&Q+Dt@&jW?R1c)bl0J5stkLA*9qdB) zsp{%4iIP{?XXn`BOkZw=J58qIC3%?yn+x&|Txe^rzb`B!Zc5|L}< zqmhrT%7^OevayYPN&l{!hMCO1&zYhHt1aQOMmO)p&3Z3E6uJ2cb!>s9kdj4 zCrPN>UG99~88lJ*9NKn}*(H`?S01n12R|jty_JHnad9oxetweIs*z9ByF;ENQCm*d z`dBrkVG`|CQOJed5N32vEX>;Jir6kxrZW#_Hv0v+s z%%sddo$X3~^}}j6Wve7uUzb5*hsM|KmKR-_EghfKje*wi)zjHGS@5D8)ut9QMxEG3 z%H*l1MdQ(eoYn#M%8i@NnsEhVkKOiR`Sh>QK}#qzg-HzObpC9M{~awnnw( zskR1W8;}h^R&|GGfLxeB8~;0vKD-IO z0{F(L>;`$04K}dbz-|M(4eag{?5ZvomiTpzVC8UoM57SoPARpkh1uin=EvC^^li|0 zN9enot=LU)xlsUG3Si@M>ou|w^pV^xhSHfQMbtoo(r)bUbfb+8-e`fn&;ktvHxL{^ z@ae|&y$OQ$IdvS&(mpf|X5q#e}#eaWg><;i|Dc6o!ydxOYnR(Kh?2Z3LG$il$LC zhpA|~8<%w_;tV2Gk9)HsR8rlbI-Q(EZyL?hXr4XPJg9MX8Vz*l8mPB%g*yS&RlS`R zp;8)1BGEav{2J9y5?Rb|-t@H{q-m39pyVByHVJ8QvG&) zz#K7O+!Ba_w}5v^oYV$^FRB7YgRxM$kfTwaiTeV92H$Lui#m>fQ-*N`f5KOnI7Wv6R_|X@)cqx4yFVS^$@TS zw0$r|GyVfJAg<8#L;cZk`kr&TA`&H8KDK9Q@sv0t~a!dSu za7!8~IuI%9s%{hwIFGYP5Erc?MKLn9nulwIa|J0@oLhKcihv1i8(Bc89BHj#0^T|< zdj!-2pCD%9GA0@8^}i5C0rT*Dj=U%!jG$*fHa6T3CO8|z1d*FiL24ozwTeufYM#7A zWmmpZ!nF#WCh&s0HDu1U3Znq7JRwTJ6f$!GX4v!D%NDOqz7V)%)PW3h;d_jnHp~*v zS|d?EmPDy;tX$*8clOdRcVc-KA;pE)nwK{zC~C=+C=9UUAPYl=Y;M{S%a2J90*=gj zkpYNMKM8?CR&e1>Bxvm~L}s1&fHMQYvsHB{0vKBo*i6~3V=wKZ#R(syEc0ta;oTfeKiq)<+rxDl{| zK#BVKQY2?YPm)5C+2X@r0%+UZQJP0V2)|Zl|1H}r%Pf-5^q;%EeyiIX-0sh@wI z)qR06zPKb4;UHIK*^rLP=lOgax$+EEW#(98YF9`wb}TmFLXTl{X+tlH3Do4LB*s>9 zOYOS#QIZoIN!(LO+!%H6uhFcM1oHaXO2dKfXUSBzoK2yPtZOvWl(m5DR_?XU?pW$0 zD2wT&be|48olY#d`|?6$b+4{O?{)^m*C)rFR&;fp`28gK&xMSCj&Z_jYX4-Eyxx6V z*RYqku}*nm`(fQG+V86FPz(5*1NO3#;7JO)fxhUB^OxX7Fva3tQ7vJNn%cY{?LA^L z)F+B_zXyUjzDHr4oV(SR7e7#pZVyi7&ceUd{HHpVc%{E}g~P>Z%aB&c$QXMf%f)CJ z=hSg7j1f0FCaDFZqa%_!GkO1v5rQ$7mUUAP>(lvQjTD31%4D z@}BG9+3(~AJ7`58diG;D>|&dN;=R>@|6qEH?kEo!p-i=4vWixXf5#lvnbK1MJJ!8P zYJDSAFl{=YJ|=m&_nKDCiDVEl4c$*-7LnKacKH#rsNT-A;sOV7NE&}j?S zV1U8}m>|Gt9qIwLZ&wbp7$ZuO!Gy<4h@f|Z1q$ORSwPESKa0rTF`+h zRmI+yB-FlkEE05!3DdRhBeH6vKKKPNnNe=m*A=ME=yj$So-U(fnub>BsN3u0IMp>s z)uA!8>UzY0Z9ckIwN#aWLLvV(5y#a?Tv@fTlY>;AxkFksk{k(G*(K~Ih2^T>Ro#ad zNY0sMT~QOJzloNlC26P+)!>tsCs8R{J2*|llTic>UQGDo4MSF8NY#2lzyORvvt%+= zoWiCPUXUNQCWDl256t`}!*=_fh(&6$YS_+Z@DCddB3~AIs4YU79*d^wB2IfbIi7V- zhr{U+n)N$J1M37GP5a0^I)%r*li6SjU&Eo%GCp2kMZvPr79aFl#s~NiUSKSKpF?p@ zXULHJC-0v8UGxy9kXDv+u%evxHt;1=K7XvYI-Zdnb<8nJQCxTDSANRYOu0?kHNn8T zM`uA7nwUL`;Of~u#5SDro}adica!ArYvd#Ep7-Tcd`$7*kG^0s^ThJSVkvkQYPLLlZ53qV#qIJs8(M z5>s&yW-&{4XL;r|YKUi~uLpaS)AFO));-ldS0ONY)U5$&BPun+tR}j~o8PJJ+`wuB zt2>3&2Gg$kJ=M)g0UW%;#Hx;ID=PVGkFoob6vkpd9YP50$5_xHSXnC?I!JVNr>12C zEjqUfJr8Kvh>*`R!m>|>r&`E2L{&11KDXG)*u%2FS#_E~N;N&Wc?mX?xe91NUO(5K ze+gcc4tWO+?Bu$QeX-QDut6iz+AI+tOf>g7BaZS?ANj${pDeJdziE?bAjY?mhP*(g ztqC?8j~J+Br)XyH6x&5rWpzYaOPZCYw%A>|W{Zw`TiH*#qw9ALe2ZvLc|%UX*j4lX zR7rm+v6G0XD{leS9SB^M0Jurg3Srrdpsm=*P}N%uRUZ2MMn{pJ6ls=&OEDd1aA=iEHFikNu3G%_?O;$LZ)TtOdVh z6CcWHxGIU!;#<2ng!CkdQJM3$d0$ec#xVaa! z7L45-+zis=OJggquM^x%K? zZ3p(nlv3Sb=&DPNFWdOCjW4^>SwV)t_edMqSA15{8N`4(39gk*1>+}@%j*f@Nua5@Z;px$E zHiJi}Gc@bWhMi-CP?X3Jo+BC4>#4=fAThu=IqnR*Q`k8=?oO?v!E5;XXlizbM{w48 zJ?omiWAxfu9bJ|~@do;LTzC<*U)^_JaTXWHxV_?9{CY_~LClO%M+8wkW{iwpr`I{^ zc8|Kfo6hN|*Bfi3JfRel5@#qL zm`mAL-Fzsqal#<0qHaWe9euM7%A%s4z6smdfx^k`Wsbs8)u~V6d^1FjT>?!dWQ({8 zU3z99jK~=;9(`;=+Zgpu2E&t+)6VhfV9?^PCSRdzjJmzyaB$k`4u`{zc)W_t^tywS z!LWZk7`BY_@kien9S>T@d-2z21HK=B1l@lB#JJ@`@|M7jNf2^@Km+ zgZTO0UCNM7AQ$K2w=wEG<*1w@$$J4!t;1-;&S$0aMV-ye^9yF8E)|%Vzapa*v!XNB z_d!Yhl)?lXX+;6!T%=h+a${YJF3xY79f;U_JdM2(Yn_sBx`##7615L-~oH-?|T z83a1K<~wX7lVZ|7HyQQLEz3i`Z?p^x`KE_mCaL`W_uq5+h0K=31TTE>(}YnE&d~=< zkT+r8(qu0|oWKjW158R7dSLC5{PQJv0p-hfP^blv=TYw^`1XZ-VIE>jj{v`YNf`17 zwA*V0Uw$D^U&!Bo|82Akf9W{Tdo+fI(K1}G3g5ACFw>W6}5EH6QbB%kYrD zv>E?$!SL6*lp1*YeWGdKTp$N>dguWnv2_sVr6(OBD@`r zTkl$$=Q2tZbKN&%?4c2L9L)H4@ThGJ${Cx^v73%ym!#H zr_j6$xiNV6iF$YIFQ1B--Hko^w%(<024=_+Z!{z(6qu*z0rWih$bV<|{##gXN~w(? ziIrR*OIFeJcdf0z=~<|W^wWXD%W)38Opy35{s&dZmKBW*U}*uj3)VCO2b(Ewuj*+b zO`;i2c4MfCzKPr2ee-;#SlV^h%B8c@=|1e7moq<0R&Nz*s%M9{_C@o z{%QaC^maA4pyWY_P`8sULZbyT@5Uaz=df5wfD#mx;xonVYc$8ao5&i|2^)Kq&RW3j zfzP+TBpb~1HR8|vfMfAX@WO%a=M@{snY{Ixhe@G&U+)_43U88=->&Fo4|i+)Tb*lH zqv)kt&6pT15aA}pZ7bAhp9@r4(nPqtDAa+;3W66iKVhI6gWpfB;4A8seag_ZVg_%- z(-H(?5E+{zsjf>;Q9m_BTt>9!gj0`oAhdI;19y&Crh1uQR>#Qg_WH)qFd_LL2B0bW z3p@lZU{mwX;2m@!<5E9PFh~2Rm~9s{c&J8Fcc4Ic>bOgWLIA1&@G$}^eE)nqU1FPI z63p=>nNb1meA+qwT|;6~he*?DRXU~#3ZOjMi4e)RisD&=+ByJEkSIiFdYHzGBWomK zGb}D5Ho}8b68HpXsC(f zRxN39oGAL{k;%#qvasmP6cgw@z9lBLIDZX|DfH3tAm*dy;crzw+H*)gRY00_}2q` z@NICjKwpRqM1x>neZUrwi7Mi&9yxr7Tp+zAA(+g;SIidt{TFie$IZvdzu%mXe)~B7 z_nY&{+kcPGZ+-!Y++&XthlAZc^f0&cfsYtq6!_FZz=dql0+3jutuKT(#-GJH`E`K^ zFrjVp78Aq7zUToaqK}-PMcpr?CjC;v0t(84duT6_5tEjHMs-yBeQDbn*eD*x{F4Y5 zZTm1}v!@7IUm$4vBT9U1A@7gb%*F&=Bj#ar4{h*cI$x;1f^l6b>mJLRx}jxGP^R`@H6 zYE9gwAl>lRZh0%ukiT?X>ah#RV0BJf(NINlOl-AB*b?z{t*B0#?oQ(6K|hOEIWyza zNm?Up0gv;Aj|lSt1U|B7N3zTmlezp*goTM2$O1T`)&`dhU?0q==O7DA9{~h^%G}5n zfM7%|WP%r87uZ|?Oe}1QXch#{(q`D?Z;xDP-XSY$g|qfc5l4dH1246J{-T{+g#Bi` z5@FBTV{iHoG!g87^{vJ6V;}a9*|hK9A;efY1te58*1pQ$rLkF)+@hWpFMBP~n!Y1~yw3C3uCULlV+XIDt!+NvLKn9`K<^GQUQ|o-1mw1&Vb(j8 zvGkEDu;q0RkGj-{cFBZ;k&O{yL8LV!d^#xzJmuxq?$O+(lzq3vVn%5509TUJ-&L^Z3_t3 z$jb`y4JRKQC!ZF$do{-WvZ$%|WCgJ_O~%b4ymfAE0)E>H_%#w5lTd{xD_0vwkeJB6 zfDGPvkodC<=Ft&Q6)}~3T982&lxc^BFE2!zhl`Nc7Ju*S=$@RWi}$>%Dg#qI;%v;j z3c|id+j77h-y^bmet9AInX(1)#0YBJDWmvQ+dB_pEBon#N!3fk==Lu9zft<>{XY-? z{Px$s?$Iy*$K3bF=f3yx*Ei;;hhN^joAiG1-_rLt58j8X```YL%_^sB?CBo!=L%P6 zig1OL)c1&;`*#~alq8V7V)#>ViBAAj}%lUR~Ox6|*nj1TZ3{Y)NP5uUfxGH$SgdESi^qyJ<9|M$M?wcXcr0BH_k%u@m{zdH0Uz0Zrll;0s|NHaL##6~- zx`LsWs1bHmCz&AmHMD9ZzNu!7YFQ^@B1 zWy05+M;4;^N8*cPI99kmhK~*+OniZRXmcD+J-j5QhoFxHNSA}$6nU-mI#u&}xq0zX zmxa8<2dW552PM;|sxu0us07LQ2-=l53uF3)HP_ai>8>KNVXJvP*7v@4*}BSIfY^^e+i!7&7W* zWtZ~;6GVcX`}Ern$oJtKWo`@jgDsFZMv1Di)4~{>qv8XK*A6p_D(M|>ytdOq9L8gD zpQ*fsauJ{DjPYF2dF75>(Rn7#ARoUGH0^wWZ1n z?ACIU>C#+ea_zI(cW|mY{4oZ-mDkPJXw6sK2`RWH-L1;-Y0#j1ejexeU<@yf#tl;yCIlM+b^6sU1Tdp^G z?%M~%pamHmL$=5+5S^5tsbH1$8jGc|SoXtW2|2M62#%Li8~ck&b+6H^B=?8Olw0SW zYxq?pY?i1&DJ$Qt&@GRkSmA0X*2T*mFkjZ>i<3n&iEt$=QFo+QXb#QCu}2v-sls5*vpC1_(WbE4A{&{@E!ItAIb;3oMifp967 zx{xgfUUJ5+;n#`|?xssDU4QUx4NkP~8_!&6z&6rWoflTg7Lq`ldD92(s ztRz>}2|rgo>Ml(!Q|oEuwPusrik5q>*@~*GL*xWpBcDr8O`1IQS1T;>BtfhXTLJ8qjDx6O{*ox)dc2E}C49k&zJj#~jz{B!#4H+X(Ym_Vkr z2Yqpi@@N4u5f)VoxC42yGPEpYMHXcXxUaLGYXMu-#WqpMv-e) z&G^cLl6~xD8aa}TvNg08Tas%)>_PVB&q?;(;wbvP8V2$DhaE(t0ahA7b%#`hjy3Jc zofPiL6*?hnKdUZ|uhHN78BWdK+e6=b+WgFfIJ|h>b2U zG8a>HxNe6V#n!$0l6YX9>L=(&uAkk zkI0k*^Qf9OoW~n#0R1@wx|(xUrL>&G7$DVy?6EA7U1oPQxqJt|GOoJ6OoHVV_Spzq zocF6OiKoeIc;R0r!RE5R13CM9&xJ*GKiY~Z<=-|G75TT?1SKNZh)E+RI}sB_q;YH` zYmTHsuO=cf0*XxHDQ<@rL!pEusbx#Y4RTxnUCh}7Fyu2#=B1KVGE<6Uz06#Mi@nq_ zID;M1-A<>|GQxd}XC*Dg)i&!wn@oRe-HXWO(pVWU7CHw$TuOr7pU1KKVCY<`Yz zUY1LO^>rB}cC3BfE_>Of+{z(L-7sklUp<|*lLarjfp2OdW7vsp)J&elS~g@Y$Y~w1 zuiO~gEHc-i7!|Q%sS@5HCX&0VYDH1MluE3u0K=wsa*}kT;TjEBq~RK@ZLoF?YZal} z0KhPTHvVT5cRP#Fj?j0#%?5@W7;a#=f#E%bVbv|V63IT$`|ytY4KO%HWj6qvY_LJ! z27Md!ZP0fg(O0q7Bw_3t!Hq-l5sgyFJEhd#ECe5Kw>SphfN%rCI|AX|?DB2`&y5}^ zp$Ak~Pls4)Bj_W!0}Z89Rmy0C1f|_rYyYf2`haI7M zoShY+idqNN>GC9c(8w;N`i z#i;Bi#~|5YlV8xN(!Efn4f;0dyN14s`~q%lU@||SQZIe5vkvga3Fu;O0kp1>-1=dY z4Wc%P+Q3B;E)*`Lvu^fVJbH>XED4M6 z5qtaKB9kGD^Vr4Gg8^Suk(C^Z*{8WN?4Wj7q*!9|>8nI1rxuta=8O9aQScV?JwQ_VsGS8%66%?QG9!V4rtd5ySooH1RTryx$r`H(2`bl14ZJis0sWn zxfQv$75^yqR3l3(SyEl@8nIU$-pVB3Td6KJajF`kvT|AceQ;SCVLCKn%60uGoKu28 z>L$VzBU7u*xJI~8o?^wh*$1Wwn9#P71%v{UCLAWdysKt1pYVkT~jlEGpB3t<#6 z56|bwiz3JfdiG;u*gZ@6QC;Y|=0a>BJQ0mrB_~d`NNl3AD?cjXc7+ZVc)?vBGUqym zQ2gYE~TKTC0e2|z>b3~3>mVyy+HgEwKIVkL<_*M(CgP|&Df8qke4dhDHFBT>_F?s?OlFXJO{t`gj z=1$Z+ic|Qt^8D}FwpwP9V&4DU?e$yT-r#nBc0cYp$L7Wn1bbYPiSVH}<=l{t${+fC z3thYl5HPeUU&k6$yGnw`V<7|=dJLOO8+uXbpe8>iHNJ{ldDl&oij3I^=3Wb?>Q=^p zzpv43BZ1`gvsH-$-OrM@ZbOcRHnOhKOjGm%(p$NpSKYbP$H*%&YcKM#bCfw{^>Wg-iF8_t78b{itWE zYv2NQ=TN@fNERgp-7sNvBKu45Vx>^zEvZ`a88w%`FYY~JGFT{zb6*L9Ilf0>z@2;K zmlw|{%C`sSh-covoZx}K{JKE@`}5C6%Mi;kVYwS@-bpz7Q*2)g9=~;|x!^$B?Q{i@$!*hl zWuk)s#tt#ubey$TJ$m;7(h{xykUo zTrZU!X&G-HT#U;TELt9?r9X$Jk++YW-=tIwb z42NBAS5myUIvOFE-m)9r14gJ)EtssbRpZ~WK%1siSHO;S@77x1krhmv&S#HvkWTqE zrYZXYBCbzu>iW-+0i>-I1y^QC4E5(@qjw%5rA_ z7vBuAHo*Tf#RPhfZ;44ogmq|4p^uISv2LzvN06mw@kQvg1p_fa;Sx*`V6+bP0Nb}K zhgpmfsI^RP43*P?4LPRyqG5*y$Wyj@Du*hE>H*}gocNQ#qT0j-kR;R|`C91c789mx z?nk86c7E^+U^1iJ(yuGftLS;Auby2_$65^y(_y#QDR8}O5VQm3an;R_0T+FAt&Q6Yf`N7@RDiP^O-m0#XH|a7lu~V(TNI^QctSf55^rz7hyd(|v zF(7>Iii9ggYX|3lcrx6e!IBBbz2VEv`BHTSS;z;BL9=51R-8iK(KN^pTa&>}w+Cka zl3~03PQ)-ZIW}x3Umb)E29YugJ=7N2Opis=t`W!7oE*=(XQ!vrBQ)!Gjt15VI-2&8 zd2|MkdndEO6uyS1M$7nkeH8`QLfd`NYZ)KlLwIAe_&tK+xY3X=`A^uunBreXxK-s*T#a?~+LDn)VK{a^VtTeI`>^lgHHb&vjnE;KQF6v5c@dx&i~ zfQ^@#ObPBG%fENGw zdL^5)i)zp)s%11O@NbaM&TX5Tn<$ltNb!+p66tv_ZXR7E-HphWpWuIxIMaDmehk^- zMkJ8F_3?qF6ZR0+}}SP;hSH2FRZvRNz$vrwb?3 z&l6yuQVxS4<3h*dSno<4=Q*jZW4#!n9;j$}7nS!z=%Kmx$)1YyJj>a&JIipdQBnLr zYJ0FpnK94P((ZLsS9yi_TQXjJBE}8*hH6mUM%z4Z7|WT^neNL0kTE$vaG} z&7o~YrFgY6b|sX;bnK_&3ZXR_izEbVaAo5OiLUO{&}OGeQjE#NZtuh;Ti~Xp*j`9+qfWJ4*7gQw+rle2eqpsKmRCgeEQQ}~p zz?H}@)Ri>jl?54mZzjV%uKriz%hL@zPb78V9#=a2p4A zrMiNYg71-Muy*@%SfV6g$hPG*Duh}HFv`0i z-%#*X6!pRNcvR#5;btHFcjIK$rFD`gex=iDCx5Q0s~1|9OKi12evB3eB~V5+i_~|b ziLI@=6m&9k5vI6~j>bo`Q|s&u_KuEEk6#}Rx~FGHr?VM6I-8+cXLi~-MhHa-5aE%Q zF)g234Gj_sjFaQeX?F@cN5|c%bu@SlUms1)&gl`HbzaZ9X73oiwpOR86;Ql^{vDTL z1npP%omZUG#ffsSxK6)bl1~sbW7rV^7LOT2qu1$mj=J5WZttdZHth9=os++emhlVq zS@78x)Mv(4)@fIbWJG}EXDmTYR;c%kGY39gN`l?vmf>I$`?a2=v6`Q~F#*%TpV;Dc z#0~mK`0eN5B4++(%&6x;&ej%W=!jtlWu25Lg`~o9jtA;zsxEhw5IJFxZK8EVeI2#4 zj?JQ?p4ti9*n!^3>}7%8QPrtW?|d^vie3U#C31_H3tf6BFnPWSZmv?Cs`qBgzm;AC*xKOUU6jM4a`Zw!wIE#tlT z+h+s5AAbbhe*eU{<+AdYz^T2Gix0^8=p*X`CPD*+KjDM;`QBa1a8Do}Bk|i9cAg3} zPnq1mfTq^*xMAnBG6AE`W~K=SGf|f&Ow3=I(TZ8o8SDF?q<%(Xf{nBygmEs?tRT6u mE`1m0H_Z-2?7GVZmpxY&;wIDEr~e-S0RR6cj^dQ7fB^vUWlC}Y diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 9254b3b0ad779679d12bc30361764d3da693e69b..ed8df4b220ff5c0286707875bea30049b969a2c1 100644 GIT binary patch literal 2577 zcmV+s3hwnEiwFP!00000|Li?&bJ{xAe?_C`OLNBo0whiO)+gE9%}ig|8pEY|QcC z2`j2xzyth|t3aa5;Td{AyucQ|2O%kEA;jC((V+wPcy3`2)Ra3C557NPMm!DqCw0N* zl(pVF&X9r)*uoA-TTova47azp6MoIc0khE?iT?P;#T|$%B?4O=pas|)zk_Vf6g;Zd znfcd3{t=Rj3o?P$71)Z4OBh?o@1pNFWJFtEnNJ)C41z2A6D;KSP|-L27}q&bik8hGgr4DG-dftpur>G);&eP@_J$X7g)ydwYv5 zECbIYVulBJIe?k79!6d>Y+;`W;+Z7~gkHwc?9k_uhD#QGomyu9D6_7al}U}QKiE_7 zh~8#+B%ber!FX}5n?6wn0uPQlosNY+2i{13dN;T5P;fr}YvuzUoX&47OdKa9i?~C< zeGrOjJY(WYu&|$KT41gK5D~HDLuLrEunGxSe4Z~!T;F#dxA4&quoX^Esse)V3k)}N z3k&!=paL8`P$B@m8NL9UDBTiHZf-4itDD)a0*)=UXDo2t8w*nf5mRJlkRHpd6`~Rm zv@*%>3z!?dw~IC+1esNzWiK;w#W~iQM`B%$I^F(F&de%KqhBamT2Yjfs$xme1eBua zMt72dt2FM2wpA6COX*67GCIKMjA!+L7G~UeYyKSO{I&RlYiWsynV(9r?pp2Ok;e;z z@aV+C9%YG7QD?*Bb1O0T-P2UHRZq4}ONudE=iJU&=?_#*gAo$oaRtbw><(Kv5H23z zsZzciwA+)gOUve7dmNehLtk)BSKHMdLwn@%QQIR@foKz-wtc}LXaAW1Yfbq7eeCt# zcJ-XH&cZ(!8M)w8^c5ng99Q80y%}-tuCw4v1o;NLf@RK=R!u@?N>Sr_snmO$&}JGA z2z%iSaN5adfImUm(~8?4!c_AUm+H~9>+!W45ITy>FNZ`;qvn31`Mn)3`zP)|4R>)t zZaH7EaSC6dQ&_~F+w+(<;4WpozN{dX;yNsWxRgzBf+(p(*s>WPE+fX}=<@hI)F!HN z;~F<^-`u#<(*i3_8FA@Pi1wnQIZpvs&HpUgFA1B}vd*icFU)jfo_9iocELQaa9O=v zO@*cXG9F7%<<>S#tkhhXnwg)*vNe`%-z?j^lYGl|!N$CzJ<}lhsfpEd0Nrz)eTuMc zB~Ot@&ohFX>QqK}|H-9_htjSyx+iX+_2(r>9tb;PS@4F_nWQ#x@u1(ebi>sH@#7Dd zAVJ(~hS3dY!>`i(??d=Mt!d{KMSDrv(}J@j=YGCITm__turiYOA?g|HmJAK6x*)Yi zWrj#CTS)-3=#4t)^*jB1b?}Mb!9Nm|bhiZJ# z#s}RuqjOYnNH!#DDl3|s5GLOXHPI}{R%8lv*L9X-fo>~qXdXcYF?goab_4Ml7^lL_2)zwaM|XxE zrof_p*UUHLA*qN^)e6Y+e&P zAVs-I)J9*_6vW1^^d+e*DXRq%T21J-%fA)5HBZxh4&3a`il{LWd&E(L>%MT&I4(F7 zxB}vyanGYF%RSG_M*^~%zh{_|xR+sWl7W=*HQP{Th^^>7WP0?YOS)mqXewU(=u9tKlu%@WSftobhM)OM>^SL)Wtjr2QY5tYoAG?r>7q-z%})!t`Gn#@6C;~N|Q zifsJbg36hcMXVEVE`jTXoJ(_DKk7`;&;*`4B}ltq&U1O~J^Q)@ zEONL;oV#nPx>87S%Cof;YQ^c7%p^hc87J<6MlQGSBnp_KE>cqvfQSIZ n%u$O(B48{$p!r2!dv%$T;}ble-^~9T00960z;LdZO?m(TJ2L(R literal 2574 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 diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index d94ef4ef3f2..4bf57b4f69a 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -4474,7 +4474,7 @@ Inputs: ] ``` -Response: `9` +Response: `11` ### StateReadState StateReadState returns the indicated actor's state. From 47145b6b82e04714146274da8dd285590d9be520 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Fri, 9 Apr 2021 10:28:50 +0200 Subject: [PATCH 34/60] fix: adjust client deal collateral overestimation to 1.2 --- markets/storageadapter/client.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 8e7c26558e3..9357cc271d9 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -212,7 +212,13 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor return res.IDs[dealIdx], nil } -const clientOverestimation = 2 +var clientOverestimation = struct { + numerator int64 + denominator int64 +}{ + numerator: 12, + denominator: 10, +} func (c *ClientNodeAdapter) DealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, isVerified bool) (abi.TokenAmount, abi.TokenAmount, error) { bounds, err := c.StateDealProviderCollateralBounds(ctx, size, isVerified, types.EmptyTSK) @@ -220,7 +226,9 @@ func (c *ClientNodeAdapter) DealProviderCollateralBounds(ctx context.Context, si return abi.TokenAmount{}, abi.TokenAmount{}, err } - return big.Mul(bounds.Min, big.NewInt(clientOverestimation)), bounds.Max, nil + min := big.Mul(bounds.Min, big.NewInt(clientOverestimation.numerator)) + min = big.Div(min, big.NewInt(clientOverestimation.denominator)) + return min, bounds.Max, nil } // TODO: Remove dealID parameter, change publishCid to be cid.Cid (instead of pointer) From 53537a0af28d451e841174797d1786eb53f3f2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 15 Apr 2021 19:43:16 +0200 Subject: [PATCH 35/60] stmgr: Improve ApplyBlocks metrics --- chain/stmgr/stmgr.go | 27 ++++++++++++++++++++++++--- metrics/metrics.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index ffbe08474ff..9dba6a781e1 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -4,14 +4,15 @@ import ( "context" "errors" "fmt" - "sync" - "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" logging "github.com/ipfs/go-log/v2" cbg "github.com/whyrusleeping/cbor-gen" + "go.opencensus.io/stats" "go.opencensus.io/trace" "golang.org/x/xerrors" + "sync" + "sync/atomic" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" @@ -43,6 +44,7 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/lotus/metrics" ) const LookbackNoLimit = abi.ChainEpoch(-1) @@ -280,6 +282,11 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c type ExecCallback func(cid.Cid, *types.Message, *vm.ApplyRet) error func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []store.BlockMessages, epoch abi.ChainEpoch, r vm.Rand, cb ExecCallback, baseFee abi.TokenAmount, ts *types.TipSet) (cid.Cid, cid.Cid, error) { + done := metrics.Timer(ctx, metrics.VMApplyBlocksTotal) + defer done() + + partDone := metrics.Timer(ctx, metrics.VMApplyEarly) + defer partDone() makeVmWithBaseState := func(base cid.Cid) (*vm.VM, error) { vmopt := &vm.VMOpts{ @@ -303,7 +310,6 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp } runCron := func(epoch abi.ChainEpoch) error { - cronMsg := &types.Message{ To: cron.Address, From: builtin.SystemActorAddr, @@ -362,6 +368,12 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp pstate = newState } + partDone() + partDone = metrics.Timer(ctx, metrics.VMApplyMessages) + + earlyDone := metrics.Timer(ctx, metrics.VMApplyEarly) + defer earlyDone() + var receipts []cbg.CBORMarshaler processedMsgs := make(map[cid.Cid]struct{}) for _, b := range bms { @@ -426,10 +438,16 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp } } + partDone() + partDone = metrics.Timer(ctx, metrics.VMApplyCron) + if err := runCron(epoch); err != nil { return cid.Cid{}, cid.Cid{}, err } + partDone() + partDone = metrics.Timer(ctx, metrics.VMApplyFlush) + rectarr := blockadt.MakeEmptyArray(sm.cs.ActorStore(ctx)) for i, receipt := range receipts { if err := rectarr.Set(uint64(i), receipt); err != nil { @@ -446,6 +464,9 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp return cid.Undef, cid.Undef, xerrors.Errorf("vm flush failed: %w", err) } + stats.Record(ctx, metrics.VMSends.M(int64(atomic.LoadUint64(&vm.StatSends))), + metrics.VMApplied.M(int64(atomic.LoadUint64(&vm.StatApplied)))) + return st, rectroot, nil } diff --git a/metrics/metrics.go b/metrics/metrics.go index 5428a81bcc7..9f6eb4b4283 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -76,6 +76,13 @@ var ( PubsubDropRPC = stats.Int64("pubsub/drop_rpc", "Counter for total dropped RPCs", stats.UnitDimensionless) VMFlushCopyDuration = stats.Float64("vm/flush_copy_ms", "Time spent in VM Flush Copy", stats.UnitMilliseconds) VMFlushCopyCount = stats.Int64("vm/flush_copy_count", "Number of copied objects", stats.UnitDimensionless) + VMApplyBlocksTotal = stats.Float64("vm/applyblocks_total_ms", "Time spent applying block state", stats.UnitMilliseconds) + VMApplyMessages = stats.Float64("vm/applyblocks_messages", "Time spent applying block messages", stats.UnitMilliseconds) + VMApplyEarly = stats.Float64("vm/applyblocks_early", "Time spent in early apply-blocks (null cron, upgrades)", stats.UnitMilliseconds) + VMApplyCron = stats.Float64("vm/applyblocks_cron", "Time spent in cron", stats.UnitMilliseconds) + VMApplyFlush = stats.Float64("vm/applyblocks_flush", "Time spent flushing vm state", stats.UnitMilliseconds) + VMSends = stats.Int64("vm/sends", "Counter for sends processed by the VM", stats.UnitDimensionless) + VMApplied = stats.Int64("vm/applied", "Counter for messages (including internal messages) processed by the VM", stats.UnitDimensionless) // miner WorkerCallsStarted = stats.Int64("sealing/worker_calls_started", "Counter of started worker tasks", stats.UnitDimensionless) @@ -208,6 +215,34 @@ var ( Measure: VMFlushCopyCount, Aggregation: view.Sum(), } + VMApplyBlocksTotalView = &view.View{ + Measure: VMApplyBlocksTotal, + Aggregation: defaultMillisecondsDistribution, + } + VMApplyMessagesView = &view.View{ + Measure: VMApplyMessages, + Aggregation: defaultMillisecondsDistribution, + } + VMApplyEarlyView = &view.View{ + Measure: VMApplyEarly, + Aggregation: defaultMillisecondsDistribution, + } + VMApplyCronView = &view.View{ + Measure: VMApplyCron, + Aggregation: defaultMillisecondsDistribution, + } + VMApplyFlushView = &view.View{ + Measure: VMApplyFlush, + Aggregation: defaultMillisecondsDistribution, + } + VMSendsView = &view.View{ + Measure: VMSends, + Aggregation: view.LastValue(), + } + VMAppliedView = &view.View{ + Measure: VMApplied, + Aggregation: view.LastValue(), + } // miner WorkerCallsStartedView = &view.View{ @@ -292,6 +327,13 @@ var ChainNodeViews = append([]*view.View{ SplitstoreCompactionHotView, SplitstoreCompactionColdView, SplitstoreCompactionDeadView, + VMApplyBlocksTotalView, + VMApplyMessagesView, + VMApplyEarlyView, + VMApplyCronView, + VMApplyFlushView, + VMSendsView, + VMAppliedView, }, DefaultViews...) var MinerNodeViews = append([]*view.View{ From 77d004ec06196eadf585bf34bc268d967a3e96db Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 15 Apr 2021 18:36:04 +0200 Subject: [PATCH 36/60] Fix nonce getting on Lotus lite Resolves #5593 #5995 Signed-off-by: Jakub Sztandera --- chain/messagesigner/messagesigner.go | 4 +- chain/messagesigner/messagesigner_test.go | 2 +- node/modules/mpoolnonceapi.go | 81 +++++++++++++++++------ 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/chain/messagesigner/messagesigner.go b/chain/messagesigner/messagesigner.go index ce9d01b3a99..9f7b7bb5ff7 100644 --- a/chain/messagesigner/messagesigner.go +++ b/chain/messagesigner/messagesigner.go @@ -23,7 +23,7 @@ const dsKeyActorNonce = "ActorNextNonce" var log = logging.Logger("messagesigner") type MpoolNonceAPI interface { - GetNonce(address.Address) (uint64, error) + GetNonce(context.Context, address.Address, types.TipSetKey) (uint64, error) } // MessageSigner keeps track of nonces per address, and increments the nonce @@ -97,7 +97,7 @@ func (ms *MessageSigner) nextNonce(addr address.Address) (uint64, error) { // that have mempool nonces, so first check the mempool for a nonce for // this address. Note that the mempool returns the actor state's nonce // by default. - nonce, err := ms.mpool.GetNonce(addr) + nonce, err := ms.mpool.GetNonce(context.TODO(), addr, types.EmptyTSK) if err != nil { return 0, xerrors.Errorf("failed to get nonce from mempool: %w", err) } diff --git a/chain/messagesigner/messagesigner_test.go b/chain/messagesigner/messagesigner_test.go index 5eebd36da5e..7bba5b3e9eb 100644 --- a/chain/messagesigner/messagesigner_test.go +++ b/chain/messagesigner/messagesigner_test.go @@ -35,7 +35,7 @@ func (mp *mockMpool) setNonce(addr address.Address, nonce uint64) { mp.nonces[addr] = nonce } -func (mp *mockMpool) GetNonce(addr address.Address) (uint64, error) { +func (mp *mockMpool) GetNonce(_ context.Context, addr address.Address, _ types.TipSetKey) (uint64, error) { mp.lk.RLock() defer mp.lk.RUnlock() diff --git a/node/modules/mpoolnonceapi.go b/node/modules/mpoolnonceapi.go index efcb14037db..61b38e821b2 100644 --- a/node/modules/mpoolnonceapi.go +++ b/node/modules/mpoolnonceapi.go @@ -2,6 +2,7 @@ package modules import ( "context" + "strings" "go.uber.org/fx" "golang.org/x/xerrors" @@ -19,41 +20,77 @@ import ( type MpoolNonceAPI struct { fx.In - StateAPI full.StateAPI + ChainModule full.ChainModuleAPI + StateModule full.StateModuleAPI } // GetNonce gets the nonce from current chain head. -func (a *MpoolNonceAPI) GetNonce(addr address.Address) (uint64, error) { - ts := a.StateAPI.Chain.GetHeaviestTipSet() +func (a *MpoolNonceAPI) GetNonce(ctx context.Context, addr address.Address, tsk types.TipSetKey) (uint64, error) { + var err error + var ts *types.TipSet + if tsk == types.EmptyTSK { + // we need consistent tsk + ts, err = a.ChainModule.ChainHead(ctx) + if err != nil { + return 0, xerrors.Errorf("getting head: %w", err) + } + tsk = ts.Key() + } else { + ts, err = a.ChainModule.ChainGetTipSet(ctx, tsk) + if err != nil { + return 0, xerrors.Errorf("getting tipset: %w", err) + } + } - // make sure we have a key address so we can compare with messages - keyAddr, err := a.StateAPI.StateManager.ResolveToKeyAddress(context.TODO(), addr, ts) - if err != nil { - return 0, err + keyAddr := addr + + if addr.Protocol() == address.ID { + // make sure we have a key address so we can compare with messages + keyAddr, err = a.StateModule.StateAccountKey(ctx, addr, tsk) + if err != nil { + return 0, xerrors.Errorf("getting account key: %w", err) + } + } else { + addr, err = a.StateModule.StateLookupID(ctx, addr, types.EmptyTSK) + if err != nil { + log.Infof("failed to look up id addr for %s: %w", addr, err) + addr = address.Undef + } } // Load the last nonce from the state, if it exists. highestNonce := uint64(0) - if baseActor, err := a.StateAPI.StateManager.LoadActorRaw(context.TODO(), addr, ts.ParentState()); err != nil { - if !xerrors.Is(err, types.ErrActorNotFound) { - return 0, err + act, err := a.StateModule.StateGetActor(ctx, keyAddr, ts.Key()) + if err != nil { + if strings.Contains(err.Error(), types.ErrActorNotFound.Error()) { + return 0, types.ErrActorNotFound } - } else { - highestNonce = baseActor.Nonce + return 0, xerrors.Errorf("getting actor: %w", err) } + highestNonce = act.Nonce - // Otherwise, find the highest nonce in the tipset. - msgs, err := a.StateAPI.Chain.MessagesForTipset(ts) - if err != nil { - return 0, err + apply := func(msg *types.Message) { + if msg.From != addr && msg.From != keyAddr { + return + } + if msg.Nonce == highestNonce { + highestNonce = msg.Nonce + 1 + } } - for _, msg := range msgs { - vmmsg := msg.VMMessage() - if vmmsg.From != keyAddr { - continue + + for _, b := range ts.Blocks() { + msgs, err := a.ChainModule.ChainGetBlockMessages(ctx, b.Cid()) + if err != nil { + return 0, xerrors.Errorf("getting block messages: %w", err) } - if vmmsg.Nonce >= highestNonce { - highestNonce = vmmsg.Nonce + 1 + if keyAddr.Protocol() == address.BLS { + for _, m := range msgs.BlsMessages { + apply(m) + } + } else { + for _, sm := range msgs.SecpkMessages { + apply(&sm.Message) + } } } return highestNonce, nil From fd0eb2ec8fc129778b14108cacae77c2d1eb3cd3 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Thu, 15 Apr 2021 19:59:25 +0200 Subject: [PATCH 37/60] Disable flaky checkpoint tests Signed-off-by: Jakub Sztandera --- chain/sync_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chain/sync_test.go b/chain/sync_test.go index c7cd66a8e67..21bc208ed7e 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -751,6 +751,8 @@ func TestSyncInputs(t *testing.T) { } func TestSyncCheckpointHead(t *testing.T) { + t.Skip("flaky") + H := 10 tu := prepSyncTest(t, H) @@ -793,6 +795,8 @@ func TestSyncCheckpointHead(t *testing.T) { } func TestSyncCheckpointEarlierThanHead(t *testing.T) { + t.Skip("flaky") + H := 10 tu := prepSyncTest(t, H) From e006310c6f23faf68d0aa7b7c0024f7937accc9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 15 Apr 2021 23:02:13 +0200 Subject: [PATCH 38/60] sigs: vector tests for bls --- lib/sigs/bls/bls_test.go | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 lib/sigs/bls/bls_test.go diff --git a/lib/sigs/bls/bls_test.go b/lib/sigs/bls/bls_test.go new file mode 100644 index 00000000000..4508d0eb9b2 --- /dev/null +++ b/lib/sigs/bls/bls_test.go @@ -0,0 +1,77 @@ +package bls_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/crypto" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/wallet" + "github.com/filecoin-project/lotus/lib/sigs" + _ "github.com/filecoin-project/lotus/lib/sigs/bls" +) + +func TestRoundtrip(t *testing.T) { + pk, err := sigs.Generate(crypto.SigTypeBLS) + require.NoError(t, err) + + ki := types.KeyInfo{ + Type: types.KTBLS, + PrivateKey: pk, + } + k, err := wallet.NewKey(ki) + require.NoError(t, err) + + p := []byte("potato") + + si, err := sigs.Sign(crypto.SigTypeBLS, pk, p) + require.NoError(t, err) + + err = sigs.Verify(si, k.Address, p) + require.NoError(t, err) +} + +func TestUncompressedFails(t *testing.T) { + // compressed + err := sigs.Verify(&crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{0x99, 0x27, 0x44, 0x4b, 0xfc, 0xff, 0xdc, 0xa3, 0x4a, 0xf5, 0x7b, 0x78, 0x75, 0x7b, 0x9b, 0x90, 0xf1, 0xcd, 0x28, 0xd2, 0xa3, 0xae, 0xed, 0x2a, 0xa6, 0xbd, 0xe2, 0x99, 0xf8, 0xbb, 0xb9, 0x18, 0x47, 0x56, 0xf2, 0x28, 0x7b, 0x5, 0x88, 0xe6, 0xd3, 0xf2, 0x86, 0xd, 0x2b, 0xb2, 0x6, 0x6e, 0xc, 0x59, 0x77, 0x8c, 0x1e, 0x64, 0x4f, 0xb2, 0xcf, 0xb3, 0x5f, 0xba, 0x8f, 0x9, 0xfa, 0x82, 0x4a, 0x9e, 0xd8, 0x25, 0x10, 0x8c, 0x82, 0xff, 0x4b, 0xf6, 0x34, 0xc1, 0x3, 0x7e, 0xea, 0xf1, 0x85, 0xf4, 0x56, 0x73, 0xd4, 0xa1, 0xc1, 0xc6, 0xee, 0xb7, 0x12, 0xb7, 0xd7, 0x2a, 0x54, 0x98}, + }, mustAddr("f3tcgq5scpfhdwh4dbalwktzf6mbv3ng2nw7tyzni5cyrsgvineid6jybnweecpa6misa6lk4tvwtxj2gkwpzq"), []byte{0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f}) + require.NoError(t, err) + + // compressed byte changed + err = sigs.Verify(&crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{0x99, 0x27, 0x44, 0x4b, 0xfc, 0xff, 0xdc, 0xa3, 0x4a, 0xf5, 0x7b, 0x78, 0x75, 0x7b, 0x9b, 0x90, 0xf1, 0xcd, 0x28, 0xd2, 0xa3, 0xae, 0xed, 0x2a, 0xa6, 0xbd, 0xe2, 0x99, 0xf8, 0xbb, 0xb9, 0x18, 0x47, 0x56, 0xf2, 0x28, 0x7b, 0x5, 0x88, 0xf6, 0xd3, 0xf2, 0x86, 0xd, 0x2b, 0xb2, 0x6, 0x6e, 0xc, 0x59, 0x77, 0x8c, 0x1e, 0x64, 0x4f, 0xb2, 0xcf, 0xb3, 0x5f, 0xba, 0x8f, 0x9, 0xfa, 0x82, 0x4a, 0x9e, 0xd8, 0x25, 0x10, 0x8c, 0x82, 0xff, 0x4b, 0xf6, 0x34, 0xc1, 0x3, 0x7e, 0xea, 0xf1, 0x85, 0xf4, 0x56, 0x73, 0xd4, 0xa1, 0xc1, 0xc6, 0xee, 0xb7, 0x12, 0xb7, 0xd7, 0x2a, 0x54, 0x98}, + }, mustAddr("f3tcgq5scpfhdwh4dbalwktzf6mbv3ng2nw7tyzni5cyrsgvineid6jybnweecpa6misa6lk4tvwtxj2gkwpzq"), []byte{0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f}) + require.Error(t, err) + + // compressed prefix + err = sigs.Verify(&crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{0x99, 0x27, 0x44, 0x4b, 0xfc, 0xff, 0xdc, 0xa3, 0x4a, 0xf5, 0x7b, 0x78, 0x75, 0x7b, 0x9b, 0x90, 0xf1, 0xcd, 0x28, 0xd2, 0xa3, 0xae, 0xed, 0x2a, 0xa6, 0xbd, 0xe2, 0x99, 0xf8, 0xbb, 0xb9, 0x18, 0x47, 0x56, 0xf2, 0x28, 0x7b, 0x5, 0x88, 0xe6, 0xd3, 0xf2, 0x86, 0xd, 0x2b, 0xb2, 0x6, 0x6e, 0xc, 0x59, 0x77, 0x8c, 0x1e, 0x64, 0x4f, 0xb2, 0xcf, 0xb3, 0x5f, 0xba, 0x8f, 0x9, 0xfa, 0x82, 0x4a, 0x9e, 0xd8, 0x25, 0x10, 0x8c, 0x82, 0xff, 0x4b, 0xf6, 0x34, 0xc1, 0x3, 0x7e, 0xea, 0xf1, 0x85, 0xf4, 0x56, 0x73, 0xd4, 0xa1, 0xc1, 0xc6, 0xee, 0xb7, 0x12, 0xb7, 0xd7, 0x2a, 0x54, 0x98, 0x55}, + }, mustAddr("f3tcgq5scpfhdwh4dbalwktzf6mbv3ng2nw7tyzni5cyrsgvineid6jybnweecpa6misa6lk4tvwtxj2gkwpzq"), []byte{0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f}) + require.Error(t, err) + + // uncompressed + err = sigs.Verify(&crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{0x19, 0x27, 0x44, 0x4b, 0xfc, 0xff, 0xdc, 0xa3, 0x4a, 0xf5, 0x7b, 0x78, 0x75, 0x7b, 0x9b, 0x90, 0xf1, 0xcd, 0x28, 0xd2, 0xa3, 0xae, 0xed, 0x2a, 0xa6, 0xbd, 0xe2, 0x99, 0xf8, 0xbb, 0xb9, 0x18, 0x47, 0x56, 0xf2, 0x28, 0x7b, 0x5, 0x88, 0xe6, 0xd3, 0xf2, 0x86, 0xd, 0x2b, 0xb2, 0x6, 0x6e, 0xc, 0x59, 0x77, 0x8c, 0x1e, 0x64, 0x4f, 0xb2, 0xcf, 0xb3, 0x5f, 0xba, 0x8f, 0x9, 0xfa, 0x82, 0x4a, 0x9e, 0xd8, 0x25, 0x10, 0x8c, 0x82, 0xff, 0x4b, 0xf6, 0x34, 0xc1, 0x3, 0x7e, 0xea, 0xf1, 0x85, 0xf4, 0x56, 0x73, 0xd4, 0xa1, 0xc1, 0xc6, 0xee, 0xb7, 0x12, 0xb7, 0xd7, 0x2a, 0x54, 0x98, 0x8, 0x94, 0x23, 0x78, 0xdb, 0xce, 0x2a, 0xd7, 0x2e, 0x87, 0xdf, 0x8, 0x3b, 0x66, 0xc6, 0x31, 0xc1, 0x8c, 0x58, 0x2f, 0x9f, 0x9e, 0x10, 0x4d, 0x2a, 0x7e, 0x13, 0xe7, 0x9c, 0xbb, 0x22, 0xde, 0xcc, 0xf6, 0x77, 0x77, 0xb0, 0x9c, 0x25, 0x5d, 0x5d, 0xe6, 0x88, 0x9, 0x8c, 0x63, 0x35, 0xd4, 0xa, 0x85, 0x76, 0x8d, 0xb7, 0x66, 0xa6, 0xc6, 0xec, 0xe6, 0xde, 0x2a, 0x9f, 0x34, 0x87, 0x28, 0x1a, 0x48, 0xfe, 0xca, 0xb1, 0x47, 0x2, 0xf6, 0x51, 0x26, 0x52, 0x70, 0x9d, 0x7e, 0xdb, 0x7e, 0x8b, 0xc9, 0xf6, 0x41, 0xaa, 0xa8, 0x3b, 0x7e, 0x8a, 0xfd, 0x7a, 0xe4, 0x79, 0xe6, 0x59, 0xe4}, + }, mustAddr("f3tcgq5scpfhdwh4dbalwktzf6mbv3ng2nw7tyzni5cyrsgvineid6jybnweecpa6misa6lk4tvwtxj2gkwpzq"), []byte{0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f}) + require.Error(t, err) + + // uncompressed one byte change + err = sigs.Verify(&crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{0x19, 0x27, 0x44, 0x4b, 0xfc, 0xff, 0xdc, 0xa3, 0x4a, 0xf5, 0x7b, 0x78, 0x75, 0x7b, 0x9b, 0x90, 0xf1, 0xcd, 0x28, 0xd2, 0xa3, 0xae, 0xed, 0x2a, 0xa6, 0xbd, 0xe2, 0x99, 0xf8, 0xbb, 0xb9, 0x18, 0x47, 0x56, 0xf2, 0x28, 0x7b, 0x5, 0x88, 0xe6, 0xd3, 0xf2, 0x86, 0xd, 0x2b, 0xb2, 0x6, 0x6e, 0xc, 0x59, 0x77, 0x8c, 0x1e, 0x64, 0x4f, 0xb2, 0xcf, 0xb3, 0x5f, 0xba, 0x8f, 0x9, 0xfa, 0x82, 0x4a, 0x9e, 0xd8, 0x25, 0x10, 0x8c, 0x82, 0xff, 0x4b, 0xf6, 0x34, 0xc1, 0x3, 0x7e, 0xea, 0xf1, 0x85, 0xf4, 0x56, 0x73, 0xd4, 0xa1, 0xc1, 0xc6, 0xee, 0xb7, 0x12, 0xb7, 0xd7, 0x2a, 0x54, 0x98, 0x8, 0x94, 0x23, 0x78, 0xdb, 0xce, 0x2a, 0xd7, 0x2e, 0x87, 0xdf, 0x8, 0x3b, 0x66, 0xc6, 0x31, 0xc1, 0x8c, 0x58, 0x2f, 0x9f, 0x9e, 0x10, 0x4d, 0x2a, 0x7e, 0x13, 0xe7, 0x9c, 0xbb, 0x22, 0xde, 0xcc, 0xf6, 0x77, 0x77, 0xb0, 0x9c, 0x25, 0x5d, 0x5d, 0xe6, 0x88, 0x9, 0x8c, 0x63, 0x35, 0xd4, 0xa, 0x85, 0x66, 0x8d, 0xb7, 0x66, 0xa6, 0xc6, 0xec, 0xe6, 0xde, 0x2a, 0x9f, 0x34, 0x87, 0x28, 0x1a, 0x48, 0xfe, 0xca, 0xb1, 0x47, 0x2, 0xf6, 0x51, 0x26, 0x52, 0x70, 0x9d, 0x7e, 0xdb, 0x7e, 0x8b, 0xc9, 0xf6, 0x41, 0xaa, 0xa8, 0x3b, 0x7e, 0x8a, 0xfd, 0x7a, 0xe4, 0x79, 0xe6, 0x59, 0xe4}, + }, mustAddr("f3tcgq5scpfhdwh4dbalwktzf6mbv3ng2nw7tyzni5cyrsgvineid6jybnweecpa6misa6lk4tvwtxj2gkwpzq"), []byte{0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f}) + require.Error(t, err) +} + +func mustAddr(a string) address.Address { + ad, _ := address.NewFromString(a) + return ad +} From 4436c184ed4e4fa591e92c11a9d615f80b1d2c15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 16 Apr 2021 00:19:26 +0200 Subject: [PATCH 39/60] Fix v0/v1 API versions --- api/docgen/docgen.go | 2 +- api/v0api/v1_wrapper.go | 11 ++++++++ api/version.go | 14 ++++++---- build/openrpc/worker.json.gz | Bin 2577 -> 2577 bytes cmd/lotus-seal-worker/main.go | 4 +-- cmd/lotus-seal-worker/rpc.go | 2 +- cmd/lotus-storage-miner/init.go | 29 ++++++++++++++++++-- cmd/lotus-storage-miner/init_restore.go | 12 +++++--- cmd/lotus-storage-miner/run.go | 22 +++++++++------ documentation/en/api-v0-methods-miner.md | 2 +- documentation/en/api-v0-methods-worker.md | 2 +- documentation/en/api-v0-methods.md | 2 +- documentation/en/api-v1-unstable-methods.md | 2 +- 13 files changed, 75 insertions(+), 29 deletions(-) diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 9ce10edfef2..8357ff9b52e 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -114,7 +114,7 @@ func init() { addExample(network.Connected) addExample(dtypes.NetworkName("lotus")) addExample(api.SyncStateStage(1)) - addExample(api.FullAPIVersion) + addExample(api.FullAPIVersion1) addExample(api.PCHInbound) addExample(time.Minute) addExample(datatransfer.TransferID(3)) diff --git a/api/v0api/v1_wrapper.go b/api/v0api/v1_wrapper.go index bb33fa12aa4..e977c6b67d9 100644 --- a/api/v0api/v1_wrapper.go +++ b/api/v0api/v1_wrapper.go @@ -46,4 +46,15 @@ func (w *WrapperV1Full) StateGetReceipt(ctx context.Context, msg cid.Cid, from t return &ml.Receipt, nil } +func (w *WrapperV1Full) Version(ctx context.Context) (api.APIVersion, error) { + ver, err := w.FullNode.Version(ctx) + if err != nil { + return api.APIVersion{}, err + } + + ver.APIVersion = api.FullAPIVersion0 + + return ver, nil +} + var _ FullNode = &WrapperV1Full{} diff --git a/api/version.go b/api/version.go index 17605b518a6..f419663e6a7 100644 --- a/api/version.go +++ b/api/version.go @@ -42,11 +42,11 @@ var RunningNodeType NodeType func VersionForType(nodeType NodeType) (Version, error) { switch nodeType { case NodeFull: - return FullAPIVersion, nil + return FullAPIVersion1, nil case NodeMiner: - return MinerAPIVersion, nil + return MinerAPIVersion0, nil case NodeWorker: - return WorkerAPIVersion, nil + return WorkerAPIVersion0, nil default: return Version(0), xerrors.Errorf("unknown node type %d", nodeType) } @@ -54,9 +54,11 @@ func VersionForType(nodeType NodeType) (Version, error) { // semver versions of the rpc api exposed var ( - FullAPIVersion = newVer(1, 1, 0) - MinerAPIVersion = newVer(1, 0, 1) - WorkerAPIVersion = newVer(1, 0, 0) + FullAPIVersion0 = newVer(1, 2, 0) + FullAPIVersion1 = newVer(2, 0, 0) + + MinerAPIVersion0 = newVer(1, 0, 1) + WorkerAPIVersion0 = newVer(1, 0, 0) ) //nolint:varcheck,deadcode diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index ed8df4b220ff5c0286707875bea30049b969a2c1..eaae7109d1ad5e5613ba22393d60c4a09e07eafd 100644 GIT binary patch delta 100 zcmV-q0Gt1j6p<9LwFz8HHm`TodE2dR^>&qg3bKjc2vz?ID5#1I6vO4R(6gDDBxpY8 z#68f+<@TLK0aMgPY6=1n5rCLEYmrC&`Tg6H#_`F{fd0RR7-oXROq GdH?`;T`v;= delta 100 zcmV-q0Gt1j6p<9LwFz81Ht*#4?YnMmqqnQvQ;kpF1PO_3YelUQd1CshycXQQHw+(U@SbK`9)rPb(xam6Fi^a%>Nqz0RR8MaITn5 GdH?{h)i1>W diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index 0f0cb88e6f1..693b833a539 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -210,8 +210,8 @@ var runCmd = &cli.Command{ if err != nil { return err } - if v.APIVersion != api.MinerAPIVersion { - return xerrors.Errorf("lotus-miner API version doesn't match: expected: %s", api.APIVersion{APIVersion: api.MinerAPIVersion}) + if v.APIVersion != api.MinerAPIVersion0 { + return xerrors.Errorf("lotus-miner API version doesn't match: expected: %s", api.APIVersion{APIVersion: api.MinerAPIVersion0}) } log.Infof("Remote version %s", v) diff --git a/cmd/lotus-seal-worker/rpc.go b/cmd/lotus-seal-worker/rpc.go index 3649d6c8f9e..6a6263671bd 100644 --- a/cmd/lotus-seal-worker/rpc.go +++ b/cmd/lotus-seal-worker/rpc.go @@ -26,7 +26,7 @@ type worker struct { } func (w *worker) Version(context.Context) (api.Version, error) { - return api.WorkerAPIVersion, nil + return api.WorkerAPIVersion0, nil } func (w *worker) StorageAddLocal(ctx context.Context, path string) error { diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index abb8d3abe48..a02520116ce 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -151,6 +151,10 @@ var initCmd = &cli.Command{ log.Info("Trying to connect to full node RPC") + if err := checkV1ApiSupport(ctx, cctx); err != nil { + return err + } + api, closer, err := lcli.GetFullNodeAPIV1(cctx) // TODO: consider storing full node address in config if err != nil { return err @@ -188,8 +192,8 @@ var initCmd = &cli.Command{ return err } - if !v.APIVersion.EqMajorMinor(lapi.FullAPIVersion) { - return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", lapi.FullAPIVersion, v.APIVersion) + if !v.APIVersion.EqMajorMinor(lapi.FullAPIVersion1) { + return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", lapi.FullAPIVersion1, v.APIVersion) } log.Info("Initializing repo") @@ -719,3 +723,24 @@ func createStorageMiner(ctx context.Context, api v1api.FullNode, peerid peer.ID, log.Infof("New miners address is: %s (%s)", retval.IDAddress, retval.RobustAddress) return retval.IDAddress, nil } + +func checkV1ApiSupport(ctx context.Context, cctx *cli.Context) error { + // check v0 api version to make sure it supports v1 api + api0, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + + v, err := api0.Version(ctx) + closer() + + if err != nil { + return err + } + + if !v.APIVersion.EqMajorMinor(lapi.FullAPIVersion0) { + return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", lapi.FullAPIVersion0, v.APIVersion) + } + + return nil +} diff --git a/cmd/lotus-storage-miner/init_restore.go b/cmd/lotus-storage-miner/init_restore.go index 082c456148d..eec7b841389 100644 --- a/cmd/lotus-storage-miner/init_restore.go +++ b/cmd/lotus-storage-miner/init_restore.go @@ -54,8 +54,14 @@ var initRestoreCmd = &cli.Command{ return xerrors.Errorf("expected 1 argument") } + ctx := lcli.ReqContext(cctx) + log.Info("Trying to connect to full node RPC") + if err := checkV1ApiSupport(ctx, cctx); err != nil { + return err + } + api, closer, err := lcli.GetFullNodeAPIV1(cctx) // TODO: consider storing full node address in config if err != nil { return err @@ -64,15 +70,13 @@ var initRestoreCmd = &cli.Command{ log.Info("Checking full node version") - ctx := lcli.ReqContext(cctx) - v, err := api.Version(ctx) if err != nil { return err } - if !v.APIVersion.EqMajorMinor(lapi.FullAPIVersion) { - return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", lapi.FullAPIVersion, v.APIVersion) + if !v.APIVersion.EqMajorMinor(lapi.FullAPIVersion1) { + return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", lapi.FullAPIVersion1, v.APIVersion) } if !cctx.Bool("nosync") { diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index f7a4efd1af0..5d67cf33dfd 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -67,19 +67,13 @@ var runCmd = &cli.Command{ } } - nodeApi, ncloser, err := lcli.GetFullNodeAPIV1(cctx) - if err != nil { - return xerrors.Errorf("getting full node api: %w", err) - } - defer ncloser() - ctx, _ := tag.New(lcli.DaemonContext(cctx), tag.Insert(metrics.Version, build.BuildVersion), tag.Insert(metrics.Commit, build.CurrentCommit), tag.Insert(metrics.NodeType, "miner"), ) // Register all metric views - if err = view.Register( + if err := view.Register( metrics.MinerNodeViews..., ); err != nil { log.Fatalf("Cannot register the view: %v", err) @@ -87,6 +81,16 @@ var runCmd = &cli.Command{ // Set the metric to one so it is published to the exporter stats.Record(ctx, metrics.LotusInfo.M(1)) + if err := checkV1ApiSupport(ctx, cctx); err != nil { + return err + } + + nodeApi, ncloser, err := lcli.GetFullNodeAPIV1(cctx) + if err != nil { + return xerrors.Errorf("getting full node api: %w", err) + } + defer ncloser() + v, err := nodeApi.Version(ctx) if err != nil { return err @@ -98,8 +102,8 @@ var runCmd = &cli.Command{ } } - if v.APIVersion != api.FullAPIVersion { - return xerrors.Errorf("lotus-daemon API version doesn't match: expected: %s", api.APIVersion{APIVersion: api.FullAPIVersion}) + if v.APIVersion != api.FullAPIVersion1 { + return xerrors.Errorf("lotus-daemon API version doesn't match: expected: %s", api.APIVersion{APIVersion: api.FullAPIVersion1}) } log.Info("Checking full node sync status") diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index 9d33a55d008..6f1c076a6aa 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -193,7 +193,7 @@ Response: ```json { "Version": "string value", - "APIVersion": 65792, + "APIVersion": 131072, "BlockDelay": 42 } ``` diff --git a/documentation/en/api-v0-methods-worker.md b/documentation/en/api-v0-methods-worker.md index 40300866edf..a697258a406 100644 --- a/documentation/en/api-v0-methods-worker.md +++ b/documentation/en/api-v0-methods-worker.md @@ -145,7 +145,7 @@ Perms: admin Inputs: `null` -Response: `65792` +Response: `131072` ## Add diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index a3b956ee798..52f09b163e9 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -276,7 +276,7 @@ Response: ```json { "Version": "string value", - "APIVersion": 65792, + "APIVersion": 131072, "BlockDelay": 42 } ``` diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 4bf57b4f69a..bfc4482c36c 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -273,7 +273,7 @@ Response: ```json { "Version": "string value", - "APIVersion": 65792, + "APIVersion": 131072, "BlockDelay": 42 } ``` From 0e6fe269754394a9dd3d6462036fb0f32b5dc065 Mon Sep 17 00:00:00 2001 From: Kwuaint <34888408+kwuaint@users.noreply.github.com> Date: Fri, 16 Apr 2021 11:43:18 +0800 Subject: [PATCH 40/60] Remove the usless commented code Remove the usless commented code --- lotuspond/spawn.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index ce01b115e50..9085bc24ab7 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -142,11 +142,6 @@ func (api *api) Spawn() (nodeInfo, error) { api.runningLk.Lock() api.running[id].meta.State = NodeStopped api.runningLk.Unlock() - - //logfile.Close() - //errlogfile.Close() - - //close(mux.stop) }, } api.runningLk.Unlock() @@ -221,11 +216,6 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { api.runningLk.Lock() api.running[id].meta.State = NodeStopped api.runningLk.Unlock() - - //logfile.Close() - //errlogfile.Close() - - //close(mux.stop) }, } api.runningLk.Unlock() @@ -272,11 +262,6 @@ func (api *api) RestartNode(id int32) (nodeInfo, error) { api.runningLk.Lock() api.running[id].meta.State = NodeStopped api.runningLk.Unlock() - - //logfile.Close() - //errlogfile.Close() - - //close(mux.stop) } nd.meta.State = NodeRunning From 1b696aae5f3e125e10132be1dcf493ef546f17c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 16 Apr 2021 14:57:59 +0200 Subject: [PATCH 41/60] stmgr: Fix VMApplyEarly metric --- chain/stmgr/stmgr.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 9dba6a781e1..ed8c1824265 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -371,9 +371,6 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp partDone() partDone = metrics.Timer(ctx, metrics.VMApplyMessages) - earlyDone := metrics.Timer(ctx, metrics.VMApplyEarly) - defer earlyDone() - var receipts []cbg.CBORMarshaler processedMsgs := make(map[cid.Cid]struct{}) for _, b := range bms { From 66c408938b4412768194ac35182328a90aaa12e4 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Fri, 16 Apr 2021 17:18:54 +0200 Subject: [PATCH 42/60] Fix signature in messagepool, wire in context Signed-off-by: Jakub Sztandera --- chain/messagepool/messagepool.go | 2 +- chain/messagepool/messagepool_test.go | 2 +- chain/messagesigner/messagesigner.go | 6 +++--- node/impl/full/mpool.go | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index c2566ae2486..40d0c4eaf5c 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -795,7 +795,7 @@ func (mp *MessagePool) addLocked(m *types.SignedMessage, strict, untrusted bool) return nil } -func (mp *MessagePool) GetNonce(addr address.Address) (uint64, error) { +func (mp *MessagePool) GetNonce(_ context.Context, addr address.Address, _ types.TipSetKey) (uint64, error) { mp.curTsLk.Lock() defer mp.curTsLk.Unlock() diff --git a/chain/messagepool/messagepool_test.go b/chain/messagepool/messagepool_test.go index e31df936c8f..8e4f16a30f9 100644 --- a/chain/messagepool/messagepool_test.go +++ b/chain/messagepool/messagepool_test.go @@ -199,7 +199,7 @@ func (tma *testMpoolAPI) ChainComputeBaseFee(ctx context.Context, ts *types.TipS func assertNonce(t *testing.T, mp *MessagePool, addr address.Address, val uint64) { t.Helper() - n, err := mp.GetNonce(addr) + n, err := mp.GetNonce(context.Background(), addr, types.EmptyTSK) if err != nil { t.Fatal(err) } diff --git a/chain/messagesigner/messagesigner.go b/chain/messagesigner/messagesigner.go index 9f7b7bb5ff7..c91f75632ea 100644 --- a/chain/messagesigner/messagesigner.go +++ b/chain/messagesigner/messagesigner.go @@ -51,7 +51,7 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, cb defer ms.lk.Unlock() // Get the next message nonce - nonce, err := ms.nextNonce(msg.From) + nonce, err := ms.nextNonce(ctx, msg.From) if err != nil { return nil, xerrors.Errorf("failed to create nonce: %w", err) } @@ -92,12 +92,12 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, cb // nextNonce gets the next nonce for the given address. // If there is no nonce in the datastore, gets the nonce from the message pool. -func (ms *MessageSigner) nextNonce(addr address.Address) (uint64, error) { +func (ms *MessageSigner) nextNonce(ctx context.Context, addr address.Address) (uint64, error) { // Nonces used to be created by the mempool and we need to support nodes // that have mempool nonces, so first check the mempool for a nonce for // this address. Note that the mempool returns the actor state's nonce // by default. - nonce, err := ms.mpool.GetNonce(context.TODO(), addr, types.EmptyTSK) + nonce, err := ms.mpool.GetNonce(ctx, addr, types.EmptyTSK) if err != nil { return 0, xerrors.Errorf("failed to get nonce from mempool: %w", err) } diff --git a/node/impl/full/mpool.go b/node/impl/full/mpool.go index 1cc2d24d78f..31c8bc4f704 100644 --- a/node/impl/full/mpool.go +++ b/node/impl/full/mpool.go @@ -226,7 +226,7 @@ func (a *MpoolAPI) MpoolBatchPushMessage(ctx context.Context, msgs []*types.Mess } func (a *MpoolAPI) MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error) { - return a.Mpool.GetNonce(addr) + return a.Mpool.GetNonce(ctx, addr, types.EmptyTSK) } func (a *MpoolAPI) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate, error) { From c118415b124ae6d662806f8c6e78092c6685bd2a Mon Sep 17 00:00:00 2001 From: frrist Date: Fri, 16 Apr 2021 15:15:38 -0700 Subject: [PATCH 43/60] polish(api): expose filReserveDisbursed via CirculatingSupply API - motivated by: https://github.com/filecoin-project/sentinel-visor/issues/462 --- api/api_full.go | 11 ++++++----- chain/stmgr/stmgr.go | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 0a2463505a3..c6d32893452 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -999,11 +999,12 @@ type DealCollateralBounds struct { } type CirculatingSupply struct { - FilVested abi.TokenAmount - FilMined abi.TokenAmount - FilBurnt abi.TokenAmount - FilLocked abi.TokenAmount - FilCirculating abi.TokenAmount + FilVested abi.TokenAmount + FilMined abi.TokenAmount + FilBurnt abi.TokenAmount + FilLocked abi.TokenAmount + FilCirculating abi.TokenAmount + FilReserveDisbursed abi.TokenAmount } type MiningBaseInfo struct { diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 38e2a32c6b9..3e9a6d836c0 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -1279,11 +1279,12 @@ func (sm *StateManager) GetVMCirculatingSupplyDetailed(ctx context.Context, heig } return api.CirculatingSupply{ - FilVested: filVested, - FilMined: filMined, - FilBurnt: filBurnt, - FilLocked: filLocked, - FilCirculating: ret, + FilVested: filVested, + FilMined: filMined, + FilBurnt: filBurnt, + FilLocked: filLocked, + FilCirculating: ret, + FilReserveDisbursed: filReserveDisbursed, }, nil } From dab2a417929a14edfae0b6348ae3eb57a44a806b Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Sat, 17 Apr 2021 00:35:40 +0200 Subject: [PATCH 44/60] Raise client MaxFee default The original value is too conservative for the current state of mainnet Resolves (temporarily) #5543 --- node/config/def.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/config/def.go b/node/config/def.go index 63099516b1e..b4cf5e2fae5 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -205,7 +205,7 @@ func defCommon() Common { } -var DefaultDefaultMaxFee = types.MustParseFIL("0.007") +var DefaultDefaultMaxFee = types.MustParseFIL("0.07") var DefaultSimultaneousTransfers = uint64(20) // DefaultFullNode returns the default config From bb7801e6b71b69034ceb247b506799c8aab4d048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 18 Apr 2021 16:17:31 +0200 Subject: [PATCH 45/60] fix lint --- chain/stmgr/stmgr.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index ed8c1824265..7f850039978 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -4,6 +4,9 @@ import ( "context" "errors" "fmt" + "sync" + "sync/atomic" + "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" logging "github.com/ipfs/go-log/v2" @@ -11,8 +14,6 @@ import ( "go.opencensus.io/stats" "go.opencensus.io/trace" "golang.org/x/xerrors" - "sync" - "sync/atomic" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" @@ -286,7 +287,9 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp defer done() partDone := metrics.Timer(ctx, metrics.VMApplyEarly) - defer partDone() + defer func() { + partDone() + }() makeVmWithBaseState := func(base cid.Cid) (*vm.VM, error) { vmopt := &vm.VMOpts{ From 03df99f2f57f7fb745ff23ebaabe38a29860aee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 18 Apr 2021 16:27:23 +0200 Subject: [PATCH 46/60] make gen --- build/openrpc/full.json.gz | Bin 22465 -> 22486 bytes documentation/en/api-v0-methods.md | 3 ++- documentation/en/api-v1-unstable-methods.md | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 1e995899520c08f65d32debb37b873695c1119d5..0e258fe6408f879d7dec01298b2524ef89e6f03b 100644 GIT binary patch literal 22486 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 LK#s5Y5fSiTw*JII diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index a3b956ee798..eaf828cf452 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -4943,7 +4943,8 @@ Response: "FilMined": "0", "FilBurnt": "0", "FilLocked": "0", - "FilCirculating": "0" + "FilCirculating": "0", + "FilReserveDisbursed": "0" } ``` diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 4bf57b4f69a..2fb9c570b28 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -4857,7 +4857,8 @@ Response: "FilMined": "0", "FilBurnt": "0", "FilLocked": "0", - "FilCirculating": "0" + "FilCirculating": "0", + "FilReserveDisbursed": "0" } ``` From 508e2d5c499f4f8b1f93b44d854230422003f93d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 20 Apr 2021 18:42:12 +0200 Subject: [PATCH 47/60] gateway: Fix api getter --- api/client/client.go | 14 ++ api/v0api/gateway.go | 50 +++++++ api/v0api/latest.go | 2 - api/v0api/proxy_gen.go | 299 +++++++++++++++++++++++++++++++++++++++++ cli/util/api.go | 11 +- 5 files changed, 373 insertions(+), 3 deletions(-) create mode 100644 api/v0api/gateway.go diff --git a/api/client/client.go b/api/client/client.go index 0165bcbd8b3..90fe714bf72 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -110,6 +110,20 @@ func NewGatewayRPCV1(ctx context.Context, addr string, requestHeader http.Header return &res, closer, err } +// NewGatewayRPCV0 creates a new http jsonrpc client for a gateway node. +func NewGatewayRPCV0(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (v0api.Gateway, jsonrpc.ClientCloser, error) { + var res v0api.GatewayStruct + closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", + []interface{}{ + &res.Internal, + }, + requestHeader, + opts..., + ) + + return &res, closer, err +} + func NewWalletRPCV0(ctx context.Context, addr string, requestHeader http.Header) (api.Wallet, jsonrpc.ClientCloser, error) { var res api.WalletStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", diff --git a/api/v0api/gateway.go b/api/v0api/gateway.go new file mode 100644 index 00000000000..a5ea73a01ca --- /dev/null +++ b/api/v0api/gateway.go @@ -0,0 +1,50 @@ +package v0api + +import ( + "context" + + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/go-state-types/network" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" +) + +type Gateway interface { + ChainHasObj(context.Context, cid.Cid) (bool, 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) + ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) + ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) + ChainNotify(context.Context) (<-chan []*api.HeadChange, error) + ChainReadObj(context.Context, cid.Cid) ([]byte, error) + GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) + MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) + MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) + MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) + MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*api.MsigTransaction, error) + StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) + StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) + StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) + StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) + StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) + StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) + StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) + StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) + StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) + StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) + StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) + StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error) + StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) + StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) + StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) + StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) +} + +var _ Gateway = *new(FullNode) diff --git a/api/v0api/latest.go b/api/v0api/latest.go index 9d64b645021..87f977be608 100644 --- a/api/v0api/latest.go +++ b/api/v0api/latest.go @@ -8,8 +8,6 @@ type Common = api.Common type CommonStruct = api.CommonStruct type CommonStub = api.CommonStub -type Gateway = api.Gateway - type StorageMiner = api.StorageMiner type StorageMinerStruct = api.StorageMinerStruct diff --git a/api/v0api/proxy_gen.go b/api/v0api/proxy_gen.go index a32371f4f97..b53f802c36a 100644 --- a/api/v0api/proxy_gen.go +++ b/api/v0api/proxy_gen.go @@ -14,6 +14,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" apitypes "github.com/filecoin-project/lotus/api/types" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -382,6 +383,71 @@ type FullNodeStub struct { CommonStub } +type GatewayStruct struct { + Internal struct { + ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `` + + ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `` + + ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `` + + ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `` + + ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` + + ChainHead func(p0 context.Context) (*types.TipSet, error) `` + + ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `` + + ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` + + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` + + MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `` + + MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `` + + MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) `` + + MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `` + + StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` + + StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) `` + + StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `` + + StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) `` + + StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `` + + StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` + + StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) `` + + StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) `` + + StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) `` + + StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) `` + + StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `` + + StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (network.Version, error) `` + + StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `` + + StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `` + + StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` + + StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `` + } +} + +type GatewayStub struct { +} + func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { return s.Internal.BeaconGetEntry(p0, p1) } @@ -1766,4 +1832,237 @@ func (s *FullNodeStub) WalletVerify(p0 context.Context, p1 address.Address, p2 [ return false, xerrors.New("method not supported") } +func (s *GatewayStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { + return s.Internal.ChainGetBlockMessages(p0, p1) +} + +func (s *GatewayStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return s.Internal.ChainGetMessage(p0, p1) +} + +func (s *GatewayStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSet(p0, p1) +} + +func (s *GatewayStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) +} + +func (s *GatewayStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return s.Internal.ChainHasObj(p0, p1) +} + +func (s *GatewayStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { + return s.Internal.ChainHead(p0) +} + +func (s *GatewayStub) ChainHead(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { + return s.Internal.ChainNotify(p0) +} + +func (s *GatewayStub) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return s.Internal.ChainReadObj(p0, p1) +} + +func (s *GatewayStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") +} + +func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) +} + +func (s *GatewayStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return s.Internal.MpoolPush(p0, p1) +} + +func (s *GatewayStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + +func (s *GatewayStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return s.Internal.MsigGetAvailableBalance(p0, p1, p2) +} + +func (s *GatewayStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *GatewayStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { + return s.Internal.MsigGetPending(p0, p1, p2) +} + +func (s *GatewayStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { + return *new([]*api.MsigTransaction), xerrors.New("method not supported") +} + +func (s *GatewayStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.MsigGetVested(p0, p1, p2, p3) +} + +func (s *GatewayStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateAccountKey(p0, p1, p2) +} + +func (s *GatewayStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { + return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) +} + +func (s *GatewayStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { + return *new(api.DealCollateralBounds), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return s.Internal.StateGetActor(p0, p1, p2) +} + +func (s *GatewayStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + return s.Internal.StateGetReceipt(p0, p1, p2) +} + +func (s *GatewayStub) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return s.Internal.StateListMiners(p0, p1) +} + +func (s *GatewayStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateLookupID(p0, p1, p2) +} + +func (s *GatewayStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { + return s.Internal.StateMarketBalance(p0, p1, p2) +} + +func (s *GatewayStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { + return *new(api.MarketBalance), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { + return s.Internal.StateMarketStorageDeal(p0, p1, p2) +} + +func (s *GatewayStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return s.Internal.StateMinerInfo(p0, p1, p2) +} + +func (s *GatewayStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return *new(miner.MinerInfo), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { + return s.Internal.StateMinerPower(p0, p1, p2) +} + +func (s *GatewayStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return s.Internal.StateMinerProvingDeadline(p0, p1, p2) +} + +func (s *GatewayStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (network.Version, error) { + return s.Internal.StateNetworkVersion(p0, p1) +} + +func (s *GatewayStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (network.Version, error) { + return *new(network.Version), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { + return s.Internal.StateSearchMsg(p0, p1) +} + +func (s *GatewayStub) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) +} + +func (s *GatewayStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return s.Internal.StateVerifiedClientStatus(p0, p1, p2) +} + +func (s *GatewayStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { + return s.Internal.StateWaitMsg(p0, p1, p2) +} + +func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + var _ FullNode = new(FullNodeStruct) +var _ Gateway = new(GatewayStruct) diff --git a/cli/util/api.go b/cli/util/api.go index 16913751d1f..ec826160423 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -255,7 +255,7 @@ func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { } func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) { - addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v0") + addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v1") if err != nil { return nil, nil, err } @@ -263,6 +263,15 @@ func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) return client.NewGatewayRPCV1(ctx.Context, addr, headers) } +func GetGatewayAPIV0(ctx *cli.Context) (v0api.Gateway, jsonrpc.ClientCloser, error) { + addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v0") + if err != nil { + return nil, nil, err + } + + return client.NewGatewayRPCV0(ctx.Context, addr, headers) +} + func DaemonContext(cctx *cli.Context) context.Context { if mtCtx, ok := cctx.App.Metadata[metadataTraceContext]; ok { return mtCtx.(context.Context) From 39e49f170035b6f890eeb185c1a8881c7fb5c98c Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Tue, 20 Apr 2021 21:55:47 -0700 Subject: [PATCH 48/60] implement WalletBalance on gateway --- api/api_gateway.go | 1 + api/proxy_gen.go | 10 ++++++++++ build/openrpc/full.json.gz | Bin 22486 -> 22482 bytes build/openrpc/miner.json.gz | Bin 7847 -> 7847 bytes build/openrpc/worker.json.gz | Bin 2577 -> 2579 bytes cmd/lotus-gateway/api.go | 5 +++++ 6 files changed, 16 insertions(+) diff --git a/api/api_gateway.go b/api/api_gateway.go index 187fad86fc0..08b3e0681ff 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -43,4 +43,5 @@ type Gateway interface { StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) + WalletBalance(context.Context, address.Address) (types.BigInt, error) } diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 402da34c0ea..bfaaade94cd 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -516,6 +516,8 @@ type GatewayStruct struct { StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `` + + WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `` } } @@ -2601,6 +2603,14 @@ func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 return nil, xerrors.New("method not supported") } +func (s *GatewayStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return s.Internal.WalletBalance(p0, p1) +} + +func (s *GatewayStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *SignableStruct) Sign(p0 context.Context, p1 SignFunc) error { return s.Internal.Sign(p0, p1) } diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 0e258fe6408f879d7dec01298b2524ef89e6f03b..83e319db5fa6dd8bb13f67159b5ecf44d0a9403d 100644 GIT binary patch delta 20599 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%0AE5_L5aQd?vMitGmy1z4t1wTT&;dlI0$k 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 delta 20645 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"IqbZ*0%i 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 xEe7zki#T-Ywm7SR5mu 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 delta 6112 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 z_catK≫HXDx^sAZ>UX73c+MO9^WL|RLlm8Q1X zUAktAj(S_!Pr9S)cMg1uXis@VPQchz^Zryxe<`t(h^Q-X0o5G{T$BK~Nzw{r3F?ZN z@ydb>zH%X37&+pj+E;WSEPtxJtR~`xyNVooS5FkCTA(@T$Ie2`O?c%839me#VKf2g ztA0;;Ws!u5YvfXo{fwZ^DrG>&>F6!21;1n!SzQm=)|%Scg~I#dmgj=Z+E>**_JBbq zz1(^-bX!Kou>u9bUA09!>}!((TrmZ>xfiq+jNKgE4ASFEV=J$(6Mx)HK?Z3p(nlv3Sb=&DPNFWdOCjW4^>SwV)t z_edMqSA8RHmbx!^?TE@@RXTfJ* zP@frFS$17Dk`d*RpRoWnS)ty8#T@u>DG7FuTZV&4?ALm-#cF=`#^_52cw%eO5jW_c zo422XiMT!XT@nZbW?@eX|bA zqN1L@3ES9#!pZDqj>1vZsZZg2GenME0!<}ki?|A1dS)Pu$QdsleQZM881+sD!;_QK z&hhDB(BiKqU!iM^y1n6WaN6k(hr^C|yo${9x`UI!uz!C%7`BY_@kien9S>T@d-2z2 z1HK=B1l@lB#JJ@`@|M7jNf2^@Km+gZTO0UCNM7AQ$K2w=wEG<*1w@ z$$J4!t;1-;&S$0aMV-ye^9yF8E)|%Vzapa*v!XNB_d!Yhl)?lXX+;6!T%=h+a${YJ mF3xY79UX|+b(gCtd#fde#?#a7)Bg_u0RR68W1hd^eE|UZ0Ph$8 diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index eaae7109d1ad5e5613ba22393d60c4a09e07eafd..33b8c5ebe2451cb053b940d3e46ec0a7d909bf7e 100644 GIT binary patch literal 2579 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 literal 2577 zcmV+s3hwnEiwFP!00000|Li?&bJ{xAe?_C`OLNBo0whiO)+gE9%}ig|8pEY|QcC z2`j2xzyth|t3aa5;Td{AyucQ|2O%kEA;jC((V+wPcy3`2)Ra3C557NPMm!DqCw0N* zl(pVF&X9r)*uoA-TTova47azp6MoIc0khE?iT?P;#T|$%B?4O=pas|)zk_Vf6g;Zd znfcd3{t=Rj3o?P$71)Z4OBh?o@1pNFWJFtEnNJ)C41z2A6D;KSP|-L27}q&bik8hGgr4DG-dftpur>G);&eP@_J$X7g)ydwYv5 zECbIYVulBJIe?k79!6d>Y+;`W;+Z7~gkHwc?9k_uhD#QGomyu9D6_7al}U}QKiE_7 zh~8#+B%ber!FX}5n?6wn0uPQlosNY+2i{13dN;T5P;fr}YvuzUoX&47OdKa9i?~C< zeGrOjJY(WYu&|$KT41gK5D~HDLuLrEunGxSe4Z~!T;F#dxA4&quoX^Esse)V3k)}N z3k&!=paL8`P$B@m8NL9UDBTiHZf-4itDD)a0*)=UXDo2t8w*nf5mRJlkRHpd6`~Rm zv@*%>3z!?dw~IC+1esNzWiK;w#W~iQM`B%$I^F(F&de%KqhBamT2Yjfs$xme1eBua zMt72dt2FM2wpA6COX*67GCIKMjA!+L7G~UeYyKSO{I&RlYiWsynV(9r?pp2Ok;e;z z@aV+C9%YG7QD?*Bb1O0T-P2UHRZq4}ONudE=iJU&=?_#*gAo$oaRtbw><(Kv5H23z zsZzciwA+)gOUve7dmNehLtk)BSKHMdLwn@%QQIR@foKz-wtc}LXaAW1Yfbq7eeCt# zcJ-XH&cZ(!8M)w8^c5ng99Q80y%}-tuCw4v1o;NLf@RK=R!u@?N>Sr_snmO$&}JGA z2z%iSaN5adfImUm(~8?4!c_AUm+H~9>+!W45ITy>FNZ`;qvn31`Mn)3`zP)|4R>)t zZaH7EaSC6dQ&_~F+w+(<;4WpozN{dX;yNsWxRgzBf+(p(*s>WPE+fX}=<@hI)F!HN z;~F<^-`u#<(*i3_8FA@Pi1wnQIZpvs&HpUgFA1B}vd*icFU)jfo_9iocELQaa9O=v zO@*cXG9F7%<<>S#tkhhXnwg)*vNe`%-z?j^lYGl|!N$CzJ<}lhsfpEd0Nrz)eTuMc zB~Ot@&ohFX>QqK}|H-9_htjSyx+iX+_2(r>9tb;PS@4F_nWQ#x@u1(ebi>sH@#7Dd zAVJ(~hS3dY!>`i(??d=Mt!d{KMSDrv(}J@j=YGCITm__turiYOA?g|HmJAK6x*)Yi zWrj#CTS)-3=#4t)^*jB1b?}Mb!9Nm|bhiZJ# z#s}RuqjOYnNH!#DDl3|s5GLOXHPI}{R%8lv*L9X-fo>~qXdXcYF?goab_4Ml7^lL_2)zwaM|XxE zrof_p*UUHLA*qN^)e6Y+e&P zAVs-I)J9*_6vW1^^d+e*DXRq%T21J-%fA)5HBZxh4&3a`il{LWd&E(L>%MT&I4(F7 zxB}vyanGYF%RSG_M*^~%zh{_|xR+sWl7W=*HQP{Th^^>7WP0?YOS)mqXewU(=u9tKlu%@WSftobhM)OM>^SL)Wtjr2QY5tYoAG?r>7q-z%})!t`Gn#@6C;~N|Q zifsJbg36hcMXVEVE`jTXoJ(_DKk7`;&;*`4B}ltq&U1O~J^Q)@ zEONL;oV#nPx>87S%Cof;YQ^c3rVve2`cnIvdF=fpkG$mRB(L;+LOMQREH5D|cw nIct$f1dN3zG{4AfuP#+`e1hlmoB4kO00960oSe!jPI>?U0=oTD diff --git a/cmd/lotus-gateway/api.go b/cmd/lotus-gateway/api.go index b1ddd369ee4..003625a84bf 100644 --- a/cmd/lotus-gateway/api.go +++ b/cmd/lotus-gateway/api.go @@ -71,6 +71,7 @@ type gatewayDepsAPI interface { StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error) + WalletBalance(context.Context, address.Address) (types.BigInt, error) //perm:read } var _ gatewayDepsAPI = *new(api.FullNode) // gateway depends on latest @@ -414,6 +415,10 @@ func (a *GatewayAPI) WalletVerify(ctx context.Context, k address.Address, msg [] return sigs.Verify(sig, k, msg) == nil, nil } +func (a *GatewayAPI) WalletBalance(ctx context.Context, k address.Address) (types.BigInt, error) { + return a.api.WalletBalance(ctx, k) +} + var _ api.Gateway = (*GatewayAPI)(nil) var _ full.ChainModuleAPI = (*GatewayAPI)(nil) var _ full.GasModuleAPI = (*GatewayAPI)(nil) From fbd003a22ba7edabf38a3db65de3d4c40ac8fe85 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Wed, 21 Apr 2021 09:46:44 -0700 Subject: [PATCH 49/60] add walletbalance to v0api --- api/v0api/gateway.go | 1 + api/v0api/proxy_gen.go | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/api/v0api/gateway.go b/api/v0api/gateway.go index a5ea73a01ca..603c099e8f0 100644 --- a/api/v0api/gateway.go +++ b/api/v0api/gateway.go @@ -45,6 +45,7 @@ type Gateway interface { StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) + WalletBalance(context.Context, address.Address) (types.BigInt, error) } var _ Gateway = *new(FullNode) diff --git a/api/v0api/proxy_gen.go b/api/v0api/proxy_gen.go index b53f802c36a..171a9e05afd 100644 --- a/api/v0api/proxy_gen.go +++ b/api/v0api/proxy_gen.go @@ -442,6 +442,8 @@ type GatewayStruct struct { StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `` + + WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `` } } @@ -2064,5 +2066,13 @@ func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (* return nil, xerrors.New("method not supported") } +func (s *GatewayStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return s.Internal.WalletBalance(p0, p1) +} + +func (s *GatewayStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + var _ FullNode = new(FullNodeStruct) var _ Gateway = new(GatewayStruct) From 61344644a4dde4c9b49799af0ebb2c597331ed7e Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Tue, 20 Apr 2021 11:19:00 +0200 Subject: [PATCH 50/60] feat: add more debug logging for unsealing --- extern/sector-storage/manager.go | 17 +++++++++++++++++ markets/retrievaladapter/provider.go | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/extern/sector-storage/manager.go b/extern/sector-storage/manager.go index 3db7ac9ec91..d3fef8533f6 100644 --- a/extern/sector-storage/manager.go +++ b/extern/sector-storage/manager.go @@ -208,6 +208,7 @@ func (m *Manager) schedFetch(sector storage.SectorRef, ft storiface.SectorFileTy func (m *Manager) readPiece(sink io.Writer, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, rok *bool) func(ctx context.Context, w Worker) error { return func(ctx context.Context, w Worker) error { + log.Debugf("read piece data from sector %d, offset %d, size %d", sector.ID, offset, size) r, err := m.waitSimpleCall(ctx)(w.ReadPiece(ctx, sink, sector, offset, size)) if err != nil { return err @@ -215,6 +216,7 @@ func (m *Manager) readPiece(sink io.Writer, sector storage.SectorRef, offset sto if r != nil { *rok = r.(bool) } + log.Debugf("completed read piece data from sector %d, offset %d, size %d: read ok? %t", sector.ID, offset, size, *rok) return nil } } @@ -225,11 +227,13 @@ func (m *Manager) tryReadUnsealedPiece(ctx context.Context, sink io.Writer, sect ctx, cancel := context.WithCancel(ctx) defer cancel() + log.Debugf("acquire read sector lock for sector %d", sector.ID) if err := m.index.StorageLock(ctx, sector.ID, storiface.FTUnsealed, storiface.FTNone); err != nil { returnErr = xerrors.Errorf("acquiring read sector lock: %w", err) return } + log.Debugf("find unsealed sector %d", sector.ID) // passing 0 spt because we only need it when allowFetch is true best, err := m.index.StorageFindSector(ctx, sector.ID, storiface.FTUnsealed, 0, false) if err != nil { @@ -240,41 +244,49 @@ func (m *Manager) tryReadUnsealedPiece(ctx context.Context, sink io.Writer, sect foundUnsealed = len(best) > 0 if foundUnsealed { // append to existing // There is unsealed sector, see if we can read from it + log.Debugf("found unsealed sector %d", sector.ID) selector = newExistingSelector(m.index, sector.ID, storiface.FTUnsealed, false) + log.Debugf("scheduling read of unsealed sector %d", sector.ID) err = m.sched.Schedule(ctx, sector, sealtasks.TTReadUnsealed, selector, m.schedFetch(sector, storiface.FTUnsealed, storiface.PathSealing, storiface.AcquireMove), m.readPiece(sink, sector, offset, size, &readOk)) if err != nil { returnErr = xerrors.Errorf("reading piece from sealed sector: %w", err) } } else { + log.Debugf("did not find unsealed sector %d", sector.ID) selector = newAllocSelector(m.index, storiface.FTUnsealed, storiface.PathSealing) } return } func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) error { + log.Debugf("fetch and read piece in sector %d, offset %d, size %d", sector.ID, offset, size) foundUnsealed, readOk, selector, err := m.tryReadUnsealedPiece(ctx, sink, sector, offset, size) if err != nil { return err } if readOk { + log.Debugf("completed read of unsealed piece in sector %d, offset %d, size %d", sector.ID, offset, size) return nil } ctx, cancel := context.WithCancel(ctx) defer cancel() + log.Debugf("acquire unseal sector lock for sector %d", sector.ID) if err := m.index.StorageLock(ctx, sector.ID, storiface.FTSealed|storiface.FTCache, storiface.FTUnsealed); err != nil { return xerrors.Errorf("acquiring unseal sector lock: %w", err) } unsealFetch := func(ctx context.Context, worker Worker) error { + log.Debugf("copy sealed/cache sector data for sector %d", sector.ID) if _, err := m.waitSimpleCall(ctx)(worker.Fetch(ctx, sector, storiface.FTSealed|storiface.FTCache, storiface.PathSealing, storiface.AcquireCopy)); err != nil { return xerrors.Errorf("copy sealed/cache sector data: %w", err) } if foundUnsealed { + log.Debugf("copy unsealed sector data for sector %d", sector.ID) if _, err := m.waitSimpleCall(ctx)(worker.Fetch(ctx, sector, storiface.FTUnsealed, storiface.PathSealing, storiface.AcquireMove)); err != nil { return xerrors.Errorf("copy unsealed sector data: %w", err) } @@ -291,13 +303,16 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage. return xerrors.Errorf("getting sector size: %w", err) } + log.Debugf("schedule unseal for sector %d", sector.ID) err = m.sched.Schedule(ctx, sector, sealtasks.TTUnseal, selector, unsealFetch, func(ctx context.Context, w Worker) error { // TODO: make restartable // NOTE: we're unsealing the whole sector here as with SDR we can't really // unseal the sector partially. Requesting the whole sector here can // save us some work in case another piece is requested from here + log.Debugf("unseal sector %d", sector.ID) _, err := m.waitSimpleCall(ctx)(w.UnsealPiece(ctx, sector, 0, abi.PaddedPieceSize(ssize).Unpadded(), ticket, unsealed)) + log.Debugf("completed unseal sector %d", sector.ID) return err }) if err != nil { @@ -306,6 +321,7 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage. selector = newExistingSelector(m.index, sector.ID, storiface.FTUnsealed, false) + log.Debugf("schedule read piece for sector %d, offset %d, size %d", sector.ID, offset, size) err = m.sched.Schedule(ctx, sector, sealtasks.TTReadUnsealed, selector, m.schedFetch(sector, storiface.FTUnsealed, storiface.PathSealing, storiface.AcquireMove), m.readPiece(sink, sector, offset, size, &readOk)) if err != nil { @@ -316,6 +332,7 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage. return xerrors.Errorf("failed to read unsealed piece") } + log.Debugf("completed read of piece in sector %d, offset %d, size %d", sector.ID, offset, size) return nil } diff --git a/markets/retrievaladapter/provider.go b/markets/retrievaladapter/provider.go index 557dd3b6d64..e58257c8abc 100644 --- a/markets/retrievaladapter/provider.go +++ b/markets/retrievaladapter/provider.go @@ -47,6 +47,8 @@ func (rpn *retrievalProviderNode) GetMinerWorkerAddress(ctx context.Context, min } func (rpn *retrievalProviderNode) UnsealSector(ctx context.Context, sectorID abi.SectorNumber, offset abi.UnpaddedPieceSize, length abi.UnpaddedPieceSize) (io.ReadCloser, error) { + log.Debugf("get sector %d, offset %d, length %d", sectorID, offset, length) + si, err := rpn.miner.GetSectorInfo(sectorID) if err != nil { return nil, err @@ -73,7 +75,9 @@ func (rpn *retrievalProviderNode) UnsealSector(ctx context.Context, sectorID abi if si.CommD != nil { commD = *si.CommD } + // Read the piece into the pipe's writer, unsealing the piece if necessary + log.Debugf("read piece in sector %d, offset %d, length %d from miner %d", sectorID, offset, length, mid) err := rpn.sealer.ReadPiece(ctx, w, ref, storiface.UnpaddedByteIndex(offset), length, si.TicketValue, commD) if err != nil { log.Errorf("failed to unseal piece from sector %d: %s", sectorID, err) From 448b5cb2a3556370072fed19ab25ec8e45f9de8b Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Thu, 22 Apr 2021 19:45:35 -0400 Subject: [PATCH 51/60] Shed util to sanity-check total balance is FilBase --- cmd/lotus-shed/balances.go | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/cmd/lotus-shed/balances.go b/cmd/lotus-shed/balances.go index 8c5bfefb8d6..bce7be3d56d 100644 --- a/cmd/lotus-shed/balances.go +++ b/cmd/lotus-shed/balances.go @@ -10,6 +10,8 @@ import ( "strings" "time" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/gen/genesis" _init "github.com/filecoin-project/lotus/chain/actors/builtin/init" @@ -64,12 +66,64 @@ var auditsCmd = &cli.Command{ Description: "a collection of utilities for auditing the filecoin chain", Subcommands: []*cli.Command{ chainBalanceCmd, + chainBalanceSanityCheckCmd, chainBalanceStateCmd, chainPledgeCmd, fillBalancesCmd, }, } +var chainBalanceSanityCheckCmd = &cli.Command{ + Name: "chain-balance-sanity", + Description: "Confirms that the total balance of every actor in state is still 2 billion", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "tipset", + Usage: "specify tipset to start from", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + + defer closer() + ctx := lcli.ReqContext(cctx) + + ts, err := lcli.LoadTipSet(ctx, cctx, api) + if err != nil { + return err + } + + tsk := ts.Key() + actors, err := api.StateListActors(ctx, tsk) + if err != nil { + return err + } + + bal := big.Zero() + for _, addr := range actors { + act, err := api.StateGetActor(ctx, addr, tsk) + if err != nil { + return err + } + + bal = big.Add(bal, act.Balance) + } + + attoBase := big.Mul(big.NewInt(int64(build.FilBase)), big.NewInt(int64(build.FilecoinPrecision))) + + if big.Cmp(attoBase, bal) != 0 { + return xerrors.Errorf("sanity check failed (expected %s, actual %s)", attoBase, bal) + } + + fmt.Println("sanity check successful") + + return nil + }, +} + var chainBalanceCmd = &cli.Command{ Name: "chain-balances", Description: "Produces a csv file of all account balances", From 7738886936de260c42643d3b824b7c5f476409d6 Mon Sep 17 00:00:00 2001 From: Reskorey <43715382+Reskorey@users.noreply.github.com> Date: Fri, 23 Apr 2021 15:43:41 +0800 Subject: [PATCH 52/60] fix full node painc fix: full node painc when calling RPC Filecoin.ClientRetrieve without the order.Tatol pecified. --- node/impl/client/client.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index cdef4d02b3b..63b9d65c6ac 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -600,6 +600,11 @@ func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref } } + if order.Total.Int == nil { + finish(xerrors.Errorf("cannot make retrieval deal for null total")) + return + } + if order.Size == 0 { finish(xerrors.Errorf("cannot make retrieval deal for zero bytes")) return From 58bee65bcbcd971448118fb1316c9703e7d73fe4 Mon Sep 17 00:00:00 2001 From: Reskorey <43715382+Reskorey@users.noreply.github.com> Date: Fri, 23 Apr 2021 16:10:51 +0800 Subject: [PATCH 53/60] go fmt --- node/impl/client/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 63b9d65c6ac..201afd0a2dd 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -604,7 +604,7 @@ func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref finish(xerrors.Errorf("cannot make retrieval deal for null total")) return } - + if order.Size == 0 { finish(xerrors.Errorf("cannot make retrieval deal for zero bytes")) return From bd753938f5ba076985dbbd79b39c0e51e7ac9fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 26 Apr 2021 18:45:55 +0200 Subject: [PATCH 54/60] Update CODEOWNERS --- .github/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6d717b44d69..1e32aefb1dd 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,9 +8,9 @@ ## the PR before merging. ### Global owners. -* @magik6k @whyrusleeping @Kubuxu +* @magik6k @arajasek ### Conformance testing. conformance/ @raulk extern/test-vectors @raulk -cmd/tvx @raulk \ No newline at end of file +cmd/tvx @raulk From 17e5d61b96c72f2bec031ca2f5feaf9ae42ba25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 26 Apr 2021 18:54:23 +0200 Subject: [PATCH 55/60] Update CODEOWNERS --- .github/CODEOWNERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1e32aefb1dd..9da543c975f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -11,6 +11,6 @@ * @magik6k @arajasek ### Conformance testing. -conformance/ @raulk -extern/test-vectors @raulk -cmd/tvx @raulk +conformance/ @ZenGround0 +extern/test-vectors @ZenGround0 +cmd/tvx @ZenGround0 From 66e8517769a346b5d2facb0ec8a3ef27a15cbce1 Mon Sep 17 00:00:00 2001 From: Yusef Napora Date: Mon, 26 Apr 2021 13:02:29 -0400 Subject: [PATCH 56/60] add "expected duration" label to inspect-deals output --- cli/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/client.go b/cli/client.go index d3074e91d0a..cd1d3d5053f 100644 --- a/cli/client.go +++ b/cli/client.go @@ -2347,7 +2347,7 @@ func renderDeal(di *lapi.DealInfo) { } for _, stg := range di.DealStages.Stages { - msg := fmt.Sprintf("%s %s: %s (%s)", color.BlueString("Stage:"), color.BlueString(strings.TrimPrefix(stg.Name, "StorageDeal")), stg.Description, color.GreenString(stg.ExpectedDuration)) + msg := fmt.Sprintf("%s %s: %s (expected duration: %s)", color.BlueString("Stage:"), color.BlueString(strings.TrimPrefix(stg.Name, "StorageDeal")), stg.Description, color.GreenString(stg.ExpectedDuration)) if stg.UpdatedTime.Time().IsZero() { msg = color.YellowString(msg) } From bfa332ca7d0361aeffbc8de5edb9850546582880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 26 Apr 2021 20:36:20 +0200 Subject: [PATCH 57/60] api: Document API change process --- api/api_common.go | 11 +++++++++++ api/api_full.go | 14 ++++++++++++++ api/api_gateway.go | 14 ++++++++++++++ api/api_storage.go | 11 +++++++++++ api/api_worker.go | 11 +++++++++++ api/v0api/full.go | 17 +++++++++++++++++ api/v0api/gateway.go | 17 +++++++++++++++++ 7 files changed, 95 insertions(+) diff --git a/api/api_common.go b/api/api_common.go index b1aaa4a82e9..2f27eb95f57 100644 --- a/api/api_common.go +++ b/api/api_common.go @@ -15,6 +15,17 @@ import ( apitypes "github.com/filecoin-project/lotus/api/types" ) +// MODIFYING THE API INTERFACE +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + type Common interface { // MethodGroup: Auth diff --git a/api/api_full.go b/api/api_full.go index c6d32893452..a90b0c89fcf 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -41,6 +41,20 @@ type ChainIO interface { const LookbackNoLimit = abi.ChainEpoch(-1) +// MODIFYING THE API INTERFACE +// +// NOTE: This is the V1 (Unstable) API - to add methods to the V0 (Stable) API +// you'll have to add those methods to interfaces in `api/v0api` +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + // FullNode API is a low-level interface to the Filecoin network full node type FullNode interface { Common diff --git a/api/api_gateway.go b/api/api_gateway.go index 08b3e0681ff..130a18c5503 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -14,6 +14,20 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +// MODIFYING THE API INTERFACE +// +// NOTE: This is the V1 (Unstable) API - to add methods to the V0 (Stable) API +// you'll have to add those methods to interfaces in `api/v0api` +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + type Gateway interface { ChainHasObj(context.Context, cid.Cid) (bool, error) ChainHead(ctx context.Context) (*types.TipSet, error) diff --git a/api/api_storage.go b/api/api_storage.go index 9662e8cd872..1131f45a0fe 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -26,6 +26,17 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/storiface" ) +// MODIFYING THE API INTERFACE +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + // StorageMiner is a low-level interface to the Filecoin network storage miner node type StorageMiner interface { Common diff --git a/api/api_worker.go b/api/api_worker.go index 3232de449d6..e834b792cfe 100644 --- a/api/api_worker.go +++ b/api/api_worker.go @@ -14,6 +14,17 @@ import ( "github.com/filecoin-project/specs-storage/storage" ) +// MODIFYING THE API INTERFACE +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + type Worker interface { Version(context.Context) (Version, error) //perm:admin diff --git a/api/v0api/full.go b/api/v0api/full.go index db5f847bf2f..35100f0322b 100644 --- a/api/v0api/full.go +++ b/api/v0api/full.go @@ -26,6 +26,23 @@ import ( //go:generate go run github.com/golang/mock/mockgen -destination=v0mocks/mock_full.go -package=v0mocks . FullNode +// MODIFYING THE API INTERFACE +// +// NOTE: This is the V0 (Stable) API - when adding methods to this interface, +// you'll need to make sure they are also present on the V1 (Unstable) API +// +// This API is implemented in `v1_wrapper.go` as a compatibility layer backed +// by the V1 api +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + // FullNode API is a low-level interface to the Filecoin network full node type FullNode interface { Common diff --git a/api/v0api/gateway.go b/api/v0api/gateway.go index 603c099e8f0..8a55b4c27a9 100644 --- a/api/v0api/gateway.go +++ b/api/v0api/gateway.go @@ -15,6 +15,23 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +// MODIFYING THE API INTERFACE +// +// NOTE: This is the V0 (Stable) API - when adding methods to this interface, +// you'll need to make sure they are also present on the V1 (Unstable) API +// +// This API is implemented in `v1_wrapper.go` as a compatibility layer backed +// by the V1 api +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + type Gateway interface { ChainHasObj(context.Context, cid.Cid) (bool, error) ChainHead(ctx context.Context) (*types.TipSet, error) From 1a980bf9711b32647810c02571ccd95c8e51ab65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 27 Apr 2021 08:38:29 +0200 Subject: [PATCH 58/60] bump version --- build/openrpc/full.json.gz | Bin 22482 -> 22483 bytes build/openrpc/miner.json.gz | Bin 7847 -> 7848 bytes build/openrpc/worker.json.gz | Bin 2579 -> 2577 bytes build/version.go | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 83e319db5fa6dd8bb13f67159b5ecf44d0a9403d..df2b87f1330c334cb1a830105c124265d0b69486 100644 GIT binary patch literal 22483 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 V!_v>ZNJ!7mOeabTl_sc2{{ikK7PSBX diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 3797357ba15b5b2e131eea02f4529e88c570d50c..a3407e7caa660f07c67af1ac5ff9477f29bdd95e 100644 GIT binary patch delta 7784 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 delta 7783 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 diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index fd67419c5abcf29e796d83fd3e9da9804d0ec360..04d82b39a9604730726072bbfec48f749f9947ce 100644 GIT binary patch literal 2577 zcmV+s3hwnEiwFP!00000|Lh%IbJ{xguV}O{%^ipDdN;hl7QP1|DQ6)>yWMCVJ8+NZ7WP0*xg&A^+Y@HQ)1ZG)7i>;h zfw)p4u+> zJdcPO?&H+}X3lyTdCjneeIkfwmLL#%8Ar2YpGz7pS@d;cnf-QZT~jNQ7+Zg^r{EF2 z&+te*-vxv5;#@aI6`kmoV%MW_zFR`!7gE$v!qp%keX7|xLGRo-o~_Uuh1#XW6#}rOj~f5(q3O$kP2}fmOxy}COAfvR3dEIjt`d-<6?Aq{2nS3Rl9Mu z8+T}K+}pDpD^3}4=?{qZqNF)b0GG}GEZQ##n^dyS>!UBsbZwsZLWK6gJg;$CwOmb! zrTsh}OHjquHcYHkT$qZPpW3q3mhHeSTd#GRZP_l^n3uF?8YDY4v3?Gqdv3B%5w@M= zDYEE!MsO3IiU{w&xm3%cwCjxSi5qDBc?psS!j4!Lyy0{vsZCtm?{zHQaP>g^<%dg< zAnrB8=!U`Yi!}dxAO25k+IdOQUQzb6;Oxk`pRW;D0;wUah~&MGdM2$wL%PXJE^M*zHX9++R@!Bi@Fbv?#szT)jnwL zgC3gE>Es-e4T+k{lIA9a$@W4`Gz+p3nF8H)ljT^T+ld>RMNm!*p6ayQKzu;h6+|AF z;l0Ia+}sMk)FfqpYXmpt*L~nNaYNd(zWoYxGA$JNZ!w(TS8?d(92pJ;w?WD)kkT+$ zDY-}hXA4LWP^azH zdhRehB^^5~gzUAtXS=C|d^shZb!=G2hKCj#_HxcAF2MyN;R};M$`?|uLI3Kr_w?{} zPI9lLXdiNt_2GMM+-l=?(8lc~=d|q-!V1i?HcbQNnKJFgnytM!KQiVi-#SHzG+?$t zigJ;ti9V|-h^<}ei&I%pR&yk@oY3u-e@k*}mZtj@xape}QDZFjSVj%5`@%)zH0Mm< z3Wz)4o<~)hd!Cn%7-Ttr&oCu%FT>m<11Xo+Y(tqLwxait>d}iX>4q_*sd({E)`l2R zM^^A3lT%qw4e4=eKXNY&);{==Y4$z9JGZ%l_@d{UPDZV%l${3!;Yfq%OfOoLP-8NM zE*xNrj%l2eS4Vn(Lx>Ptxswe_ODo=jT5FkN=s)46R+wZw>x_O78%Xy-I@8lxmvm3n zs4MTl^S|@Qzx-gvJ^%a28^dhe?Tu+Sn4Jaz^g8!F<6>_UUrAND8obERMK9Iv zHEriY)25qDALt#dU7@njC{Sp5#fe2VHL-h3nqwU*!xuN}J4>(T&eBOMw{%5Sd-in& znCEbfICnQxbtRBIQ`xobhCCwfBvMmY@H3GJ%y-QNUpLSvu8^7%{TG!;f>M-Cu9-(> zNRc~01dZVVNw7I{BvKq{B}yhlf&QR~yhEB%oxt5<9oesWbG9zj`p`XT=bdR85A2=e zgjavdvV0OcKhO}AO*V0U3Rgb+Z!K5|lNrSx0gb;9w9Q91Umq*xWVQb!^6uOytdeXP zgUn??Ag>-)h=n_|)vwtobvn*~v-9=shv^wgP7w zz^yXo5@pSouYxbTIlOvV_YH$UNeIOK<#*456Rqo5Hj>_H5={^gzegL95jT zWL_5e>F{d<;i*;H+`mXlX2I*4a~AC0e+n!9e4_NC3=Au)IO*lYUZ#4n z%8L;($g1zxWxW#d+|P7n9)_PFn>vjFbt+`clXIx=3)HFeLT}-{#P=Hx_9wXxtUw`M zpdYEX%{!A>MUccbpbipxcnM7DsYr0g$EMFnN85IUgE)==DZxQ>iLHSylwN=_7allh zG(!aa*Zd%)g$NpO2W<4_VM^^OqRgRsih2w$a22)nx5qxQ@4#7(qC)4JFb5IzQTLh> zIc+2vXFHbx>L2Z>51Q(OCgTg9C!nB8GSCt(lZBqm%)~*nIcM1eja+WuNfaA&6znT9(00960SA~2>PkI0Vz-#yv literal 2579 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 diff --git a/build/version.go b/build/version.go index 5af3cce3991..84f49ead8b2 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.7.1-dev" +const BuildVersion = "1.11.0-dev" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit From ada7f97ba86a13b3fbe497021c9f3c939c617285 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Mon, 17 May 2021 16:23:17 -0400 Subject: [PATCH 59/60] docsgen --- build/openrpc/full.json.gz | Bin 22483 -> 22479 bytes build/openrpc/miner.json.gz | Bin 7848 -> 7844 bytes build/openrpc/worker.json.gz | Bin 2577 -> 2574 bytes build/version.go | 1 - 4 files changed, 1 deletion(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index df2b87f1330c334cb1a830105c124265d0b69486..0c0a08621b64c753e5765b8369c1e8ed921b4843 100644 GIT binary patch literal 22479 zcmbTdV~l7`7jE0OZQHhO+qP}nHg)#GZBpPQBf z%&mGpYnz@<^s4N#4Fr_S|0ywTiRO|FJB>W8+LAXc?CrP zy0>>Akr~C!%fKyepW0S$b%lo@iz-Gpo1b_1zjr`}GTysdKfiDBhLP7VBS7{Tg;rkx zy<>X7@8hB@HZEU%_Vh%A3Jkw~K5vQLB*Ph>=a}R4aE1l%BHtb83fGWl73)769dJEk zpxRKa!9RBSpx6=c5}Jb<$)0q_y6&Byu0k`y`lk0Ptnmd=>d!boK9lsKAVhE!hgRdt z10oI#s#y|1zP^%voF)B#zhCuwM-RtA#20t$YS&OKHE<#s{{(u43Up&MNbuq$TK}=I zPy-3fImF_^(^Gm^YsEE=qd>NR0)hpgfFeE_#e4Gw9T*f0u#-UeBiPqPjiM|Fl;YM~ z41Bi+!ZEO#0pfwsM|%D2O&E74LT`#QZi^|S9~Oh${C47MxH%BJ0EfETQit#m&K?Fi zlaG!i4~CH1=c5#lxDQd(1i5t}i4l-9F!J$l#QVwH>Da$|1D%ZWf9rwxkB|WMwo(^j zknAx4!9%~BL;%D6ekH_u;6QL9K2jbND`Y8~CTGn~%0A!jU`ChkZf@^fy~5S^{o9;g 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 diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 04d82b39a9604730726072bbfec48f749f9947ce..49e8306c3fdce35f5f874ef031a87caff3b2b049 100644 GIT binary patch delta 2533 zcmV-7k>u`kld8FZnC$VnSQXz?e?L`Y=nIPHMZm{$w_F2|Gp#37#rKc zcA=LLPiNX9bdHXs^Q|NCgt-q)_%8`h_|f{o?F-hHRX=PgKtlm5l=(?L0zypWvzFPGk>ID1GcaO(iYTL2Kx5) zcEYdOIAAt1GE5p<9CqFnSw{vIy3)T$Uj0-aX}`~x&m8qaS3A! z`CatwhKy+I3-gKNfI)CYe}IMj9xD2#ALBYFiX5Of`Xe0^8(L??buZ2>1VV6efS#_| zwGyBL!H{fSFn$T+(pKqOViS>>p*;HM26QvGoUg3Lep043EU~T`(9g&UMpA%0S@3 zQK!?f@Tb5V=}&Lx79I-D$A8Xzz=PBIjfIKhgk%wSD1W#QLQ#!pOk4>T_7hDD%oPA4 zB9=VJ3?UX)Apwie^CgMv`_AJQKKc%}!s$s>K=5sW;bv}O0e=NlfP)801fVy=7hn^m zTf)iBt>tcYGrLv5v8DEm1+IHzVX7cvip&hsW0|!=R3d^_Ci!gvbEEfm(ME(Iv+A?# zWk#+z$A3EWNUY0Ir`x~DnOVhY^b18xD~fVbRV*o*fKn9Q=uR?lmBt;>wyL6XDP8GM zMh6(3@vI)u!i+n=n?Hv+e=YvtT3RAv=BHAuyH-1R))st=0l41n!|>k&z2dMPDI; z%5fDA(3=tG?m7#;M38T=D_G_{Y1JfTrW7@hEyD|8Br*mHXx z(+1q7tk;(nq*7dmB@mag2~H3tl?Yol~h z`U9f9sA$epz*X}gWqI-G7+poe-g2FwZMoRxejmVQD{)#}ZVzwG9(1 zH5aC4=BKf2jb+<2%hvClf;XJbB(;f)2mP+48?GLRAAh(63F2NejBYp^et(hX zfA7QpX-zw?DB4TPo)(-PIrsAw;wm6Dgq4xJ_fgMSw`6Eo)di_FDlghx0ult& zX?^*!-k-`K%NGv=sFk!J%;6r=xDg+thmbTR4ZMXWz(DA2h&sA6^e_b$^?$o&z8Mcm zMTDwWK$a(W@jNqYnEa;1IY}wQx0S-B^`>l3WT7DOehH*jwPg%f6pK*a`YNab5yv2_ zkxBC0d{OH4&zXV?=D=fkfSy|fRwHal68lRJ(c?wxz4IoP+Ra$%xx?^`bZoH@ zvft^QZl@OV<&<MpNvQBNcdUd64joir3f%+*wwAdG)K9Q1fj5$4SqXP)ny3^}$!tkusdhrTcEM8ZeU_xj95gn*vGK3S#-A2c z&ZI12op^HzTrcEYn&bLWXNra<@Z2du+68l-%WE&sqBnM_u}k}Am);f>z0|wcw3!P{ z>uxfApm(rxg-FUmqd=kfiW7@!Y7+OBG{-trhA(b5ca~nwou%VWVd;vh_w4Huu*l&W zaqh0E>PjJbrm`#UhCCwfBvMmY@H3GJ%y;btU$>Lf2QhzO9oesWbG9ke`p`Q*Dmv3L z9@sm_39tTEW%)F8aiAe6o2=vf46b7K-&n8^CNs)C0-AgwXp@g_zCKng$ZG#dD`w~`|2A#=zSFkD@TuKxSo3FCvs;ji(R*U- zZ4J&efE#~h%ot_Em#=~^dj-MRVo$0*zY@dc2V@@czhyW6MuyN&^L1fb5_>*#E_$HD z>!8!=0WvR({B-!WhVaZPt?yqZC9~jl%{dEpA3TK>e?C!qQHH6EMC-S;DUAJ2E*$p@ zVlPv@Sm(uv1Z3U!>+)WScU)@37!$pZ|46G00960kQ?7uN_qeQUUTDA delta 2536 zcmVdN;hl z7QP1|DQ6)>yWMCVJ8+NZ7WP0*xg&A^+Y@HQ)1ZG)7i>;h&FdMy*=(n$2+<~}KBCypFT7bRrTgc{2!J}#n%)b`$+ej)d$OIZ!U@I;z zVQeA4gTCF65p8^7K5-l{2(IW4u#n$HdEfMwxXy_pN9c|INXNv6#(=o)#kqw*2riD$ z(>1$R0#qOvl7Ed0ra&;_He#e|(ljA@K#lt7n$54-?d>hLunatph#BtV)c|JBdKh`l zu!Vghh-a1{5PBI$vtyr28ZKG%bz+(Qc4}QyE0Y*of3TQ)1dONr9P;fr}bLIo?pUrP9OdKa9i+{L7!F>>lYCL1&O0cjWYg%9~ z0T2UR%^*3JSt~>(B4}-r-xe@8dT$qPL%Da>Qf z-FZw~aF^0vUs{j~aUGUGT*@XmMwC<{Y}t+vmlES*bb0(9Dic+^akU$FXl~rwvm7f< z8FA?ki1wnSIZptW&HpUgFA1Aevd-(HFMrH*ZJzf+g!aKauW?zmTuq6k{X8B^P{r0Z zOsrH~n2MR7+OpM_?Z7NsuXUPj*)G_am$YXZBs(>+eh#2}Zn94iww>fDvgmn6a1))1 z2=BkSRLh~X>x}M+8)*G`36clGj#w7F;dCacO2$wL%PXJE^M*zHX9++R@!Bi@Fbv?#szT)jnwLgC3gE>Es-e z4T+k{lIA9a$@W4`Gz+p3nF8H)lYiw{pxcQXnnh4f44&$=+dzCk*cC(`m*Ks|Y24fj zztkjUe`^Fc<=1`SHgQARv%dWbbTTaz_-`?s-&b+y<{TLg1-C)UE0EGKS1Gwj0A~wG z5KyP_<;!M&DupatJPe>#(tIG=+4l?6n|LM@0$5$ zJR}tns$2nCmfS7pnOej6HwDf~3K_ng6fSKxWd|Y)If?g6AeE{umvDKp2<45hf+`Tp z7-T&%iJzM6;Z%V=VSqMh&j}!hc2MH0Mm<3Wz)4 zo<~)hd!Cn%7-Ttr&oCu%FT>m<11Xo+Y(tqLwxait>d}iX>4q_*sd({E)`l2RM^^A3 zlT%qw4e4=eKXNY&);{==Y4$z9JGZ%l_@d{UPDZV%l${3!;Yfq%OfOoLP-8NME*xNr zj%l2eS4Vn(Lx>Ptxqp)lN=qx=f?8{tV(35NrdF6_JnM{p5F1GMK|0gZS(kKA)u=1) z!1KTJ$G`kw#y$W0$Q#3K-0h8NH<+CU0rWceJ>z0;6JJSHxf;COe#V!f4CFSwpgP{G z=dPFams=tBY36D%v>t>jqN!kvmHDnV2{TT)x9y^yYbuv7=1C8;w9wT-WB{428Y zXE~KK35!@I-dq7!3prQjxO&u?prH;t_ezlV!JKFE+RL-(wOy+1(xKUd>G)$TQI z=R(t_n@k_*9ZRfTp|a2@P-uC@iA6Ovv3pCJV;w5P7dPuWORwh6(n%|~bVXHr_H_lA z=WvZUcQ;gZC6GK**|qG3JRAA zooN{l?49F;SAWa0d=ff8&=8bOHgSFmS3di1Em#PX8O0s}jlU4I%||z1A1mf$wf`jY z?%XJ>l57}*%w<6!uGV5Q9L79Q^DH|iaqgZKQ}h*oo3?r1YT9A=)a=x(`7^B9$w|iO zJu&vS0%sb)t$#A+5@pSouYxbTIlOvV_YH$UNeIOK<#*456Rqo5Hj>_H5={ z^gzegL95jTWL_5e>F{d<;i*;H+`mXlX2I*4a~AC0e+n!9e4_NC3=Au) zIO*lYUZ#4n%8L;($g1zxWxW#d+|P7n9)_PFn>vjFb$=>k%#(Ad?+eta^FnXoy~Ot$ z4)!Ox4y-^SU7#PSx6M0~Sw)bdUy#;>8VI?$H%76NJratgo8Ma04c#ibcwBj zE|gw?F&7>6 zn=l6v^nX$Jni4r}BpGKrmjUV@?Whl$>VqcZ3!da;CL>uc=?6wo*>TNMJv{G+t#It* zJ;}U@t=e~F^SbSB=d7~T+gJ9<$tHd!RQ)HQph_~(5-yX4p3Tg}L9;n$*#nJSZr@21 yFhyOYrXT Date: Tue, 15 Jun 2021 21:04:11 +0200 Subject: [PATCH 60/60] sealing: Fix restartSectors race --- extern/storage-sealing/fsm.go | 3 +++ extern/storage-sealing/garbage.go | 2 ++ extern/storage-sealing/input.go | 4 ++++ extern/storage-sealing/sealing.go | 7 +++++++ 4 files changed, 16 insertions(+) diff --git a/extern/storage-sealing/fsm.go b/extern/storage-sealing/fsm.go index a765d26173f..1ad2d7ec04e 100644 --- a/extern/storage-sealing/fsm.go +++ b/extern/storage-sealing/fsm.go @@ -514,6 +514,8 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) (uint64, err } func (m *Sealing) restartSectors(ctx context.Context) error { + defer m.startupWait.Done() + trackedSectors, err := m.ListSectors() if err != nil { log.Errorf("loading sector list: %+v", err) @@ -531,6 +533,7 @@ func (m *Sealing) restartSectors(ctx context.Context) error { } func (m *Sealing) ForceSectorState(ctx context.Context, id abi.SectorNumber, state SectorState) error { + m.startupWait.Wait() return m.sectors.Send(id, SectorForceState{state}) } diff --git a/extern/storage-sealing/garbage.go b/extern/storage-sealing/garbage.go index c8ec21a84d8..d429b5b438d 100644 --- a/extern/storage-sealing/garbage.go +++ b/extern/storage-sealing/garbage.go @@ -9,6 +9,8 @@ import ( ) func (m *Sealing) PledgeSector(ctx context.Context) (storage.SectorRef, error) { + m.startupWait.Wait() + m.inputLk.Lock() defer m.inputLk.Unlock() diff --git a/extern/storage-sealing/input.go b/extern/storage-sealing/input.go index 44d2e8275b4..1ba8b4c2c54 100644 --- a/extern/storage-sealing/input.go +++ b/extern/storage-sealing/input.go @@ -376,6 +376,8 @@ func (m *Sealing) updateInput(ctx context.Context, sp abi.RegisteredSealProof) e } func (m *Sealing) tryCreateDealSector(ctx context.Context, sp abi.RegisteredSealProof) error { + m.startupWait.Wait() + cfg, err := m.getConfig() if err != nil { return xerrors.Errorf("getting storage config: %w", err) @@ -422,6 +424,8 @@ func (m *Sealing) createSector(ctx context.Context, cfg sealiface.Config, sp abi } func (m *Sealing) StartPacking(sid abi.SectorNumber) error { + m.startupWait.Wait() + return m.sectors.Send(uint64(sid), SectorStartPacking{}) } diff --git a/extern/storage-sealing/sealing.go b/extern/storage-sealing/sealing.go index cfe4b9f909c..ee29a724f1a 100644 --- a/extern/storage-sealing/sealing.go +++ b/extern/storage-sealing/sealing.go @@ -83,6 +83,8 @@ type Sealing struct { feeCfg config.MinerFeeConfig events Events + startupWait sync.WaitGroup + maddr address.Address sealer sectorstorage.SectorManager @@ -161,6 +163,7 @@ func New(api SealingAPI, fc config.MinerFeeConfig, events Events, maddr address. bySector: map[abi.SectorID]statSectorState{}, }, } + s.startupWait.Add(1) s.sectors = statemachine.New(namespace.Wrap(ds, datastore.NewKey(SectorStorePrefix)), s, SectorInfo{}) @@ -188,10 +191,14 @@ func (m *Sealing) Stop(ctx context.Context) error { } func (m *Sealing) Remove(ctx context.Context, sid abi.SectorNumber) error { + m.startupWait.Wait() + return m.sectors.Send(uint64(sid), SectorRemove{}) } func (m *Sealing) Terminate(ctx context.Context, sid abi.SectorNumber) error { + m.startupWait.Wait() + return m.sectors.Send(uint64(sid), SectorTerminate{}) }