From 6491becbe1ae83d4f9c59b61105c63a85cf3e12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 16 Jan 2023 14:54:26 +0100 Subject: [PATCH 1/5] rpc: Switch eth_subscribe to reverse calls --- api/api_full.go | 10 +- api/proxy_gen.go | 1158 +++++++++++++++++++++------------------- api/v0api/proxy_gen.go | 462 ++++++++-------- gateway/handler.go | 2 +- gen/api/proxygen.go | 8 +- go.mod | 2 +- go.sum | 2 + node/impl/full/eth.go | 49 +- node/rpc.go | 2 +- 9 files changed, 881 insertions(+), 814 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index ec7b23170..20d374b50 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -6,6 +6,8 @@ import ( "fmt" "time" + "github.com/filecoin-project/go-jsonrpc" + "github.com/google/uuid" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" @@ -831,7 +833,7 @@ type FullNode interface { // - logs: notify new event logs that match a criteria // params contains additional parameters used with the log event type // The client will receive a stream of EthSubscriptionResponse values until EthUnsubscribe is called. - EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) //perm:write + EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) //perm:write // Unsubscribe from a websocket subscription EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) //perm:write @@ -849,6 +851,12 @@ type FullNode interface { RaftLeader(ctx context.Context) (peer.ID, error) //perm:read } +// reverse interface to the client, called after EthSubscribe +type EthSubscriber interface { + // note: the parameter is ethtypes.EthSubscriptionResponse serialized as json object + EthSubscription(ctx context.Context, r jsonrpc.RawParams) error //rpc_method:eth_subscription notify:true +} + type StorageAsk struct { Response *storagemarket.StorageAsk diff --git a/api/proxy_gen.go b/api/proxy_gen.go index a7345f098..43089c6fa 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -7,21 +7,13 @@ import ( "encoding/json" "time" - "github.com/google/uuid" - blocks "github.com/ipfs/go-block-format" - "github.com/ipfs/go-cid" - "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" - "golang.org/x/xerrors" - "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/piecestore" "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/builtin/v8/paych" @@ -31,7 +23,6 @@ import ( "github.com/filecoin-project/go-state-types/dline" abinetwork "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/go-state-types/proof" - apitypes "github.com/filecoin-project/lotus/api/types" builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin" lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -44,47 +35,59 @@ import ( "github.com/filecoin-project/lotus/storage/sealer/fsutil" "github.com/filecoin-project/lotus/storage/sealer/sealtasks" "github.com/filecoin-project/lotus/storage/sealer/storiface" + "github.com/google/uuid" + blocks "github.com/ipfs/go-block-format" + "github.com/ipfs/go-cid" + "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" + "golang.org/x/xerrors" ) var ErrNotSupported = xerrors.New("method not supported") type ChainIOStruct struct { - Internal struct { - ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` + Internal ChainIOMethods +} - ChainPutObj func(p0 context.Context, p1 blocks.Block) error `` +type ChainIOMethods struct { + ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` - ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` - } + ChainPutObj func(p0 context.Context, p1 blocks.Block) error `` + + ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` } type ChainIOStub struct { } type CommonStruct struct { - Internal struct { - AuthNew func(p0 context.Context, p1 []auth.Permission) ([]byte, error) `perm:"admin"` + Internal CommonMethods +} - AuthVerify func(p0 context.Context, p1 string) ([]auth.Permission, error) `perm:"read"` +type CommonMethods struct { + AuthNew func(p0 context.Context, p1 []auth.Permission) ([]byte, error) `perm:"admin"` - Closing func(p0 context.Context) (<-chan struct{}, error) `perm:"read"` + AuthVerify func(p0 context.Context, p1 string) ([]auth.Permission, error) `perm:"read"` - Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) `perm:"read"` + Closing func(p0 context.Context) (<-chan struct{}, error) `perm:"read"` - LogAlerts func(p0 context.Context) ([]alerting.Alert, error) `perm:"admin"` + Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) `perm:"read"` - LogList func(p0 context.Context) ([]string, error) `perm:"write"` + LogAlerts func(p0 context.Context) ([]alerting.Alert, error) `perm:"admin"` - LogSetLevel func(p0 context.Context, p1 string, p2 string) error `perm:"write"` + LogList func(p0 context.Context) ([]string, error) `perm:"write"` - Session func(p0 context.Context) (uuid.UUID, error) `perm:"read"` + LogSetLevel func(p0 context.Context, p1 string, p2 string) error `perm:"write"` - Shutdown func(p0 context.Context) error `perm:"admin"` + Session func(p0 context.Context) (uuid.UUID, error) `perm:"read"` - StartTime func(p0 context.Context) (time.Time, error) `perm:"read"` + Shutdown func(p0 context.Context) error `perm:"admin"` - Version func(p0 context.Context) (APIVersion, error) `perm:"read"` - } + StartTime func(p0 context.Context) (time.Time, error) `perm:"read"` + + Version func(p0 context.Context) (APIVersion, error) `perm:"read"` } type CommonStub struct { @@ -95,8 +98,10 @@ type CommonNetStruct struct { NetStruct - Internal struct { - } + Internal CommonNetMethods +} + +type CommonNetMethods struct { } type CommonNetStub struct { @@ -105,486 +110,499 @@ type CommonNetStub struct { NetStub } +type EthSubscriberStruct struct { + Internal EthSubscriberMethods +} + +type EthSubscriberMethods struct { + EthSubscription func(p0 context.Context, p1 jsonrpc.RawParams) error `notify:"true"rpc_method:"eth_subscription"` +} + +type EthSubscriberStub struct { +} + type FullNodeStruct struct { CommonStruct NetStruct - Internal struct { - ChainBlockstoreInfo func(p0 context.Context) (map[string]interface{}, error) `perm:"read"` + Internal FullNodeMethods +} - ChainCheckBlockstore func(p0 context.Context) error `perm:"admin"` +type FullNodeMethods struct { + ChainBlockstoreInfo func(p0 context.Context) (map[string]interface{}, error) `perm:"read"` - ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + ChainCheckBlockstore func(p0 context.Context) error `perm:"admin"` - ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"` + ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` - ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"` + ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"` - ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `perm:"read"` + ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"` - ChainGetEvents func(p0 context.Context, p1 cid.Cid) ([]types.Event, 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"` + ChainGetEvents func(p0 context.Context, p1 cid.Cid) ([]types.Event, error) `perm:"read"` - ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"` + ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `perm:"read"` - ChainGetMessagesInTipset func(p0 context.Context, p1 types.TipSetKey) ([]Message, error) `perm:"read"` + ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"` - ChainGetNode func(p0 context.Context, p1 string) (*IpldObject, error) `perm:"read"` + ChainGetMessagesInTipset func(p0 context.Context, p1 types.TipSetKey) ([]Message, error) `perm:"read"` - ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]Message, error) `perm:"read"` + ChainGetNode func(p0 context.Context, p1 string) (*IpldObject, error) `perm:"read"` - ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` + ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]Message, error) `perm:"read"` - ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) `perm:"read"` + ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` - ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `perm:"read"` + ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) `perm:"read"` - ChainGetTipSetAfterHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, 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"` + ChainGetTipSetAfterHeight 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"` + ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `perm:"read"` - ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"` + ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"read"` - ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `perm:"read"` + ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"` - ChainPrune func(p0 context.Context, p1 PruneOpts) error `perm:"admin"` + ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `perm:"read"` - ChainPutObj func(p0 context.Context, p1 blocks.Block) error `perm:"admin"` + ChainPrune func(p0 context.Context, p1 PruneOpts) error `perm:"admin"` - ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"` + ChainPutObj func(p0 context.Context, p1 blocks.Block) error `perm:"admin"` - ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` + ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"` - ChainStatObj func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) `perm:"read"` + ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` - ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"` + ChainStatObj func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) `perm:"read"` - ClientCalcCommP func(p0 context.Context, p1 string) (*CommPRet, error) `perm:"write"` + ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"` - ClientCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + ClientCalcCommP func(p0 context.Context, p1 string) (*CommPRet, error) `perm:"write"` - ClientCancelRetrievalDeal func(p0 context.Context, p1 retrievalmarket.DealID) 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 DataTransferChannel, error) `perm:"write"` + ClientCancelRetrievalDeal func(p0 context.Context, p1 retrievalmarket.DealID) error `perm:"write"` - ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) `perm:"read"` + ClientDataTransferUpdates func(p0 context.Context) (<-chan DataTransferChannel, error) `perm:"write"` - ClientDealSize func(p0 context.Context, p1 cid.Cid) (DataSize, error) `perm:"read"` + ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) `perm:"read"` - ClientExport func(p0 context.Context, p1 ExportRef, p2 FileRef) error `perm:"admin"` + ClientDealSize func(p0 context.Context, p1 cid.Cid) (DataSize, error) `perm:"read"` - ClientFindData func(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) `perm:"read"` + ClientExport func(p0 context.Context, p1 ExportRef, p2 FileRef) error `perm:"admin"` - ClientGenCar func(p0 context.Context, p1 FileRef, p2 string) error `perm:"write"` + ClientFindData func(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) `perm:"read"` - ClientGetDealInfo func(p0 context.Context, p1 cid.Cid) (*DealInfo, error) `perm:"read"` + ClientGenCar func(p0 context.Context, p1 FileRef, p2 string) error `perm:"write"` - ClientGetDealStatus func(p0 context.Context, p1 uint64) (string, error) `perm:"read"` + ClientGetDealInfo func(p0 context.Context, p1 cid.Cid) (*DealInfo, error) `perm:"read"` - ClientGetDealUpdates func(p0 context.Context) (<-chan DealInfo, error) `perm:"write"` + ClientGetDealStatus func(p0 context.Context, p1 uint64) (string, error) `perm:"read"` - ClientGetRetrievalUpdates func(p0 context.Context) (<-chan RetrievalInfo, 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"` + ClientGetRetrievalUpdates func(p0 context.Context) (<-chan RetrievalInfo, error) `perm:"write"` - ClientImport func(p0 context.Context, p1 FileRef) (*ImportRes, error) `perm:"admin"` + ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"` - ClientListDataTransfers func(p0 context.Context) ([]DataTransferChannel, error) `perm:"write"` + ClientImport func(p0 context.Context, p1 FileRef) (*ImportRes, error) `perm:"admin"` - ClientListDeals func(p0 context.Context) ([]DealInfo, error) `perm:"write"` + ClientListDataTransfers func(p0 context.Context) ([]DataTransferChannel, error) `perm:"write"` - ClientListImports func(p0 context.Context) ([]Import, error) `perm:"write"` + ClientListDeals func(p0 context.Context) ([]DealInfo, error) `perm:"write"` - ClientListRetrievals func(p0 context.Context) ([]RetrievalInfo, 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) (QueryOffer, error) `perm:"read"` + ClientListRetrievals func(p0 context.Context) ([]RetrievalInfo, error) `perm:"write"` - ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*StorageAsk, error) `perm:"read"` + ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) `perm:"read"` - ClientRemoveImport func(p0 context.Context, p1 imports.ID) error `perm:"admin"` + ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*StorageAsk, error) `perm:"read"` - ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + ClientRemoveImport func(p0 context.Context, p1 imports.ID) error `perm:"admin"` - ClientRetrieve func(p0 context.Context, p1 RetrievalOrder) (*RestrievalRes, error) `perm:"admin"` + ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` - ClientRetrieveTryRestartInsufficientFunds func(p0 context.Context, p1 address.Address) error `perm:"write"` + ClientRetrieve func(p0 context.Context, p1 RetrievalOrder) (*RestrievalRes, error) `perm:"admin"` - ClientRetrieveWait func(p0 context.Context, p1 retrievalmarket.DealID) error `perm:"admin"` + ClientRetrieveTryRestartInsufficientFunds func(p0 context.Context, p1 address.Address) error `perm:"write"` - ClientStartDeal func(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) `perm:"admin"` + ClientRetrieveWait func(p0 context.Context, p1 retrievalmarket.DealID) error `perm:"admin"` - ClientStatelessDeal func(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) `perm:"write"` + ClientStartDeal func(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) `perm:"admin"` - CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` + ClientStatelessDeal func(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) `perm:"write"` - EthAccounts func(p0 context.Context) ([]ethtypes.EthAddress, error) `perm:"read"` + CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` - EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` + EthAccounts func(p0 context.Context) ([]ethtypes.EthAddress, error) `perm:"read"` - EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) `perm:"read"` + EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` - EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` + EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) `perm:"read"` - EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) `perm:"read"` + EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` - EthFeeHistory func(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) `perm:"read"` + EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) `perm:"read"` - EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"` + EthFeeHistory func(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) `perm:"read"` - EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) `perm:"read"` + EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"` - EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) `perm:"read"` + EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) `perm:"read"` - EthGetBlockByNumber func(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) `perm:"read"` + EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) `perm:"read"` - EthGetBlockTransactionCountByHash func(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) `perm:"read"` + EthGetBlockByNumber func(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) `perm:"read"` - EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) `perm:"read"` + EthGetBlockTransactionCountByHash func(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) `perm:"read"` - EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) `perm:"read"` + EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) `perm:"read"` - EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"write"` + EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) `perm:"read"` - EthGetFilterLogs func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"write"` + EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"write"` - EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) `perm:"read"` + EthGetFilterLogs func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"write"` - EthGetMessageCidByTransactionHash func(p0 context.Context, p1 *ethtypes.EthHash) (*cid.Cid, error) `perm:"read"` + EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) `perm:"read"` - EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `perm:"read"` + EthGetMessageCidByTransactionHash func(p0 context.Context, p1 *ethtypes.EthHash) (*cid.Cid, error) `perm:"read"` - EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `perm:"read"` + EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `perm:"read"` - EthGetTransactionByBlockNumberAndIndex func(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `perm:"read"` + EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `perm:"read"` - EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) `perm:"read"` + EthGetTransactionByBlockNumberAndIndex func(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `perm:"read"` - EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `perm:"read"` + EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) `perm:"read"` - EthGetTransactionHashByCid func(p0 context.Context, p1 cid.Cid) (*ethtypes.EthHash, error) `perm:"read"` + EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `perm:"read"` - EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) `perm:"read"` + EthGetTransactionHashByCid func(p0 context.Context, p1 cid.Cid) (*ethtypes.EthHash, error) `perm:"read"` - EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"` + EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) `perm:"read"` - EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `perm:"write"` + EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"` - EthNewFilter func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) `perm:"write"` + EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `perm:"write"` - EthNewPendingTransactionFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `perm:"write"` + EthNewFilter func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) `perm:"write"` - EthProtocolVersion func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` + EthNewPendingTransactionFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `perm:"write"` - EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) `perm:"read"` + EthProtocolVersion func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` - EthSubscribe func(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) `perm:"write"` + EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) `perm:"read"` - EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `perm:"write"` + EthSubscribe func(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) `perm:"write"` - EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) `perm:"write"` + EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `perm:"write"` - GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) `perm:"write"` - GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"` + GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` - GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) `perm:"read"` + GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"` - GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `perm:"read"` + GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) `perm:"read"` - MarketAddBalance func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `perm:"read"` - MarketGetReserved func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"sign"` + MarketAddBalance func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` - MarketReleaseFunds func(p0 context.Context, p1 address.Address, p2 types.BigInt) error `perm:"sign"` + MarketGetReserved func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"sign"` - MarketReserveFunds func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + MarketReleaseFunds func(p0 context.Context, p1 address.Address, p2 types.BigInt) error `perm:"sign"` - MarketWithdraw func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + MarketReserveFunds func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` - MinerCreateBlock func(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) `perm:"write"` + MarketWithdraw func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` - MinerGetBaseInfo func(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) `perm:"read"` + MinerCreateBlock func(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) `perm:"write"` - MpoolBatchPush func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` + MinerGetBaseInfo func(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) `perm:"read"` - MpoolBatchPushMessage func(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"` + MpoolBatchPush func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` - MpoolBatchPushUntrusted func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` + MpoolBatchPushMessage func(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"` - MpoolCheckMessages func(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) `perm:"read"` + MpoolBatchPushUntrusted func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` - MpoolCheckPendingMessages func(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) `perm:"read"` + MpoolCheckMessages func(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) `perm:"read"` - MpoolCheckReplaceMessages func(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) `perm:"read"` + MpoolCheckPendingMessages func(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) `perm:"read"` - MpoolClear func(p0 context.Context, p1 bool) error `perm:"write"` + MpoolCheckReplaceMessages func(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) `perm:"read"` - MpoolGetConfig func(p0 context.Context) (*types.MpoolConfig, error) `perm:"read"` + MpoolClear func(p0 context.Context, p1 bool) error `perm:"write"` - MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"read"` + MpoolGetConfig func(p0 context.Context) (*types.MpoolConfig, error) `perm:"read"` - MpoolPending func(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"` + MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"read"` - MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` + MpoolPending func(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"` - MpoolPushMessage func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"` + MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` - MpoolPushUntrusted func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` + MpoolPushMessage func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"` - MpoolSelect func(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) `perm:"read"` + MpoolPushUntrusted func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` - MpoolSetConfig func(p0 context.Context, p1 *types.MpoolConfig) error `perm:"admin"` + MpoolSelect func(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) `perm:"read"` - MpoolSub func(p0 context.Context) (<-chan MpoolUpdate, error) `perm:"read"` + MpoolSetConfig func(p0 context.Context, p1 *types.MpoolConfig) error `perm:"admin"` - MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) `perm:"sign"` + MpoolSub func(p0 context.Context) (<-chan MpoolUpdate, error) `perm:"read"` - MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) `perm:"sign"` + MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) `perm:"sign"` - MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) `perm:"sign"` + MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) `perm:"sign"` - MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) `perm:"sign"` + MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, 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) (*MessagePrototype, error) `perm:"sign"` + MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) `perm:"sign"` - MsigCancel func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, 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) (*MessagePrototype, error) `perm:"sign"` - MsigCancelTxnHash func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) `perm:"sign"` + MsigCancel func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, 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) (*MessagePrototype, error) `perm:"sign"` + MsigCancelTxnHash func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) `perm:"sign"` - MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` + MsigCreate func(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) `perm:"sign"` - MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) `perm:"read"` + MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` - MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) `perm:"read"` - MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) `perm:"read"` + MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` - MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) `perm:"sign"` + MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) `perm:"read"` - MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) `perm:"sign"` + MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, 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) (*MessagePrototype, error) `perm:"sign"` + MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) `perm:"sign"` - MsigSwapCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, 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) (*MessagePrototype, error) `perm:"sign"` - MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) `perm:"sign"` + MsigSwapCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) `perm:"sign"` - NetListening func(p0 context.Context) (bool, error) `perm:"read"` + MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) `perm:"sign"` - NetVersion func(p0 context.Context) (string, error) `perm:"read"` + NetListening func(p0 context.Context) (bool, error) `perm:"read"` - NodeStatus func(p0 context.Context, p1 bool) (NodeStatus, error) `perm:"read"` + NetVersion func(p0 context.Context) (string, error) `perm:"read"` - PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"` + NodeStatus func(p0 context.Context, p1 bool) (NodeStatus, error) `perm:"read"` - PaychAvailableFunds func(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) `perm:"sign"` + PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"` - PaychAvailableFundsByFromTo func(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) `perm:"sign"` + PaychAvailableFunds func(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) `perm:"sign"` - PaychCollect func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` + PaychAvailableFundsByFromTo func(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) `perm:"sign"` - PaychFund func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, 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, p4 PaychGetOpts) (*ChannelInfo, error) `perm:"sign"` + PaychFund 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"` + PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 PaychGetOpts) (*ChannelInfo, error) `perm:"sign"` - PaychList func(p0 context.Context) ([]address.Address, error) `perm:"read"` + PaychGetWaitReady func(p0 context.Context, p1 cid.Cid) (address.Address, error) `perm:"sign"` - PaychNewPayment func(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) `perm:"sign"` + PaychList func(p0 context.Context) ([]address.Address, error) `perm:"read"` - PaychSettle func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` + PaychNewPayment func(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) `perm:"sign"` - PaychStatus func(p0 context.Context, p1 address.Address) (*PaychStatus, error) `perm:"read"` + PaychSettle func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` - PaychVoucherAdd func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) `perm:"write"` + PaychStatus func(p0 context.Context, p1 address.Address) (*PaychStatus, error) `perm:"read"` - PaychVoucherCheckSpendable func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) `perm:"read"` + PaychVoucherAdd func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) `perm:"write"` - PaychVoucherCheckValid func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error `perm:"read"` + PaychVoucherCheckSpendable func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) `perm:"read"` - PaychVoucherCreate func(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) `perm:"sign"` + PaychVoucherCheckValid func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error `perm:"read"` - PaychVoucherList func(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) `perm:"write"` + PaychVoucherCreate func(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) `perm:"sign"` - PaychVoucherSubmit func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) `perm:"sign"` + PaychVoucherList func(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) `perm:"write"` - RaftLeader func(p0 context.Context) (peer.ID, error) `perm:"read"` + PaychVoucherSubmit func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) `perm:"sign"` - RaftState func(p0 context.Context) (*RaftStateData, error) `perm:"read"` + RaftLeader func(p0 context.Context) (peer.ID, error) `perm:"read"` - StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` + RaftState func(p0 context.Context) (*RaftStateData, error) `perm:"read"` - StateActorCodeCIDs func(p0 context.Context, p1 abinetwork.Version) (map[string]cid.Cid, error) `perm:"read"` + StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` - StateActorManifestCID func(p0 context.Context, p1 abinetwork.Version) (cid.Cid, error) `perm:"read"` + StateActorCodeCIDs func(p0 context.Context, p1 abinetwork.Version) (map[string]cid.Cid, error) `perm:"read"` - StateAllMinerFaults func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) `perm:"read"` + StateActorManifestCID func(p0 context.Context, p1 abinetwork.Version) (cid.Cid, error) `perm:"read"` - StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) `perm:"read"` + StateAllMinerFaults func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) `perm:"read"` - StateChangedActors func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) `perm:"read"` + StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) `perm:"read"` - StateCirculatingSupply func(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) `perm:"read"` + StateChangedActors func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) `perm:"read"` - StateCompute func(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*ComputeStateOutput, error) `perm:"read"` + StateCirculatingSupply func(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) `perm:"read"` - StateComputeDataCID func(p0 context.Context, p1 address.Address, p2 abi.RegisteredSealProof, p3 []abi.DealID, p4 types.TipSetKey) (cid.Cid, 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) (DealCollateralBounds, error) `perm:"read"` + StateComputeDataCID func(p0 context.Context, p1 address.Address, p2 abi.RegisteredSealProof, p3 []abi.DealID, p4 types.TipSetKey) (cid.Cid, error) `perm:"read"` - StateDecodeParams func(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) `perm:"read"` + StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) `perm:"read"` - StateEncodeParams func(p0 context.Context, p1 cid.Cid, p2 abi.MethodNum, p3 json.RawMessage) ([]byte, 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"` + StateEncodeParams func(p0 context.Context, p1 cid.Cid, p2 abi.MethodNum, p3 json.RawMessage) ([]byte, error) `perm:"read"` - StateGetAllocation func(p0 context.Context, p1 address.Address, p2 verifregtypes.AllocationId, p3 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"` + StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"` - StateGetAllocationForPendingDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"` + StateGetAllocation func(p0 context.Context, p1 address.Address, p2 verifregtypes.AllocationId, p3 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"` - StateGetAllocations func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.AllocationId]verifregtypes.Allocation, error) `perm:"read"` + StateGetAllocationForPendingDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"` - StateGetBeaconEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"` + StateGetAllocations func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.AllocationId]verifregtypes.Allocation, error) `perm:"read"` - StateGetClaim func(p0 context.Context, p1 address.Address, p2 verifregtypes.ClaimId, p3 types.TipSetKey) (*verifregtypes.Claim, error) `perm:"read"` + StateGetBeaconEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"` - StateGetClaims func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.ClaimId]verifregtypes.Claim, error) `perm:"read"` + StateGetClaim func(p0 context.Context, p1 address.Address, p2 verifregtypes.ClaimId, p3 types.TipSetKey) (*verifregtypes.Claim, error) `perm:"read"` - StateGetNetworkParams func(p0 context.Context) (*NetworkParams, error) `perm:"read"` + StateGetClaims func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.ClaimId]verifregtypes.Claim, error) `perm:"read"` - StateGetRandomnessFromBeacon func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"` + StateGetNetworkParams func(p0 context.Context) (*NetworkParams, error) `perm:"read"` - StateGetRandomnessFromTickets func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"` + StateGetRandomnessFromBeacon func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"` - StateListActors func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` + StateGetRandomnessFromTickets func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"` - StateListMessages func(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` + StateListActors func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` - StateListMiners 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"` - StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` + StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` - StateLookupRobustAddress func(p0 context.Context, p1 address.Address, p2 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) (MarketBalance, error) `perm:"read"` + StateLookupRobustAddress func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` - StateMarketDeals func(p0 context.Context, p1 types.TipSetKey) (map[string]*MarketDeal, error) `perm:"read"` + StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) `perm:"read"` - StateMarketParticipants func(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) `perm:"read"` + StateMarketDeals func(p0 context.Context, p1 types.TipSetKey) (map[string]*MarketDeal, error) `perm:"read"` - StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) `perm:"read"` + StateMarketParticipants func(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) `perm:"read"` - StateMinerActiveSectors func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` + StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) `perm:"read"` - StateMinerAllocated func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*bitfield.BitField, 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"` + StateMinerAllocated func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*bitfield.BitField, error) `perm:"read"` - StateMinerDeadlines func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) `perm:"read"` + StateMinerAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateMinerFaults func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` + StateMinerDeadlines func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) `perm:"read"` - StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerInfo, error) `perm:"read"` + StateMinerFaults func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` - StateMinerInitialPledgeCollateral func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerInfo, error) `perm:"read"` - StateMinerPartitions func(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) `perm:"read"` + StateMinerInitialPledgeCollateral func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) `perm:"read"` + StateMinerPartitions func(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) `perm:"read"` - StateMinerPreCommitDepositForPower func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) `perm:"read"` - StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `perm:"read"` + StateMinerPreCommitDepositForPower func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateMinerRecoveries func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` + StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `perm:"read"` - StateMinerSectorAllocated func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) `perm:"read"` + StateMinerRecoveries func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` - StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) `perm:"read"` + StateMinerSectorAllocated func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) `perm:"read"` - StateMinerSectors func(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` + StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) `perm:"read"` - StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) `perm:"read"` + StateMinerSectors func(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` - StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `perm:"read"` + StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) `perm:"read"` - StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) `perm:"read"` + StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `perm:"read"` - StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) `perm:"read"` + StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) `perm:"read"` - StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `perm:"read"` + StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) `perm:"read"` - StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"` + StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `perm:"read"` - StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"` + StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"` - StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"` + StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"` - StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorPreCommitOnChainInfo, error) `perm:"read"` + StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"` - StateVMCirculatingSupplyInternal func(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) `perm:"read"` + StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorPreCommitOnChainInfo, error) `perm:"read"` - StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` + StateVMCirculatingSupplyInternal func(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) `perm:"read"` - StateVerifiedRegistryRootKey func(p0 context.Context, p1 types.TipSetKey) (address.Address, error) `perm:"read"` + StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` - StateVerifierStatus 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"` - StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `perm:"read"` + StateVerifierStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` - SyncCheckBad func(p0 context.Context, p1 cid.Cid) (string, error) `perm:"read"` + StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `perm:"read"` - SyncCheckpoint func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` + SyncCheckBad func(p0 context.Context, p1 cid.Cid) (string, error) `perm:"read"` - SyncIncomingBlocks func(p0 context.Context) (<-chan *types.BlockHeader, error) `perm:"read"` + SyncCheckpoint func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` - SyncMarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + SyncIncomingBlocks func(p0 context.Context) (<-chan *types.BlockHeader, error) `perm:"read"` - SyncState func(p0 context.Context) (*SyncState, error) `perm:"read"` + SyncMarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` - SyncSubmitBlock func(p0 context.Context, p1 *types.BlockMsg) error `perm:"write"` + SyncState func(p0 context.Context) (*SyncState, error) `perm:"read"` - SyncUnmarkAllBad func(p0 context.Context) error `perm:"admin"` + SyncSubmitBlock func(p0 context.Context, p1 *types.BlockMsg) error `perm:"write"` - SyncUnmarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + SyncUnmarkAllBad func(p0 context.Context) error `perm:"admin"` - SyncValidateTipset func(p0 context.Context, p1 types.TipSetKey) (bool, error) `perm:"read"` + SyncUnmarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` - WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"read"` + SyncValidateTipset func(p0 context.Context, p1 types.TipSetKey) (bool, error) `perm:"read"` - WalletDefaultAddress func(p0 context.Context) (address.Address, error) `perm:"write"` + WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"read"` - WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"` + WalletDefaultAddress func(p0 context.Context) (address.Address, error) `perm:"write"` - WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"` + WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"` - WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"write"` + WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"` - WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"` + WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"write"` - WalletList func(p0 context.Context) ([]address.Address, error) `perm:"write"` + WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"` - WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"write"` + WalletList func(p0 context.Context) ([]address.Address, error) `perm:"write"` - WalletSetDefault func(p0 context.Context, p1 address.Address) error `perm:"write"` + WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"write"` - WalletSign func(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) `perm:"sign"` + WalletSetDefault func(p0 context.Context, p1 address.Address) error `perm:"write"` - WalletSignMessage func(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) `perm:"sign"` + WalletSign func(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) `perm:"sign"` - WalletValidateAddress func(p0 context.Context, p1 string) (address.Address, error) `perm:"read"` + WalletSignMessage func(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) `perm:"sign"` - WalletVerify func(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) `perm:"read"` + WalletValidateAddress func(p0 context.Context, p1 string) (address.Address, error) `perm:"read"` - Web3ClientVersion func(p0 context.Context) (string, error) `perm:"read"` - } + WalletVerify func(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) `perm:"read"` + + Web3ClientVersion func(p0 context.Context) (string, error) `perm:"read"` } type FullNodeStub struct { @@ -594,215 +612,221 @@ type FullNodeStub struct { } type GatewayStruct struct { - Internal struct { - ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `` + Internal GatewayMethods +} - ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `` +type GatewayMethods struct { + ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `` - ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `` + ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `` - ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]Message, error) `` + ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `` - ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `` + ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]Message, error) `` - ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) `` + ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `` - ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `` + ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) `` - ChainGetTipSetAfterHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, 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) `` + ChainGetTipSetAfterHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `` - ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` + ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `` - ChainHead func(p0 context.Context) (*types.TipSet, error) `` + ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` - ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `` + ChainHead func(p0 context.Context) (*types.TipSet, error) `` - ChainPutObj func(p0 context.Context, p1 blocks.Block) error `` + ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `` - ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` + ChainPutObj func(p0 context.Context, p1 blocks.Block) error `` - Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) `` + ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` - EthAccounts func(p0 context.Context) ([]ethtypes.EthAddress, error) `` + Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) `` - EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) `` + EthAccounts func(p0 context.Context) ([]ethtypes.EthAddress, error) `` - EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) `` + EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) `` - EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `` + EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) `` - EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) `` + EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `` - EthFeeHistory func(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) `` + EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) `` - EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `` + EthFeeHistory func(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) `` - EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) `` + EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `` - EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) `` + EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) `` - EthGetBlockByNumber func(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) `` + EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) `` - EthGetBlockTransactionCountByHash func(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) `` + EthGetBlockByNumber func(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) `` - EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) `` + EthGetBlockTransactionCountByHash func(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) `` - EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) `` + EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) `` - EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `` + EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) `` - EthGetFilterLogs func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `` + EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `` - EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) `` + EthGetFilterLogs func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `` - EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `` + EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) `` - EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `` + EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `` - EthGetTransactionByBlockNumberAndIndex func(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `` + EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `` - EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) `` + EthGetTransactionByBlockNumberAndIndex func(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `` - EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `` + EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) `` - EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) `` + EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `` - EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) `` + EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) `` - EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `` + EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) `` - EthNewFilter func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) `` + EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `` - EthNewPendingTransactionFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `` + EthNewFilter func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) `` - EthProtocolVersion func(p0 context.Context) (ethtypes.EthUint64, error) `` + EthNewPendingTransactionFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `` - EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) `` + EthProtocolVersion func(p0 context.Context) (ethtypes.EthUint64, error) `` - EthSubscribe func(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) `` + EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) `` - EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `` + EthSubscribe func(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) `` - EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) `` + EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `` - GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` + EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) `` - MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `` + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` - MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `` + MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `` - MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) `` + MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `` - MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `` + MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) `` - MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) `` + MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `` - NetListening func(p0 context.Context) (bool, error) `` + MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) `` - NetVersion func(p0 context.Context) (string, error) `` + NetListening func(p0 context.Context) (bool, error) `` - StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` + NetVersion func(p0 context.Context) (string, error) `` - StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) `` + StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` - StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `` + StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) `` - StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `` + StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `` - StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` + StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `` - StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) `` + StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` - StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) `` + StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) `` - StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerInfo, error) `` + StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) `` - StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) `` + StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerInfo, error) `` - StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `` + StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) `` - StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `` + StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `` - StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) `perm:"read"` + StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `` - StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `` + StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) `perm:"read"` - StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `` + StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `` - StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` + StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `` - StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `` + StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` - Version func(p0 context.Context) (APIVersion, 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) `` - } + Version func(p0 context.Context) (APIVersion, error) `` + + WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `` } type GatewayStub struct { } type NetStruct struct { - Internal struct { - ID func(p0 context.Context) (peer.ID, error) `perm:"read"` + Internal NetMethods +} - NetAddrsListen func(p0 context.Context) (peer.AddrInfo, error) `perm:"read"` +type NetMethods struct { + ID func(p0 context.Context) (peer.ID, error) `perm:"read"` - NetAgentVersion func(p0 context.Context, p1 peer.ID) (string, error) `perm:"read"` + NetAddrsListen func(p0 context.Context) (peer.AddrInfo, error) `perm:"read"` - NetAutoNatStatus func(p0 context.Context) (NatInfo, error) `perm:"read"` + NetAgentVersion func(p0 context.Context, p1 peer.ID) (string, error) `perm:"read"` - NetBandwidthStats func(p0 context.Context) (metrics.Stats, error) `perm:"read"` + NetAutoNatStatus func(p0 context.Context) (NatInfo, error) `perm:"read"` - NetBandwidthStatsByPeer func(p0 context.Context) (map[string]metrics.Stats, error) `perm:"read"` + NetBandwidthStats func(p0 context.Context) (metrics.Stats, error) `perm:"read"` - NetBandwidthStatsByProtocol func(p0 context.Context) (map[protocol.ID]metrics.Stats, error) `perm:"read"` + NetBandwidthStatsByPeer func(p0 context.Context) (map[string]metrics.Stats, error) `perm:"read"` - NetBlockAdd func(p0 context.Context, p1 NetBlockList) error `perm:"admin"` + NetBandwidthStatsByProtocol func(p0 context.Context) (map[protocol.ID]metrics.Stats, error) `perm:"read"` - NetBlockList func(p0 context.Context) (NetBlockList, error) `perm:"read"` + NetBlockAdd func(p0 context.Context, p1 NetBlockList) error `perm:"admin"` - NetBlockRemove func(p0 context.Context, p1 NetBlockList) error `perm:"admin"` + NetBlockList func(p0 context.Context) (NetBlockList, error) `perm:"read"` - NetConnect func(p0 context.Context, p1 peer.AddrInfo) error `perm:"write"` + NetBlockRemove func(p0 context.Context, p1 NetBlockList) error `perm:"admin"` - NetConnectedness func(p0 context.Context, p1 peer.ID) (network.Connectedness, error) `perm:"read"` + NetConnect func(p0 context.Context, p1 peer.AddrInfo) error `perm:"write"` - NetDisconnect func(p0 context.Context, p1 peer.ID) error `perm:"write"` + NetConnectedness func(p0 context.Context, p1 peer.ID) (network.Connectedness, error) `perm:"read"` - NetFindPeer func(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) `perm:"read"` + NetDisconnect func(p0 context.Context, p1 peer.ID) error `perm:"write"` - NetLimit func(p0 context.Context, p1 string) (NetLimit, error) `perm:"read"` + NetFindPeer func(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) `perm:"read"` - NetPeerInfo func(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) `perm:"read"` + NetLimit func(p0 context.Context, p1 string) (NetLimit, error) `perm:"read"` - NetPeers func(p0 context.Context) ([]peer.AddrInfo, error) `perm:"read"` + NetPeerInfo func(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) `perm:"read"` - NetPing func(p0 context.Context, p1 peer.ID) (time.Duration, error) `perm:"read"` + NetPeers func(p0 context.Context) ([]peer.AddrInfo, error) `perm:"read"` - NetProtectAdd func(p0 context.Context, p1 []peer.ID) error `perm:"admin"` + NetPing func(p0 context.Context, p1 peer.ID) (time.Duration, error) `perm:"read"` - NetProtectList func(p0 context.Context) ([]peer.ID, error) `perm:"read"` + NetProtectAdd func(p0 context.Context, p1 []peer.ID) error `perm:"admin"` - NetProtectRemove func(p0 context.Context, p1 []peer.ID) error `perm:"admin"` + NetProtectList func(p0 context.Context) ([]peer.ID, error) `perm:"read"` - NetPubsubScores func(p0 context.Context) ([]PubsubScore, error) `perm:"read"` + NetProtectRemove func(p0 context.Context, p1 []peer.ID) error `perm:"admin"` - NetSetLimit func(p0 context.Context, p1 string, p2 NetLimit) error `perm:"admin"` + NetPubsubScores func(p0 context.Context) ([]PubsubScore, error) `perm:"read"` - NetStat func(p0 context.Context, p1 string) (NetStat, error) `perm:"read"` - } + NetSetLimit func(p0 context.Context, p1 string, p2 NetLimit) error `perm:"admin"` + + NetStat func(p0 context.Context, p1 string) (NetStat, error) `perm:"read"` } type NetStub struct { } type SignableStruct struct { - Internal struct { - Sign func(p0 context.Context, p1 SignFunc) error `` - } + Internal SignableMethods +} + +type SignableMethods struct { + Sign func(p0 context.Context, p1 SignFunc) error `` } type SignableStub struct { @@ -813,271 +837,273 @@ type StorageMinerStruct struct { NetStruct - Internal struct { - ActorAddress func(p0 context.Context) (address.Address, error) `perm:"read"` + Internal StorageMinerMethods +} - ActorAddressConfig func(p0 context.Context) (AddressConfig, error) `perm:"read"` +type StorageMinerMethods struct { + ActorAddress func(p0 context.Context) (address.Address, error) `perm:"read"` - ActorSectorSize func(p0 context.Context, p1 address.Address) (abi.SectorSize, error) `perm:"read"` + ActorAddressConfig func(p0 context.Context) (AddressConfig, error) `perm:"read"` - ActorWithdrawBalance func(p0 context.Context, p1 abi.TokenAmount) (cid.Cid, error) `perm:"admin"` + ActorSectorSize func(p0 context.Context, p1 address.Address) (abi.SectorSize, error) `perm:"read"` - BeneficiaryWithdrawBalance func(p0 context.Context, p1 abi.TokenAmount) (cid.Cid, error) `perm:"admin"` + ActorWithdrawBalance func(p0 context.Context, p1 abi.TokenAmount) (cid.Cid, error) `perm:"admin"` - CheckProvable func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storiface.SectorRef) (map[abi.SectorNumber]string, error) `perm:"admin"` + BeneficiaryWithdrawBalance func(p0 context.Context, p1 abi.TokenAmount) (cid.Cid, error) `perm:"admin"` - ComputeDataCid func(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storiface.Data) (abi.PieceInfo, error) `perm:"admin"` + CheckProvable func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storiface.SectorRef) (map[abi.SectorNumber]string, error) `perm:"admin"` - ComputeProof func(p0 context.Context, p1 []builtinactors.ExtendedSectorInfo, p2 abi.PoStRandomness, p3 abi.ChainEpoch, p4 abinetwork.Version) ([]builtinactors.PoStProof, error) `perm:"read"` + ComputeDataCid func(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storiface.Data) (abi.PieceInfo, error) `perm:"admin"` - ComputeWindowPoSt func(p0 context.Context, p1 uint64, p2 types.TipSetKey) ([]miner.SubmitWindowedPoStParams, error) `perm:"admin"` + ComputeProof func(p0 context.Context, p1 []builtinactors.ExtendedSectorInfo, p2 abi.PoStRandomness, p3 abi.ChainEpoch, p4 abinetwork.Version) ([]builtinactors.PoStProof, error) `perm:"read"` - CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` + ComputeWindowPoSt func(p0 context.Context, p1 uint64, p2 types.TipSetKey) ([]miner.SubmitWindowedPoStParams, error) `perm:"admin"` - DagstoreGC func(p0 context.Context) ([]DagstoreShardResult, error) `perm:"admin"` + CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` - DagstoreInitializeAll func(p0 context.Context, p1 DagstoreInitializeAllParams) (<-chan DagstoreInitializeAllEvent, error) `perm:"write"` + DagstoreGC func(p0 context.Context) ([]DagstoreShardResult, error) `perm:"admin"` - DagstoreInitializeShard func(p0 context.Context, p1 string) error `perm:"write"` + DagstoreInitializeAll func(p0 context.Context, p1 DagstoreInitializeAllParams) (<-chan DagstoreInitializeAllEvent, error) `perm:"write"` - DagstoreListShards func(p0 context.Context) ([]DagstoreShardInfo, error) `perm:"read"` + DagstoreInitializeShard func(p0 context.Context, p1 string) error `perm:"write"` - DagstoreLookupPieces func(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) `perm:"admin"` + DagstoreListShards func(p0 context.Context) ([]DagstoreShardInfo, error) `perm:"read"` - DagstoreRecoverShard func(p0 context.Context, p1 string) error `perm:"write"` + DagstoreLookupPieces func(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) `perm:"admin"` - DagstoreRegisterShard func(p0 context.Context, p1 string) error `perm:"admin"` + DagstoreRecoverShard func(p0 context.Context, p1 string) error `perm:"write"` - DealsConsiderOfflineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"` + DagstoreRegisterShard func(p0 context.Context, p1 string) error `perm:"admin"` - DealsConsiderOfflineStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` + DealsConsiderOfflineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"` - DealsConsiderOnlineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"` + DealsConsiderOfflineStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` - DealsConsiderOnlineStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` + DealsConsiderOnlineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"` - DealsConsiderUnverifiedStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` + DealsConsiderOnlineStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` - DealsConsiderVerifiedStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` + DealsConsiderUnverifiedStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` - DealsImportData func(p0 context.Context, p1 cid.Cid, p2 string) error `perm:"admin"` + DealsConsiderVerifiedStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` - DealsList func(p0 context.Context) ([]*MarketDeal, error) `perm:"admin"` + DealsImportData func(p0 context.Context, p1 cid.Cid, p2 string) error `perm:"admin"` - DealsPieceCidBlocklist func(p0 context.Context) ([]cid.Cid, error) `perm:"admin"` + DealsList func(p0 context.Context) ([]*MarketDeal, error) `perm:"admin"` - DealsSetConsiderOfflineRetrievalDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + DealsPieceCidBlocklist func(p0 context.Context) ([]cid.Cid, error) `perm:"admin"` - DealsSetConsiderOfflineStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + DealsSetConsiderOfflineRetrievalDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - DealsSetConsiderOnlineRetrievalDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + DealsSetConsiderOfflineStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - DealsSetConsiderOnlineStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + DealsSetConsiderOnlineRetrievalDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - DealsSetConsiderUnverifiedStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + DealsSetConsiderOnlineStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - DealsSetConsiderVerifiedStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + DealsSetConsiderUnverifiedStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - DealsSetPieceCidBlocklist func(p0 context.Context, p1 []cid.Cid) error `perm:"admin"` + DealsSetConsiderVerifiedStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - IndexerAnnounceAllDeals func(p0 context.Context) error `perm:"admin"` + DealsSetPieceCidBlocklist func(p0 context.Context, p1 []cid.Cid) error `perm:"admin"` - IndexerAnnounceDeal func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + IndexerAnnounceAllDeals func(p0 context.Context) error `perm:"admin"` - MarketCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + IndexerAnnounceDeal func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` - MarketDataTransferDiagnostics func(p0 context.Context, p1 peer.ID) (*TransferDiagnostics, error) `perm:"write"` + MarketCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` - MarketDataTransferUpdates func(p0 context.Context) (<-chan DataTransferChannel, error) `perm:"write"` + MarketDataTransferDiagnostics func(p0 context.Context, p1 peer.ID) (*TransferDiagnostics, error) `perm:"write"` - MarketGetAsk func(p0 context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"` + MarketDataTransferUpdates func(p0 context.Context) (<-chan DataTransferChannel, error) `perm:"write"` - MarketGetDealUpdates func(p0 context.Context) (<-chan storagemarket.MinerDeal, error) `perm:"read"` + MarketGetAsk func(p0 context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"` - MarketGetRetrievalAsk func(p0 context.Context) (*retrievalmarket.Ask, error) `perm:"read"` + MarketGetDealUpdates func(p0 context.Context) (<-chan storagemarket.MinerDeal, error) `perm:"read"` - MarketImportDealData func(p0 context.Context, p1 cid.Cid, p2 string) error `perm:"write"` + MarketGetRetrievalAsk func(p0 context.Context) (*retrievalmarket.Ask, error) `perm:"read"` - MarketListDataTransfers func(p0 context.Context) ([]DataTransferChannel, error) `perm:"write"` + MarketImportDealData func(p0 context.Context, p1 cid.Cid, p2 string) error `perm:"write"` - MarketListDeals func(p0 context.Context) ([]*MarketDeal, error) `perm:"read"` + MarketListDataTransfers func(p0 context.Context) ([]DataTransferChannel, error) `perm:"write"` - MarketListIncompleteDeals func(p0 context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"` + MarketListDeals func(p0 context.Context) ([]*MarketDeal, error) `perm:"read"` - MarketListRetrievalDeals func(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) `perm:"read"` + MarketListIncompleteDeals func(p0 context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"` - MarketPendingDeals func(p0 context.Context) (PendingDealInfo, error) `perm:"write"` + MarketListRetrievalDeals func(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) `perm:"read"` - MarketPublishPendingDeals func(p0 context.Context) error `perm:"admin"` + MarketPendingDeals func(p0 context.Context) (PendingDealInfo, error) `perm:"write"` - MarketRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + MarketPublishPendingDeals func(p0 context.Context) error `perm:"admin"` - MarketRetryPublishDeal func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + MarketRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` - MarketSetAsk func(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error `perm:"admin"` + MarketRetryPublishDeal func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` - MarketSetRetrievalAsk func(p0 context.Context, p1 *retrievalmarket.Ask) error `perm:"admin"` + MarketSetAsk func(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error `perm:"admin"` - MiningBase func(p0 context.Context) (*types.TipSet, error) `perm:"read"` + MarketSetRetrievalAsk func(p0 context.Context, p1 *retrievalmarket.Ask) error `perm:"admin"` - PiecesGetCIDInfo func(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) `perm:"read"` + MiningBase func(p0 context.Context) (*types.TipSet, error) `perm:"read"` - PiecesGetPieceInfo func(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) `perm:"read"` + PiecesGetCIDInfo func(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) `perm:"read"` - PiecesListCidInfos func(p0 context.Context) ([]cid.Cid, error) `perm:"read"` + PiecesGetPieceInfo func(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) `perm:"read"` - PiecesListPieces func(p0 context.Context) ([]cid.Cid, error) `perm:"read"` + PiecesListCidInfos func(p0 context.Context) ([]cid.Cid, error) `perm:"read"` - PledgeSector func(p0 context.Context) (abi.SectorID, error) `perm:"write"` + PiecesListPieces func(p0 context.Context) ([]cid.Cid, error) `perm:"read"` - RecoverFault func(p0 context.Context, p1 []abi.SectorNumber) ([]cid.Cid, error) `perm:"admin"` + PledgeSector func(p0 context.Context) (abi.SectorID, error) `perm:"write"` - ReturnAddPiece func(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error `perm:"admin"` + RecoverFault func(p0 context.Context, p1 []abi.SectorNumber) ([]cid.Cid, error) `perm:"admin"` - ReturnDataCid func(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error `perm:"admin"` + ReturnAddPiece func(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error `perm:"admin"` - ReturnDownloadSector func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + ReturnDataCid func(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error `perm:"admin"` - ReturnFetch func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + ReturnDownloadSector func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - ReturnFinalizeReplicaUpdate func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + ReturnFetch func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - ReturnFinalizeSector func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + ReturnFinalizeReplicaUpdate func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - ReturnGenerateSectorKeyFromData func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + ReturnFinalizeSector func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - ReturnMoveStorage func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + ReturnGenerateSectorKeyFromData func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - ReturnProveReplicaUpdate1 func(p0 context.Context, p1 storiface.CallID, p2 storiface.ReplicaVanillaProofs, p3 *storiface.CallError) error `perm:"admin"` + ReturnMoveStorage func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - ReturnProveReplicaUpdate2 func(p0 context.Context, p1 storiface.CallID, p2 storiface.ReplicaUpdateProof, p3 *storiface.CallError) error `perm:"admin"` + ReturnProveReplicaUpdate1 func(p0 context.Context, p1 storiface.CallID, p2 storiface.ReplicaVanillaProofs, p3 *storiface.CallError) error `perm:"admin"` - ReturnReadPiece func(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error `perm:"admin"` + ReturnProveReplicaUpdate2 func(p0 context.Context, p1 storiface.CallID, p2 storiface.ReplicaUpdateProof, p3 *storiface.CallError) error `perm:"admin"` - ReturnReleaseUnsealed func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + ReturnReadPiece func(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error `perm:"admin"` - ReturnReplicaUpdate func(p0 context.Context, p1 storiface.CallID, p2 storiface.ReplicaUpdateOut, p3 *storiface.CallError) error `perm:"admin"` + ReturnReleaseUnsealed func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - ReturnSealCommit1 func(p0 context.Context, p1 storiface.CallID, p2 storiface.Commit1Out, p3 *storiface.CallError) error `perm:"admin"` + ReturnReplicaUpdate func(p0 context.Context, p1 storiface.CallID, p2 storiface.ReplicaUpdateOut, p3 *storiface.CallError) error `perm:"admin"` - ReturnSealCommit2 func(p0 context.Context, p1 storiface.CallID, p2 storiface.Proof, p3 *storiface.CallError) error `perm:"admin"` + ReturnSealCommit1 func(p0 context.Context, p1 storiface.CallID, p2 storiface.Commit1Out, p3 *storiface.CallError) error `perm:"admin"` - ReturnSealPreCommit1 func(p0 context.Context, p1 storiface.CallID, p2 storiface.PreCommit1Out, p3 *storiface.CallError) error `perm:"admin"` + ReturnSealCommit2 func(p0 context.Context, p1 storiface.CallID, p2 storiface.Proof, p3 *storiface.CallError) error `perm:"admin"` - ReturnSealPreCommit2 func(p0 context.Context, p1 storiface.CallID, p2 storiface.SectorCids, p3 *storiface.CallError) error `perm:"admin"` + ReturnSealPreCommit1 func(p0 context.Context, p1 storiface.CallID, p2 storiface.PreCommit1Out, p3 *storiface.CallError) error `perm:"admin"` - ReturnUnsealPiece func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + ReturnSealPreCommit2 func(p0 context.Context, p1 storiface.CallID, p2 storiface.SectorCids, p3 *storiface.CallError) error `perm:"admin"` - RuntimeSubsystems func(p0 context.Context) (MinerSubsystems, error) `perm:"read"` + ReturnUnsealPiece func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - SealingAbort func(p0 context.Context, p1 storiface.CallID) error `perm:"admin"` + RuntimeSubsystems func(p0 context.Context) (MinerSubsystems, error) `perm:"read"` - SealingRemoveRequest func(p0 context.Context, p1 uuid.UUID) error `perm:"admin"` + SealingAbort func(p0 context.Context, p1 storiface.CallID) error `perm:"admin"` - SealingSchedDiag func(p0 context.Context, p1 bool) (interface{}, error) `perm:"admin"` + SealingRemoveRequest func(p0 context.Context, p1 uuid.UUID) error `perm:"admin"` - SectorAbortUpgrade func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` + SealingSchedDiag func(p0 context.Context, p1 bool) (interface{}, error) `perm:"admin"` - SectorAddPieceToAny func(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storiface.Data, p3 PieceDealInfo) (SectorOffset, error) `perm:"admin"` + SectorAbortUpgrade func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` - SectorCommitFlush func(p0 context.Context) ([]sealiface.CommitBatchRes, error) `perm:"admin"` + SectorAddPieceToAny func(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storiface.Data, p3 PieceDealInfo) (SectorOffset, error) `perm:"admin"` - SectorCommitPending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"` + SectorCommitFlush func(p0 context.Context) ([]sealiface.CommitBatchRes, error) `perm:"admin"` - SectorGetExpectedSealDuration func(p0 context.Context) (time.Duration, error) `perm:"read"` + SectorCommitPending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"` - SectorGetSealDelay func(p0 context.Context) (time.Duration, error) `perm:"read"` + SectorGetExpectedSealDuration func(p0 context.Context) (time.Duration, error) `perm:"read"` - SectorMarkForUpgrade func(p0 context.Context, p1 abi.SectorNumber, p2 bool) error `perm:"admin"` + SectorGetSealDelay func(p0 context.Context) (time.Duration, error) `perm:"read"` - SectorMatchPendingPiecesToOpenSectors func(p0 context.Context) error `perm:"admin"` + SectorMarkForUpgrade func(p0 context.Context, p1 abi.SectorNumber, p2 bool) error `perm:"admin"` - SectorNumAssignerMeta func(p0 context.Context) (NumAssignerMeta, error) `perm:"read"` + SectorMatchPendingPiecesToOpenSectors func(p0 context.Context) error `perm:"admin"` - SectorNumFree func(p0 context.Context, p1 string) error `perm:"admin"` + SectorNumAssignerMeta func(p0 context.Context) (NumAssignerMeta, error) `perm:"read"` - SectorNumReservations func(p0 context.Context) (map[string]bitfield.BitField, error) `perm:"read"` + SectorNumFree func(p0 context.Context, p1 string) error `perm:"admin"` - SectorNumReserve func(p0 context.Context, p1 string, p2 bitfield.BitField, p3 bool) error `perm:"admin"` + SectorNumReservations func(p0 context.Context) (map[string]bitfield.BitField, error) `perm:"read"` - SectorNumReserveCount func(p0 context.Context, p1 string, p2 uint64) (bitfield.BitField, error) `perm:"admin"` + SectorNumReserve func(p0 context.Context, p1 string, p2 bitfield.BitField, p3 bool) error `perm:"admin"` - SectorPreCommitFlush func(p0 context.Context) ([]sealiface.PreCommitBatchRes, error) `perm:"admin"` + SectorNumReserveCount func(p0 context.Context, p1 string, p2 uint64) (bitfield.BitField, error) `perm:"admin"` - SectorPreCommitPending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"` + SectorPreCommitFlush func(p0 context.Context) ([]sealiface.PreCommitBatchRes, error) `perm:"admin"` - SectorReceive func(p0 context.Context, p1 RemoteSectorMeta) error `perm:"admin"` + SectorPreCommitPending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"` - SectorRemove func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` + SectorReceive func(p0 context.Context, p1 RemoteSectorMeta) error `perm:"admin"` - SectorSetExpectedSealDuration func(p0 context.Context, p1 time.Duration) error `perm:"write"` + SectorRemove func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` - SectorSetSealDelay func(p0 context.Context, p1 time.Duration) error `perm:"write"` + SectorSetExpectedSealDuration func(p0 context.Context, p1 time.Duration) error `perm:"write"` - SectorStartSealing func(p0 context.Context, p1 abi.SectorNumber) error `perm:"write"` + SectorSetSealDelay func(p0 context.Context, p1 time.Duration) error `perm:"write"` - SectorTerminate func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` + SectorStartSealing func(p0 context.Context, p1 abi.SectorNumber) error `perm:"write"` - SectorTerminateFlush func(p0 context.Context) (*cid.Cid, error) `perm:"admin"` + SectorTerminate func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` - SectorTerminatePending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"` + SectorTerminateFlush func(p0 context.Context) (*cid.Cid, error) `perm:"admin"` - SectorsList func(p0 context.Context) ([]abi.SectorNumber, error) `perm:"read"` + SectorTerminatePending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"` - SectorsListInStates func(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) `perm:"read"` + SectorsList func(p0 context.Context) ([]abi.SectorNumber, error) `perm:"read"` - SectorsRefs func(p0 context.Context) (map[string][]SealedRef, error) `perm:"read"` + SectorsListInStates func(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) `perm:"read"` - SectorsStatus func(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) `perm:"read"` + SectorsRefs func(p0 context.Context) (map[string][]SealedRef, error) `perm:"read"` - SectorsSummary func(p0 context.Context) (map[SectorState]int, error) `perm:"read"` + SectorsStatus func(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) `perm:"read"` - SectorsUnsealPiece func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 *cid.Cid) error `perm:"admin"` + SectorsSummary func(p0 context.Context) (map[SectorState]int, error) `perm:"read"` - SectorsUpdate func(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error `perm:"admin"` + SectorsUnsealPiece func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 *cid.Cid) error `perm:"admin"` - StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"` + SectorsUpdate func(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error `perm:"admin"` - StorageAttach func(p0 context.Context, p1 storiface.StorageInfo, p2 fsutil.FsStat) error `perm:"admin"` + StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"` - StorageAuthVerify func(p0 context.Context, p1 string) ([]auth.Permission, error) `perm:"read"` + StorageAttach func(p0 context.Context, p1 storiface.StorageInfo, p2 fsutil.FsStat) error `perm:"admin"` - StorageBestAlloc func(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]storiface.StorageInfo, error) `perm:"admin"` + StorageAuthVerify func(p0 context.Context, p1 string) ([]auth.Permission, error) `perm:"read"` - StorageDeclareSector func(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error `perm:"admin"` + StorageBestAlloc func(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]storiface.StorageInfo, error) `perm:"admin"` - StorageDetach func(p0 context.Context, p1 storiface.ID, p2 string) error `perm:"admin"` + StorageDeclareSector func(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error `perm:"admin"` - StorageDetachLocal func(p0 context.Context, p1 string) error `perm:"admin"` + StorageDetach func(p0 context.Context, p1 storiface.ID, p2 string) error `perm:"admin"` - StorageDropSector func(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error `perm:"admin"` + StorageDetachLocal func(p0 context.Context, p1 string) error `perm:"admin"` - StorageFindSector func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]storiface.SectorStorageInfo, error) `perm:"admin"` + StorageDropSector func(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error `perm:"admin"` - StorageGetLocks func(p0 context.Context) (storiface.SectorLocks, error) `perm:"admin"` + StorageFindSector func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]storiface.SectorStorageInfo, error) `perm:"admin"` - StorageInfo func(p0 context.Context, p1 storiface.ID) (storiface.StorageInfo, error) `perm:"admin"` + StorageGetLocks func(p0 context.Context) (storiface.SectorLocks, error) `perm:"admin"` - StorageList func(p0 context.Context) (map[storiface.ID][]storiface.Decl, error) `perm:"admin"` + StorageInfo func(p0 context.Context, p1 storiface.ID) (storiface.StorageInfo, error) `perm:"admin"` - StorageLocal func(p0 context.Context) (map[storiface.ID]string, error) `perm:"admin"` + StorageList func(p0 context.Context) (map[storiface.ID][]storiface.Decl, error) `perm:"admin"` - StorageLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error `perm:"admin"` + StorageLocal func(p0 context.Context) (map[storiface.ID]string, error) `perm:"admin"` - StorageRedeclareLocal func(p0 context.Context, p1 *storiface.ID, p2 bool) error `perm:"admin"` + StorageLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error `perm:"admin"` - StorageReportHealth func(p0 context.Context, p1 storiface.ID, p2 storiface.HealthReport) error `perm:"admin"` + StorageRedeclareLocal func(p0 context.Context, p1 *storiface.ID, p2 bool) error `perm:"admin"` - StorageStat func(p0 context.Context, p1 storiface.ID) (fsutil.FsStat, error) `perm:"admin"` + StorageReportHealth func(p0 context.Context, p1 storiface.ID, p2 storiface.HealthReport) error `perm:"admin"` - StorageTryLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) `perm:"admin"` + StorageStat func(p0 context.Context, p1 storiface.ID) (fsutil.FsStat, error) `perm:"admin"` - WorkerConnect func(p0 context.Context, p1 string) error `perm:"admin"` + StorageTryLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) `perm:"admin"` - WorkerJobs func(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) `perm:"admin"` + WorkerConnect func(p0 context.Context, p1 string) error `perm:"admin"` - WorkerStats func(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) `perm:"admin"` - } + WorkerJobs func(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) `perm:"admin"` + + WorkerStats func(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) `perm:"admin"` } type StorageMinerStub struct { @@ -1087,102 +1113,106 @@ type StorageMinerStub struct { } type WalletStruct struct { - Internal struct { - WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"` + Internal WalletMethods +} - WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"` +type WalletMethods struct { + WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"` - WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"admin"` + WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"` - WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"` + WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"admin"` - WalletList func(p0 context.Context) ([]address.Address, error) `perm:"admin"` + WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"` - WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"admin"` + WalletList func(p0 context.Context) ([]address.Address, error) `perm:"admin"` - WalletSign func(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) `perm:"admin"` - } + WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"admin"` + + WalletSign func(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) `perm:"admin"` } type WalletStub struct { } type WorkerStruct struct { - Internal struct { - AddPiece func(p0 context.Context, p1 storiface.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storiface.Data) (storiface.CallID, error) `perm:"admin"` + Internal WorkerMethods +} - DataCid func(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storiface.Data) (storiface.CallID, error) `perm:"admin"` +type WorkerMethods struct { + AddPiece func(p0 context.Context, p1 storiface.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storiface.Data) (storiface.CallID, error) `perm:"admin"` - DownloadSectorData func(p0 context.Context, p1 storiface.SectorRef, p2 bool, p3 map[storiface.SectorFileType]storiface.SectorLocation) (storiface.CallID, error) `perm:"admin"` + DataCid func(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storiface.Data) (storiface.CallID, error) `perm:"admin"` - Enabled func(p0 context.Context) (bool, error) `perm:"admin"` + DownloadSectorData func(p0 context.Context, p1 storiface.SectorRef, p2 bool, p3 map[storiface.SectorFileType]storiface.SectorLocation) (storiface.CallID, error) `perm:"admin"` - Fetch func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) `perm:"admin"` + Enabled func(p0 context.Context) (bool, error) `perm:"admin"` - FinalizeReplicaUpdate func(p0 context.Context, p1 storiface.SectorRef) (storiface.CallID, error) `perm:"admin"` + Fetch func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) `perm:"admin"` - FinalizeSector func(p0 context.Context, p1 storiface.SectorRef) (storiface.CallID, error) `perm:"admin"` + FinalizeReplicaUpdate func(p0 context.Context, p1 storiface.SectorRef) (storiface.CallID, error) `perm:"admin"` - GenerateSectorKeyFromData func(p0 context.Context, p1 storiface.SectorRef, p2 cid.Cid) (storiface.CallID, error) `perm:"admin"` + FinalizeSector func(p0 context.Context, p1 storiface.SectorRef) (storiface.CallID, error) `perm:"admin"` - GenerateWindowPoSt func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 abi.ActorID, p3 []storiface.PostSectorChallenge, p4 int, p5 abi.PoStRandomness) (storiface.WindowPoStResult, error) `perm:"admin"` + GenerateSectorKeyFromData func(p0 context.Context, p1 storiface.SectorRef, p2 cid.Cid) (storiface.CallID, error) `perm:"admin"` - GenerateWinningPoSt func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 abi.ActorID, p3 []storiface.PostSectorChallenge, p4 abi.PoStRandomness) ([]proof.PoStProof, error) `perm:"admin"` + GenerateWindowPoSt func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 abi.ActorID, p3 []storiface.PostSectorChallenge, p4 int, p5 abi.PoStRandomness) (storiface.WindowPoStResult, error) `perm:"admin"` - Info func(p0 context.Context) (storiface.WorkerInfo, error) `perm:"admin"` + GenerateWinningPoSt func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 abi.ActorID, p3 []storiface.PostSectorChallenge, p4 abi.PoStRandomness) ([]proof.PoStProof, error) `perm:"admin"` - MoveStorage func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) `perm:"admin"` + Info func(p0 context.Context) (storiface.WorkerInfo, error) `perm:"admin"` - Paths func(p0 context.Context) ([]storiface.StoragePath, error) `perm:"admin"` + MoveStorage func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) `perm:"admin"` - ProcessSession func(p0 context.Context) (uuid.UUID, error) `perm:"admin"` + Paths func(p0 context.Context) ([]storiface.StoragePath, error) `perm:"admin"` - ProveReplicaUpdate1 func(p0 context.Context, p1 storiface.SectorRef, p2 cid.Cid, p3 cid.Cid, p4 cid.Cid) (storiface.CallID, error) `perm:"admin"` + ProcessSession func(p0 context.Context) (uuid.UUID, error) `perm:"admin"` - ProveReplicaUpdate2 func(p0 context.Context, p1 storiface.SectorRef, p2 cid.Cid, p3 cid.Cid, p4 cid.Cid, p5 storiface.ReplicaVanillaProofs) (storiface.CallID, error) `perm:"admin"` + ProveReplicaUpdate1 func(p0 context.Context, p1 storiface.SectorRef, p2 cid.Cid, p3 cid.Cid, p4 cid.Cid) (storiface.CallID, error) `perm:"admin"` - ReleaseUnsealed func(p0 context.Context, p1 storiface.SectorRef, p2 []storiface.Range) (storiface.CallID, error) `perm:"admin"` + ProveReplicaUpdate2 func(p0 context.Context, p1 storiface.SectorRef, p2 cid.Cid, p3 cid.Cid, p4 cid.Cid, p5 storiface.ReplicaVanillaProofs) (storiface.CallID, error) `perm:"admin"` - Remove func(p0 context.Context, p1 abi.SectorID) error `perm:"admin"` + ReleaseUnsealed func(p0 context.Context, p1 storiface.SectorRef, p2 []storiface.Range) (storiface.CallID, error) `perm:"admin"` - ReplicaUpdate func(p0 context.Context, p1 storiface.SectorRef, p2 []abi.PieceInfo) (storiface.CallID, error) `perm:"admin"` + Remove func(p0 context.Context, p1 abi.SectorID) error `perm:"admin"` - SealCommit1 func(p0 context.Context, p1 storiface.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storiface.SectorCids) (storiface.CallID, error) `perm:"admin"` + ReplicaUpdate func(p0 context.Context, p1 storiface.SectorRef, p2 []abi.PieceInfo) (storiface.CallID, error) `perm:"admin"` - SealCommit2 func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.Commit1Out) (storiface.CallID, error) `perm:"admin"` + SealCommit1 func(p0 context.Context, p1 storiface.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storiface.SectorCids) (storiface.CallID, error) `perm:"admin"` - SealPreCommit1 func(p0 context.Context, p1 storiface.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) `perm:"admin"` + SealCommit2 func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.Commit1Out) (storiface.CallID, error) `perm:"admin"` - SealPreCommit2 func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.PreCommit1Out) (storiface.CallID, error) `perm:"admin"` + SealPreCommit1 func(p0 context.Context, p1 storiface.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) `perm:"admin"` - Session func(p0 context.Context) (uuid.UUID, error) `perm:"admin"` + SealPreCommit2 func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.PreCommit1Out) (storiface.CallID, error) `perm:"admin"` - SetEnabled func(p0 context.Context, p1 bool) error `perm:"admin"` + Session func(p0 context.Context) (uuid.UUID, error) `perm:"admin"` - Shutdown func(p0 context.Context) error `perm:"admin"` + SetEnabled func(p0 context.Context, p1 bool) error `perm:"admin"` - StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"` + Shutdown func(p0 context.Context) error `perm:"admin"` - StorageDetachAll func(p0 context.Context) error `perm:"admin"` + StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"` - StorageDetachLocal func(p0 context.Context, p1 string) error `perm:"admin"` + StorageDetachAll func(p0 context.Context) error `perm:"admin"` - StorageLocal func(p0 context.Context) (map[storiface.ID]string, error) `perm:"admin"` + StorageDetachLocal func(p0 context.Context, p1 string) error `perm:"admin"` - StorageRedeclareLocal func(p0 context.Context, p1 *storiface.ID, p2 bool) error `perm:"admin"` + StorageLocal func(p0 context.Context) (map[storiface.ID]string, error) `perm:"admin"` - TaskDisable func(p0 context.Context, p1 sealtasks.TaskType) error `perm:"admin"` + StorageRedeclareLocal func(p0 context.Context, p1 *storiface.ID, p2 bool) error `perm:"admin"` - TaskEnable func(p0 context.Context, p1 sealtasks.TaskType) error `perm:"admin"` + TaskDisable func(p0 context.Context, p1 sealtasks.TaskType) error `perm:"admin"` - TaskTypes func(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) `perm:"admin"` + TaskEnable func(p0 context.Context, p1 sealtasks.TaskType) error `perm:"admin"` - UnsealPiece func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) `perm:"admin"` + TaskTypes func(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) `perm:"admin"` - Version func(p0 context.Context) (Version, error) `perm:"admin"` + UnsealPiece func(p0 context.Context, p1 storiface.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) `perm:"admin"` - WaitQuiet func(p0 context.Context) error `perm:"admin"` - } + Version func(p0 context.Context) (Version, error) `perm:"admin"` + + WaitQuiet func(p0 context.Context) error `perm:"admin"` } type WorkerStub struct { @@ -1342,6 +1372,17 @@ func (s *CommonStub) Version(p0 context.Context) (APIVersion, error) { return *new(APIVersion), ErrNotSupported } +func (s *EthSubscriberStruct) EthSubscription(p0 context.Context, p1 jsonrpc.RawParams) error { + if s.Internal.EthSubscription == nil { + return ErrNotSupported + } + return s.Internal.EthSubscription(p0, p1) +} + +func (s *EthSubscriberStub) EthSubscription(p0 context.Context, p1 jsonrpc.RawParams) error { + return ErrNotSupported +} + func (s *FullNodeStruct) ChainBlockstoreInfo(p0 context.Context) (map[string]interface{}, error) { if s.Internal.ChainBlockstoreInfo == nil { return *new(map[string]interface{}), ErrNotSupported @@ -2277,15 +2318,15 @@ func (s *FullNodeStub) EthSendRawTransaction(p0 context.Context, p1 ethtypes.Eth return *new(ethtypes.EthHash), ErrNotSupported } -func (s *FullNodeStruct) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) { +func (s *FullNodeStruct) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { if s.Internal.EthSubscribe == nil { - return nil, ErrNotSupported + return *new(ethtypes.EthSubscriptionID), ErrNotSupported } return s.Internal.EthSubscribe(p0, p1, p2) } -func (s *FullNodeStub) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) { - return nil, ErrNotSupported +func (s *FullNodeStub) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { + return *new(ethtypes.EthSubscriptionID), ErrNotSupported } func (s *FullNodeStruct) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) { @@ -6955,6 +6996,7 @@ func (s *WorkerStub) WaitQuiet(p0 context.Context) error { var _ ChainIO = new(ChainIOStruct) var _ Common = new(CommonStruct) var _ CommonNet = new(CommonNetStruct) +var _ EthSubscriber = new(EthSubscriberStruct) var _ FullNode = new(FullNodeStruct) var _ Gateway = new(GatewayStruct) var _ Net = new(NetStruct) diff --git a/api/v0api/proxy_gen.go b/api/v0api/proxy_gen.go index b1a07dacc..f66588b8e 100644 --- a/api/v0api/proxy_gen.go +++ b/api/v0api/proxy_gen.go @@ -5,11 +5,6 @@ package v0api import ( "context" - blocks "github.com/ipfs/go-block-format" - "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p/core/peer" - "golang.org/x/xerrors" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-bitfield" datatransfer "github.com/filecoin-project/go-data-transfer" @@ -22,7 +17,6 @@ import ( "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/dline" abinetwork "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/api" apitypes "github.com/filecoin-project/lotus/api/types" lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -30,6 +24,10 @@ import ( marketevents "github.com/filecoin-project/lotus/markets/loggers" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/repo/imports" + blocks "github.com/ipfs/go-block-format" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p/core/peer" + "golang.org/x/xerrors" ) var ErrNotSupported = xerrors.New("method not supported") @@ -39,383 +37,385 @@ type FullNodeStruct struct { NetStruct - Internal struct { - BeaconGetEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"` + Internal FullNodeMethods +} - ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` +type FullNodeMethods struct { + BeaconGetEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"` - ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"` + ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` - ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"` + ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"` - ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `perm:"read"` + ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"` - ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `perm:"read"` + ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `perm:"read"` - ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"` + ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `perm:"read"` - ChainGetMessagesInTipset func(p0 context.Context, p1 types.TipSetKey) ([]api.Message, 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"` + ChainGetMessagesInTipset func(p0 context.Context, p1 types.TipSetKey) ([]api.Message, error) `perm:"read"` - ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]api.Message, error) `perm:"read"` + ChainGetNode func(p0 context.Context, p1 string) (*api.IpldObject, error) `perm:"read"` - ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` + ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]api.Message, error) `perm:"read"` - ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) `perm:"read"` + ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` - ChainGetRandomnessFromBeacon func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"` + ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) `perm:"read"` - ChainGetRandomnessFromTickets func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"` + ChainGetRandomnessFromBeacon 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"` + ChainGetRandomnessFromTickets func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"` - ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `perm:"read"` + ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `perm:"read"` - ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"read"` + ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `perm:"read"` - ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"` + ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"read"` - ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `perm:"read"` + ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"` - ChainPutObj func(p0 context.Context, p1 blocks.Block) error `` + ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `perm:"read"` - ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"` + ChainPutObj func(p0 context.Context, p1 blocks.Block) error `` - ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` + ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"` - ChainStatObj func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) `perm:"read"` + ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` - ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"` + ChainStatObj func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) `perm:"read"` - ClientCalcCommP func(p0 context.Context, p1 string) (*api.CommPRet, error) `perm:"write"` + ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"` - ClientCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + ClientCalcCommP func(p0 context.Context, p1 string) (*api.CommPRet, error) `perm:"write"` - ClientCancelRetrievalDeal func(p0 context.Context, p1 retrievalmarket.DealID) 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"` + ClientCancelRetrievalDeal func(p0 context.Context, p1 retrievalmarket.DealID) error `perm:"write"` - ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) `perm:"read"` + ClientDataTransferUpdates func(p0 context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"` - ClientDealSize func(p0 context.Context, p1 cid.Cid) (api.DataSize, error) `perm:"read"` + ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) `perm:"read"` - ClientFindData func(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) `perm:"read"` + ClientDealSize func(p0 context.Context, p1 cid.Cid) (api.DataSize, error) `perm:"read"` - ClientGenCar func(p0 context.Context, p1 api.FileRef, p2 string) error `perm:"write"` + ClientFindData func(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) `perm:"read"` - ClientGetDealInfo func(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) `perm:"read"` + ClientGenCar func(p0 context.Context, p1 api.FileRef, p2 string) error `perm:"write"` - ClientGetDealStatus func(p0 context.Context, p1 uint64) (string, error) `perm:"read"` + ClientGetDealInfo func(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) `perm:"read"` - ClientGetDealUpdates func(p0 context.Context) (<-chan api.DealInfo, error) `perm:"write"` + ClientGetDealStatus func(p0 context.Context, p1 uint64) (string, error) `perm:"read"` - ClientGetRetrievalUpdates func(p0 context.Context) (<-chan api.RetrievalInfo, error) `perm:"write"` + ClientGetDealUpdates func(p0 context.Context) (<-chan api.DealInfo, error) `perm:"write"` - ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"` + ClientGetRetrievalUpdates func(p0 context.Context) (<-chan api.RetrievalInfo, error) `perm:"write"` - ClientImport func(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) `perm:"admin"` + ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"` - ClientListDataTransfers func(p0 context.Context) ([]api.DataTransferChannel, error) `perm:"write"` + ClientImport func(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) `perm:"admin"` - ClientListDeals func(p0 context.Context) ([]api.DealInfo, error) `perm:"write"` + ClientListDataTransfers func(p0 context.Context) ([]api.DataTransferChannel, error) `perm:"write"` - ClientListImports func(p0 context.Context) ([]api.Import, error) `perm:"write"` + ClientListDeals func(p0 context.Context) ([]api.DealInfo, error) `perm:"write"` - ClientListRetrievals func(p0 context.Context) ([]api.RetrievalInfo, 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"` + ClientListRetrievals func(p0 context.Context) ([]api.RetrievalInfo, error) `perm:"write"` - ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"` + ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) `perm:"read"` - ClientRemoveImport func(p0 context.Context, p1 imports.ID) error `perm:"admin"` + ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"` - ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + ClientRemoveImport func(p0 context.Context, p1 imports.ID) error `perm:"admin"` - ClientRetrieve func(p0 context.Context, p1 RetrievalOrder, p2 *api.FileRef) error `perm:"admin"` + ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` - ClientRetrieveTryRestartInsufficientFunds func(p0 context.Context, p1 address.Address) error `perm:"write"` + ClientRetrieve func(p0 context.Context, p1 RetrievalOrder, p2 *api.FileRef) error `perm:"admin"` - ClientRetrieveWithEvents func(p0 context.Context, p1 RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"` + ClientRetrieveTryRestartInsufficientFunds func(p0 context.Context, p1 address.Address) error `perm:"write"` - ClientStartDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"admin"` + ClientRetrieveWithEvents func(p0 context.Context, p1 RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"` - ClientStatelessDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"write"` + ClientStartDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"admin"` - CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` + ClientStatelessDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"write"` - GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` - GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"` + GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` - GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) `perm:"read"` + GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"` - GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `perm:"read"` + GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) `perm:"read"` - MarketAddBalance func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `perm:"read"` - MarketGetReserved func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"sign"` + MarketAddBalance func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` - MarketReleaseFunds func(p0 context.Context, p1 address.Address, p2 types.BigInt) error `perm:"sign"` + MarketGetReserved func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"sign"` - MarketReserveFunds func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + MarketReleaseFunds func(p0 context.Context, p1 address.Address, p2 types.BigInt) error `perm:"sign"` - MarketWithdraw func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + MarketReserveFunds 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"` + MarketWithdraw func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` - MinerGetBaseInfo func(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"` + MinerCreateBlock func(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"` - MpoolBatchPush func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` + MinerGetBaseInfo func(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"` - MpoolBatchPushMessage func(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"` + MpoolBatchPush func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` - MpoolBatchPushUntrusted 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"` - MpoolClear func(p0 context.Context, p1 bool) error `perm:"write"` + MpoolBatchPushUntrusted func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` - MpoolGetConfig func(p0 context.Context) (*types.MpoolConfig, error) `perm:"read"` + MpoolClear func(p0 context.Context, p1 bool) error `perm:"write"` - MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"read"` + MpoolGetConfig func(p0 context.Context) (*types.MpoolConfig, error) `perm:"read"` - MpoolPending func(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"` + MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"read"` - MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` + MpoolPending func(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"` - MpoolPushMessage func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"` + MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` - MpoolPushUntrusted 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"` - MpoolSelect func(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) `perm:"read"` + MpoolPushUntrusted func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` - MpoolSetConfig func(p0 context.Context, p1 *types.MpoolConfig) error `perm:"admin"` + MpoolSelect func(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) `perm:"read"` - MpoolSub func(p0 context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"` + MpoolSetConfig func(p0 context.Context, p1 *types.MpoolConfig) error `perm:"admin"` - 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"` + MpoolSub func(p0 context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"` - MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) `perm:"sign"` + 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"` - MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 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"` - MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (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"` - 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"` + MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (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"` + 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"` - 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"` + 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"` - MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` + 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"` - MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) `perm:"read"` + MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` - MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) `perm:"read"` - MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) `perm:"read"` + MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, 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"` + MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) `perm:"read"` - MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"` + 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"` - 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"` + MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (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"` + 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"` - MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 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"` - PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, 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"` - PaychAvailableFunds func(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"` + PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"` - PaychAvailableFundsByFromTo func(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"` + PaychAvailableFunds func(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"` - PaychCollect func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` + PaychAvailableFundsByFromTo func(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"` - PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) `perm:"sign"` + PaychCollect func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` - PaychGetWaitReady func(p0 context.Context, p1 cid.Cid) (address.Address, error) `perm:"sign"` + PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) `perm:"sign"` - PaychList func(p0 context.Context) ([]address.Address, error) `perm:"read"` + PaychGetWaitReady func(p0 context.Context, p1 cid.Cid) (address.Address, error) `perm:"sign"` - PaychNewPayment func(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"` + PaychList func(p0 context.Context) ([]address.Address, error) `perm:"read"` - PaychSettle func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` + PaychNewPayment func(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"` - PaychStatus func(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) `perm:"read"` + PaychSettle func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` - PaychVoucherAdd func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) `perm:"write"` + PaychStatus func(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) `perm:"read"` - PaychVoucherCheckSpendable func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) `perm:"read"` + PaychVoucherAdd func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) `perm:"write"` - PaychVoucherCheckValid func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error `perm:"read"` + PaychVoucherCheckSpendable func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) `perm:"read"` - PaychVoucherCreate func(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) `perm:"sign"` + PaychVoucherCheckValid func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error `perm:"read"` - PaychVoucherList func(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) `perm:"write"` + PaychVoucherCreate func(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) `perm:"sign"` - PaychVoucherSubmit func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) `perm:"sign"` + PaychVoucherList func(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) `perm:"write"` - StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` + PaychVoucherSubmit func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) `perm:"sign"` - StateActorCodeCIDs func(p0 context.Context, p1 abinetwork.Version) (map[string]cid.Cid, error) `perm:"read"` + StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` - StateActorManifestCID func(p0 context.Context, p1 abinetwork.Version) (cid.Cid, error) `perm:"read"` + StateActorCodeCIDs func(p0 context.Context, p1 abinetwork.Version) (map[string]cid.Cid, error) `perm:"read"` - StateAllMinerFaults func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) `perm:"read"` + StateActorManifestCID func(p0 context.Context, p1 abinetwork.Version) (cid.Cid, error) `perm:"read"` - StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) `perm:"read"` + StateAllMinerFaults func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) `perm:"read"` - StateChangedActors func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) `perm:"read"` + StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) `perm:"read"` - StateCirculatingSupply func(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) `perm:"read"` + StateChangedActors func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) `perm:"read"` - StateCompute func(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"` + StateCirculatingSupply func(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) `perm:"read"` - StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"` + StateCompute func(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"` - StateDecodeParams func(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) `perm:"read"` + StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"` - StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"` + StateDecodeParams func(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) `perm:"read"` - StateGetAllocation func(p0 context.Context, p1 address.Address, p2 verifregtypes.AllocationId, p3 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"` + StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"` - StateGetAllocationForPendingDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"` + StateGetAllocation func(p0 context.Context, p1 address.Address, p2 verifregtypes.AllocationId, p3 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"` - StateGetAllocations func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.AllocationId]verifregtypes.Allocation, error) `perm:"read"` + StateGetAllocationForPendingDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"` - StateGetClaim func(p0 context.Context, p1 address.Address, p2 verifregtypes.ClaimId, p3 types.TipSetKey) (*verifregtypes.Claim, error) `perm:"read"` + StateGetAllocations func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.AllocationId]verifregtypes.Allocation, error) `perm:"read"` - StateGetClaims func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.ClaimId]verifregtypes.Claim, error) `perm:"read"` + StateGetClaim func(p0 context.Context, p1 address.Address, p2 verifregtypes.ClaimId, p3 types.TipSetKey) (*verifregtypes.Claim, error) `perm:"read"` - StateGetNetworkParams func(p0 context.Context) (*api.NetworkParams, error) `perm:"read"` + StateGetClaims func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.ClaimId]verifregtypes.Claim, error) `perm:"read"` - StateGetRandomnessFromBeacon func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"` + StateGetNetworkParams func(p0 context.Context) (*api.NetworkParams, error) `perm:"read"` - StateGetRandomnessFromTickets func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"` + StateGetRandomnessFromBeacon func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"` - StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"` + StateGetRandomnessFromTickets func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"` - StateListActors func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` + StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"` - StateListMessages func(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` + StateListActors func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` - StateListMiners 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"` - StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` + StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` - StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) `perm:"read"` + StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` - StateMarketDeals func(p0 context.Context, p1 types.TipSetKey) (map[string]*api.MarketDeal, error) `perm:"read"` + StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) `perm:"read"` - StateMarketParticipants func(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) `perm:"read"` + StateMarketDeals func(p0 context.Context, p1 types.TipSetKey) (map[string]*api.MarketDeal, error) `perm:"read"` - StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) `perm:"read"` + StateMarketParticipants func(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) `perm:"read"` - StateMinerActiveSectors func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` + StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) `perm:"read"` - StateMinerAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` + StateMinerActiveSectors func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` - StateMinerDeadlines func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) `perm:"read"` + StateMinerAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateMinerFaults func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` + StateMinerDeadlines func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) `perm:"read"` - StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerInfo, error) `perm:"read"` + StateMinerFaults func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` - StateMinerInitialPledgeCollateral func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerInfo, error) `perm:"read"` - StateMinerPartitions func(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) `perm:"read"` + StateMinerInitialPledgeCollateral func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) `perm:"read"` + StateMinerPartitions func(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) `perm:"read"` - StateMinerPreCommitDepositForPower func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) `perm:"read"` - StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `perm:"read"` + StateMinerPreCommitDepositForPower func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` - StateMinerRecoveries func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` + StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `perm:"read"` - StateMinerSectorAllocated func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) `perm:"read"` + StateMinerRecoveries func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` - StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) `perm:"read"` + StateMinerSectorAllocated func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) `perm:"read"` - StateMinerSectors func(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` + StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) `perm:"read"` - StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) `perm:"read"` + StateMinerSectors func(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` - StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `perm:"read"` + StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) `perm:"read"` - StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) `perm:"read"` + StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `perm:"read"` - StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) `perm:"read"` + StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) `perm:"read"` - StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `perm:"read"` + StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) `perm:"read"` - StateSearchMsgLimited func(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"` + StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `perm:"read"` - StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"` + StateSearchMsgLimited func(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"` - StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"` + StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"` - StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"` + StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"` - StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"` + StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"` - StateVMCirculatingSupplyInternal func(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"` + StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"` - StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` + StateVMCirculatingSupplyInternal func(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"` - StateVerifiedRegistryRootKey func(p0 context.Context, p1 types.TipSetKey) (address.Address, error) `perm:"read"` + StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` - StateVerifierStatus 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"` - StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `perm:"read"` + StateVerifierStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` - StateWaitMsgLimited func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"` + StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `perm:"read"` - SyncCheckBad func(p0 context.Context, p1 cid.Cid) (string, error) `perm:"read"` + StateWaitMsgLimited func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"` - SyncCheckpoint func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` + SyncCheckBad func(p0 context.Context, p1 cid.Cid) (string, error) `perm:"read"` - SyncIncomingBlocks func(p0 context.Context) (<-chan *types.BlockHeader, error) `perm:"read"` + SyncCheckpoint func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` - SyncMarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + SyncIncomingBlocks func(p0 context.Context) (<-chan *types.BlockHeader, error) `perm:"read"` - SyncState func(p0 context.Context) (*api.SyncState, error) `perm:"read"` + SyncMarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` - SyncSubmitBlock func(p0 context.Context, p1 *types.BlockMsg) error `perm:"write"` + SyncState func(p0 context.Context) (*api.SyncState, error) `perm:"read"` - SyncUnmarkAllBad func(p0 context.Context) error `perm:"admin"` + SyncSubmitBlock func(p0 context.Context, p1 *types.BlockMsg) error `perm:"write"` - SyncUnmarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + SyncUnmarkAllBad func(p0 context.Context) error `perm:"admin"` - SyncValidateTipset func(p0 context.Context, p1 types.TipSetKey) (bool, error) `perm:"read"` + SyncUnmarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` - WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"read"` + SyncValidateTipset func(p0 context.Context, p1 types.TipSetKey) (bool, error) `perm:"read"` - WalletDefaultAddress func(p0 context.Context) (address.Address, error) `perm:"write"` + WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"read"` - WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"` + WalletDefaultAddress func(p0 context.Context) (address.Address, error) `perm:"write"` - WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"` + WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"` - WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"write"` + WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"` - WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"` + WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"write"` - WalletList func(p0 context.Context) ([]address.Address, error) `perm:"write"` + WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"` - WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"write"` + WalletList func(p0 context.Context) ([]address.Address, error) `perm:"write"` - WalletSetDefault func(p0 context.Context, p1 address.Address) error `perm:"write"` + WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"write"` - WalletSign func(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) `perm:"sign"` + WalletSetDefault func(p0 context.Context, p1 address.Address) error `perm:"write"` - WalletSignMessage func(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) `perm:"sign"` + WalletSign func(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) `perm:"sign"` - WalletValidateAddress func(p0 context.Context, p1 string) (address.Address, error) `perm:"read"` + WalletSignMessage func(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) `perm:"sign"` - WalletVerify func(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) `perm:"read"` - } + 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"` } type FullNodeStub struct { @@ -425,71 +425,73 @@ type FullNodeStub struct { } type GatewayStruct struct { - Internal struct { - ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `` + Internal GatewayMethods +} - ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `` +type GatewayMethods struct { + ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `` - ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `` + ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `` - ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `` + ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `` - ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` + ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `` - ChainHead func(p0 context.Context) (*types.TipSet, error) `` + ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` - ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `` + ChainHead func(p0 context.Context) (*types.TipSet, error) `` - ChainPutObj func(p0 context.Context, p1 blocks.Block) error `` + ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `` - ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` + ChainPutObj func(p0 context.Context, p1 blocks.Block) error `` - GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` + ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` - MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `` + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` - MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `` + MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `` - MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) `` + MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `` - MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `` + MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) `` - StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` + MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `` - StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) `` + StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` - StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `` + StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) `` - StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) `` + StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `` - StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `` + StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) `` - StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` + StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `` - StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) `` + StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` - StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) `` + StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) `` - StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerInfo, error) `` + StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) `` - StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) `` + StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerInfo, error) `` - StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `` + StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) `` - StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (abinetwork.Version, error) `` + StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `` - StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `` + StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (abinetwork.Version, error) `` - StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `` + StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `` - StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` + StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `` - StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `` + StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` - Version func(p0 context.Context) (api.APIVersion, 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) `` - } + Version func(p0 context.Context) (api.APIVersion, error) `` + + WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `` } type GatewayStub struct { diff --git a/gateway/handler.go b/gateway/handler.go index e9bee6d52..8760598cc 100644 --- a/gateway/handler.go +++ b/gateway/handler.go @@ -34,7 +34,7 @@ func Handler(gwapi lapi.Gateway, api lapi.FullNode, rateLimit int64, connPerMinu m := mux.NewRouter() serveRpc := func(path string, hnd interface{}) { - rpcServer := jsonrpc.NewServer(append(opts, jsonrpc.WithServerErrors(lapi.RPCErrors))...) + rpcServer := jsonrpc.NewServer(append(opts, jsonrpc.WithReverseClient[lapi.EthSubscriberMethods]("Filecoin"), jsonrpc.WithServerErrors(lapi.RPCErrors))...) rpcServer.Register("Filecoin", hnd) rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover") diff --git a/gen/api/proxygen.go b/gen/api/proxygen.go index f756c0d0c..75fbc668c 100644 --- a/gen/api/proxygen.go +++ b/gen/api/proxygen.go @@ -259,7 +259,7 @@ func generate(path, pkg, outpkg, outfile string) error { if len(tf) != 2 { continue } - if tf[0] != "perm" { // todo: allow more tag types + if tf[0] != "perm" && tf[0] != "rpc_method" && tf[0] != "notify" { // todo: allow more tag types continue } info.Methods[mname].Tags[tf[0]] = tf @@ -302,12 +302,14 @@ type {{.Num}}Struct struct { {{range .Include}} {{.}}Struct {{end}} - Internal struct { + Internal {{.Num}}Methods +} + +type {{.Num}}Methods struct { {{range .Methods}} {{.Num}} func({{.NamedParams}}) ({{.Results}}) `+"`"+`{{range .Tags}}{{index . 0}}:"{{index . 1}}"{{end}}`+"`"+` {{end}} } -} type {{.Num}}Stub struct { {{range .Include}} diff --git a/go.mod b/go.mod index 242fb9137..d5059ac30 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/filecoin-project/go-fil-commcid v0.1.0 github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 github.com/filecoin-project/go-fil-markets v1.25.2 - github.com/filecoin-project/go-jsonrpc v0.1.9 + github.com/filecoin-project/go-jsonrpc v0.1.10-0.20230116095704-da92324a76e1 github.com/filecoin-project/go-legs v0.4.4 github.com/filecoin-project/go-padreader v0.0.1 github.com/filecoin-project/go-paramfetch v0.0.4 diff --git a/go.sum b/go.sum index 9ffaf17d6..a6d00a0b3 100644 --- a/go.sum +++ b/go.sum @@ -342,6 +342,8 @@ github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0 h1:rVVNq0x6RGQIzCo1iiJlGFm9AG github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0/go.mod h1:bxmzgT8tmeVQA1/gvBwFmYdT8SOFUwB3ovSUfG1Ux0g= github.com/filecoin-project/go-jsonrpc v0.1.9 h1:HRWLxo7HAWzI3xZGeFG4LZJoYpms+Q+8kwmMTLnyS3A= github.com/filecoin-project/go-jsonrpc v0.1.9/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= +github.com/filecoin-project/go-jsonrpc v0.1.10-0.20230116095704-da92324a76e1 h1:GcF3gSvesv1epB2SrTfalrYvhFzT1UnmSS1Bh+jprQY= +github.com/filecoin-project/go-jsonrpc v0.1.10-0.20230116095704-da92324a76e1/go.mod h1:jBSvPTl8V1N7gSTuCR4bis8wnQnIjHbRPpROol6iQKM= github.com/filecoin-project/go-legs v0.4.4 h1:mpMmAOOnamaz0CV9rgeKhEWA8j9kMC+f+UGCGrxKaZo= github.com/filecoin-project/go-legs v0.4.4/go.mod h1:JQ3hA6xpJdbR8euZ2rO0jkxaMxeidXf0LDnVuqPAe9s= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20/go.mod h1:mPn+LRRd5gEKNAtc+r3ScpW2JRU/pj4NBKdADYWHiak= diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 5dbca7357..ef7f7ff6d 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -3,8 +3,10 @@ package full import ( "bytes" "context" + "encoding/json" "errors" "fmt" + "github.com/filecoin-project/go-jsonrpc" "strconv" "sync" "time" @@ -75,7 +77,7 @@ type EthEventAPI interface { EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error) - EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) + EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) } @@ -1100,16 +1102,19 @@ const ( EthSubscribeEventTypeLogs = "logs" ) -func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) { +func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { if e.SubManager == nil { - return nil, api.ErrNotSupported + return ethtypes.EthSubscriptionID{}, api.ErrNotSupported } - // Note that go-jsonrpc will set the method field of the response to "xrpc.ch.val" but the ethereum api expects the name of the - // method to be "eth_subscription". This probably doesn't matter in practice. - sub, err := e.SubManager.StartSubscription(ctx) + ethCb, ok := jsonrpc.ExtractReverseClient[api.EthSubscriberMethods](ctx) + if !ok { + return ethtypes.EthSubscriptionID{}, xerrors.Errorf("connection doesn't support callbacks") + } + + sub, err := e.SubManager.StartSubscription(ctx, ethCb.EthSubscription) if err != nil { - return nil, err + return ethtypes.EthSubscriptionID{}, err } switch eventType { @@ -1118,7 +1123,7 @@ func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *e if err != nil { // clean up any previous filters added and stop the sub _, _ = e.EthUnsubscribe(ctx, sub.id) - return nil, err + return ethtypes.EthSubscriptionID{}, err } sub.addFilter(ctx, f) @@ -1138,14 +1143,14 @@ func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *e if err != nil { // clean up any previous filters added and stop the sub _, _ = e.EthUnsubscribe(ctx, sub.id) - return nil, err + return ethtypes.EthSubscriptionID{}, err } sub.addFilter(ctx, f) default: - return nil, xerrors.Errorf("unsupported event type: %s", eventType) + return ethtypes.EthSubscriptionID{}, xerrors.Errorf("unsupported event type: %s", eventType) } - return sub.out, nil + return sub.id, nil } func (e *EthEvent) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) { @@ -1294,7 +1299,7 @@ type EthSubscriptionManager struct { subs map[ethtypes.EthSubscriptionID]*ethSubscription } -func (e *EthSubscriptionManager) StartSubscription(ctx context.Context) (*ethSubscription, error) { // nolint +func (e *EthSubscriptionManager) StartSubscription(ctx context.Context, out ethSubscriptionCallback) (*ethSubscription, error) { // nolint rawid, err := uuid.NewRandom() if err != nil { return nil, xerrors.Errorf("new uuid: %w", err) @@ -1310,7 +1315,7 @@ func (e *EthSubscriptionManager) StartSubscription(ctx context.Context) (*ethSub ChainAPI: e.ChainAPI, id: id, in: make(chan interface{}, 200), - out: make(chan ethtypes.EthSubscriptionResponse, 20), + out: out, quit: quit, } @@ -1340,13 +1345,15 @@ func (e *EthSubscriptionManager) StopSubscription(ctx context.Context, id ethtyp return sub.filters, nil } +type ethSubscriptionCallback func(context.Context, jsonrpc.RawParams) error + type ethSubscription struct { Chain *store.ChainStore StateAPI StateAPI ChainAPI ChainAPI id ethtypes.EthSubscriptionID in chan interface{} - out chan ethtypes.EthSubscriptionResponse + out ethSubscriptionCallback mu sync.Mutex filters []filter.Filter @@ -1390,10 +1397,15 @@ func (e *ethSubscription) start(ctx context.Context) { continue } - select { - case e.out <- resp: - default: - // Skip if client is not reading responses + outParam, err := json.Marshal(resp) + if err != nil { + log.Warnw("marshaling subscription response", "sub", e.id, "error", err) + continue + } + + if err := e.out(ctx, outParam); err != nil { + log.Warnw("sending subscription response", "sub", e.id, "error", err) + continue } } } @@ -1405,7 +1417,6 @@ func (e *ethSubscription) stop() { if e.quit != nil { e.quit() - close(e.out) e.quit = nil } } diff --git a/node/rpc.go b/node/rpc.go index a96e6e3ac..c846646fe 100644 --- a/node/rpc.go +++ b/node/rpc.go @@ -75,7 +75,7 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server m := mux.NewRouter() serveRpc := func(path string, hnd interface{}) { - rpcServer := jsonrpc.NewServer(append(opts, jsonrpc.WithServerErrors(api.RPCErrors))...) + rpcServer := jsonrpc.NewServer(append(opts, jsonrpc.WithReverseClient[api.EthSubscriberMethods]("Filecoin"), jsonrpc.WithServerErrors(api.RPCErrors))...) rpcServer.Register("Filecoin", hnd) rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover") From 1286d769889f10c72e2136f74f03dcf6e227ae12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 16 Jan 2023 15:28:55 +0100 Subject: [PATCH 2/5] gateway: eth_subscribe support --- api/api_full.go | 3 +- api/api_gateway.go | 2 +- api/client/client.go | 4 +- api/mocks/mock_full.go | 4 +- api/proxy_gen.go | 28 +++--- api/v0api/proxy_gen.go | 10 +- build/openrpc/full.json.gz | Bin 32994 -> 33267 bytes build/openrpc/gateway.json.gz | Bin 8494 -> 8582 bytes build/openrpc/miner.json.gz | Bin 16047 -> 16048 bytes build/openrpc/worker.json.gz | Bin 5222 -> 5225 bytes cli/util/api.go | 24 ++++- cmd/lotus-gateway/main.go | 6 +- documentation/en/api-v1-unstable-methods.md | 71 +++++++-------- gateway/eth_sub.go | 70 ++++++++++++++ gateway/handler.go | 4 +- gateway/node.go | 6 +- gateway/node_test.go | 8 +- gateway/proxy_eth.go | 96 +++++++++++++++++--- go.mod | 2 +- go.sum | 7 +- itests/gateway_test.go | 2 +- node/impl/full/eth.go | 2 +- 22 files changed, 255 insertions(+), 94 deletions(-) create mode 100644 gateway/eth_sub.go diff --git a/api/api_full.go b/api/api_full.go index 20d374b50..e9cf4a58f 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -6,8 +6,6 @@ import ( "fmt" "time" - "github.com/filecoin-project/go-jsonrpc" - "github.com/google/uuid" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" @@ -18,6 +16,7 @@ import ( datatransfer "github.com/filecoin-project/go-data-transfer" "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/builtin/v8/paych" diff --git a/api/api_gateway.go b/api/api_gateway.go index c78710026..fdadd2ae6 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -102,6 +102,6 @@ type Gateway interface { EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error) - EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) + EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) } diff --git a/api/client/client.go b/api/client/client.go index 32583097e..8b159c5b1 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -35,10 +35,10 @@ func NewFullNodeRPCV0(ctx context.Context, addr string, requestHeader http.Heade } // NewFullNodeRPCV1 creates a new http jsonrpc client. -func NewFullNodeRPCV1(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) { +func NewFullNodeRPCV1(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.FullNode, jsonrpc.ClientCloser, error) { var res v1api.FullNodeStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", - api.GetInternalStructs(&res), requestHeader, jsonrpc.WithErrors(api.RPCErrors)) + api.GetInternalStructs(&res), requestHeader, append([]jsonrpc.Option{jsonrpc.WithErrors(api.RPCErrors)}, opts...)...) return &res, closer, err } diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 02ded88a5..30df05226 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -1388,10 +1388,10 @@ func (mr *MockFullNodeMockRecorder) EthSendRawTransaction(arg0, arg1 interface{} } // EthSubscribe mocks base method. -func (m *MockFullNode) EthSubscribe(arg0 context.Context, arg1 string, arg2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) { +func (m *MockFullNode) EthSubscribe(arg0 context.Context, arg1 string, arg2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "EthSubscribe", arg0, arg1, arg2) - ret0, _ := ret[0].(<-chan ethtypes.EthSubscriptionResponse) + ret0, _ := ret[0].(ethtypes.EthSubscriptionID) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 43089c6fa..9b8890a7c 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -7,6 +7,15 @@ import ( "encoding/json" "time" + "github.com/google/uuid" + blocks "github.com/ipfs/go-block-format" + "github.com/ipfs/go-cid" + "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" + "golang.org/x/xerrors" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-bitfield" datatransfer "github.com/filecoin-project/go-data-transfer" @@ -23,6 +32,7 @@ import ( "github.com/filecoin-project/go-state-types/dline" abinetwork "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/go-state-types/proof" + apitypes "github.com/filecoin-project/lotus/api/types" builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin" lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -35,14 +45,6 @@ import ( "github.com/filecoin-project/lotus/storage/sealer/fsutil" "github.com/filecoin-project/lotus/storage/sealer/sealtasks" "github.com/filecoin-project/lotus/storage/sealer/storiface" - "github.com/google/uuid" - blocks "github.com/ipfs/go-block-format" - "github.com/ipfs/go-cid" - "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" - "golang.org/x/xerrors" ) var ErrNotSupported = xerrors.New("method not supported") @@ -702,7 +704,7 @@ type GatewayMethods struct { EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) `` - EthSubscribe func(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) `` + EthSubscribe func(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) `` EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `` @@ -4463,15 +4465,15 @@ func (s *GatewayStub) EthSendRawTransaction(p0 context.Context, p1 ethtypes.EthB return *new(ethtypes.EthHash), ErrNotSupported } -func (s *GatewayStruct) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) { +func (s *GatewayStruct) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { if s.Internal.EthSubscribe == nil { - return nil, ErrNotSupported + return *new(ethtypes.EthSubscriptionID), ErrNotSupported } return s.Internal.EthSubscribe(p0, p1, p2) } -func (s *GatewayStub) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) { - return nil, ErrNotSupported +func (s *GatewayStub) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { + return *new(ethtypes.EthSubscriptionID), ErrNotSupported } func (s *GatewayStruct) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) { diff --git a/api/v0api/proxy_gen.go b/api/v0api/proxy_gen.go index f66588b8e..4acf2e111 100644 --- a/api/v0api/proxy_gen.go +++ b/api/v0api/proxy_gen.go @@ -5,6 +5,11 @@ package v0api import ( "context" + blocks "github.com/ipfs/go-block-format" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p/core/peer" + "golang.org/x/xerrors" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-bitfield" datatransfer "github.com/filecoin-project/go-data-transfer" @@ -17,6 +22,7 @@ import ( "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/dline" abinetwork "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/api" apitypes "github.com/filecoin-project/lotus/api/types" lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -24,10 +30,6 @@ import ( marketevents "github.com/filecoin-project/lotus/markets/loggers" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/repo/imports" - blocks "github.com/ipfs/go-block-format" - "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p/core/peer" - "golang.org/x/xerrors" ) var ErrNotSupported = xerrors.New("method not supported") diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 4fc58a93a6f9db32082e1c3941745e4fd50f2902..4524108b1c12310be48c34b90d68fc7f028cd230 100644 GIT binary patch literal 33267 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 literal 32994 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%0Di6a^A#g*kgj36Cg?;82tn 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 ZxStO*vA*BD002KfiTr{^RJou4{|6Ct7%Kn( diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index d145c8939094c574aac4b8fbf5b83121686d0a13..688e01963366a9415a90b54451b0ff6a5fb1f9f0 100644 GIT binary patch delta 8442 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 delta 8337 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 diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index b2a53e031c8e1d6baf37e6dcefd13e53135a8f2b..5582011e53875be4206e9a04bbc0c6b8b0479ff3 100644 GIT binary patch delta 13789 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 S|1SUl|No)%0tHF+8v_77Wi4R< diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index cc24b84900760c236390a361c651559253cd134f..452cdab557321e5fc603d5e550c53f3d8e4154ef 100644 GIT binary patch delta 4070 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 W_rEG#|9=1g0RR7tLLp48E&%|()6%j4 diff --git a/cli/util/api.go b/cli/util/api.go index b35974c69..3d06f9e31 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -319,11 +319,33 @@ func GetFullNodeAPIV1Single(ctx *cli.Context) (v1api.FullNode, jsonrpc.ClientClo return v1API, closer, nil } -func GetFullNodeAPIV1(ctx *cli.Context) (v1api.FullNode, jsonrpc.ClientCloser, error) { +type GetFullNodeOptions struct { + ethSubHandler api.EthSubscriber +} + +type GetFullNodeOption func(*GetFullNodeOptions) + +func FullNodeWithEthSubscribtionHandler(sh api.EthSubscriber) GetFullNodeOption { + return func(opts *GetFullNodeOptions) { + opts.ethSubHandler = sh + } +} + +func GetFullNodeAPIV1(ctx *cli.Context, opts ...GetFullNodeOption) (v1api.FullNode, jsonrpc.ClientCloser, error) { if tn, ok := ctx.App.Metadata["testnode-full"]; ok { return tn.(v1api.FullNode), func() {}, nil } + var options GetFullNodeOptions + for _, opt := range opts { + opt(&options) + } + + var rpcOpts []jsonrpc.Option + if options.ethSubHandler != nil { + rpcOpts = append(rpcOpts, jsonrpc.WithClientHandler("Filecoin", options.ethSubHandler), jsonrpc.WithClientHandlerAlias("eth_subscription", "Filecoin.EthSubscription")) + } + heads, err := GetRawAPIMulti(ctx, repo.FullNode, "v1") if err != nil { return nil, nil, err diff --git a/cmd/lotus-gateway/main.go b/cmd/lotus-gateway/main.go index 89b2152dd..2023551ef 100644 --- a/cmd/lotus-gateway/main.go +++ b/cmd/lotus-gateway/main.go @@ -162,7 +162,9 @@ var runCmd = &cli.Command{ log.Fatalf("Cannot register the view: %v", err) } - api, closer, err := lcli.GetFullNodeAPIV1(cctx) + subHnd := gateway.NewEthSubHandler() + + api, closer, err := lcli.GetFullNodeAPIV1(cctx, cliutil.FullNodeWithEthSubscribtionHandler(subHnd)) if err != nil { return err } @@ -195,7 +197,7 @@ var runCmd = &cli.Command{ return xerrors.Errorf("failed to convert endpoint address to multiaddr: %w", err) } - gwapi := gateway.NewNode(api, lookbackCap, waitLookback, rateLimit, rateLimitTimeout) + gwapi := gateway.NewNode(api, subHnd, lookbackCap, waitLookback, rateLimit, rateLimitTimeout) h, err := gateway.Handler(gwapi, api, perConnRateLimit, connPerMinute, serverOptions...) if err != nil { return xerrors.Errorf("failed to set up gateway HTTP handler") diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 445b24f82..299d71308 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -3073,43 +3073,40 @@ Inputs: Response: ```json -{ - "subscription": [ - 55, - 105, - 12, - 254, - 198, - 193, - 191, - 76, - 59, - 146, - 136, - 199, - 165, - 215, - 131, - 233, - 135, - 49, - 233, - 11, - 10, - 76, - 23, - 124, - 42, - 55, - 76, - 122, - 148, - 39, - 53, - 94 - ], - "result": {} -} +[ + 55, + 105, + 12, + 254, + 198, + 193, + 191, + 76, + 59, + 146, + 136, + 199, + 165, + 215, + 131, + 233, + 135, + 49, + 233, + 11, + 10, + 76, + 23, + 124, + 42, + 55, + 76, + 122, + 148, + 39, + 53, + 94 +] ``` ### EthUninstallFilter diff --git a/gateway/eth_sub.go b/gateway/eth_sub.go new file mode 100644 index 000000000..2f82fc32b --- /dev/null +++ b/gateway/eth_sub.go @@ -0,0 +1,70 @@ +package gateway + +import ( + "context" + "sync" + + "github.com/filecoin-project/go-jsonrpc" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types/ethtypes" +) + +type EthSubHandler struct { + queued map[ethtypes.EthSubscriptionID][]ethtypes.EthSubscriptionResponse + sinks map[ethtypes.EthSubscriptionID]func(context.Context, *ethtypes.EthSubscriptionResponse) error + + lk sync.Mutex +} + +func NewEthSubHandler() *EthSubHandler { + return &EthSubHandler{ + queued: make(map[ethtypes.EthSubscriptionID][]ethtypes.EthSubscriptionResponse), + sinks: make(map[ethtypes.EthSubscriptionID]func(context.Context, *ethtypes.EthSubscriptionResponse) error), + } +} + +func (e *EthSubHandler) addSub(ctx context.Context, id ethtypes.EthSubscriptionID, sink func(context.Context, *ethtypes.EthSubscriptionResponse) error) error { + e.lk.Lock() + defer e.lk.Unlock() + + for _, p := range e.queued[id] { + if err := sink(ctx, &p); err != nil { + return err + } + } + delete(e.queued, id) + e.sinks[id] = sink + return nil +} + +func (e *EthSubHandler) removeSub(id ethtypes.EthSubscriptionID) { + e.lk.Lock() + defer e.lk.Unlock() + + delete(e.sinks, id) + delete(e.queued, id) +} + +func (e *EthSubHandler) EthSubscription(ctx context.Context, r jsonrpc.RawParams) error { + p, err := jsonrpc.DecodeParams[ethtypes.EthSubscriptionResponse](r) + if err != nil { + return err + } + + e.lk.Lock() + + sink := e.sinks[p.SubscriptionID] + + if sink == nil { + e.queued[p.SubscriptionID] = append(e.queued[p.SubscriptionID], p) + e.lk.Unlock() + return nil + } + + e.lk.Unlock() + + return sink(ctx, &p) // todo track errors and auto-unsubscribe on rpc conn close? +} + +var _ api.EthSubscriber = (*EthSubHandler)(nil) diff --git a/gateway/handler.go b/gateway/handler.go index 8760598cc..54ab2467f 100644 --- a/gateway/handler.go +++ b/gateway/handler.go @@ -27,7 +27,7 @@ const perConnLimiterKey perConnLimiterKeyType = "limiter" type filterTrackerKeyType string -const filterTrackerKey filterTrackerKeyType = "filterTracker" +const statefulCallTrackerKey filterTrackerKeyType = "statefulCallTracker" // Handler returns a gateway http.Handler, to be mounted as-is on the server. func Handler(gwapi lapi.Gateway, api lapi.FullNode, rateLimit int64, connPerMinute int64, opts ...jsonrpc.ServerOption) (http.Handler, error) { @@ -90,7 +90,7 @@ func (h RateLimiterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { r = r.WithContext(context.WithValue(r.Context(), perConnLimiterKey, h.limiter)) // also add a filter tracker to the context - r = r.WithContext(context.WithValue(r.Context(), filterTrackerKey, newFilterTracker())) + r = r.WithContext(context.WithValue(r.Context(), statefulCallTrackerKey, newStatefulCallTracker())) h.handler.ServeHTTP(w, r) } diff --git a/gateway/node.go b/gateway/node.go index f18189ae2..bcb515b3c 100644 --- a/gateway/node.go +++ b/gateway/node.go @@ -117,7 +117,7 @@ type TargetAPI interface { EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error) - EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) + EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) } @@ -125,6 +125,7 @@ var _ TargetAPI = *new(api.FullNode) // gateway depends on latest type Node struct { target TargetAPI + subHnd *EthSubHandler lookbackCap time.Duration stateWaitLookbackLimit abi.ChainEpoch rateLimiter *rate.Limiter @@ -141,7 +142,7 @@ var ( ) // NewNode creates a new gateway node. -func NewNode(api TargetAPI, lookbackCap time.Duration, stateWaitLookbackLimit abi.ChainEpoch, rateLimit int64, rateLimitTimeout time.Duration) *Node { +func NewNode(api TargetAPI, sHnd *EthSubHandler, lookbackCap time.Duration, stateWaitLookbackLimit abi.ChainEpoch, rateLimit int64, rateLimitTimeout time.Duration) *Node { var limit rate.Limit if rateLimit == 0 { limit = rate.Inf @@ -150,6 +151,7 @@ func NewNode(api TargetAPI, lookbackCap time.Duration, stateWaitLookbackLimit ab } return &Node{ target: api, + subHnd: sHnd, lookbackCap: lookbackCap, stateWaitLookbackLimit: stateWaitLookbackLimit, rateLimiter: rate.NewLimiter(limit, stateRateLimitTokens), diff --git a/gateway/node_test.go b/gateway/node_test.go index 805767dc6..aa33e8bfb 100644 --- a/gateway/node_test.go +++ b/gateway/node_test.go @@ -89,7 +89,7 @@ func TestGatewayAPIChainGetTipSetByHeight(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { mock := &mockGatewayDepsAPI{} - a := NewNode(mock, DefaultLookbackCap, DefaultStateWaitLookbackLimit, 0, time.Minute) + a := NewNode(mock, nil, DefaultLookbackCap, DefaultStateWaitLookbackLimit, 0, time.Minute) // Create tipsets from genesis up to tskh and return the highest ts := mock.createTipSets(tt.args.tskh, tt.args.genesisTS) @@ -245,7 +245,7 @@ func TestGatewayVersion(t *testing.T) { //stm: @GATEWAY_NODE_GET_VERSION_001 ctx := context.Background() mock := &mockGatewayDepsAPI{} - a := NewNode(mock, DefaultLookbackCap, DefaultStateWaitLookbackLimit, 0, time.Minute) + a := NewNode(mock, nil, DefaultLookbackCap, DefaultStateWaitLookbackLimit, 0, time.Minute) v, err := a.Version(ctx) require.NoError(t, err) @@ -256,7 +256,7 @@ func TestGatewayLimitTokensAvailable(t *testing.T) { ctx := context.Background() mock := &mockGatewayDepsAPI{} tokens := 3 - a := NewNode(mock, DefaultLookbackCap, DefaultStateWaitLookbackLimit, int64(tokens), time.Minute) + a := NewNode(mock, nil, DefaultLookbackCap, DefaultStateWaitLookbackLimit, int64(tokens), time.Minute) require.NoError(t, a.limit(ctx, tokens), "requests should not be limited when there are enough tokens available") } @@ -264,7 +264,7 @@ func TestGatewayLimitTokensNotAvailable(t *testing.T) { ctx := context.Background() mock := &mockGatewayDepsAPI{} tokens := 3 - a := NewNode(mock, DefaultLookbackCap, DefaultStateWaitLookbackLimit, int64(1), time.Millisecond) + a := NewNode(mock, nil, DefaultLookbackCap, DefaultStateWaitLookbackLimit, int64(1), time.Millisecond) var err error // try to be rate limited for i := 0; i <= 1000; i++ { diff --git a/gateway/proxy_eth.go b/gateway/proxy_eth.go index fcad213d9..9518b2a15 100644 --- a/gateway/proxy_eth.go +++ b/gateway/proxy_eth.go @@ -3,12 +3,14 @@ package gateway import ( "bytes" "context" + "encoding/json" "fmt" "sync" "time" "golang.org/x/xerrors" + "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" @@ -352,7 +354,7 @@ func (gw *Node) EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID return nil, err } - ft := filterTrackerFromContext(ctx) + ft := statefulCallFromContext(ctx) ft.lk.Lock() _, ok := ft.userFilters[id] ft.lk.Unlock() @@ -369,7 +371,7 @@ func (gw *Node) EthGetFilterLogs(ctx context.Context, id ethtypes.EthFilterID) ( return nil, err } - ft := filterTrackerFromContext(ctx) + ft := statefulCallFromContext(ctx) ft.lk.Lock() _, ok := ft.userFilters[id] ft.lk.Unlock() @@ -417,7 +419,7 @@ func (gw *Node) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) } // check if the filter belongs to this connection - ft := filterTrackerFromContext(ctx) + ft := statefulCallFromContext(ctx) ft.lk.Lock() defer ft.lk.Unlock() @@ -434,18 +436,82 @@ func (gw *Node) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) return ok, nil } -func (gw *Node) EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) { - return nil, xerrors.Errorf("not implemented") +func (gw *Node) EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return ethtypes.EthSubscriptionID{}, err + } + + if gw.subHnd == nil { + return ethtypes.EthSubscriptionID{}, xerrors.New("subscription support not enabled") + } + + ethCb, ok := jsonrpc.ExtractReverseClient[api.EthSubscriberMethods](ctx) + if !ok { + return ethtypes.EthSubscriptionID{}, xerrors.Errorf("connection doesn't support callbacks") + } + + ft := statefulCallFromContext(ctx) + ft.lk.Lock() + defer ft.lk.Unlock() + + if len(ft.userSubscriptions) >= EthMaxFiltersPerConn { + return ethtypes.EthSubscriptionID{}, fmt.Errorf("too many subscriptions") + } + + sub, err := gw.target.EthSubscribe(ctx, eventType, params) + if err != nil { + return ethtypes.EthSubscriptionID{}, err + } + + err = gw.subHnd.addSub(ctx, sub, func(ctx context.Context, response *ethtypes.EthSubscriptionResponse) error { + outParam, err := json.Marshal(response) + if err != nil { + return err + } + + return ethCb.EthSubscription(ctx, outParam) + }) + if err != nil { + return ethtypes.EthSubscriptionID{}, err + } + + ft.userSubscriptions[sub] = time.Now() + + return sub, err } func (gw *Node) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) { - return false, xerrors.Errorf("not implemented") + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return false, err + } + + // check if the filter belongs to this connection + ft := statefulCallFromContext(ctx) + ft.lk.Lock() + defer ft.lk.Unlock() + + if _, ok := ft.userSubscriptions[id]; !ok { + return false, nil + } + + ok, err := gw.target.EthUnsubscribe(ctx, id) + if err != nil { + return false, err + } + + delete(ft.userSubscriptions, id) + + if gw.subHnd != nil { + gw.subHnd.removeSub(id) + } + + return ok, nil } var EthMaxFiltersPerConn = 16 // todo make this configurable func addUserFilterLimited(ctx context.Context, cb func() (ethtypes.EthFilterID, error)) (ethtypes.EthFilterID, error) { - ft := filterTrackerFromContext(ctx) + ft := statefulCallFromContext(ctx) ft.lk.Lock() defer ft.lk.Unlock() @@ -463,19 +529,21 @@ func addUserFilterLimited(ctx context.Context, cb func() (ethtypes.EthFilterID, return id, nil } -func filterTrackerFromContext(ctx context.Context) *filterTracker { - return ctx.Value(filterTrackerKey).(*filterTracker) +func statefulCallFromContext(ctx context.Context) *statefulCallTracker { + return ctx.Value(statefulCallTrackerKey).(*statefulCallTracker) } -type filterTracker struct { +type statefulCallTracker struct { lk sync.Mutex - userFilters map[ethtypes.EthFilterID]time.Time + userFilters map[ethtypes.EthFilterID]time.Time + userSubscriptions map[ethtypes.EthSubscriptionID]time.Time } // called per request (ws connection) -func newFilterTracker() *filterTracker { - return &filterTracker{ - userFilters: make(map[ethtypes.EthFilterID]time.Time), +func newStatefulCallTracker() *statefulCallTracker { + return &statefulCallTracker{ + userFilters: make(map[ethtypes.EthFilterID]time.Time), + userSubscriptions: make(map[ethtypes.EthSubscriptionID]time.Time), } } diff --git a/go.mod b/go.mod index d5059ac30..120a10db1 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/filecoin-project/go-fil-commcid v0.1.0 github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 github.com/filecoin-project/go-fil-markets v1.25.2 - github.com/filecoin-project/go-jsonrpc v0.1.10-0.20230116095704-da92324a76e1 + github.com/filecoin-project/go-jsonrpc v0.2.0 github.com/filecoin-project/go-legs v0.4.4 github.com/filecoin-project/go-padreader v0.0.1 github.com/filecoin-project/go-paramfetch v0.0.4 diff --git a/go.sum b/go.sum index a6d00a0b3..95813bdcd 100644 --- a/go.sum +++ b/go.sum @@ -340,10 +340,8 @@ github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0/go.mod h1:7aWZdaQ1b16BVoQUYR+ github.com/filecoin-project/go-hamt-ipld/v3 v3.0.1/go.mod h1:gXpNmr3oQx8l3o7qkGyDjJjYSRX7hp/FGOStdqrWyDI= github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0 h1:rVVNq0x6RGQIzCo1iiJlGFm9AGIZzeifggxtKMU7zmI= github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0/go.mod h1:bxmzgT8tmeVQA1/gvBwFmYdT8SOFUwB3ovSUfG1Ux0g= -github.com/filecoin-project/go-jsonrpc v0.1.9 h1:HRWLxo7HAWzI3xZGeFG4LZJoYpms+Q+8kwmMTLnyS3A= -github.com/filecoin-project/go-jsonrpc v0.1.9/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= -github.com/filecoin-project/go-jsonrpc v0.1.10-0.20230116095704-da92324a76e1 h1:GcF3gSvesv1epB2SrTfalrYvhFzT1UnmSS1Bh+jprQY= -github.com/filecoin-project/go-jsonrpc v0.1.10-0.20230116095704-da92324a76e1/go.mod h1:jBSvPTl8V1N7gSTuCR4bis8wnQnIjHbRPpROol6iQKM= +github.com/filecoin-project/go-jsonrpc v0.2.0 h1:lhcu0Oa7xxwdclU4EyBPgnZihiZOaTFiAnW6P3NRqko= +github.com/filecoin-project/go-jsonrpc v0.2.0/go.mod h1:jBSvPTl8V1N7gSTuCR4bis8wnQnIjHbRPpROol6iQKM= github.com/filecoin-project/go-legs v0.4.4 h1:mpMmAOOnamaz0CV9rgeKhEWA8j9kMC+f+UGCGrxKaZo= github.com/filecoin-project/go-legs v0.4.4/go.mod h1:JQ3hA6xpJdbR8euZ2rO0jkxaMxeidXf0LDnVuqPAe9s= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20/go.mod h1:mPn+LRRd5gEKNAtc+r3ScpW2JRU/pj4NBKdADYWHiak= @@ -826,7 +824,6 @@ github.com/ipfs/go-log/v2 v2.0.1/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= -github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.2/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= diff --git a/itests/gateway_test.go b/itests/gateway_test.go index b9c861bf3..d20b3bd1a 100644 --- a/itests/gateway_test.go +++ b/itests/gateway_test.go @@ -290,7 +290,7 @@ func startNodes( ens.InterconnectAll().BeginMining(blocktime) // Create a gateway server in front of the full node - gwapi := gateway.NewNode(full, lookbackCap, stateWaitLookbackLimit, 0, time.Minute) + gwapi := gateway.NewNode(full, nil, lookbackCap, stateWaitLookbackLimit, 0, time.Minute) handler, err := gateway.Handler(gwapi, full, 0, 0) require.NoError(t, err) diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index ef7f7ff6d..898776d10 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/filecoin-project/go-jsonrpc" "strconv" "sync" "time" @@ -18,6 +17,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" builtintypes "github.com/filecoin-project/go-state-types/builtin" From 965b1cf03cdaca6e4916e930ebcb7d6d6974abf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 26 Jan 2023 15:20:49 +0100 Subject: [PATCH 3/5] itests: Fix TestEthSubscribeLogs --- cli/util/api.go | 2 +- gateway/eth_sub.go | 5 +++-- gateway/proxy_eth.go | 4 ++-- itests/eth_filter_test.go | 14 +++++++------- itests/kit/ensemble.go | 3 ++- itests/kit/node_full.go | 5 +++++ itests/kit/rpc.go | 9 ++++++++- node/impl/full/eth.go | 3 ++- node/modules/actorevent.go | 1 + 9 files changed, 31 insertions(+), 15 deletions(-) diff --git a/cli/util/api.go b/cli/util/api.go index 3d06f9e31..1d6928c3f 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -359,7 +359,7 @@ func GetFullNodeAPIV1(ctx *cli.Context, opts ...GetFullNodeOption) (v1api.FullNo var closers []jsonrpc.ClientCloser for _, head := range heads { - v1api, closer, err := client.NewFullNodeRPCV1(ctx.Context, head.addr, head.header) + v1api, closer, err := client.NewFullNodeRPCV1(ctx.Context, head.addr, head.header, rpcOpts...) if err != nil { log.Warnf("Not able to establish connection to node with addr: ", head.addr) continue diff --git a/gateway/eth_sub.go b/gateway/eth_sub.go index 2f82fc32b..76d913983 100644 --- a/gateway/eth_sub.go +++ b/gateway/eth_sub.go @@ -24,11 +24,12 @@ func NewEthSubHandler() *EthSubHandler { } } -func (e *EthSubHandler) addSub(ctx context.Context, id ethtypes.EthSubscriptionID, sink func(context.Context, *ethtypes.EthSubscriptionResponse) error) error { +func (e *EthSubHandler) AddSub(ctx context.Context, id ethtypes.EthSubscriptionID, sink func(context.Context, *ethtypes.EthSubscriptionResponse) error) error { e.lk.Lock() defer e.lk.Unlock() for _, p := range e.queued[id] { + p := p // copy if err := sink(ctx, &p); err != nil { return err } @@ -38,7 +39,7 @@ func (e *EthSubHandler) addSub(ctx context.Context, id ethtypes.EthSubscriptionI return nil } -func (e *EthSubHandler) removeSub(id ethtypes.EthSubscriptionID) { +func (e *EthSubHandler) RemoveSub(id ethtypes.EthSubscriptionID) { e.lk.Lock() defer e.lk.Unlock() diff --git a/gateway/proxy_eth.go b/gateway/proxy_eth.go index 9518b2a15..4e8136835 100644 --- a/gateway/proxy_eth.go +++ b/gateway/proxy_eth.go @@ -463,7 +463,7 @@ func (gw *Node) EthSubscribe(ctx context.Context, eventType string, params *etht return ethtypes.EthSubscriptionID{}, err } - err = gw.subHnd.addSub(ctx, sub, func(ctx context.Context, response *ethtypes.EthSubscriptionResponse) error { + err = gw.subHnd.AddSub(ctx, sub, func(ctx context.Context, response *ethtypes.EthSubscriptionResponse) error { outParam, err := json.Marshal(response) if err != nil { return err @@ -502,7 +502,7 @@ func (gw *Node) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionI delete(ft.userSubscriptions, id) if gw.subHnd != nil { - gw.subHnd.removeSub(id) + gw.subHnd.RemoveSub(id) } return ok, nil diff --git a/itests/eth_filter_test.go b/itests/eth_filter_test.go index 5fbe1cb6a..1127ffdb2 100644 --- a/itests/eth_filter_test.go +++ b/itests/eth_filter_test.go @@ -438,15 +438,15 @@ func TestEthSubscribeLogsNoTopicSpec(t *testing.T) { t.Logf("actor ID address is %s", idAddr) // install filter - respCh, err := client.EthSubscribe(ctx, "logs", nil) + subId, err := client.EthSubscribe(ctx, "logs", nil) require.NoError(err) - subResponses := []ethtypes.EthSubscriptionResponse{} - go func() { - for resp := range respCh { - subResponses = append(subResponses, resp) - } - }() + var subResponses []ethtypes.EthSubscriptionResponse + err = client.EthSubRouter.AddSub(ctx, subId, func(ctx context.Context, resp *ethtypes.EthSubscriptionResponse) error { + subResponses = append(subResponses, *resp) + return nil + }) + require.NoError(err) const iterations = 10 ethContractAddr, messages := invokeLogFourData(t, client, iterations) diff --git a/itests/kit/ensemble.go b/itests/kit/ensemble.go index 8b92202dc..6d4ca1c12 100644 --- a/itests/kit/ensemble.go +++ b/itests/kit/ensemble.go @@ -47,6 +47,7 @@ import ( "github.com/filecoin-project/lotus/chain/wallet/key" "github.com/filecoin-project/lotus/cmd/lotus-seed/seed" "github.com/filecoin-project/lotus/cmd/lotus-worker/sealworker" + "github.com/filecoin-project/lotus/gateway" "github.com/filecoin-project/lotus/genesis" "github.com/filecoin-project/lotus/markets/idxprov" "github.com/filecoin-project/lotus/markets/idxprov/idxprov_test" @@ -210,7 +211,7 @@ func (n *Ensemble) FullNode(full *TestFullNode, opts ...NodeOpt) *Ensemble { n.genesis.accounts = append(n.genesis.accounts, genacc) } - *full = TestFullNode{t: n.t, options: options, DefaultKey: key} + *full = TestFullNode{t: n.t, options: options, DefaultKey: key, EthSubRouter: gateway.NewEthSubHandler()} n.inactive.fullnodes = append(n.inactive.fullnodes, full) return n diff --git a/itests/kit/node_full.go b/itests/kit/node_full.go index 682ae118a..3e80ed688 100644 --- a/itests/kit/node_full.go +++ b/itests/kit/node_full.go @@ -22,6 +22,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet/key" cliutil "github.com/filecoin-project/lotus/cli/util" + "github.com/filecoin-project/lotus/gateway" "github.com/filecoin-project/lotus/node" ) @@ -46,6 +47,10 @@ type TestFullNode struct { Stop node.StopFunc + // gateway handler makes it convenient to register callbalks per topic, so we + // also use it for tests + EthSubRouter *gateway.EthSubHandler + options nodeOpts } diff --git a/itests/kit/rpc.go b/itests/kit/rpc.go index f8c2c6e53..5d40ac3e9 100644 --- a/itests/kit/rpc.go +++ b/itests/kit/rpc.go @@ -13,6 +13,8 @@ import ( manet "github.com/multiformats/go-multiaddr/net" "github.com/stretchr/testify/require" + "github.com/filecoin-project/go-jsonrpc" + "github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/cmd/lotus-worker/sealworker" "github.com/filecoin-project/lotus/node" @@ -52,7 +54,12 @@ func fullRpc(t *testing.T, f *TestFullNode) (*TestFullNode, Closer) { fmt.Printf("FULLNODE RPC ENV FOR CLI DEBUGGING `export FULLNODE_API_INFO=%s`\n", "ws://"+srv.Listener.Addr().String()) sendItestdNotif("FULLNODE_API_INFO", t.Name(), "ws://"+srv.Listener.Addr().String()) - cl, stop, err := client.NewFullNodeRPCV1(context.Background(), "ws://"+srv.Listener.Addr().String()+"/rpc/v1", nil) + rpcOpts := []jsonrpc.Option{ + jsonrpc.WithClientHandler("Filecoin", f.EthSubRouter), + jsonrpc.WithClientHandlerAlias("eth_subscription", "Filecoin.EthSubscription"), + } + + cl, stop, err := client.NewFullNodeRPCV1(context.Background(), "ws://"+srv.Listener.Addr().String()+"/rpc/v1", nil, rpcOpts...) require.NoError(t, err) f.ListenAddr, f.ListenURL, f.FullNode = maddr, srv.URL, cl diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 898776d10..83ea6fcd5 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -134,6 +134,7 @@ type EthEvent struct { FilterStore filter.FilterStore SubManager *EthSubscriptionManager MaxFilterHeightRange abi.ChainEpoch + SubscribtionCtx context.Context } var _ EthEventAPI = (*EthEvent)(nil) @@ -1112,7 +1113,7 @@ func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *e return ethtypes.EthSubscriptionID{}, xerrors.Errorf("connection doesn't support callbacks") } - sub, err := e.SubManager.StartSubscription(ctx, ethCb.EthSubscription) + sub, err := e.SubManager.StartSubscription(e.SubscribtionCtx, ethCb.EthSubscription) if err != nil { return ethtypes.EthSubscriptionID{}, err } diff --git a/node/modules/actorevent.go b/node/modules/actorevent.go index eb5afb8e6..55a79a59a 100644 --- a/node/modules/actorevent.go +++ b/node/modules/actorevent.go @@ -40,6 +40,7 @@ func EthEventAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRepo ee := &full.EthEvent{ Chain: cs, MaxFilterHeightRange: abi.ChainEpoch(cfg.Events.MaxFilterHeightRange), + SubscribtionCtx: ctx, } if !cfg.EnableEthRPC || cfg.Events.DisableRealTimeFilterAPI { From 9701b116419a92d96669a99936c8d7ef8715ee19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 26 Jan 2023 15:50:18 +0100 Subject: [PATCH 4/5] ethtypes: Serialize EthFilterID/EthSubscriptionID correctly --- build/openrpc/full.json.gz | Bin 33267 -> 33162 bytes build/openrpc/gateway.json.gz | Bin 8582 -> 8487 bytes chain/types/ethtypes/eth_types.go | 48 +++- chain/types/ethtypes/eth_types_test.go | 42 +++ documentation/en/api-v1-unstable-methods.md | 292 +------------------- 5 files changed, 86 insertions(+), 296 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 4524108b1c12310be48c34b90d68fc7f028cd230..4757ee49b471aaf7a2aa2b98934e7dff3f6c01fa 100644 GIT binary patch delta 30489 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 EKUm=&*Z=?k delta 30587 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ν@r6ivJ$DaX7g=H?~V4hcVk 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 Grv?D=c4(Xc diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index 688e01963366a9415a90b54451b0ff6a5fb1f9f0..050ab611e97f605204623467a2df05e693cb3e38 100644 GIT binary patch literal 8487 zcmV+?A=us@iwFP!00000|LnbcQ`$p!Mp=_Hrta>0T{dvisxJd&l;Wzq!Hd#OXM_%n1a$mY50oq0itPut?!=wS|>) z16mkO5Og!Jj*+3b&~c&X&lo5kG$-$An=!Jc^w=z{0K;&h=Rre35wsoU94p9Q=NuZ! zc%=a4FN$~_1t`b10d?ig!wl&&1z85t0fuCZ`NG6VCvV?7K)-`VGzwlh@T~$YLjlSK zX*C1hjO-g+g1KWtx-}ojzJbZAKmG}H2($;!mQdQWKGrYj~&&8|1OXV4RwUw1tgp0xR6ZS zP)8GBdXV&Up|>zG+34Vm-j!2K=5@ibCDwRkdQlJZ`>&9o2mOwEYpWx5((U!Nf!a|& zy7rv?eQ8@dqz(T9=7P+yt9H~g;C)7Ogw@f3|KlTs$H0kSUb%3N7W3f2g^#l8sMk@i z0;E*`Ynk2u-5kwy>pwI2=WoBM9rgJ9giJkoBIB`R!0ElKp@D9D@BzkMuS8~AOgei*&8sgT-$*zM&xLHYU-#C^C*S%zf^?b-2X!W1jU4k zE|l_Bd;A0Hm~0}03pKh1I2AKqYcU`D%r?JaaR?$nODa7}fj&M+ike z+GJiIOkzoX7@PL^!yI@Rx*vdpJ~*zuT>bx3Xzfhx|L?PQaIj0(RBS_@K?{1Qw)Gfv z&#@bctw?s#+qp%~4a7XAVgRjCBQc)gwoSua3xwU0tO1gG%VU2~;b<*Pv!nXM@bgZ@F&M$tc>uJn#Py$aZF???h+ ziESvXXwB+DIR z4Y|gwPs%kZ*DB;%F81X}xuSMlGVgSWFxgXe)a|I(KK|xQi!IH9MoeI+{1bt~Jo^_NLmx za-s2aZ?d!o(;vHE&-GF;`}H?@3|E3gwPFOBL8tmu9=EscWFMZ9XSKv3*<%LPTjWg(}ipuIVTMV(7q z+OpA0t7y(`vmqo;6TVK8SKXWA9K#+D=Qx~T=mtBq7879r74Z`=Ms)O3$JS>Bx@S!m z!wkOxZj)SG8@15n-d6iDBGWAi=F)$xAWs2G)P$k4UbolnF(Ni-BQ-+FJzp00-0Smj z&!bfntTTl26nrxrdjm|9S(fCOl4DAa`La3YzE;99KLPKL@sC<;l6I}W6C2yMS;_Y( zuzY4mw^EedMbm4WIV!KTT6U#H5Hz#1!NY2fLq=j|L;68rJ#(IMFeu|05E%711_VYE zNe2W@b9zxQE178U8l+*bTb5dLwZL_yA?;cu4aff0@AxP1mZEndc2h|C_$`Rq(WKfY z1KIuH!{lNtB^X$n_g^l|Ebk8qm5lr)$mieR*P}#w%QXdmX?l zy}c%Y#ILR6nYN8Aq-xkQ)sUiC&fRYCxSDZgW0va9udN(KD~QBAL7r~k=U`?9HwpXY zYl^@@R1NyWf!6ia@rkW32u+splMrGFFDU{m#9f$~w?UgMT2t2JR@{(B#}uiS)!*rT zm_iG>1dD&`cl+Ji0*3{`>B5)a@pVX?^cxYIG55bpR$Cf0YPh*m+kR ztUxJ?BUa%#ljEQug6$N~4t3pLSmM#pOxJv({QEn^Gm1i_Efpwb6v;p=74SJ=g(xyP z^EMD=?wWE0Onxg4N3z;o?&@O*^~u43p-qgjHtFv|t$U#B{o!EJA9Tm#?r=EhYCSa> zEENA$$F-jEqkr$HbFe(8K>OW}I!6}sD;*5=b1jt#ElI%m4x>Mfl)E2_jfY8!utg8_B5(PH5hsfC%cS z*cRTp5o(-vl0kn;(gYk@|D)=f?!GnT8lv6xA z^)Q+P49`Fv=LFN6S23(Z6wELiC5+^9+IB}FHAATxO3kpb07xl!HZ6Dh-GX4IQ#|_! z;V0x_+g;TVJ8@?osS}Er$RW{D98LNA`^2;X5fVv(6vM6%N^wI@nG|;rl}m~BhE5Bz zinfZURufCBtVCuuTFzxefTMgD5WW76mb_SK%Al*_pC!~>*o;Sau}uSd^usl@2G$sO z@FRp*&?O2hHGIk5PiZNRYk-lhj_6L1IX?i`Aa;kKo{<`cw|ab5$Y$j_Gff6;rB0IA z2_DTLTst#JLyN#KxB~c~-zx}HJjJuKP}vffSYg*{FToL-o|gwzFyMH7w5?ta@l3b>>mbqHu-6t0FF1h{oJ3HLy!- z`^Aw++=5Wp!X`Y-BC!h3Pr;L{Y_qIPD+sF&NR}u}N2^c36D}T>0l>r3NIRdOjcq&a z>hwWzFtd0>UWVo;H`L%~iM6$zrv+!oMFZO2@Sv+tpgz=l7~BjSUDxj- z=BZ$hn#V`NoL0@xWlV)W7cvzo7)zPm=B{XpWKitrVTftdS8f5Pd&&!`h&G>c%dPN3 zFPoaeK0AZ`oCyRhkOxCq5&D#ymJ}pUITKa|c+z?JT%P9)8ExSyC(KAvo>^xEI9I2H zw5xQ7=jJTs%sitVJ>@Cy$xBOKTJqA8mzKP=1S5>*_Hm6$2xC5C@(+W1VS6tYpn84O{Ko)`I&%9}t zS#6P@(l(k83?#8VNXWj}CH(vs&BTGijJO5P4p;Enn2UYJ8l>lWARiHP;HJza}; zk^b9eTx86~xmK_c$+9HNk}T`VSXQsN)XN#f^_f)}o613f8wcv^ajJ%SR7<&2!PW_s z6bnjGsC}*5>-W2=PfWf^Dr|6K+d+Epc`U&&lW5E>T$5D?9;AQ!A6t6*TXp8Req{q+ zuwC|!o=o2Ew&gamDb6az(F+ns{gNs!5Z_?i1ygt^{FUldcTv}8j>pr{)^dnOQ`xXr zlwI<3C_pCNqebq~m*ICTtC}Vqz^~o`tZAhMj+l$xqt#KUq#atuxn;m*J)uwzQ>b=G z^ZnuUuri z2(Pj)@1wumIK?LTOEmYT9cF*xFnPkNBgExt{EUjEKYjj9fTg4(`YT6Qa;P}Wb;&4A$w zK?*W+->s#A7boM^ia*L*NvngAr1M=kFeOI=&c2r_uvCGi3M^G%sRBzCSgOF!S_K}K z)~iWZEm&Iv_MtSA<;`3AAwBq}t3Bi_w(V|b8Q}PA^1o$Gi;Zx>{nBzc3`t+pqJnGl z!2pgxjjngT@fGwFVtYZK%{T($g|y8RARPh1jsOqxCgupcfkBTX6+! z$KrPztbgrcfETe_fN&fa=s1-7f-}<>^Mwg8x`$_}%Gc>i*l;p|deD%5?Kt!)Re`q}}sFxxB+awihxJ|+p%o+fdp5UDnV#9P4CI1)el`5GKJY4mX9)jn5pF@j3>n{~>??3T+X7V_#Sk2w4QNkt;@ zM&@4P%X<3ruH#sHtjyuvYMFoc$qQtM3KCzH@z!`!pC|V5yLDfhv-P03bmm3gwS%~q zArDNBlOdfT?tc`%!l{r4nm1G2hcD_(Em+I8eGKxW`x_;SLASWR;w60W1G#Apj2h&S z1W-)~VR5YrQb>a3B!Z~;nIIWt*3dQrU@DTyvSlwK<$cgAE*f|VAJ!qqLQ1Tt!c~t- zw?&}Qs@moRm$kVzqJp>6^p~}{nz&+>;_StVvwm?w$xHZf1uX+vQ|3~09RXJatx4sx zXpGGZx{}pNwN%pahUr)w=s@<>k-nW@!A!~&KtED#*Q_^O1=yFx}-Cvh9-+cqmCL27_}c|bQ?jOk}*-e#3l`cQZ|8^Ni}41q-Gcq_q;j4UUB~67t32iTV#6kP<~2FPt9AJ0>Jr7J_jc~YJAcc_!6s?1X)P@Xx+(65?aiH#hV1+ijMa~Vxzr)pA z#%Y#?uKm%V-%)REb)-(Zy}mY3JL*T8k`?{Fq~#Y# z!@t7HDQZVO1KwveM_3&l_&+{EcnqBQ<&_KPXfY2ST=+{?N4<_3n2#g%zn0nk-_6lX zxBfGOfByEH+EI_sPsmh1kevXNRe$^w=x{uC3^=`aH8jv|4?f`8%A4*k@0QNL6RZC) z(SHu-_x;)2zQYe=V|fRb15bSvG!#Du86IMJA~;&1crF~PUIjPrsAP`--RWQItxu%=j(S21DP%@}d`e-$9E}t~ zQUui$K}`1q?hByQNsumIZ+k=&U)QcXn5X>)96!T3NyF40yAhWN2VBwovW3 zhL);3y@K@23lB}tAU?bY$OK~(9sv^&E+eY^ncIYGM~O*%koFO< zjsQ;6{?Kt;TJ$Q$Du0jSXa@l^C5FaZQY~X4r6WG6?O$y|idd%4#oWv@ziK8zv{klg z1xd02@BRyVWWx1C8|}P?WGjfh5LEQ(G&ZQ-N9$~B;DwZNFG0r1dthk|wLoGF3evF| zW{9lmjXs0M!mR5VN$? zJ+}}>zziM2)Cju4z{RJIt?p|0BtE6_=VFf-MC zJykfcAFd4EP8zCadq>)B0l_aYIN7hEdpHHt?m z4K7{VZkIW;%Am`l)k zyDsW*)J;05nUzVES*py^J^k#so>q{<MxW!1dQu<84<#8RHdb(>r1Sa`sTfc)w9S>~?M%0cDM||CW+Cf3?3Bz%2 zu=O;x@TMCM_;bh9psLeTV^A^-fW*qJ3#_sWU2OGM_ldM_5 zryG++PBlsP9S>V3GqpWnk{A9(aBk_Lx<1+XYI)S_YJI<$44NQl_%jTaeQY9VVK%EX zyiRAIeFkG_(xv3YIGL{g7w@G|!OqBl^-wwp8j zXW-#4jzNwtH4PJZv*e?23yw{I=IW>`TA_(OF@bL3E(<%LGn*m`AwCZ-!%@SDDvw*g+wEOqggWIT4RPPxq2~_ z$N)mCkCw;(T#s!hm(?zuIw>uHf;?=>y^5KOfK8MZ95=)*QOta)ZVtyCVR zCI3Rz#bP>S-|(o4e>_-8mF%nS-X))0!iVfbLbk4L2B?)r9oqhQ2COMeDoR%ny61*E zQhWUq?RVS$diHbq^Y{P#_a1)wKkS?h4?XwGe~$F8%TGriZ~C9SQ~T_8>0W%k|NZ~) zMD3`4{W*fz{)m}MAY^Q08TP}KeS@!D+n&&>f%}m}@pS@ipzR*)Y5Ur6KhXiW*grkm z)}w(3$F}7`%UgIK!NSC+CU87*I>CaDpamyLM|7j3{b3&8Lf4lqe=cmlHYm|bzj)AK zf1fTLluYF#Tjdx0$$@kU9}0%Ogbys(OZbq192ZMDS|y-R1dLx^+H+(3yg+fxRQ8g$R1yIbHv>1i?bRQV?caHgWt44cQd;VX(~ulVVj=iViHWg z<4nc~JB)s**Wlr3g<ergXz^u{l6YwsO6+H6wP%$+$(LYbb zCKn_CIWu8V;gQ^g^`&ici=XdGUYdN|D=4zS2nN@_N7nQN0>eaB&B&P?Kx@iOAI1*9 zqb)Uh)6z4uHYrD?9NnTEjmaS^M-%V3a&8u`3oV@Xjk(A+{5y~6*|}xFCG|u7;lS93 zb8OlkjDO95X+monKk@wt#|vyvCegF6zG>tS5|UBi;`$mGO@zW|gJh=&J~golUVgUi zyD`x3l9M=rx(TQWnwXEEBxjb$_b2bgTigH6nS|*aKm0Kn;CTA^^#5*3#B$;O4Y;Axrd`$QV zY+kn4YOhyT{N)A$SD#&Y!nJCXy*c$opMgi;>vc3g$>4YfkmZ|f9mN^=#mD@69&bvM zOe=YMG>hhVI=e8oLKvB$R2kdPTuUXA{J!T?e&4gKSX+`EY_Q&4uiI-NQD*Q&1@H1N z2Sa|Db2rGm68!#mGupy6)FE;(4e3Id%JMFGPPlLWcfiho_r;H#I_RjU_k_BxZ5uZ= zr^j&c6Q~n4rlV3O+8BK_#U4BACy1sqT+h`S_T~FtS#;`RN)~gvBC&mmGZh;#Mk3D7 zi+|yc!3$BcR%~3}WiE?mB5G)ik*_)@cCTMn{D}sYok3hXlOX{?#1BDa741yLO+mrj zcXMPxH)#2XuqiQ+h^tENF&3>RF{JW)D~GJcP$@H0YPWguHuF~ zN>~D&h!S)|3t8KfAO`}N&}cLpm}aLliR6bmM)%2tgPa@$((P-YXZW5bHXSkXBKS(t zl?jb0jMF8cj-hb^R@d+WxJK%Em?6pbxrUAjbZF2mI%Mw3!#8PYwB_$`)#!%ZAaY!P z9@Y2`3b1kF+j`)alm%BNQ^9LQvu8xh(e81;L;; zUyg0W8+e;X%tO$lnxdpSy+fwPHPs}I%UN zO`fku1vJkU;-5E%=9J}v70Pf$c`3L>g)>bQSxqyih5Sr!nkf#-3Lbt12-m#@3;GtZ zzWBbYuPl&-hlA#>zJj5f<9P8}+I;OLZ*baigOg?K6u~#<{une--%Q>+$$KYx? zVIhrrT5o^Q?WjloH|?PbR_bWb7xm;a0D0)09gMTST?D*<_+JR&4GYTFeFdgjyC!|2 zGpCd4t@4KYDUQ(e+`?s~nE+oxpe#Hg5>3y)ZMiG0b3f&A7IyawTvE|X=|4%+<=#+z VeEk0S{{jF2|Nl+25H@4R0RZW&g^U0I literal 8582 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 M{|vsy4b#T~06#F<)c^nh diff --git a/chain/types/ethtypes/eth_types.go b/chain/types/ethtypes/eth_types.go index 235cc7c79..64c08c2ae 100644 --- a/chain/types/ethtypes/eth_types.go +++ b/chain/types/ethtypes/eth_types.go @@ -363,6 +363,18 @@ func (h *EthHash) UnmarshalJSON(b []byte) error { return nil } +func (h EthHash) String() string { + return "0x" + hex.EncodeToString(h[:]) +} + +// Should ONLY be used for blocks and Filecoin messages. Eth transactions expect a different hashing scheme. +func (h EthHash) ToCid() cid.Cid { + // err is always nil + mh, _ := multihash.EncodeName(h[:], "blake2b-256") + + return cid.NewCidV1(cid.DagCBOR, mh) +} + func decodeHexString(s string, expectedLen int) ([]byte, error) { s = handleHexStringPrefix(s) if len(s) != expectedLen*2 { @@ -420,18 +432,6 @@ func EthHashFromTxBytes(b []byte) EthHash { return ethHash } -func (h EthHash) String() string { - return "0x" + hex.EncodeToString(h[:]) -} - -// Should ONLY be used for blocks and Filecoin messages. Eth transactions expect a different hashing scheme. -func (h EthHash) ToCid() cid.Cid { - // err is always nil - mh, _ := multihash.EncodeName(h[:], "blake2b-256") - - return cid.NewCidV1(cid.DagCBOR, mh) -} - type EthFeeHistory struct { OldestBlock uint64 `json:"oldestBlock"` BaseFeePerGas []EthBigInt `json:"baseFeePerGas"` @@ -441,9 +441,33 @@ type EthFeeHistory struct { type EthFilterID EthHash +func (h EthFilterID) MarshalJSON() ([]byte, error) { + return (EthHash)(h).MarshalJSON() +} + +func (h *EthFilterID) UnmarshalJSON(b []byte) error { + return (*EthHash)(h).UnmarshalJSON(b) +} + +func (h EthFilterID) String() string { + return (EthHash)(h).String() +} + // An opaque identifier generated by the Lotus node to refer to an active subscription. type EthSubscriptionID EthHash +func (h EthSubscriptionID) MarshalJSON() ([]byte, error) { + return (EthHash)(h).MarshalJSON() +} + +func (h *EthSubscriptionID) UnmarshalJSON(b []byte) error { + return (*EthHash)(h).UnmarshalJSON(b) +} + +func (h EthSubscriptionID) String() string { + return (EthHash)(h).String() +} + type EthFilterSpec struct { // Interpreted as an epoch or one of "latest" for last mined block, "earliest" for first, // "pending" for not yet committed messages. diff --git a/chain/types/ethtypes/eth_types_test.go b/chain/types/ethtypes/eth_types_test.go index 89c38ba29..e42d2bdc3 100644 --- a/chain/types/ethtypes/eth_types_test.go +++ b/chain/types/ethtypes/eth_types_test.go @@ -93,6 +93,48 @@ func TestEthHash(t *testing.T) { h1, err := EthHashFromCid(c) require.Nil(t, err) require.Equal(t, h, h1) + + jm, err := json.Marshal(h) + require.NoError(t, err) + require.Equal(t, hash, string(jm)) + } +} + +func TestEthFilterID(t *testing.T) { + testcases := []string{ + `"0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"`, + `"0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"`, + } + + for _, hash := range testcases { + var h EthFilterID + err := h.UnmarshalJSON([]byte(hash)) + + require.Nil(t, err) + require.Equal(t, h.String(), strings.Replace(hash, `"`, "", -1)) + + jm, err := json.Marshal(h) + require.NoError(t, err) + require.Equal(t, hash, string(jm)) + } +} + +func TestEthSubscriptionID(t *testing.T) { + testcases := []string{ + `"0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"`, + `"0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"`, + } + + for _, hash := range testcases { + var h EthSubscriptionID + err := h.UnmarshalJSON([]byte(hash)) + + require.Nil(t, err) + require.Equal(t, h.String(), strings.Replace(hash, `"`, "", -1)) + + jm, err := json.Marshal(h) + require.NoError(t, err) + require.Equal(t, hash, string(jm)) } } diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 299d71308..c9d5f8814 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -2520,40 +2520,7 @@ Perms: write Inputs: ```json [ - [ - 55, - 105, - 12, - 254, - 198, - 193, - 191, - 76, - 59, - 146, - 136, - 199, - 165, - 215, - 131, - 233, - 135, - 49, - 233, - 11, - 10, - 76, - 23, - 124, - 42, - 55, - 76, - 122, - 148, - 39, - 53, - 94 - ] + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" ] ``` @@ -2574,40 +2541,7 @@ Perms: write Inputs: ```json [ - [ - 55, - 105, - 12, - 254, - 198, - 193, - 191, - 76, - 59, - 146, - 136, - 199, - 165, - 215, - 131, - 233, - 135, - 49, - 233, - 11, - 10, - 76, - 23, - 124, - 42, - 55, - 76, - 122, - 148, - 39, - 53, - 94 - ] + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" ] ``` @@ -2881,43 +2815,7 @@ Perms: write Inputs: `null` -Response: -```json -[ - 55, - 105, - 12, - 254, - 198, - 193, - 191, - 76, - 59, - 146, - 136, - 199, - 165, - 215, - 131, - 233, - 135, - 49, - 233, - 11, - 10, - 76, - 23, - 124, - 42, - 55, - 76, - 122, - 148, - 39, - 53, - 94 -] -``` +Response: `"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"` ### EthNewFilter Installs a persistent filter based on given filter spec. @@ -2938,43 +2836,7 @@ Inputs: ] ``` -Response: -```json -[ - 55, - 105, - 12, - 254, - 198, - 193, - 191, - 76, - 59, - 146, - 136, - 199, - 165, - 215, - 131, - 233, - 135, - 49, - 233, - 11, - 10, - 76, - 23, - 124, - 42, - 55, - 76, - 122, - 148, - 39, - 53, - 94 -] -``` +Response: `"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"` ### EthNewPendingTransactionFilter Installs a persistent filter to notify when new messages arrive in the message pool. @@ -2984,43 +2846,7 @@ Perms: write Inputs: `null` -Response: -```json -[ - 55, - 105, - 12, - 254, - 198, - 193, - 191, - 76, - 59, - 146, - 136, - 199, - 165, - 215, - 131, - 233, - 135, - 49, - 233, - 11, - 10, - 76, - 23, - 124, - 42, - 55, - 76, - 122, - 148, - 39, - 53, - 94 -] -``` +Response: `"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"` ### EthProtocolVersion @@ -3071,43 +2897,7 @@ Inputs: ] ``` -Response: -```json -[ - 55, - 105, - 12, - 254, - 198, - 193, - 191, - 76, - 59, - 146, - 136, - 199, - 165, - 215, - 131, - 233, - 135, - 49, - 233, - 11, - 10, - 76, - 23, - 124, - 42, - 55, - 76, - 122, - 148, - 39, - 53, - 94 -] -``` +Response: `"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"` ### EthUninstallFilter Uninstalls a filter with given id. @@ -3118,40 +2908,7 @@ Perms: write Inputs: ```json [ - [ - 55, - 105, - 12, - 254, - 198, - 193, - 191, - 76, - 59, - 146, - 136, - 199, - 165, - 215, - 131, - 233, - 135, - 49, - 233, - 11, - 10, - 76, - 23, - 124, - 42, - 55, - 76, - 122, - 148, - 39, - 53, - 94 - ] + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" ] ``` @@ -3166,40 +2923,7 @@ Perms: write Inputs: ```json [ - [ - 55, - 105, - 12, - 254, - 198, - 193, - 191, - 76, - 59, - 146, - 136, - 199, - 165, - 215, - 131, - 233, - 135, - 49, - 233, - 11, - 10, - 76, - 23, - 124, - 42, - 55, - 76, - 122, - 148, - 39, - 53, - 94 - ] + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" ] ``` From ad14d71978f9d63ff6268b5fbedb781a05fbe384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 31 Jan 2023 11:00:15 +0100 Subject: [PATCH 5/5] eth rpc: Params are optional in eth_subscribe --- api/api_full.go | 2 +- api/api_gateway.go | 3 +- api/mocks/mock_full.go | 9 ++-- api/proxy_gen.go | 16 +++---- build/openrpc/full.json.gz | Bin 33162 -> 33148 bytes build/openrpc/gateway.json.gz | Bin 8487 -> 8472 bytes chain/types/ethtypes/eth_types.go | 37 ++++++++++++++++ documentation/en/api-v1-unstable-methods.md | 9 +--- gateway/node.go | 3 +- gateway/proxy_eth.go | 10 ++++- itests/eth_filter_test.go | 45 +++++++++----------- lib/result/result.go | 8 +++- node/impl/full/eth.go | 19 ++++++--- 13 files changed, 103 insertions(+), 58 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index e9cf4a58f..2ac92a764 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -832,7 +832,7 @@ type FullNode interface { // - logs: notify new event logs that match a criteria // params contains additional parameters used with the log event type // The client will receive a stream of EthSubscriptionResponse values until EthUnsubscribe is called. - EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) //perm:write + EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) //perm:write // Unsubscribe from a websocket subscription EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) //perm:write diff --git a/api/api_gateway.go b/api/api_gateway.go index fdadd2ae6..2c91fc6f5 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -7,6 +7,7 @@ import ( "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/builtin/v9/miner" "github.com/filecoin-project/go-state-types/dline" @@ -102,6 +103,6 @@ type Gateway interface { EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error) - EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) + EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) } diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 30df05226..c944e2de1 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -23,6 +23,7 @@ import ( bitfield "github.com/filecoin-project/go-bitfield" datatransfer "github.com/filecoin-project/go-data-transfer" retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket" + jsonrpc "github.com/filecoin-project/go-jsonrpc" auth "github.com/filecoin-project/go-jsonrpc/auth" abi "github.com/filecoin-project/go-state-types/abi" big "github.com/filecoin-project/go-state-types/big" @@ -1388,18 +1389,18 @@ func (mr *MockFullNodeMockRecorder) EthSendRawTransaction(arg0, arg1 interface{} } // EthSubscribe mocks base method. -func (m *MockFullNode) EthSubscribe(arg0 context.Context, arg1 string, arg2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { +func (m *MockFullNode) EthSubscribe(arg0 context.Context, arg1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EthSubscribe", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "EthSubscribe", arg0, arg1) ret0, _ := ret[0].(ethtypes.EthSubscriptionID) ret1, _ := ret[1].(error) return ret0, ret1 } // EthSubscribe indicates an expected call of EthSubscribe. -func (mr *MockFullNodeMockRecorder) EthSubscribe(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockFullNodeMockRecorder) EthSubscribe(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthSubscribe", reflect.TypeOf((*MockFullNode)(nil).EthSubscribe), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthSubscribe", reflect.TypeOf((*MockFullNode)(nil).EthSubscribe), arg0, arg1) } // EthUninstallFilter mocks base method. diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 9b8890a7c..7a6b0d508 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -302,7 +302,7 @@ type FullNodeMethods struct { EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) `perm:"read"` - EthSubscribe func(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) `perm:"write"` + EthSubscribe func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) `perm:"write"` EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `perm:"write"` @@ -704,7 +704,7 @@ type GatewayMethods struct { EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) `` - EthSubscribe func(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) `` + EthSubscribe func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) `` EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `` @@ -2320,14 +2320,14 @@ func (s *FullNodeStub) EthSendRawTransaction(p0 context.Context, p1 ethtypes.Eth return *new(ethtypes.EthHash), ErrNotSupported } -func (s *FullNodeStruct) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { +func (s *FullNodeStruct) EthSubscribe(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) { if s.Internal.EthSubscribe == nil { return *new(ethtypes.EthSubscriptionID), ErrNotSupported } - return s.Internal.EthSubscribe(p0, p1, p2) + return s.Internal.EthSubscribe(p0, p1) } -func (s *FullNodeStub) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { +func (s *FullNodeStub) EthSubscribe(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) { return *new(ethtypes.EthSubscriptionID), ErrNotSupported } @@ -4465,14 +4465,14 @@ func (s *GatewayStub) EthSendRawTransaction(p0 context.Context, p1 ethtypes.EthB return *new(ethtypes.EthHash), ErrNotSupported } -func (s *GatewayStruct) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { +func (s *GatewayStruct) EthSubscribe(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) { if s.Internal.EthSubscribe == nil { return *new(ethtypes.EthSubscriptionID), ErrNotSupported } - return s.Internal.EthSubscribe(p0, p1, p2) + return s.Internal.EthSubscribe(p0, p1) } -func (s *GatewayStub) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { +func (s *GatewayStub) EthSubscribe(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) { return *new(ethtypes.EthSubscriptionID), ErrNotSupported } diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 4757ee49b471aaf7a2aa2b98934e7dff3f6c01fa..0211629fe149ce42317eaa73ac55aa7a554ff27f 100644 GIT binary patch delta 23645 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 ALI3~& delta 23700 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 Pd`z||c}xyMK|=f&&p$>A delta 8328 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 S`2PX`0RR6@v=BC9#sL6;3o`Wp diff --git a/chain/types/ethtypes/eth_types.go b/chain/types/ethtypes/eth_types.go index 64c08c2ae..584a7d2be 100644 --- a/chain/types/ethtypes/eth_types.go +++ b/chain/types/ethtypes/eth_types.go @@ -619,6 +619,43 @@ type EthLog struct { BlockNumber EthUint64 `json:"blockNumber"` } +// EthSubscribeParams handles raw jsonrpc params for eth_subscribe +type EthSubscribeParams struct { + EventType string + Params *EthSubscriptionParams +} + +func (e *EthSubscribeParams) UnmarshalJSON(b []byte) error { + var params []json.RawMessage + err := json.Unmarshal(b, ¶ms) + if err != nil { + return err + } + switch len(params) { + case 2: + err = json.Unmarshal(params[1], &e.Params) + if err != nil { + return err + } + fallthrough + case 1: + err = json.Unmarshal(params[0], &e.EventType) + if err != nil { + return err + } + default: + return xerrors.Errorf("expected 1 or 2 params, got %d", len(params)) + } + return nil +} + +func (e EthSubscribeParams) MarshalJSON() ([]byte, error) { + if e.Params != nil { + return json.Marshal([]interface{}{e.EventType, e.Params}) + } + return json.Marshal([]interface{}{e.EventType}) +} + type EthSubscriptionParams struct { // List of topics to be matched. // Optional, default: empty list diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index c9d5f8814..c8c650395 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -2886,14 +2886,7 @@ Perms: write Inputs: ```json [ - "string value", - { - "topics": [ - [ - "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" - ] - ] - } + "Bw==" ] ``` diff --git a/gateway/node.go b/gateway/node.go index bcb515b3c..56f1f6134 100644 --- a/gateway/node.go +++ b/gateway/node.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/dline" "github.com/filecoin-project/go-state-types/network" @@ -117,7 +118,7 @@ type TargetAPI interface { EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error) - EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) + EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) } diff --git a/gateway/proxy_eth.go b/gateway/proxy_eth.go index 4e8136835..cf65f484c 100644 --- a/gateway/proxy_eth.go +++ b/gateway/proxy_eth.go @@ -436,7 +436,13 @@ func (gw *Node) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) return ok, nil } -func (gw *Node) EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { +func (gw *Node) EthSubscribe(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) { + // validate params + _, err := jsonrpc.DecodeParams[ethtypes.EthSubscribeParams](p) + if err != nil { + return ethtypes.EthSubscriptionID{}, xerrors.Errorf("decoding params: %w", err) + } + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { return ethtypes.EthSubscriptionID{}, err } @@ -458,7 +464,7 @@ func (gw *Node) EthSubscribe(ctx context.Context, eventType string, params *etht return ethtypes.EthSubscriptionID{}, fmt.Errorf("too many subscriptions") } - sub, err := gw.target.EthSubscribe(ctx, eventType, params) + sub, err := gw.target.EthSubscribe(ctx, p) if err != nil { return ethtypes.EthSubscriptionID{}, err } diff --git a/itests/eth_filter_test.go b/itests/eth_filter_test.go index 1127ffdb2..22fb17757 100644 --- a/itests/eth_filter_test.go +++ b/itests/eth_filter_test.go @@ -6,6 +6,7 @@ import ( "context" "encoding/binary" "encoding/hex" + "encoding/json" "fmt" "os" "sort" @@ -21,6 +22,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" @@ -29,6 +31,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/ethtypes" "github.com/filecoin-project/lotus/itests/kit" + res "github.com/filecoin-project/lotus/lib/result" ) // SolidityContractDef holds information about one of the test contracts @@ -438,7 +441,7 @@ func TestEthSubscribeLogsNoTopicSpec(t *testing.T) { t.Logf("actor ID address is %s", idAddr) // install filter - subId, err := client.EthSubscribe(ctx, "logs", nil) + subId, err := client.EthSubscribe(ctx, res.Wrap[jsonrpc.RawParams](json.Marshal(ethtypes.EthSubscribeParams{EventType: "logs"})).Assert(require.NoError)) require.NoError(err) var subResponses []ethtypes.EthSubscriptionResponse @@ -567,44 +570,33 @@ func TestEthSubscribeLogs(t *testing.T) { testResponses := map[string]chan ethtypes.EthSubscriptionResponse{} - // quit is used to signal that we're ready to start testing collected results - quit := make(chan struct{}) - // Create all the filters for _, tc := range testCases { - // subscribe to topics in filter - subCh, err := client.EthSubscribe(ctx, "logs", ðtypes.EthSubscriptionParams{Topics: tc.spec.Topics}) + subParam, err := json.Marshal(ethtypes.EthSubscribeParams{ + EventType: "logs", + Params: ðtypes.EthSubscriptionParams{Topics: tc.spec.Topics}, + }) + require.NoError(err) + + subId, err := client.EthSubscribe(ctx, subParam) require.NoError(err) responseCh := make(chan ethtypes.EthSubscriptionResponse, len(invocations)) testResponses[tc.name] = responseCh - // start a goroutine to forward responses from subscription to a buffered channel with guaranteed capacity - go func(subCh <-chan ethtypes.EthSubscriptionResponse, responseCh chan<- ethtypes.EthSubscriptionResponse, quit chan struct{}) { - defer func() { - close(responseCh) - }() - for { - select { - case resp := <-subCh: - responseCh <- resp - case <-quit: - return - case <-ctx.Done(): - return - } - } - }(subCh, responseCh, quit) - + err = client.EthSubRouter.AddSub(ctx, subId, func(ctx context.Context, resp *ethtypes.EthSubscriptionResponse) error { + responseCh <- *resp + return nil + }) + require.NoError(err) } // Perform all the invocations messages := invokeAndWaitUntilAllOnChain(t, client, invocations) - // wait a little for subscriptions to gather results and then tell all the goroutines to stop + // wait a little for subscriptions to gather results time.Sleep(blockTime * 6) - close(quit) for _, tc := range testCases { tc := tc // appease the lint despot @@ -612,6 +604,9 @@ func TestEthSubscribeLogs(t *testing.T) { responseCh, ok := testResponses[tc.name] require.True(ok) + // don't expect any more responses + close(responseCh) + var elogs []*ethtypes.EthLog for resp := range responseCh { rlist, ok := resp.Result.([]interface{}) diff --git a/lib/result/result.go b/lib/result/result.go index bec839d7a..56a9ffab7 100644 --- a/lib/result/result.go +++ b/lib/result/result.go @@ -30,6 +30,12 @@ func Wrap[T any](value T, err error) Result[T] { } } -func (r *Result[T]) Unwrap() (T, error) { +func (r Result[T]) Unwrap() (T, error) { return r.Value, r.Error } + +func (r Result[T]) Assert(noErrFn func(err error, msgAndArgs ...interface{})) T { + noErrFn(r.Error) + + return r.Value +} diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 83ea6fcd5..938631d43 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -77,7 +77,7 @@ type EthEventAPI interface { EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error) - EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) + EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) } @@ -1103,7 +1103,12 @@ const ( EthSubscribeEventTypeLogs = "logs" ) -func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (ethtypes.EthSubscriptionID, error) { +func (e *EthEvent) EthSubscribe(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) { + params, err := jsonrpc.DecodeParams[ethtypes.EthSubscribeParams](p) + if err != nil { + return ethtypes.EthSubscriptionID{}, xerrors.Errorf("decoding params: %w", err) + } + if e.SubManager == nil { return ethtypes.EthSubscriptionID{}, api.ErrNotSupported } @@ -1118,7 +1123,7 @@ func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *e return ethtypes.EthSubscriptionID{}, err } - switch eventType { + switch params.EventType { case EthSubscribeEventTypeHeads: f, err := e.TipSetFilterManager.Install(ctx) if err != nil { @@ -1130,13 +1135,13 @@ func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *e case EthSubscribeEventTypeLogs: keys := map[string][][]byte{} - if params != nil { + if params.Params != nil { var err error - keys, err = parseEthTopics(params.Topics) + keys, err = parseEthTopics(params.Params.Topics) if err != nil { // clean up any previous filters added and stop the sub _, _ = e.EthUnsubscribe(ctx, sub.id) - return nil, err + return ethtypes.EthSubscriptionID{}, err } } @@ -1148,7 +1153,7 @@ func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *e } sub.addFilter(ctx, f) default: - return ethtypes.EthSubscriptionID{}, xerrors.Errorf("unsupported event type: %s", eventType) + return ethtypes.EthSubscriptionID{}, xerrors.Errorf("unsupported event type: %s", params.EventType) } return sub.id, nil