From 708618d11c85965008c8ecb65e8c358cfd3bdd2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 13 Dec 2022 18:14:03 +0100 Subject: [PATCH] feat: gateway: eth_ api support --- api/api_gateway.go | 35 +++ api/eth_aliases.go | 44 +++ api/proxy_gen.go | 429 +++++++++++++++++++++++++++++ api/types/rpc.go | 5 + build/buildinfo/gomod.txt | 339 +++++++++++++++++++++++ build/buildinfo/head.txt | 5 + build/buildinfo/status.txt | 2 + build/openrpc/gateway.json.gz | Bin 5163 -> 8486 bytes build/openrpc/miner.json.gz | Bin 16046 -> 16049 bytes build/openrpc/worker.json.gz | Bin 5224 -> 5225 bytes gateway/handler.go | 2 + gateway/node.go | 498 +++------------------------------- gateway/proxy_eth.go | 300 ++++++++++++++++++++ gateway/proxy_fil.go | 482 ++++++++++++++++++++++++++++++++ node/rpc.go | 39 +-- 15 files changed, 1678 insertions(+), 502 deletions(-) create mode 100644 api/eth_aliases.go create mode 100644 api/types/rpc.go create mode 100644 build/buildinfo/gomod.txt create mode 100644 build/buildinfo/head.txt create mode 100644 build/buildinfo/status.txt create mode 100644 gateway/proxy_eth.go create mode 100644 gateway/proxy_fil.go diff --git a/api/api_gateway.go b/api/api_gateway.go index b95299493..c78710026 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -13,6 +13,7 @@ import ( apitypes "github.com/filecoin-project/lotus/api/types" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/types/ethtypes" ) // MODIFYING THE API INTERFACE @@ -69,4 +70,38 @@ type Gateway interface { WalletBalance(context.Context, address.Address) (types.BigInt, error) Version(context.Context) (APIVersion, error) Discover(context.Context) (apitypes.OpenRPCDocument, error) + + EthAccounts(ctx context.Context) ([]ethtypes.EthAddress, error) + EthBlockNumber(ctx context.Context) (ethtypes.EthUint64, error) + EthGetBlockTransactionCountByNumber(ctx context.Context, blkNum ethtypes.EthUint64) (ethtypes.EthUint64, error) + EthGetBlockTransactionCountByHash(ctx context.Context, blkHash ethtypes.EthHash) (ethtypes.EthUint64, error) + EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error) + EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error) + EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) + EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) + EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error) + EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) + EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) + EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) + EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) + EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) + EthChainId(ctx context.Context) (ethtypes.EthUint64, error) + NetVersion(ctx context.Context) (string, error) + NetListening(ctx context.Context) (bool, error) + EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) + EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) + EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint64, newestBlk string, rewardPercentiles []float64) (ethtypes.EthFeeHistory, error) + EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) + EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) + EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) + EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) + EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) + EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) + EthGetFilterLogs(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) + EthNewFilter(ctx context.Context, filter *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) + 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) + EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) } diff --git a/api/eth_aliases.go b/api/eth_aliases.go new file mode 100644 index 000000000..d6e27aa96 --- /dev/null +++ b/api/eth_aliases.go @@ -0,0 +1,44 @@ +package api + +import apitypes "github.com/filecoin-project/lotus/api/types" + +func CrateEthRPCAliases(as apitypes.Aliaser) { + // TODO: maybe use reflect to automatically register all the eth aliases + as.AliasMethod("eth_accounts", "Filecoin.EthAccounts") + as.AliasMethod("eth_blockNumber", "Filecoin.EthBlockNumber") + as.AliasMethod("eth_getBlockTransactionCountByNumber", "Filecoin.EthGetBlockTransactionCountByNumber") + as.AliasMethod("eth_getBlockTransactionCountByHash", "Filecoin.EthGetBlockTransactionCountByHash") + + as.AliasMethod("eth_getBlockByHash", "Filecoin.EthGetBlockByHash") + as.AliasMethod("eth_getBlockByNumber", "Filecoin.EthGetBlockByNumber") + as.AliasMethod("eth_getTransactionByHash", "Filecoin.EthGetTransactionByHash") + as.AliasMethod("eth_getTransactionCount", "Filecoin.EthGetTransactionCount") + as.AliasMethod("eth_getTransactionReceipt", "Filecoin.EthGetTransactionReceipt") + as.AliasMethod("eth_getTransactionByBlockHashAndIndex", "Filecoin.EthGetTransactionByBlockHashAndIndex") + as.AliasMethod("eth_getTransactionByBlockNumberAndIndex", "Filecoin.EthGetTransactionByBlockNumberAndIndex") + + as.AliasMethod("eth_getCode", "Filecoin.EthGetCode") + as.AliasMethod("eth_getStorageAt", "Filecoin.EthGetStorageAt") + as.AliasMethod("eth_getBalance", "Filecoin.EthGetBalance") + as.AliasMethod("eth_chainId", "Filecoin.EthChainId") + as.AliasMethod("eth_feeHistory", "Filecoin.EthFeeHistory") + as.AliasMethod("eth_protocolVersion", "Filecoin.EthProtocolVersion") + as.AliasMethod("eth_maxPriorityFeePerGas", "Filecoin.EthMaxPriorityFeePerGas") + as.AliasMethod("eth_gasPrice", "Filecoin.EthGasPrice") + as.AliasMethod("eth_sendRawTransaction", "Filecoin.EthSendRawTransaction") + as.AliasMethod("eth_estimateGas", "Filecoin.EthEstimateGas") + as.AliasMethod("eth_call", "Filecoin.EthCall") + + as.AliasMethod("eth_getLogs", "Filecoin.EthGetLogs") + as.AliasMethod("eth_getFilterChanges", "Filecoin.EthGetFilterChanges") + as.AliasMethod("eth_getFilterLogs", "Filecoin.EthGetFilterLogs") + as.AliasMethod("eth_newFilter", "Filecoin.EthNewFilter") + as.AliasMethod("eth_newBlockFilter", "Filecoin.EthNewBlockFilter") + as.AliasMethod("eth_newPendingTransactionFilter", "Filecoin.EthNewPendingTransactionFilter") + as.AliasMethod("eth_uninstallFilter", "Filecoin.EthUninstallFilter") + as.AliasMethod("eth_subscribe", "Filecoin.EthSubscribe") + as.AliasMethod("eth_unsubscribe", "Filecoin.EthUnsubscribe") + + as.AliasMethod("net_version", "Filecoin.NetVersion") + as.AliasMethod("net_listening", "Filecoin.NetListening") +} diff --git a/api/proxy_gen.go b/api/proxy_gen.go index d308533e9..67249bb5f 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -619,6 +619,68 @@ type GatewayStruct struct { Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) `` + EthAccounts func(p0 context.Context) ([]ethtypes.EthAddress, error) `` + + EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) `` + + EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) `` + + EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `` + + EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) `` + + EthFeeHistory func(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) `` + + EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `` + + EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) `` + + EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) `` + + EthGetBlockByNumber func(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) `` + + EthGetBlockTransactionCountByHash func(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) `` + + EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) `` + + EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) `` + + EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `` + + EthGetFilterLogs func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `` + + EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) `` + + EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `` + + EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `` + + EthGetTransactionByBlockNumberAndIndex func(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `` + + EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) `` + + EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `` + + EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) `` + + EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) `` + + EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `` + + EthNewFilter func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) `` + + EthNewPendingTransactionFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `` + + EthProtocolVersion func(p0 context.Context) (ethtypes.EthUint64, error) `` + + 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) `` + + EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `` + + EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) `` + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `` @@ -631,6 +693,10 @@ type GatewayStruct struct { MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) `` + NetListening func(p0 context.Context) (bool, error) `` + + NetVersion func(p0 context.Context) (string, error) `` + StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) `` @@ -4009,6 +4075,347 @@ func (s *GatewayStub) Discover(p0 context.Context) (apitypes.OpenRPCDocument, er return *new(apitypes.OpenRPCDocument), ErrNotSupported } +func (s *GatewayStruct) EthAccounts(p0 context.Context) ([]ethtypes.EthAddress, error) { + if s.Internal.EthAccounts == nil { + return *new([]ethtypes.EthAddress), ErrNotSupported + } + return s.Internal.EthAccounts(p0) +} + +func (s *GatewayStub) EthAccounts(p0 context.Context) ([]ethtypes.EthAddress, error) { + return *new([]ethtypes.EthAddress), ErrNotSupported +} + +func (s *GatewayStruct) EthBlockNumber(p0 context.Context) (ethtypes.EthUint64, error) { + if s.Internal.EthBlockNumber == nil { + return *new(ethtypes.EthUint64), ErrNotSupported + } + return s.Internal.EthBlockNumber(p0) +} + +func (s *GatewayStub) EthBlockNumber(p0 context.Context) (ethtypes.EthUint64, error) { + return *new(ethtypes.EthUint64), ErrNotSupported +} + +func (s *GatewayStruct) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) { + if s.Internal.EthCall == nil { + return *new(ethtypes.EthBytes), ErrNotSupported + } + return s.Internal.EthCall(p0, p1, p2) +} + +func (s *GatewayStub) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) { + return *new(ethtypes.EthBytes), ErrNotSupported +} + +func (s *GatewayStruct) EthChainId(p0 context.Context) (ethtypes.EthUint64, error) { + if s.Internal.EthChainId == nil { + return *new(ethtypes.EthUint64), ErrNotSupported + } + return s.Internal.EthChainId(p0) +} + +func (s *GatewayStub) EthChainId(p0 context.Context) (ethtypes.EthUint64, error) { + return *new(ethtypes.EthUint64), ErrNotSupported +} + +func (s *GatewayStruct) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) { + if s.Internal.EthEstimateGas == nil { + return *new(ethtypes.EthUint64), ErrNotSupported + } + return s.Internal.EthEstimateGas(p0, p1) +} + +func (s *GatewayStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) { + return *new(ethtypes.EthUint64), ErrNotSupported +} + +func (s *GatewayStruct) EthFeeHistory(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) { + if s.Internal.EthFeeHistory == nil { + return *new(ethtypes.EthFeeHistory), ErrNotSupported + } + return s.Internal.EthFeeHistory(p0, p1, p2, p3) +} + +func (s *GatewayStub) EthFeeHistory(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) { + return *new(ethtypes.EthFeeHistory), ErrNotSupported +} + +func (s *GatewayStruct) EthGasPrice(p0 context.Context) (ethtypes.EthBigInt, error) { + if s.Internal.EthGasPrice == nil { + return *new(ethtypes.EthBigInt), ErrNotSupported + } + return s.Internal.EthGasPrice(p0) +} + +func (s *GatewayStub) EthGasPrice(p0 context.Context) (ethtypes.EthBigInt, error) { + return *new(ethtypes.EthBigInt), ErrNotSupported +} + +func (s *GatewayStruct) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) { + if s.Internal.EthGetBalance == nil { + return *new(ethtypes.EthBigInt), ErrNotSupported + } + return s.Internal.EthGetBalance(p0, p1, p2) +} + +func (s *GatewayStub) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) { + return *new(ethtypes.EthBigInt), ErrNotSupported +} + +func (s *GatewayStruct) EthGetBlockByHash(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) { + if s.Internal.EthGetBlockByHash == nil { + return *new(ethtypes.EthBlock), ErrNotSupported + } + return s.Internal.EthGetBlockByHash(p0, p1, p2) +} + +func (s *GatewayStub) EthGetBlockByHash(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) { + return *new(ethtypes.EthBlock), ErrNotSupported +} + +func (s *GatewayStruct) EthGetBlockByNumber(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) { + if s.Internal.EthGetBlockByNumber == nil { + return *new(ethtypes.EthBlock), ErrNotSupported + } + return s.Internal.EthGetBlockByNumber(p0, p1, p2) +} + +func (s *GatewayStub) EthGetBlockByNumber(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) { + return *new(ethtypes.EthBlock), ErrNotSupported +} + +func (s *GatewayStruct) EthGetBlockTransactionCountByHash(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) { + if s.Internal.EthGetBlockTransactionCountByHash == nil { + return *new(ethtypes.EthUint64), ErrNotSupported + } + return s.Internal.EthGetBlockTransactionCountByHash(p0, p1) +} + +func (s *GatewayStub) EthGetBlockTransactionCountByHash(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) { + return *new(ethtypes.EthUint64), ErrNotSupported +} + +func (s *GatewayStruct) EthGetBlockTransactionCountByNumber(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) { + if s.Internal.EthGetBlockTransactionCountByNumber == nil { + return *new(ethtypes.EthUint64), ErrNotSupported + } + return s.Internal.EthGetBlockTransactionCountByNumber(p0, p1) +} + +func (s *GatewayStub) EthGetBlockTransactionCountByNumber(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) { + return *new(ethtypes.EthUint64), ErrNotSupported +} + +func (s *GatewayStruct) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) { + if s.Internal.EthGetCode == nil { + return *new(ethtypes.EthBytes), ErrNotSupported + } + return s.Internal.EthGetCode(p0, p1, p2) +} + +func (s *GatewayStub) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) { + return *new(ethtypes.EthBytes), ErrNotSupported +} + +func (s *GatewayStruct) EthGetFilterChanges(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) { + if s.Internal.EthGetFilterChanges == nil { + return nil, ErrNotSupported + } + return s.Internal.EthGetFilterChanges(p0, p1) +} + +func (s *GatewayStub) EthGetFilterChanges(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) { + return nil, ErrNotSupported +} + +func (s *GatewayStruct) EthGetFilterLogs(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) { + if s.Internal.EthGetFilterLogs == nil { + return nil, ErrNotSupported + } + return s.Internal.EthGetFilterLogs(p0, p1) +} + +func (s *GatewayStub) EthGetFilterLogs(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) { + return nil, ErrNotSupported +} + +func (s *GatewayStruct) EthGetLogs(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) { + if s.Internal.EthGetLogs == nil { + return nil, ErrNotSupported + } + return s.Internal.EthGetLogs(p0, p1) +} + +func (s *GatewayStub) EthGetLogs(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) { + return nil, ErrNotSupported +} + +func (s *GatewayStruct) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) { + if s.Internal.EthGetStorageAt == nil { + return *new(ethtypes.EthBytes), ErrNotSupported + } + return s.Internal.EthGetStorageAt(p0, p1, p2, p3) +} + +func (s *GatewayStub) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) { + return *new(ethtypes.EthBytes), ErrNotSupported +} + +func (s *GatewayStruct) EthGetTransactionByBlockHashAndIndex(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) { + if s.Internal.EthGetTransactionByBlockHashAndIndex == nil { + return *new(ethtypes.EthTx), ErrNotSupported + } + return s.Internal.EthGetTransactionByBlockHashAndIndex(p0, p1, p2) +} + +func (s *GatewayStub) EthGetTransactionByBlockHashAndIndex(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) { + return *new(ethtypes.EthTx), ErrNotSupported +} + +func (s *GatewayStruct) EthGetTransactionByBlockNumberAndIndex(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) { + if s.Internal.EthGetTransactionByBlockNumberAndIndex == nil { + return *new(ethtypes.EthTx), ErrNotSupported + } + return s.Internal.EthGetTransactionByBlockNumberAndIndex(p0, p1, p2) +} + +func (s *GatewayStub) EthGetTransactionByBlockNumberAndIndex(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) { + return *new(ethtypes.EthTx), ErrNotSupported +} + +func (s *GatewayStruct) EthGetTransactionByHash(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) { + if s.Internal.EthGetTransactionByHash == nil { + return nil, ErrNotSupported + } + return s.Internal.EthGetTransactionByHash(p0, p1) +} + +func (s *GatewayStub) EthGetTransactionByHash(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) { + return nil, ErrNotSupported +} + +func (s *GatewayStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) { + if s.Internal.EthGetTransactionCount == nil { + return *new(ethtypes.EthUint64), ErrNotSupported + } + return s.Internal.EthGetTransactionCount(p0, p1, p2) +} + +func (s *GatewayStub) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) { + return *new(ethtypes.EthUint64), ErrNotSupported +} + +func (s *GatewayStruct) EthGetTransactionReceipt(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) { + if s.Internal.EthGetTransactionReceipt == nil { + return nil, ErrNotSupported + } + return s.Internal.EthGetTransactionReceipt(p0, p1) +} + +func (s *GatewayStub) EthGetTransactionReceipt(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) { + return nil, ErrNotSupported +} + +func (s *GatewayStruct) EthMaxPriorityFeePerGas(p0 context.Context) (ethtypes.EthBigInt, error) { + if s.Internal.EthMaxPriorityFeePerGas == nil { + return *new(ethtypes.EthBigInt), ErrNotSupported + } + return s.Internal.EthMaxPriorityFeePerGas(p0) +} + +func (s *GatewayStub) EthMaxPriorityFeePerGas(p0 context.Context) (ethtypes.EthBigInt, error) { + return *new(ethtypes.EthBigInt), ErrNotSupported +} + +func (s *GatewayStruct) EthNewBlockFilter(p0 context.Context) (ethtypes.EthFilterID, error) { + if s.Internal.EthNewBlockFilter == nil { + return *new(ethtypes.EthFilterID), ErrNotSupported + } + return s.Internal.EthNewBlockFilter(p0) +} + +func (s *GatewayStub) EthNewBlockFilter(p0 context.Context) (ethtypes.EthFilterID, error) { + return *new(ethtypes.EthFilterID), ErrNotSupported +} + +func (s *GatewayStruct) EthNewFilter(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) { + if s.Internal.EthNewFilter == nil { + return *new(ethtypes.EthFilterID), ErrNotSupported + } + return s.Internal.EthNewFilter(p0, p1) +} + +func (s *GatewayStub) EthNewFilter(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) { + return *new(ethtypes.EthFilterID), ErrNotSupported +} + +func (s *GatewayStruct) EthNewPendingTransactionFilter(p0 context.Context) (ethtypes.EthFilterID, error) { + if s.Internal.EthNewPendingTransactionFilter == nil { + return *new(ethtypes.EthFilterID), ErrNotSupported + } + return s.Internal.EthNewPendingTransactionFilter(p0) +} + +func (s *GatewayStub) EthNewPendingTransactionFilter(p0 context.Context) (ethtypes.EthFilterID, error) { + return *new(ethtypes.EthFilterID), ErrNotSupported +} + +func (s *GatewayStruct) EthProtocolVersion(p0 context.Context) (ethtypes.EthUint64, error) { + if s.Internal.EthProtocolVersion == nil { + return *new(ethtypes.EthUint64), ErrNotSupported + } + return s.Internal.EthProtocolVersion(p0) +} + +func (s *GatewayStub) EthProtocolVersion(p0 context.Context) (ethtypes.EthUint64, error) { + return *new(ethtypes.EthUint64), ErrNotSupported +} + +func (s *GatewayStruct) EthSendRawTransaction(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) { + if s.Internal.EthSendRawTransaction == nil { + return *new(ethtypes.EthHash), ErrNotSupported + } + return s.Internal.EthSendRawTransaction(p0, p1) +} + +func (s *GatewayStub) EthSendRawTransaction(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) { + return *new(ethtypes.EthHash), ErrNotSupported +} + +func (s *GatewayStruct) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) { + if s.Internal.EthSubscribe == nil { + return nil, 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 *GatewayStruct) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) { + if s.Internal.EthUninstallFilter == nil { + return false, ErrNotSupported + } + return s.Internal.EthUninstallFilter(p0, p1) +} + +func (s *GatewayStub) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) { + return false, ErrNotSupported +} + +func (s *GatewayStruct) EthUnsubscribe(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) { + if s.Internal.EthUnsubscribe == nil { + return false, ErrNotSupported + } + return s.Internal.EthUnsubscribe(p0, p1) +} + +func (s *GatewayStub) EthUnsubscribe(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) { + return false, ErrNotSupported +} + func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { if s.Internal.GasEstimateMessageGas == nil { return nil, ErrNotSupported @@ -4075,6 +4482,28 @@ func (s *GatewayStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Addr return *new(MsigVesting), ErrNotSupported } +func (s *GatewayStruct) NetListening(p0 context.Context) (bool, error) { + if s.Internal.NetListening == nil { + return false, ErrNotSupported + } + return s.Internal.NetListening(p0) +} + +func (s *GatewayStub) NetListening(p0 context.Context) (bool, error) { + return false, ErrNotSupported +} + +func (s *GatewayStruct) NetVersion(p0 context.Context) (string, error) { + if s.Internal.NetVersion == nil { + return "", ErrNotSupported + } + return s.Internal.NetVersion(p0) +} + +func (s *GatewayStub) NetVersion(p0 context.Context) (string, error) { + return "", ErrNotSupported +} + func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { if s.Internal.StateAccountKey == nil { return *new(address.Address), ErrNotSupported diff --git a/api/types/rpc.go b/api/types/rpc.go new file mode 100644 index 000000000..4bde6dfbc --- /dev/null +++ b/api/types/rpc.go @@ -0,0 +1,5 @@ +package apitypes + +type Aliaser interface { + AliasMethod(alias, original string) +} diff --git a/build/buildinfo/gomod.txt b/build/buildinfo/gomod.txt new file mode 100644 index 000000000..0fe5f1948 --- /dev/null +++ b/build/buildinfo/gomod.txt @@ -0,0 +1,339 @@ +module github.com/filecoin-project/lotus + +go 1.18 + +retract v1.14.0 // Accidentally force-pushed tag, use v1.14.1+ instead. + +require ( + contrib.go.opencensus.io/exporter/prometheus v0.4.0 + github.com/BurntSushi/toml v1.1.0 + github.com/DataDog/zstd v1.4.1 + github.com/GeertJohan/go.rice v1.0.2 + github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee + github.com/Kubuxu/imtui v0.0.0-20210401140320-41663d68d0fa + github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d + github.com/alecthomas/jsonschema v0.0.0-20200530073317-71f438968921 + github.com/buger/goterm v1.0.3 + github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e + github.com/containerd/cgroups v1.0.4 + github.com/coreos/go-systemd/v22 v22.3.2 + github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e + github.com/dgraph-io/badger/v2 v2.2007.3 + github.com/docker/go-units v0.4.0 + github.com/drand/drand v1.3.0 + github.com/drand/kyber v1.1.7 + github.com/dustin/go-humanize v1.0.0 + github.com/elastic/go-sysinfo v1.7.0 + github.com/elastic/gosigar v0.14.2 + github.com/etclabscore/go-openrpc-reflect v0.0.36 + github.com/fatih/color v1.13.0 + github.com/filecoin-project/dagstore v0.5.2 + github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200910194244-f640612a1a1f + github.com/filecoin-project/go-address v1.0.0 + github.com/filecoin-project/go-bitfield v0.2.4 + github.com/filecoin-project/go-cbor-util v0.0.1 + github.com/filecoin-project/go-commp-utils v0.1.3 + github.com/filecoin-project/go-crypto v0.0.1 + github.com/filecoin-project/go-data-transfer v1.15.2 + 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.24.0 + github.com/filecoin-project/go-jsonrpc v0.1.8 + 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 + github.com/filecoin-project/go-state-types v0.1.12-beta + github.com/filecoin-project/go-statemachine v1.0.2 + github.com/filecoin-project/go-statestore v0.2.0 + github.com/filecoin-project/go-storedcounter v0.1.0 + github.com/filecoin-project/index-provider v0.8.1 + github.com/filecoin-project/pubsub v1.0.0 + github.com/filecoin-project/specs-actors v0.9.15 + github.com/filecoin-project/specs-actors/v2 v2.3.6 + github.com/filecoin-project/specs-actors/v3 v3.1.2 + github.com/filecoin-project/specs-actors/v4 v4.0.2 + github.com/filecoin-project/specs-actors/v5 v5.0.6 + github.com/filecoin-project/specs-actors/v6 v6.0.2 + github.com/filecoin-project/specs-actors/v7 v7.0.1 + github.com/filecoin-project/specs-actors/v8 v8.0.1 + github.com/filecoin-project/test-vectors/schema v0.0.5 + github.com/gbrlsnchs/jwt/v3 v3.0.1 + github.com/gdamore/tcell/v2 v2.2.0 + github.com/go-kit/kit v0.12.0 + github.com/golang/mock v1.6.0 + github.com/google/uuid v1.3.0 + github.com/gorilla/mux v1.7.4 + github.com/gorilla/websocket v1.5.0 + github.com/hako/durafmt v0.0.0-20200710122514-c0fb7b4da026 + github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e + github.com/hashicorp/go-multierror v1.1.1 + github.com/hashicorp/golang-lru v0.5.4 + github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94 + github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab + github.com/ipfs/bbloom v0.0.4 + github.com/ipfs/go-bitswap v0.10.2 + github.com/ipfs/go-block-format v0.0.3 + github.com/ipfs/go-blockservice v0.4.0 + github.com/ipfs/go-cid v0.2.0 + github.com/ipfs/go-cidutil v0.1.0 + github.com/ipfs/go-datastore v0.5.1 + github.com/ipfs/go-ds-badger2 v0.1.2 + github.com/ipfs/go-ds-leveldb v0.5.0 + github.com/ipfs/go-ds-measure v0.2.0 + github.com/ipfs/go-fs-lock v0.0.7 + github.com/ipfs/go-graphsync v0.13.1 + github.com/ipfs/go-ipfs-blockstore v1.2.0 + github.com/ipfs/go-ipfs-blocksutil v0.0.1 + github.com/ipfs/go-ipfs-chunker v0.0.5 + github.com/ipfs/go-ipfs-ds-help v1.1.0 + github.com/ipfs/go-ipfs-exchange-interface v0.2.0 + github.com/ipfs/go-ipfs-exchange-offline v0.3.0 + github.com/ipfs/go-ipfs-files v0.1.1 + github.com/ipfs/go-ipfs-http-client v0.4.0 + github.com/ipfs/go-ipfs-routing v0.2.1 + github.com/ipfs/go-ipfs-util v0.0.2 + github.com/ipfs/go-ipld-cbor v0.0.6 + github.com/ipfs/go-ipld-format v0.4.0 + github.com/ipfs/go-log/v2 v2.5.1 + github.com/ipfs/go-merkledag v0.8.0 + github.com/ipfs/go-metrics-interface v0.0.1 + github.com/ipfs/go-metrics-prometheus v0.0.2 + github.com/ipfs/go-unixfs v0.3.1 + github.com/ipfs/go-unixfsnode v1.4.0 + github.com/ipfs/interface-go-ipfs-core v0.7.0 + github.com/ipld/go-car v0.4.0 + github.com/ipld/go-car/v2 v2.4.1 + github.com/ipld/go-codec-dagpb v1.3.2 + github.com/ipld/go-ipld-prime v0.17.0 + github.com/ipld/go-ipld-selector-text-lite v0.0.1 + github.com/kelseyhightower/envconfig v1.4.0 + github.com/koalacxr/quantile v0.0.1 + github.com/libp2p/go-buffer-pool v0.1.0 + github.com/libp2p/go-libp2p v0.22.0 + github.com/libp2p/go-libp2p-kad-dht v0.18.0 + github.com/libp2p/go-libp2p-peerstore v0.8.0 + github.com/libp2p/go-libp2p-pubsub v0.8.0 + github.com/libp2p/go-libp2p-record v0.2.0 + github.com/libp2p/go-libp2p-routing-helpers v0.2.3 + github.com/libp2p/go-maddr-filter v0.1.0 + github.com/mattn/go-isatty v0.0.16 + github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 + github.com/mitchellh/go-homedir v1.1.0 + github.com/multiformats/go-base32 v0.0.4 + github.com/multiformats/go-multiaddr v0.6.0 + github.com/multiformats/go-multiaddr-dns v0.3.1 + github.com/multiformats/go-multibase v0.1.1 + github.com/multiformats/go-multihash v0.2.1 + github.com/multiformats/go-varint v0.0.6 + github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333 + github.com/opentracing/opentracing-go v1.2.0 + github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e + github.com/prometheus/client_golang v1.12.1 + github.com/raulk/clock v1.1.0 + github.com/raulk/go-watchdog v1.3.0 + github.com/stretchr/testify v1.8.0 + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/urfave/cli/v2 v2.8.1 + github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba + github.com/whyrusleeping/cbor-gen v0.0.0-20220514204315-f29c37e9c44c + github.com/whyrusleeping/ledger-filecoin-go v0.9.1-0.20201010031517-c3dcc1bddce4 + github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 + github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 + go.opencensus.io v0.23.0 + go.opentelemetry.io/otel v1.7.0 + go.opentelemetry.io/otel/bridge/opencensus v0.25.0 + go.opentelemetry.io/otel/exporters/jaeger v1.2.0 + go.opentelemetry.io/otel/sdk v1.2.0 + go.uber.org/fx v1.15.0 + go.uber.org/multierr v1.8.0 + go.uber.org/zap v1.22.0 + golang.org/x/net v0.0.0-20220812174116-3211cb980234 + golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac + golang.org/x/tools v0.1.12 + golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f + gopkg.in/cheggaaa/pb.v1 v1.0.28 + gotest.tools v2.2.0+incompatible +) + +require ( + github.com/GeertJohan/go.incremental v1.0.0 // indirect + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect + github.com/Stebalien/go-bitfield v0.0.1 // indirect + github.com/akavel/rsrc v0.8.0 // indirect + github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/benbjohnson/clock v1.3.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bep/debounce v1.2.0 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cheekybits/genny v1.0.0 // indirect + github.com/cilium/ebpf v0.4.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect + github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect + github.com/cskr/pubsub v1.0.2 // indirect + github.com/daaku/go.zipexe v1.0.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/dgraph-io/ristretto v0.1.0 // indirect + github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect + github.com/drand/kyber-bls12381 v0.2.1 // indirect + github.com/elastic/go-windows v1.0.0 // indirect + github.com/etclabscore/go-jsonschema-walk v0.0.6 // indirect + github.com/filecoin-project/go-amt-ipld/v2 v2.1.0 // indirect + github.com/filecoin-project/go-amt-ipld/v3 v3.1.0 // indirect + github.com/filecoin-project/go-amt-ipld/v4 v4.0.0 // indirect + github.com/filecoin-project/go-commp-utils/nonffi v0.0.0-20220905160352-62059082a837 // indirect + github.com/filecoin-project/go-ds-versioning v0.1.1 // indirect + github.com/filecoin-project/go-hamt-ipld v0.1.5 // indirect + github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 // indirect + github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0 // indirect + github.com/filecoin-project/storetheindex v0.4.17 // indirect + github.com/flynn/noise v1.0.0 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/gdamore/encoding v1.0.0 // indirect + github.com/go-kit/log v0.2.0 // indirect + github.com/go-logfmt/logfmt v0.5.1 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.5 // indirect + github.com/go-openapi/jsonpointer v0.19.3 // indirect + github.com/go-openapi/jsonreference v0.19.4 // indirect + github.com/go-openapi/spec v0.19.11 // indirect + github.com/go-openapi/swag v0.19.11 // indirect + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v1.0.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/go-cmp v0.5.8 // indirect + github.com/google/gopacket v1.1.19 // indirect + github.com/hannahhoward/cbor-gen-for v0.0.0-20200817222906-ea96cece81f1 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/huin/goupnp v1.0.3 // indirect + github.com/iancoleman/orderedmap v0.1.0 // indirect + github.com/ipfs/go-bitfield v1.0.0 // indirect + github.com/ipfs/go-filestore v1.2.0 // indirect + github.com/ipfs/go-ipfs-cmds v0.7.0 // indirect + github.com/ipfs/go-ipfs-config v0.18.0 // indirect + github.com/ipfs/go-ipfs-delay v0.0.1 // indirect + github.com/ipfs/go-ipfs-posinfo v0.0.1 // indirect + github.com/ipfs/go-ipfs-pq v0.0.2 // indirect + github.com/ipfs/go-ipld-legacy v0.1.1 // indirect + github.com/ipfs/go-ipns v0.2.0 // indirect + github.com/ipfs/go-log v1.0.5 // indirect + github.com/ipfs/go-path v0.3.0 // indirect + github.com/ipfs/go-peertaskqueue v0.7.1 // indirect + github.com/ipfs/go-verifcid v0.0.1 // indirect + github.com/ipsn/go-secp256k1 v0.0.0-20180726113642-9d62b9f0bc52 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect + github.com/jbenet/goprocess v0.1.4 // indirect + github.com/jessevdk/go-flags v1.4.0 // indirect + github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect + github.com/jonboulle/clockwork v0.2.2 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/jpillora/backoff v1.0.0 // indirect + github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391 // indirect + github.com/klauspost/compress v1.15.1 // indirect + github.com/klauspost/cpuid/v2 v2.1.0 // indirect + github.com/koron/go-ssdp v0.0.3 // indirect + github.com/libp2p/go-cidranger v1.1.0 // indirect + github.com/libp2p/go-flow-metrics v0.1.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-connmgr v0.4.0 // indirect + github.com/libp2p/go-libp2p-core v0.20.0 // indirect + github.com/libp2p/go-libp2p-gostream v0.4.0 // indirect + github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect + github.com/libp2p/go-libp2p-noise v0.5.0 // indirect + github.com/libp2p/go-libp2p-tls v0.5.0 // indirect + github.com/libp2p/go-msgio v0.2.0 // indirect + github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-netroute v0.2.0 // indirect + github.com/libp2p/go-openssl v0.1.0 // indirect + github.com/libp2p/go-reuseport v0.2.0 // indirect + github.com/libp2p/go-yamux/v3 v3.1.2 // indirect + github.com/lucas-clemente/quic-go v0.28.1 // indirect + github.com/lucasb-eyer/go-colorful v1.0.3 // indirect + github.com/magefile/mage v1.9.0 // indirect + github.com/mailru/easyjson v0.7.6 // indirect + github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect + github.com/marten-seemann/qtls-go1-17 v0.1.2 // indirect + github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect + github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect + github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect + github.com/mattn/go-colorable v0.1.9 // indirect + github.com/mattn/go-pointer v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.10 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/miekg/dns v1.1.50 // indirect + github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect + github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect + github.com/multiformats/go-multicodec v0.5.0 // indirect + github.com/multiformats/go-multistream v0.3.3 // indirect + github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c // indirect + github.com/nkovacs/streamquote v1.0.0 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/onsi/ginkgo v1.16.5 // indirect + github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect + github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/statsd_exporter v0.21.0 // indirect + github.com/rivo/uniseg v0.1.0 // indirect + github.com/rs/cors v1.7.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/shirou/gopsutil v2.18.12+incompatible // indirect + github.com/sirupsen/logrus v1.8.1 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.0.1 // indirect + github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect + github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect + github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect + github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 // indirect + github.com/zondax/ledger-go v0.12.1 // indirect + go.opentelemetry.io/otel/metric v0.25.0 // indirect + go.opentelemetry.io/otel/sdk/export/metric v0.25.0 // indirect + go.opentelemetry.io/otel/trace v1.7.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/dig v1.12.0 // indirect + go4.org v0.0.0-20200411211856-f5505b9728dd // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5 // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4 // indirect + google.golang.org/grpc v1.45.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect + lukechampine.com/blake3 v1.1.7 // indirect +) + +replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi + +replace github.com/filecoin-project/test-vectors => ./extern/test-vectors diff --git a/build/buildinfo/head.txt b/build/buildinfo/head.txt new file mode 100644 index 000000000..395bba07a --- /dev/null +++ b/build/buildinfo/head.txt @@ -0,0 +1,5 @@ +commit 2f35a39e435c52270a2d6a4c376325569f3de06a +Author: Ɓukasz Magiera +Date: Tue Oct 11 10:59:27 2022 +0200 + + cli docsgen diff --git a/build/buildinfo/status.txt b/build/buildinfo/status.txt new file mode 100644 index 000000000..f805d1611 --- /dev/null +++ b/build/buildinfo/status.txt @@ -0,0 +1,2 @@ +On branch feat/buildinfo +nothing to commit (use -u to show untracked files) diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index 9277b2d1fff4f246d1a08c9cf1fa492c7fb5b657..daeddd75400eadc583cdfa995306979e58c97a78 100644 GIT binary patch literal 8486 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 E0U}w84*&oF literal 5163 zcmV+`6x8b+1hFE?3)b};Sn)= zzf6Xh1I?cKo-p4tuKOp(QUAhhm@`N{L~zifb-2@dZNr&)*D$A$O^EH8y)VB^45qy6 zTjW5CAiQ%j0SKQ%cI*)A<`Q}y7(>r&m^Sn*id-h(egFP_Oupigk1gYcXS_NG4Bmpp zfKlIKFO6IvFWjbK5zOG6?VN~z8;095EM)JTAp529;#H!3!+?|$`qKFI6@O)DWOzFl zm_dqxlRr!2k3S5I9MS$OqmcO&^Cu1CjM6K@2EOYO%Am~~-0{D{Hme}NaGQLpFTdiu zulW1-?`FgF{OJ_Xh1oMdP9TK_pwPgC84Jh^fER{Erc;QSXN(9n*aUfo!1|8aFkL{w zRN%^|9Q(t?YnON^KyLUtu{&-nvjZX45;NgHtO=X~nJ5BOV`f~~5HmDFkY-?=AlsnO zrO*pz3=9uCqt~L%5aF@dHp~oQ+Z1{pv<IharoqXTy$n1E=l}GXKZ*7i8-G7*0oUG3ss6^9G}my zX*SGr;Jrsv#LV7d@Z&9nC%}zg_9>hqe;Pix3`o}OwHjtWBueu?*lGTEa6GZ_zb5dn zKmITq=E=n=pL%jfhC|ne;~DLsu0=d}%O(qNyf?p@yZ?-E`*vjg+@H?clPS4jw?lh= z1Lj@NyyK`HK+C;JtULU{2YCi4XqW>u#z4r1U*^YvLfZ}V6flrC`rXEN-~`zlWHJsB z*mfY^fYYbMg_I$_wE;IZOjml8BKlt@VsIM#M+1bQgcV%`=bL2s16qtDQKE$kT|=6R z1uyoe!$8=Et;64UNg~r7DWXS}aY6=AX&TY?FLMfQ6iA{W!hkN$utjVx895<%aKFo2 zhuuS&c_$cAcO@ZDYIlnS!0Kh)<#Z1p07}6k;GBTeB{F-Qs%m1L6aSeOm|12_xIYRgwJc&;hyB~&>_R!DexGiyTC=e zE+zBD|BoTw8I%8e-#O^M;cF`PAzn(ztt46u);+PVtcrtVr=; zcZEoa*vzoK3i*dkH%k8TbnEEI?>7OrJ35je*dpN+zgCe>&ma__=Q-E5bZtx1r)OsF zAC@cKKA;e@bx$O_1tirOjZyt6rC z9H(Zl*)XpI`pwrC=fL~q@hKlR%(EHa*lR-Aru1cX{gIrDo@|d7uju^=45&1YP+7?@ zdj@Ldu(e99ut{}g!X`y3M2;c<2^S5+ZKt0J_3{n^`(y&Js(ZvH<*FoxS5bikYvOC* zbKWM^kwTxU;yD{#3&KVjveQFVp2JfBT# zqi}ScsM^z46o<`rxuPgIEL2n#qPL>5sB&m4T5j~vYB}d^^C4=PrhS}LA9dfKQSDv~E)h{Wh;F0m#Bwr52VBMpBK(k8jMZL~s@xLqB`Sh{XWFjv82 z19=88mQ5r+Yc*TVmZW0CHnl}qOV6hzJ=3O`^gy@W*{0_MpjeQS7Q(9InF>8rg zOU$P&F*|!D67wDKJ`8_U5|g6q>NBw+AkJ0 zU^aZXTH^4Lq}lL(5a35HGrId_G6Mp;n#6#>-o&K?4rgv*Qy#ul|{xMilHAhDdY z-SF{h!IjNfsye@Il_-Y=nV6@@v&bxmGFM2Gs9(ON2wWu0pbsv@*Zq@IV)>jW%j8J} zu|$>>fz^^O(#*HPnk-sVHsV&?P{qd7sg~8=Y3+_7hLltBAMIwl`MTA5-EMzu9`xGn zUbp?ax!-Fxlf|^YH8M52IJdfham4o%X$(8Bijx%tXDQ?=JYII}Hk$<*Z0Eo`^B9@} z2E&xhbD*6UoeQK$<)`n`x^3fC_+tREJ#eAbFx*aY%v|9fQ0{~_;u{t%H42&Ysc)0* zP~Y^dZ+g}@J%9I2&$4r&wD42p(MvFY3nO;B^v0ijWb22L!R=s#U=BwrE0xAtNZ4^ zzrt)?SF%Yv(Tbb6JM6=rAVQ3K5_kg!K z@*xv&0V0<#752P&Pusnv!mv|tp(Et(KE#0yP)!Dgz1I_cU%tKK;674-Jz%jwW3Ci{ z;mGC17gAuWNWXZ6wa}}D-h&oDNKtQI1%zx9C5&>H_%IzKkOKjVuKkhgQZnNUiK(i3 zg@hQI>USJ69uiA^A42&4t6fMP&-Agln@_$-M7P;3xOx-H?!TeOCtOXniOy?iwu0OX zO+#Ny;~vfXjWqQ}F4xfWc2;fPfjYAw40E z0~n;hIVL`~wJ)!%1Xxz*sSj)$+I<8qI6yzeZ5C14BsYq}he?B9DKpFFRw707#?lw1 zD-g4_(UWIogq4ei$ z)INk0VOFn~a%%PyQ(vuSK_!krc)v#;yF?h$YJOAPUHz*BU%u%^jp9*C6Q|aW8zok= zZMSV|&7hNpv?>mh*FpiGOT$1tTj+^rv$R?Tl|=+c5pv_Z7pK*POW65gL)6iz_Zgs; zR#uzLwaHwEryrfvYZu&24%qt=&>P4q-qXoKSThqt2DMW9C0du|VaVu8wG^zS z-~(o1l=5f#txD+N%(E!D4PEm0#JYiYl?ZJFM%RyyMts(B+E%CF0;MEz28>WJ4oee(E^NqR6jl5;2Vijb_ZAqxpaFYzNi{s?KHTmJG%Q1^~orJp=#%fHX&E=pcg;iw9VS>!;v zg0}_3Ucp-#>=nGtK#mIm94``31Odh`ugDZ(2*Ym*X&ST%$l8e&*(K{llcW`^7y%)| zbSEioVa51UA|oW1##E-C<;0B@WRRIn0$Qn(LK?OtRdlBr$}DYDJrq5^a@>VNR;y4E zBgIx(%Q~0I@|vajTzADO_E)OpxD+7k6SXXHRmLt8#G3tM$*wO3Hq zBQ}xyrV7V^)SQN(=?25i@;Yi)p>`D>GO}FEg2{J^mocIay4^aD48KVK83(`5U!XxlLKf?of*K`Q4h4GM&Gpd%&e`}qqQD= zKs_3>LspL_-YMO=@hOFvrDJ0h5j!~ZSU$VJHk^w%)CU*FF`N^JcrgAo0geOlIDQhu z5l(zYMx*7k&w*-$lU zSBDo+Me!$~GwtrFl*U2j1iUR3JO^cEY_1`&MJ7oVnX~M@rh9V~CYZ3*w*!_#ZqBEX zS5fZB)SgK#)yh4Sn3A)eN#dP~XOg^TzuDRVQTmwnVe-RXv|o|s_8dN(-#RQS{xX1o zT9Zpp`$Htj-ir2OAi$U3qI5gKC4-X*Ksa#O8iv~qijM{7JlUtm$TTMOqUlX zR|w-XtWC!47p|omss47|@BDUMS+TaHIJn1pcdce?0~ckwzp3C|{^4LGFLTZYrB|BY zw%v@ia1AYpTqaVw5EHt*$)9uSoBxfQbKrdnGN%q3=GlyM*EJz*Q**kD20w)sH)9&6 z5TYC7k4=fkhWQSn@q|?iwMKo_zQwcLbv+|X+FhO8zQmsDjTjS=;-_;zDd*rtBv~mp zF7Gf`CNmu~G^WUBeJ8fvDl7gZlFH5@t9+9o0YN7Y!F84BEYwXw!Q59x=8L?F`5E~&YE4t4ONV=1UYddXdnt% zlTmmF0yxm#=xtzeJ6*a+eq=E;OI|q0xr4yFeGcu6AkrjXM@+m3zrfLVpgo51bqQ!O zXrF?`HM|AXPCbuqNXmV#q3Zw(+5$yK(ph=*CJjxr{1YxVim(CV+x6E`^`tf#!z$Lv za*L!Kegy%t8gM$NU*0?I3&q(jtqLNw`xU@wrOc-YR6BbvOMO*ANTjWH$95?jRGTk_ zhh{`I#Yt6qM?y_$s!1NpOZ?1}H_zKRN;4dFva?IOW*~}|3nyXub^z*XW%%M zYtkn=D+Z}v8ZShg;uwuDFe_ut1o#pLmEmczXnOwJc6Vj#!cTdUMaF(XNNV}Aj-RCY Za(~afyZd(czW@LL|NnxNSM*r;003*~|2F^t diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 3937893cb81dee4fc332d9b0d4bb2aa2197fbd93..4f67b5393c45ac4f20fd5d09cab5b6b0e4c22634 100644 GIT binary patch literal 16049 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 z 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 literal 16046 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 diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 3ecfb6abfc95b8aab44241269114d81d897585ab..88e4498042fb5a85b47d9ac54f2a3c511dcb3231 100644 GIT binary patch delta 2947 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 delta 2947 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 diff --git a/gateway/handler.go b/gateway/handler.go index be824b430..52b19b717 100644 --- a/gateway/handler.go +++ b/gateway/handler.go @@ -34,6 +34,8 @@ func Handler(gwapi lapi.Gateway, api lapi.FullNode, rateLimit int64, connPerMinu rpcServer.Register("Filecoin", hnd) rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover") + lapi.CrateEthRPCAliases(rpcServer) + m.Handle(path, rpcServer) } diff --git a/gateway/node.go b/gateway/node.go index 13ac57c82..f58705056 100644 --- a/gateway/node.go +++ b/gateway/node.go @@ -9,21 +9,17 @@ import ( "github.com/ipfs/go-cid" "go.opencensus.io/stats" "golang.org/x/time/rate" - "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/dline" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" - apitypes "github.com/filecoin-project/lotus/api/types" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/sigs" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/delegated" _ "github.com/filecoin-project/lotus/lib/sigs/secp" @@ -88,7 +84,40 @@ type TargetAPI interface { StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error) - WalletBalance(context.Context, address.Address) (types.BigInt, error) //perm:read + WalletBalance(context.Context, address.Address) (types.BigInt, error) + + EthBlockNumber(ctx context.Context) (api.EthUint64, error) + EthGetBlockTransactionCountByNumber(ctx context.Context, blkNum api.EthUint64) (api.EthUint64, error) + EthGetBlockTransactionCountByHash(ctx context.Context, blkHash api.EthHash) (api.EthUint64, error) + EthGetBlockByHash(ctx context.Context, blkHash api.EthHash, fullTxInfo bool) (api.EthBlock, error) + EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (api.EthBlock, error) + EthGetTransactionByHash(ctx context.Context, txHash *api.EthHash) (*api.EthTx, error) + EthGetTransactionCount(ctx context.Context, sender api.EthAddress, blkOpt string) (api.EthUint64, error) + EthGetTransactionReceipt(ctx context.Context, txHash api.EthHash) (*api.EthTxReceipt, error) + EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash api.EthHash, txIndex api.EthUint64) (api.EthTx, error) + EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum api.EthUint64, txIndex api.EthUint64) (api.EthTx, error) + EthGetCode(ctx context.Context, address api.EthAddress, blkOpt string) (api.EthBytes, error) + EthGetStorageAt(ctx context.Context, address api.EthAddress, position api.EthBytes, blkParam string) (api.EthBytes, error) + EthGetBalance(ctx context.Context, address api.EthAddress, blkParam string) (api.EthBigInt, error) + EthChainId(ctx context.Context) (api.EthUint64, error) + NetVersion(ctx context.Context) (string, error) + NetListening(ctx context.Context) (bool, error) + EthProtocolVersion(ctx context.Context) (api.EthUint64, error) + EthGasPrice(ctx context.Context) (api.EthBigInt, error) + EthFeeHistory(ctx context.Context, blkCount api.EthUint64, newestBlk string, rewardPercentiles []float64) (api.EthFeeHistory, error) + EthMaxPriorityFeePerGas(ctx context.Context) (api.EthBigInt, error) + EthEstimateGas(ctx context.Context, tx api.EthCall) (api.EthUint64, error) + EthCall(ctx context.Context, tx api.EthCall, blkParam string) (api.EthBytes, error) + EthSendRawTransaction(ctx context.Context, rawTx api.EthBytes) (api.EthHash, error) + EthGetLogs(ctx context.Context, filter *api.EthFilterSpec) (*api.EthFilterResult, error) + EthGetFilterChanges(ctx context.Context, id api.EthFilterID) (*api.EthFilterResult, error) + EthGetFilterLogs(ctx context.Context, id api.EthFilterID) (*api.EthFilterResult, error) + EthNewFilter(ctx context.Context, filter *api.EthFilterSpec) (api.EthFilterID, error) + EthNewBlockFilter(ctx context.Context) (api.EthFilterID, error) + EthNewPendingTransactionFilter(ctx context.Context) (api.EthFilterID, error) + EthUninstallFilter(ctx context.Context, id api.EthFilterID) (bool, error) + EthSubscribe(ctx context.Context, eventType string, params *api.EthSubscriptionParams) (<-chan api.EthSubscriptionResponse, error) + EthUnsubscribe(ctx context.Context, id api.EthSubscriptionID) (bool, error) } var _ TargetAPI = *new(api.FullNode) // gateway depends on latest @@ -184,462 +213,3 @@ func (gw *Node) limit(ctx context.Context, tokens int) error { } return nil } - -func (gw *Node) Discover(ctx context.Context) (apitypes.OpenRPCDocument, error) { - return build.OpenRPCDiscoverJSON_Gateway(), nil -} - -func (gw *Node) Version(ctx context.Context) (api.APIVersion, error) { - if err := gw.limit(ctx, basicRateLimitTokens); err != nil { - return api.APIVersion{}, err - } - return gw.target.Version(ctx) -} - -func (gw *Node) ChainGetParentMessages(ctx context.Context, c cid.Cid) ([]api.Message, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - return gw.target.ChainGetParentMessages(ctx, c) -} - -func (gw *Node) ChainGetParentReceipts(ctx context.Context, c cid.Cid) ([]*types.MessageReceipt, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - return gw.target.ChainGetParentReceipts(ctx, c) -} - -func (gw *Node) ChainGetBlockMessages(ctx context.Context, c cid.Cid) (*api.BlockMessages, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - return gw.target.ChainGetBlockMessages(ctx, c) -} - -func (gw *Node) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return false, err - } - return gw.target.ChainHasObj(ctx, c) -} - -func (gw *Node) ChainHead(ctx context.Context) (*types.TipSet, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - - return gw.target.ChainHead(ctx) -} - -func (gw *Node) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - return gw.target.ChainGetMessage(ctx, mc) -} - -func (gw *Node) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - return gw.target.ChainGetTipSet(ctx, tsk) -} - -func (gw *Node) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipSetHeight(ctx, h, tsk); err != nil { - return nil, err - } - return gw.target.ChainGetTipSetByHeight(ctx, h, tsk) -} - -func (gw *Node) ChainGetTipSetAfterHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipSetHeight(ctx, h, tsk); err != nil { - return nil, err - } - return gw.target.ChainGetTipSetAfterHeight(ctx, h, tsk) -} - -func (gw *Node) checkTipSetHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) error { - var ts *types.TipSet - if tsk.IsEmpty() { - head, err := gw.target.ChainHead(ctx) - if err != nil { - return err - } - ts = head - } else { - gts, err := gw.target.ChainGetTipSet(ctx, tsk) - if err != nil { - return err - } - ts = gts - } - - // Check if the tipset key refers to gw tipset that's too far in the past - if err := gw.checkTipset(ts); err != nil { - return err - } - - // Check if the height is too far in the past - if err := gw.checkTipsetHeight(ts, h); err != nil { - return err - } - - return nil -} - -func (gw *Node) ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - return gw.target.ChainGetNode(ctx, p) -} - -func (gw *Node) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - return gw.target.ChainNotify(ctx) -} - -func (gw *Node) ChainGetPath(ctx context.Context, from, to types.TipSetKey) ([]*api.HeadChange, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, from); err != nil { - return nil, xerrors.Errorf("gateway: checking 'from' tipset: %w", err) - } - if err := gw.checkTipsetKey(ctx, to); err != nil { - return nil, xerrors.Errorf("gateway: checking 'to' tipset: %w", err) - } - return gw.target.ChainGetPath(ctx, from, to) -} - -func (gw *Node) ChainGetGenesis(ctx context.Context) (*types.TipSet, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - return gw.target.ChainGetGenesis(ctx) -} - -func (gw *Node) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { - if err := gw.limit(ctx, chainRateLimitTokens); err != nil { - return nil, err - } - return gw.target.ChainReadObj(ctx, c) -} - -func (gw *Node) ChainPutObj(context.Context, blocks.Block) error { - return xerrors.New("not supported") -} - -func (gw *Node) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.GasEstimateMessageGas(ctx, msg, spec, tsk) -} - -func (gw *Node) MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return cid.Cid{}, err - } - // TODO: additional anti-spam checks - return gw.target.MpoolPushUntrusted(ctx, sm) -} - -func (gw *Node) MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) { - if err := gw.limit(ctx, walletRateLimitTokens); err != nil { - return types.BigInt{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return types.NewInt(0), err - } - return gw.target.MsigGetAvailableBalance(ctx, addr, tsk) -} - -func (gw *Node) MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) { - if err := gw.limit(ctx, walletRateLimitTokens); err != nil { - return types.BigInt{}, err - } - if err := gw.checkTipsetKey(ctx, start); err != nil { - return types.NewInt(0), err - } - if err := gw.checkTipsetKey(ctx, end); err != nil { - return types.NewInt(0), err - } - return gw.target.MsigGetVested(ctx, addr, start, end) -} - -func (gw *Node) MsigGetVestingSchedule(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MsigVesting, error) { - if err := gw.limit(ctx, walletRateLimitTokens); err != nil { - return api.MsigVesting{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return api.MsigVesting{}, err - } - return gw.target.MsigGetVestingSchedule(ctx, addr, tsk) -} - -func (gw *Node) MsigGetPending(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.MsigTransaction, error) { - if err := gw.limit(ctx, walletRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.MsigGetPending(ctx, addr, tsk) -} - -func (gw *Node) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return address.Address{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return address.Undef, err - } - return gw.target.StateAccountKey(ctx, addr, tsk) -} - -func (gw *Node) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return api.DealCollateralBounds{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return api.DealCollateralBounds{}, err - } - return gw.target.StateDealProviderCollateralBounds(ctx, size, verified, tsk) -} - -func (gw *Node) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.StateGetActor(ctx, actor, tsk) -} - -func (gw *Node) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.StateListMiners(ctx, tsk) -} - -func (gw *Node) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return address.Address{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return address.Undef, err - } - return gw.target.StateLookupID(ctx, addr, tsk) -} - -func (gw *Node) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return api.MarketBalance{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return api.MarketBalance{}, err - } - return gw.target.StateMarketBalance(ctx, addr, tsk) -} - -func (gw *Node) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.StateMarketStorageDeal(ctx, dealId, tsk) -} - -func (gw *Node) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return network.VersionMax, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return network.VersionMax, err - } - return gw.target.StateNetworkVersion(ctx, tsk) -} - -func (gw *Node) StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if limit == api.LookbackNoLimit { - limit = gw.stateWaitLookbackLimit - } - if gw.stateWaitLookbackLimit != api.LookbackNoLimit && limit > gw.stateWaitLookbackLimit { - limit = gw.stateWaitLookbackLimit - } - if err := gw.checkTipsetKey(ctx, from); err != nil { - return nil, err - } - return gw.target.StateSearchMsg(ctx, from, msg, limit, allowReplaced) -} - -func (gw *Node) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if limit == api.LookbackNoLimit { - limit = gw.stateWaitLookbackLimit - } - if gw.stateWaitLookbackLimit != api.LookbackNoLimit && limit > gw.stateWaitLookbackLimit { - limit = gw.stateWaitLookbackLimit - } - return gw.target.StateWaitMsg(ctx, msg, confidence, limit, allowReplaced) -} - -func (gw *Node) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.StateReadState(ctx, actor, tsk) -} - -func (gw *Node) StateMinerPower(ctx context.Context, m address.Address, tsk types.TipSetKey) (*api.MinerPower, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.StateMinerPower(ctx, m, tsk) -} - -func (gw *Node) StateMinerFaults(ctx context.Context, m address.Address, tsk types.TipSetKey) (bitfield.BitField, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return bitfield.BitField{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return bitfield.BitField{}, err - } - return gw.target.StateMinerFaults(ctx, m, tsk) -} - -func (gw *Node) StateMinerRecoveries(ctx context.Context, m address.Address, tsk types.TipSetKey) (bitfield.BitField, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return bitfield.BitField{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return bitfield.BitField{}, err - } - return gw.target.StateMinerRecoveries(ctx, m, tsk) -} - -func (gw *Node) StateMinerInfo(ctx context.Context, m address.Address, tsk types.TipSetKey) (api.MinerInfo, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return api.MinerInfo{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return api.MinerInfo{}, err - } - return gw.target.StateMinerInfo(ctx, m, tsk) -} - -func (gw *Node) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) ([]api.Deadline, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.StateMinerDeadlines(ctx, m, tsk) -} - -func (gw *Node) StateMinerAvailableBalance(ctx context.Context, m address.Address, tsk types.TipSetKey) (types.BigInt, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return types.BigInt{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return types.BigInt{}, err - } - return gw.target.StateMinerAvailableBalance(ctx, m, tsk) -} - -func (gw *Node) StateMinerProvingDeadline(ctx context.Context, m address.Address, tsk types.TipSetKey) (*dline.Info, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.StateMinerProvingDeadline(ctx, m, tsk) -} - -func (gw *Node) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return abi.TokenAmount{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return abi.TokenAmount{}, err - } - return gw.target.StateCirculatingSupply(ctx, tsk) -} - -func (gw *Node) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.StateSectorGetInfo(ctx, maddr, n, tsk) -} - -func (gw *Node) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return nil, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - return gw.target.StateVerifiedClientStatus(ctx, addr, tsk) -} - -func (gw *Node) StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return api.CirculatingSupply{}, err - } - if err := gw.checkTipsetKey(ctx, tsk); err != nil { - return api.CirculatingSupply{}, err - } - return gw.target.StateVMCirculatingSupplyInternal(ctx, tsk) -} - -func (gw *Node) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return false, err - } - return sigs.Verify(sig, k, msg) == nil, nil -} - -func (gw *Node) WalletBalance(ctx context.Context, k address.Address) (types.BigInt, error) { - if err := gw.limit(ctx, stateRateLimitTokens); err != nil { - return types.BigInt{}, err - } - return gw.target.WalletBalance(ctx, k) -} diff --git a/gateway/proxy_eth.go b/gateway/proxy_eth.go new file mode 100644 index 000000000..8d6980ef1 --- /dev/null +++ b/gateway/proxy_eth.go @@ -0,0 +1,300 @@ +package gateway + +import ( + "context" + + "github.com/filecoin-project/go-state-types/big" + + "github.com/filecoin-project/lotus/api" +) + +func (gw *Node) EthAccounts(ctx context.Context) ([]api.EthAddress, error) { + // gateway provides public API, so it can't hold user accounts + return []api.EthAddress{}, nil +} + +func (gw *Node) EthBlockNumber(ctx context.Context) (api.EthUint64, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return 0, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetBlockTransactionCountByNumber(ctx context.Context, blkNum api.EthUint64) (api.EthUint64, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return 0, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetBlockTransactionCountByHash(ctx context.Context, blkHash api.EthHash) (api.EthUint64, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return 0, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetBlockByHash(ctx context.Context, blkHash api.EthHash, fullTxInfo bool) (api.EthBlock, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthBlock{}, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (api.EthBlock, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthBlock{}, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetTransactionByHash(ctx context.Context, txHash *api.EthHash) (*api.EthTx, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetTransactionCount(ctx context.Context, sender api.EthAddress, blkOpt string) (api.EthUint64, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return 0, err + } + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetTransactionReceipt(ctx context.Context, txHash api.EthHash) (*api.EthTxReceipt, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash api.EthHash, txIndex api.EthUint64) (api.EthTx, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthTx{}, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum api.EthUint64, txIndex api.EthUint64) (api.EthTx, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthTx{}, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetCode(ctx context.Context, address api.EthAddress, blkOpt string) (api.EthBytes, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetStorageAt(ctx context.Context, address api.EthAddress, position api.EthBytes, blkParam string) (api.EthBytes, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetBalance(ctx context.Context, address api.EthAddress, blkParam string) (api.EthBigInt, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthBigInt(big.Zero()), err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthChainId(ctx context.Context) (api.EthUint64, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return 0, err + } + //TODO implement me + panic("implement me") +} + +func (gw *Node) NetVersion(ctx context.Context) (string, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return "", err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) NetListening(ctx context.Context) (bool, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return false, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthProtocolVersion(ctx context.Context) (api.EthUint64, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return 0, err + } + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGasPrice(ctx context.Context) (api.EthBigInt, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthBigInt(big.Zero()), err + } + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthFeeHistory(ctx context.Context, blkCount api.EthUint64, newestBlk string, rewardPercentiles []float64) (api.EthFeeHistory, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthFeeHistory{}, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthMaxPriorityFeePerGas(ctx context.Context) (api.EthBigInt, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthBigInt(big.Zero()), err + } + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthEstimateGas(ctx context.Context, tx api.EthCall) (api.EthUint64, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return 0, err + } + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthCall(ctx context.Context, tx api.EthCall, blkParam string) (api.EthBytes, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthSendRawTransaction(ctx context.Context, rawTx api.EthBytes) (api.EthHash, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthHash{}, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetLogs(ctx context.Context, filter *api.EthFilterSpec) (*api.EthFilterResult, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetFilterChanges(ctx context.Context, id api.EthFilterID) (*api.EthFilterResult, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthGetFilterLogs(ctx context.Context, id api.EthFilterID) (*api.EthFilterResult, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + + //TODO implement me + panic("implement me") +} + +/* FILTERS: Those are stateful.. figure out how to properly either bind them to users, or time out? */ + +func (gw *Node) EthNewFilter(ctx context.Context, filter *api.EthFilterSpec) (api.EthFilterID, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthFilterID{}, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthNewBlockFilter(ctx context.Context) (api.EthFilterID, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthFilterID{}, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthNewPendingTransactionFilter(ctx context.Context) (api.EthFilterID, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.EthFilterID{}, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthUninstallFilter(ctx context.Context, id api.EthFilterID) (bool, error) { + // todo rate limit this? + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return false, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthSubscribe(ctx context.Context, eventType string, params *api.EthSubscriptionParams) (<-chan api.EthSubscriptionResponse, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + + //TODO implement me + panic("implement me") +} + +func (gw *Node) EthUnsubscribe(ctx context.Context, id api.EthSubscriptionID) (bool, error) { + // todo should we actually rate limit this + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return false, err + } + + //TODO implement me + panic("implement me") +} diff --git a/gateway/proxy_fil.go b/gateway/proxy_fil.go new file mode 100644 index 000000000..0e53130fb --- /dev/null +++ b/gateway/proxy_fil.go @@ -0,0 +1,482 @@ +package gateway + +import ( + "context" + + blocks "github.com/ipfs/go-block-format" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/go-state-types/network" + + "github.com/filecoin-project/lotus/api" + apitypes "github.com/filecoin-project/lotus/api/types" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/sigs" +) + +func (gw *Node) Discover(ctx context.Context) (apitypes.OpenRPCDocument, error) { + return build.OpenRPCDiscoverJSON_Gateway(), nil +} + +func (gw *Node) Version(ctx context.Context) (api.APIVersion, error) { + if err := gw.limit(ctx, basicRateLimitTokens); err != nil { + return api.APIVersion{}, err + } + return gw.target.Version(ctx) +} + +func (gw *Node) ChainGetParentMessages(ctx context.Context, c cid.Cid) ([]api.Message, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + return gw.target.ChainGetParentMessages(ctx, c) +} + +func (gw *Node) ChainGetParentReceipts(ctx context.Context, c cid.Cid) ([]*types.MessageReceipt, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + return gw.target.ChainGetParentReceipts(ctx, c) +} + +func (gw *Node) ChainGetBlockMessages(ctx context.Context, c cid.Cid) (*api.BlockMessages, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + return gw.target.ChainGetBlockMessages(ctx, c) +} + +func (gw *Node) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return false, err + } + return gw.target.ChainHasObj(ctx, c) +} + +func (gw *Node) ChainHead(ctx context.Context) (*types.TipSet, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + + return gw.target.ChainHead(ctx) +} + +func (gw *Node) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + return gw.target.ChainGetMessage(ctx, mc) +} + +func (gw *Node) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + return gw.target.ChainGetTipSet(ctx, tsk) +} + +func (gw *Node) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipSetHeight(ctx, h, tsk); err != nil { + return nil, err + } + return gw.target.ChainGetTipSetByHeight(ctx, h, tsk) +} + +func (gw *Node) ChainGetTipSetAfterHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipSetHeight(ctx, h, tsk); err != nil { + return nil, err + } + return gw.target.ChainGetTipSetAfterHeight(ctx, h, tsk) +} + +func (gw *Node) checkTipSetHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) error { + var ts *types.TipSet + if tsk.IsEmpty() { + head, err := gw.target.ChainHead(ctx) + if err != nil { + return err + } + ts = head + } else { + gts, err := gw.target.ChainGetTipSet(ctx, tsk) + if err != nil { + return err + } + ts = gts + } + + // Check if the tipset key refers to gw tipset that's too far in the past + if err := gw.checkTipset(ts); err != nil { + return err + } + + // Check if the height is too far in the past + if err := gw.checkTipsetHeight(ts, h); err != nil { + return err + } + + return nil +} + +func (gw *Node) ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + return gw.target.ChainGetNode(ctx, p) +} + +func (gw *Node) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + return gw.target.ChainNotify(ctx) +} + +func (gw *Node) ChainGetPath(ctx context.Context, from, to types.TipSetKey) ([]*api.HeadChange, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, from); err != nil { + return nil, xerrors.Errorf("gateway: checking 'from' tipset: %w", err) + } + if err := gw.checkTipsetKey(ctx, to); err != nil { + return nil, xerrors.Errorf("gateway: checking 'to' tipset: %w", err) + } + return gw.target.ChainGetPath(ctx, from, to) +} + +func (gw *Node) ChainGetGenesis(ctx context.Context) (*types.TipSet, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + return gw.target.ChainGetGenesis(ctx) +} + +func (gw *Node) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) { + if err := gw.limit(ctx, chainRateLimitTokens); err != nil { + return nil, err + } + return gw.target.ChainReadObj(ctx, c) +} + +func (gw *Node) ChainPutObj(context.Context, blocks.Block) error { + return xerrors.New("not supported") +} + +func (gw *Node) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.GasEstimateMessageGas(ctx, msg, spec, tsk) +} + +func (gw *Node) MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return cid.Cid{}, err + } + // TODO: additional anti-spam checks + return gw.target.MpoolPushUntrusted(ctx, sm) +} + +func (gw *Node) MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) { + if err := gw.limit(ctx, walletRateLimitTokens); err != nil { + return types.BigInt{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return types.NewInt(0), err + } + return gw.target.MsigGetAvailableBalance(ctx, addr, tsk) +} + +func (gw *Node) MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) { + if err := gw.limit(ctx, walletRateLimitTokens); err != nil { + return types.BigInt{}, err + } + if err := gw.checkTipsetKey(ctx, start); err != nil { + return types.NewInt(0), err + } + if err := gw.checkTipsetKey(ctx, end); err != nil { + return types.NewInt(0), err + } + return gw.target.MsigGetVested(ctx, addr, start, end) +} + +func (gw *Node) MsigGetVestingSchedule(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MsigVesting, error) { + if err := gw.limit(ctx, walletRateLimitTokens); err != nil { + return api.MsigVesting{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return api.MsigVesting{}, err + } + return gw.target.MsigGetVestingSchedule(ctx, addr, tsk) +} + +func (gw *Node) MsigGetPending(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.MsigTransaction, error) { + if err := gw.limit(ctx, walletRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.MsigGetPending(ctx, addr, tsk) +} + +func (gw *Node) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return address.Address{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return address.Undef, err + } + return gw.target.StateAccountKey(ctx, addr, tsk) +} + +func (gw *Node) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.DealCollateralBounds{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return api.DealCollateralBounds{}, err + } + return gw.target.StateDealProviderCollateralBounds(ctx, size, verified, tsk) +} + +func (gw *Node) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateGetActor(ctx, actor, tsk) +} + +func (gw *Node) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateListMiners(ctx, tsk) +} + +func (gw *Node) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return address.Address{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return address.Undef, err + } + return gw.target.StateLookupID(ctx, addr, tsk) +} + +func (gw *Node) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.MarketBalance{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return api.MarketBalance{}, err + } + return gw.target.StateMarketBalance(ctx, addr, tsk) +} + +func (gw *Node) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateMarketStorageDeal(ctx, dealId, tsk) +} + +func (gw *Node) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return network.VersionMax, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return network.VersionMax, err + } + return gw.target.StateNetworkVersion(ctx, tsk) +} + +func (gw *Node) StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if limit == api.LookbackNoLimit { + limit = gw.stateWaitLookbackLimit + } + if gw.stateWaitLookbackLimit != api.LookbackNoLimit && limit > gw.stateWaitLookbackLimit { + limit = gw.stateWaitLookbackLimit + } + if err := gw.checkTipsetKey(ctx, from); err != nil { + return nil, err + } + return gw.target.StateSearchMsg(ctx, from, msg, limit, allowReplaced) +} + +func (gw *Node) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if limit == api.LookbackNoLimit { + limit = gw.stateWaitLookbackLimit + } + if gw.stateWaitLookbackLimit != api.LookbackNoLimit && limit > gw.stateWaitLookbackLimit { + limit = gw.stateWaitLookbackLimit + } + return gw.target.StateWaitMsg(ctx, msg, confidence, limit, allowReplaced) +} + +func (gw *Node) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateReadState(ctx, actor, tsk) +} + +func (gw *Node) StateMinerPower(ctx context.Context, m address.Address, tsk types.TipSetKey) (*api.MinerPower, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateMinerPower(ctx, m, tsk) +} + +func (gw *Node) StateMinerFaults(ctx context.Context, m address.Address, tsk types.TipSetKey) (bitfield.BitField, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return bitfield.BitField{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return bitfield.BitField{}, err + } + return gw.target.StateMinerFaults(ctx, m, tsk) +} + +func (gw *Node) StateMinerRecoveries(ctx context.Context, m address.Address, tsk types.TipSetKey) (bitfield.BitField, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return bitfield.BitField{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return bitfield.BitField{}, err + } + return gw.target.StateMinerRecoveries(ctx, m, tsk) +} + +func (gw *Node) StateMinerInfo(ctx context.Context, m address.Address, tsk types.TipSetKey) (api.MinerInfo, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.MinerInfo{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return api.MinerInfo{}, err + } + return gw.target.StateMinerInfo(ctx, m, tsk) +} + +func (gw *Node) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) ([]api.Deadline, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateMinerDeadlines(ctx, m, tsk) +} + +func (gw *Node) StateMinerAvailableBalance(ctx context.Context, m address.Address, tsk types.TipSetKey) (types.BigInt, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return types.BigInt{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return types.BigInt{}, err + } + return gw.target.StateMinerAvailableBalance(ctx, m, tsk) +} + +func (gw *Node) StateMinerProvingDeadline(ctx context.Context, m address.Address, tsk types.TipSetKey) (*dline.Info, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateMinerProvingDeadline(ctx, m, tsk) +} + +func (gw *Node) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return abi.TokenAmount{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return abi.TokenAmount{}, err + } + return gw.target.StateCirculatingSupply(ctx, tsk) +} + +func (gw *Node) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateSectorGetInfo(ctx, maddr, n, tsk) +} + +func (gw *Node) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return nil, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return nil, err + } + return gw.target.StateVerifiedClientStatus(ctx, addr, tsk) +} + +func (gw *Node) StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return api.CirculatingSupply{}, err + } + if err := gw.checkTipsetKey(ctx, tsk); err != nil { + return api.CirculatingSupply{}, err + } + return gw.target.StateVMCirculatingSupplyInternal(ctx, tsk) +} + +func (gw *Node) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return false, err + } + return sigs.Verify(sig, k, msg) == nil, nil +} + +func (gw *Node) WalletBalance(ctx context.Context, k address.Address) (types.BigInt, error) { + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { + return types.BigInt{}, err + } + return gw.target.WalletBalance(ctx, k) +} diff --git a/node/rpc.go b/node/rpc.go index c454e39be..ccdb20e89 100644 --- a/node/rpc.go +++ b/node/rpc.go @@ -79,44 +79,7 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server rpcServer.Register("Filecoin", hnd) rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover") - // TODO: use reflect to automatically register all the eth aliases - rpcServer.AliasMethod("eth_accounts", "Filecoin.EthAccounts") - rpcServer.AliasMethod("eth_blockNumber", "Filecoin.EthBlockNumber") - rpcServer.AliasMethod("eth_getBlockTransactionCountByNumber", "Filecoin.EthGetBlockTransactionCountByNumber") - rpcServer.AliasMethod("eth_getBlockTransactionCountByHash", "Filecoin.EthGetBlockTransactionCountByHash") - - rpcServer.AliasMethod("eth_getBlockByHash", "Filecoin.EthGetBlockByHash") - rpcServer.AliasMethod("eth_getBlockByNumber", "Filecoin.EthGetBlockByNumber") - rpcServer.AliasMethod("eth_getTransactionByHash", "Filecoin.EthGetTransactionByHash") - rpcServer.AliasMethod("eth_getTransactionCount", "Filecoin.EthGetTransactionCount") - rpcServer.AliasMethod("eth_getTransactionReceipt", "Filecoin.EthGetTransactionReceipt") - rpcServer.AliasMethod("eth_getTransactionByBlockHashAndIndex", "Filecoin.EthGetTransactionByBlockHashAndIndex") - rpcServer.AliasMethod("eth_getTransactionByBlockNumberAndIndex", "Filecoin.EthGetTransactionByBlockNumberAndIndex") - - rpcServer.AliasMethod("eth_getCode", "Filecoin.EthGetCode") - rpcServer.AliasMethod("eth_getStorageAt", "Filecoin.EthGetStorageAt") - rpcServer.AliasMethod("eth_getBalance", "Filecoin.EthGetBalance") - rpcServer.AliasMethod("eth_chainId", "Filecoin.EthChainId") - rpcServer.AliasMethod("eth_feeHistory", "Filecoin.EthFeeHistory") - rpcServer.AliasMethod("eth_protocolVersion", "Filecoin.EthProtocolVersion") - rpcServer.AliasMethod("eth_maxPriorityFeePerGas", "Filecoin.EthMaxPriorityFeePerGas") - rpcServer.AliasMethod("eth_gasPrice", "Filecoin.EthGasPrice") - rpcServer.AliasMethod("eth_sendRawTransaction", "Filecoin.EthSendRawTransaction") - rpcServer.AliasMethod("eth_estimateGas", "Filecoin.EthEstimateGas") - rpcServer.AliasMethod("eth_call", "Filecoin.EthCall") - - rpcServer.AliasMethod("eth_getLogs", "Filecoin.EthGetLogs") - rpcServer.AliasMethod("eth_getFilterChanges", "Filecoin.EthGetFilterChanges") - rpcServer.AliasMethod("eth_getFilterLogs", "Filecoin.EthGetFilterLogs") - rpcServer.AliasMethod("eth_newFilter", "Filecoin.EthNewFilter") - rpcServer.AliasMethod("eth_newBlockFilter", "Filecoin.EthNewBlockFilter") - rpcServer.AliasMethod("eth_newPendingTransactionFilter", "Filecoin.EthNewPendingTransactionFilter") - rpcServer.AliasMethod("eth_uninstallFilter", "Filecoin.EthUninstallFilter") - rpcServer.AliasMethod("eth_subscribe", "Filecoin.EthSubscribe") - rpcServer.AliasMethod("eth_unsubscribe", "Filecoin.EthUnsubscribe") - - rpcServer.AliasMethod("net_version", "Filecoin.NetVersion") - rpcServer.AliasMethod("net_listening", "Filecoin.NetListening") + api.CrateEthRPCAliases(rpcServer) var handler http.Handler = rpcServer if permissioned {